269473047d747f7815af570197e4ef7322d3632cEvan Yan * CDDL HEADER START
269473047d747f7815af570197e4ef7322d3632cEvan Yan * The contents of this file are subject to the terms of the
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Common Development and Distribution License (the "License").
269473047d747f7815af570197e4ef7322d3632cEvan Yan * You may not use this file except in compliance with the License.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
269473047d747f7815af570197e4ef7322d3632cEvan Yan * See the License for the specific language governing permissions
269473047d747f7815af570197e4ef7322d3632cEvan Yan * and limitations under the License.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * When distributing Covered Code, include this CDDL HEADER in each
269473047d747f7815af570197e4ef7322d3632cEvan Yan * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * If applicable, add the following below this CDDL HEADER, with the
269473047d747f7815af570197e4ef7322d3632cEvan Yan * fields enclosed by brackets "[]" replaced with your own identifying
269473047d747f7815af570197e4ef7322d3632cEvan Yan * information: Portions Copyright [yyyy] [name of copyright owner]
269473047d747f7815af570197e4ef7322d3632cEvan Yan * CDDL HEADER END
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Use is subject to license terms.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Define long options for command line.
269473047d747f7815af570197e4ef7322d3632cEvan Yan { 0, 0, 0, 0 }
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Local functions.
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic void usage(void);
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic int daemonize(void);
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic void init_signals(void);
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic void shutdown_daemon(void);
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Global variables.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * The hotplug daemon is designed to be a background daemon
269473047d747f7815af570197e4ef7322d3632cEvan Yan * controlled by SMF. So by default it will daemonize and
269473047d747f7815af570197e4ef7322d3632cEvan Yan * do some coordination with its parent process in order to
269473047d747f7815af570197e4ef7322d3632cEvan Yan * indicate proper success or failure back to SMF. And all
269473047d747f7815af570197e4ef7322d3632cEvan Yan * output will be sent to syslog.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * But if given the '-d' command line option, it will instead
269473047d747f7815af570197e4ef7322d3632cEvan Yan * run in the foreground in a standalone, debug mode. Errors
269473047d747f7815af570197e4ef7322d3632cEvan Yan * and additional debug messages will be printed to the controlling
269473047d747f7815af570197e4ef7322d3632cEvan Yan * terminal instead of to syslog.
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Check privileges */
269473047d747f7815af570197e4ef7322d3632cEvan Yan "(All privileges are required.)\n");
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (-1);
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Process options */
269473047d747f7815af570197e4ef7322d3632cEvan Yan while ((opt = getopt_clip(argc, argv, "dV?", lopts, NULL)) != -1) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (0);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (0);
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr, "Unrecognized option '%c'.\n",
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (-1);
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Initialize semaphore for daemon shutdown */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (sema_init(&signal_sem, 1, USYNC_THREAD, NULL) != 0)
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Initialize signal handling */
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Daemonize, if not in DEBUG mode */
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Initialize door service */
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Daemon initialized */
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Note that daemon is running */
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Wait for shutdown signal */
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (0);
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Print a brief usage synopsis for the command line options.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * check_privileges()
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Check if the current process has enough privileges
269473047d747f7815af570197e4ef7322d3632cEvan Yan * to run the daemon. Note that all privileges are
269473047d747f7815af570197e4ef7322d3632cEvan Yan * required in order for RCM interactions to work.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * daemonize()
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Fork the daemon process into the background, and detach from
269473047d747f7815af570197e4ef7322d3632cEvan Yan * the controlling terminal. Setup a shared pipe that will later
269473047d747f7815af570197e4ef7322d3632cEvan Yan * be used to report startup status to the parent process.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Temporarily block all signals. They will remain blocked in
269473047d747f7815af570197e4ef7322d3632cEvan Yan * the parent, but will be unblocked in the child once it has
269473047d747f7815af570197e4ef7322d3632cEvan Yan * notified the parent of its startup status.
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Create the shared pipe */
269473047d747f7815af570197e4ef7322d3632cEvan Yan log_err("Cannot create pipe (%s)\n", strerror(errno));
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Fork the daemon process */
269473047d747f7815af570197e4ef7322d3632cEvan Yan log_err("Cannot fork daemon process (%s)\n", strerror(errno));
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Parent: waits for exit status from child. */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (read(pfds[0], &status, sizeof (status)) == sizeof (status))
269473047d747f7815af570197e4ef7322d3632cEvan Yan if ((waitpid(pid, &status, 0) == pid) && WIFEXITED(status))
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Child continues... */
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Detach from controlling terminal */
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Use syslog for future messages */
269473047d747f7815af570197e4ef7322d3632cEvan Yan * init_signals()
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Initialize signal handling.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * signal_handler()
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Most signals cause the hotplug daemon to shut down.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Shutdown is triggered using a semaphore to wake up
269473047d747f7815af570197e4ef7322d3632cEvan Yan * the main thread for a clean exit.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Except SIGPIPE is used to coordinate between the parent
269473047d747f7815af570197e4ef7322d3632cEvan Yan * and child processes when the daemon first starts.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * shutdown_daemon()
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Perform a clean shutdown of the daemon.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * log_err()
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Display an error message. Use syslog if in daemon
269473047d747f7815af570197e4ef7322d3632cEvan Yan * mode, otherwise print to stderr when in debug mode.
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*PRINTFLIKE1*/
269473047d747f7815af570197e4ef7322d3632cEvan Yan * log_info()
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Display an information message. Use syslog if in daemon
269473047d747f7815af570197e4ef7322d3632cEvan Yan * mode, otherwise print to stdout when in debug mode.
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*PRINTFLIKE1*/
269473047d747f7815af570197e4ef7322d3632cEvan Yan * dprintf()
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Print a debug tracing statement. Only works in debug
269473047d747f7815af570197e4ef7322d3632cEvan Yan * mode, and always prints to stdout.
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*PRINTFLIKE1*/