fmd_main.c revision fee9b58de523a707cd144b0b6fe4dc12b571ec83
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * CDDL HEADER START
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner * The contents of this file are subject to the terms of the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Common Development and Distribution License (the "License").
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * You may not use this file except in compliance with the License.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * See the License for the specific language governing permissions
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * and limitations under the License.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * When distributing Covered Code, include this CDDL HEADER in each
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If applicable, add the following below this CDDL HEADER, with the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * fields enclosed by brackets "[]" replaced with your own identifying
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * information: Portions Copyright [yyyy] [name of copyright owner]
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * CDDL HEADER END
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Use is subject to license terms.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma ident "%Z%%M% %I% %E% SMI"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * For DEBUG builds, we define a set of hooks for libumem that provide useful
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * default settings for the allocator's debugging facilities.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinconst char *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinconst char *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* DEBUG */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * We use a two-phase algorithm for becoming a daemon because we want the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * daemon process (the child) to do the work of becoming MT-hot and opening our
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * event transport. Since these operations can fail and need to result in the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * daemon failing to start, the parent must wait until fmd_run() completes to
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * know whether it can return zero or non-zero status to the invoking command.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The parent waits on a pipe inside this function to read the exit status.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The child gets the write-end of the pipe returned by daemonize_init() and
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * then fmd_run() uses the pipe to set the exit status and detach the parent.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Set our per-process core file path to leave core files in our
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * var/fm/fmd directory, named after the PID to aid in debugging,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * and make sure that there is no restriction on core file size.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "%s/var/fm/fmd/core.%s.%%p", fmd.d_rootdir, fmd.d_pname);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (void) core_set_process_path(path, strlen(path) + 1, fmd.d_pid);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Reset all of our privilege sets to the minimum set of required
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * privileges. We continue to run as root so that files we create
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * such as logs and checkpoints are secured in the /var filesystem.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (__init_daemon_priv(PU_RESETGROUPS | PU_LIMITPRIVS | PU_INHERITPRIVS,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin 0, 0, /* run as uid 0 and gid 0 */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PRIV_FILE_DAC_EXECUTE, PRIV_FILE_DAC_READ, PRIV_FILE_DAC_SEARCH,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin PRIV_SYS_DEVICES, PRIV_SYS_RES_CONFIG, PRIV_NET_PRIVADDR,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fmd_error(EFMD_EXIT, "additional privileges required to run\n");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Block all signals prior to the fork and leave them blocked in the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * parent so we don't get in a situation where the parent gets SIGINT
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * and returns non-zero exit status and the child is actually running.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * In the child, restore the signal mask once we've done our setsid().
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fmd_error(EFMD_EXIT, "failed to create pipe for daemonize");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fmd_error(EFMD_EXIT, "failed to fork into background");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If we're the parent process, wait for either the child to send us
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the appropriate exit status over the pipe or for the read to fail
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * (presumably with 0 for EOF if our child terminated abnormally).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If the read fails, exit with either the child's exit status if it
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * exited or with FMD_EXIT_ERROR if it died from a fatal signal.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pid != 0) {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (read(pfds[0], &status, sizeof (status)) == sizeof (status))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (waitpid(pid, &status, 0) == pid && WIFEXITED(status))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "Usage: %s [-V] [-f file] [-o opt=val] [-R dir]\n", arg0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Parse the command-line once to validate all options and retrieve
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * any overrides for our configuration file and root directory.
opt_V++;
if (opt_V) {
#ifdef DEBUG
return (FMD_EXIT_SUCCESS);
return (FMD_EXIT_USAGE);
(void) fmd_stresc2chr(++p);
return (FMD_EXIT_USAGE);
return (FMD_EXIT_SUCCESS);
return (FMD_EXIT_SUCCESS);