xref: /onnv-gate/usr/src/cmd/ndmpd/ndmp/ndmpd_main.c (revision 13051:60ed88a16f55)
17917SReza.Sabdar@Sun.COM /*
212186SJanice.Chang@Sun.COM  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
37917SReza.Sabdar@Sun.COM  */
47917SReza.Sabdar@Sun.COM 
57917SReza.Sabdar@Sun.COM /*
67917SReza.Sabdar@Sun.COM  * BSD 3 Clause License
77917SReza.Sabdar@Sun.COM  *
87917SReza.Sabdar@Sun.COM  * Copyright (c) 2007, The Storage Networking Industry Association.
97917SReza.Sabdar@Sun.COM  *
107917SReza.Sabdar@Sun.COM  * Redistribution and use in source and binary forms, with or without
117917SReza.Sabdar@Sun.COM  * modification, are permitted provided that the following conditions
127917SReza.Sabdar@Sun.COM  * are met:
137917SReza.Sabdar@Sun.COM  * 	- Redistributions of source code must retain the above copyright
147917SReza.Sabdar@Sun.COM  *	  notice, this list of conditions and the following disclaimer.
157917SReza.Sabdar@Sun.COM  *
167917SReza.Sabdar@Sun.COM  * 	- Redistributions in binary form must reproduce the above copyright
177917SReza.Sabdar@Sun.COM  *	  notice, this list of conditions and the following disclaimer in
187917SReza.Sabdar@Sun.COM  *	  the documentation and/or other materials provided with the
197917SReza.Sabdar@Sun.COM  *	  distribution.
207917SReza.Sabdar@Sun.COM  *
217917SReza.Sabdar@Sun.COM  *	- Neither the name of The Storage Networking Industry Association (SNIA)
227917SReza.Sabdar@Sun.COM  *	  nor the names of its contributors may be used to endorse or promote
237917SReza.Sabdar@Sun.COM  *	  products derived from this software without specific prior written
247917SReza.Sabdar@Sun.COM  *	  permission.
257917SReza.Sabdar@Sun.COM  *
267917SReza.Sabdar@Sun.COM  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
277917SReza.Sabdar@Sun.COM  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
287917SReza.Sabdar@Sun.COM  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
297917SReza.Sabdar@Sun.COM  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
307917SReza.Sabdar@Sun.COM  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
317917SReza.Sabdar@Sun.COM  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
327917SReza.Sabdar@Sun.COM  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
337917SReza.Sabdar@Sun.COM  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
347917SReza.Sabdar@Sun.COM  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
357917SReza.Sabdar@Sun.COM  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
367917SReza.Sabdar@Sun.COM  * POSSIBILITY OF SUCH DAMAGE.
377917SReza.Sabdar@Sun.COM  */
387917SReza.Sabdar@Sun.COM /* Copyright (c) 1996, 1997 PDC, Network Appliance. All Rights Reserved */
397917SReza.Sabdar@Sun.COM 
407917SReza.Sabdar@Sun.COM #include <errno.h>
417917SReza.Sabdar@Sun.COM #include <signal.h>
427917SReza.Sabdar@Sun.COM #include <libgen.h>
437917SReza.Sabdar@Sun.COM #include <libscf.h>
447917SReza.Sabdar@Sun.COM #include <libintl.h>
457917SReza.Sabdar@Sun.COM #include <sys/wait.h>
467917SReza.Sabdar@Sun.COM #include <zone.h>
477917SReza.Sabdar@Sun.COM #include <tsol/label.h>
487917SReza.Sabdar@Sun.COM #include <dlfcn.h>
497917SReza.Sabdar@Sun.COM #include "ndmpd.h"
507917SReza.Sabdar@Sun.COM #include "ndmpd_common.h"
517917SReza.Sabdar@Sun.COM 
527917SReza.Sabdar@Sun.COM /* zfs library handle & mutex */
537917SReza.Sabdar@Sun.COM libzfs_handle_t *zlibh;
547917SReza.Sabdar@Sun.COM mutex_t	zlib_mtx;
557917SReza.Sabdar@Sun.COM void *mod_plp;
567917SReza.Sabdar@Sun.COM 
577917SReza.Sabdar@Sun.COM static void ndmpd_sig_handler(int sig);
587917SReza.Sabdar@Sun.COM 
597917SReza.Sabdar@Sun.COM typedef struct ndmpd {
607917SReza.Sabdar@Sun.COM 	int s_shutdown_flag;	/* Fields for shutdown control */
617917SReza.Sabdar@Sun.COM 	int s_sigval;
627917SReza.Sabdar@Sun.COM } ndmpd_t;
637917SReza.Sabdar@Sun.COM 
647917SReza.Sabdar@Sun.COM ndmpd_t	ndmpd;
657917SReza.Sabdar@Sun.COM 
667917SReza.Sabdar@Sun.COM 
677917SReza.Sabdar@Sun.COM /*
687917SReza.Sabdar@Sun.COM  * Load and initialize the plug-in module
697917SReza.Sabdar@Sun.COM  */
707917SReza.Sabdar@Sun.COM static int
mod_init()717917SReza.Sabdar@Sun.COM mod_init()
727917SReza.Sabdar@Sun.COM {
737917SReza.Sabdar@Sun.COM 	char *plname;
747917SReza.Sabdar@Sun.COM 	ndmp_plugin_t *(*plugin_init)(int);
757917SReza.Sabdar@Sun.COM 
767917SReza.Sabdar@Sun.COM 	ndmp_pl = NULL;
777917SReza.Sabdar@Sun.COM 	if ((plname = ndmpd_get_prop(NDMP_PLUGIN_PATH)) == NULL)
787917SReza.Sabdar@Sun.COM 		return (0);
797917SReza.Sabdar@Sun.COM 
807917SReza.Sabdar@Sun.COM 	if ((mod_plp = dlopen(plname, RTLD_LOCAL | RTLD_NOW)) == NULL) {
817917SReza.Sabdar@Sun.COM 		syslog(LOG_ERR, "Error loading the plug-in %s", plname);
827917SReza.Sabdar@Sun.COM 		return (0);
837917SReza.Sabdar@Sun.COM 	}
847917SReza.Sabdar@Sun.COM 
857917SReza.Sabdar@Sun.COM 	plugin_init = (ndmp_plugin_t *(*)(int))dlsym(mod_plp, "_ndmp_init");
867917SReza.Sabdar@Sun.COM 	if (plugin_init == NULL) {
877917SReza.Sabdar@Sun.COM 		(void) dlclose(mod_plp);
887917SReza.Sabdar@Sun.COM 		return (0);
897917SReza.Sabdar@Sun.COM 	}
907917SReza.Sabdar@Sun.COM 	if ((ndmp_pl = plugin_init(NDMP_PLUGIN_VERSION)) == NULL) {
917917SReza.Sabdar@Sun.COM 		syslog(LOG_ERR, "Error loading the plug-in %s", plname);
927917SReza.Sabdar@Sun.COM 		return (-1);
937917SReza.Sabdar@Sun.COM 	}
947917SReza.Sabdar@Sun.COM 	return (0);
957917SReza.Sabdar@Sun.COM }
967917SReza.Sabdar@Sun.COM 
977917SReza.Sabdar@Sun.COM /*
987917SReza.Sabdar@Sun.COM  * Unload
997917SReza.Sabdar@Sun.COM  */
1007917SReza.Sabdar@Sun.COM static void
mod_fini()1017917SReza.Sabdar@Sun.COM mod_fini()
1027917SReza.Sabdar@Sun.COM {
1037917SReza.Sabdar@Sun.COM 	if (ndmp_pl == NULL)
1047917SReza.Sabdar@Sun.COM 		return;
1057917SReza.Sabdar@Sun.COM 
1067917SReza.Sabdar@Sun.COM 	void (*plugin_fini)(ndmp_plugin_t *);
1077917SReza.Sabdar@Sun.COM 
1087917SReza.Sabdar@Sun.COM 	plugin_fini = (void (*)(ndmp_plugin_t *))dlsym(mod_plp, "_ndmp_fini");
1097917SReza.Sabdar@Sun.COM 	if (plugin_fini == NULL) {
1107917SReza.Sabdar@Sun.COM 		(void) dlclose(mod_plp);
1117917SReza.Sabdar@Sun.COM 		return;
1127917SReza.Sabdar@Sun.COM 	}
1137917SReza.Sabdar@Sun.COM 	plugin_fini(ndmp_pl);
1147917SReza.Sabdar@Sun.COM 	(void) dlclose(mod_plp);
1157917SReza.Sabdar@Sun.COM }
1167917SReza.Sabdar@Sun.COM 
1177917SReza.Sabdar@Sun.COM static void
daemonize_init(char * arg)1187917SReza.Sabdar@Sun.COM daemonize_init(char *arg)
1197917SReza.Sabdar@Sun.COM {
1207917SReza.Sabdar@Sun.COM 	sigset_t set, oset;
1217917SReza.Sabdar@Sun.COM 	pid_t pid;
12211537SCasper.Dik@Sun.COM 	priv_set_t *pset = priv_allocset();
1237917SReza.Sabdar@Sun.COM 
1247917SReza.Sabdar@Sun.COM 	/*
1257917SReza.Sabdar@Sun.COM 	 * Set effective sets privileges to 'least' required. If fails, send
1267917SReza.Sabdar@Sun.COM 	 * error messages to log file and proceed.
1277917SReza.Sabdar@Sun.COM 	 */
12811537SCasper.Dik@Sun.COM 	if (pset != NULL) {
12911537SCasper.Dik@Sun.COM 		priv_basicset(pset);
13011537SCasper.Dik@Sun.COM 		(void) priv_addset(pset, PRIV_PROC_AUDIT);
13111537SCasper.Dik@Sun.COM 		(void) priv_addset(pset, PRIV_PROC_SETID);
13211537SCasper.Dik@Sun.COM 		(void) priv_addset(pset, PRIV_PROC_OWNER);
13311537SCasper.Dik@Sun.COM 		(void) priv_addset(pset, PRIV_FILE_CHOWN);
13411537SCasper.Dik@Sun.COM 		(void) priv_addset(pset, PRIV_FILE_CHOWN_SELF);
13511537SCasper.Dik@Sun.COM 		(void) priv_addset(pset, PRIV_FILE_DAC_READ);
13611537SCasper.Dik@Sun.COM 		(void) priv_addset(pset, PRIV_FILE_DAC_SEARCH);
13711537SCasper.Dik@Sun.COM 		(void) priv_addset(pset, PRIV_FILE_DAC_WRITE);
13811537SCasper.Dik@Sun.COM 		(void) priv_addset(pset, PRIV_FILE_OWNER);
13911537SCasper.Dik@Sun.COM 		(void) priv_addset(pset, PRIV_FILE_SETID);
14011537SCasper.Dik@Sun.COM 		(void) priv_addset(pset, PRIV_SYS_LINKDIR);
14111537SCasper.Dik@Sun.COM 		(void) priv_addset(pset, PRIV_SYS_DEVICES);
14211537SCasper.Dik@Sun.COM 		(void) priv_addset(pset, PRIV_SYS_MOUNT);
14311537SCasper.Dik@Sun.COM 		(void) priv_addset(pset, PRIV_SYS_CONFIG);
14411537SCasper.Dik@Sun.COM 	}
14511537SCasper.Dik@Sun.COM 
14611537SCasper.Dik@Sun.COM 	if (pset == NULL || setppriv(PRIV_SET, PRIV_EFFECTIVE, pset) != 0) {
14711537SCasper.Dik@Sun.COM 		syslog(LOG_ERR, "Failed to set least required privileges to "
14811537SCasper.Dik@Sun.COM 		    "the service.");
14911537SCasper.Dik@Sun.COM 	}
15011537SCasper.Dik@Sun.COM 	priv_freeset(pset);
1517917SReza.Sabdar@Sun.COM 
1527917SReza.Sabdar@Sun.COM 	/*
1537917SReza.Sabdar@Sun.COM 	 * Block all signals prior to the fork and leave them blocked in the
1547917SReza.Sabdar@Sun.COM 	 * parent so we don't get in a situation where the parent gets SIGINT
1557917SReza.Sabdar@Sun.COM 	 * and returns non-zero exit status and the child is actually running.
1567917SReza.Sabdar@Sun.COM 	 * In the child, restore the signal mask once we've done our setsid().
1577917SReza.Sabdar@Sun.COM 	 */
1587917SReza.Sabdar@Sun.COM 	(void) sigfillset(&set);
1597917SReza.Sabdar@Sun.COM 	(void) sigdelset(&set, SIGABRT);
1607917SReza.Sabdar@Sun.COM 	(void) sigprocmask(SIG_BLOCK, &set, &oset);
1617917SReza.Sabdar@Sun.COM 
1627917SReza.Sabdar@Sun.COM 	if ((pid = fork()) == -1) {
1637917SReza.Sabdar@Sun.COM 		openlog(arg, LOG_PID | LOG_NDELAY, LOG_DAEMON);
1647917SReza.Sabdar@Sun.COM 		syslog(LOG_ERR, "Failed to start process in background.");
1657917SReza.Sabdar@Sun.COM 		exit(SMF_EXIT_ERR_CONFIG);
1667917SReza.Sabdar@Sun.COM 	}
1677917SReza.Sabdar@Sun.COM 
1687917SReza.Sabdar@Sun.COM 	/* If we're the parent process, exit. */
1697917SReza.Sabdar@Sun.COM 	if (pid != 0) {
1707917SReza.Sabdar@Sun.COM 		_exit(0);
1717917SReza.Sabdar@Sun.COM 	}
1727917SReza.Sabdar@Sun.COM 	(void) setsid();
1737917SReza.Sabdar@Sun.COM 	(void) sigprocmask(SIG_SETMASK, &oset, NULL);
1747917SReza.Sabdar@Sun.COM 	(void) chdir("/");
1757917SReza.Sabdar@Sun.COM 	(void) umask(0);
1767917SReza.Sabdar@Sun.COM }
1777917SReza.Sabdar@Sun.COM 
1787917SReza.Sabdar@Sun.COM static void
daemonize_fini(void)1797917SReza.Sabdar@Sun.COM daemonize_fini(void)
1807917SReza.Sabdar@Sun.COM {
1817917SReza.Sabdar@Sun.COM 	int fd;
1827917SReza.Sabdar@Sun.COM 
1837917SReza.Sabdar@Sun.COM 	if ((fd = open("/dev/null", O_RDWR)) >= 0) {
1847917SReza.Sabdar@Sun.COM 		(void) fcntl(fd, F_DUP2FD, STDIN_FILENO);
1857917SReza.Sabdar@Sun.COM 		(void) fcntl(fd, F_DUP2FD, STDOUT_FILENO);
1867917SReza.Sabdar@Sun.COM 		(void) fcntl(fd, F_DUP2FD, STDERR_FILENO);
1877917SReza.Sabdar@Sun.COM 		(void) close(fd);
1887917SReza.Sabdar@Sun.COM 	}
1897917SReza.Sabdar@Sun.COM }
1907917SReza.Sabdar@Sun.COM 
1917917SReza.Sabdar@Sun.COM /*
1927917SReza.Sabdar@Sun.COM  * main
1937917SReza.Sabdar@Sun.COM  *
1947917SReza.Sabdar@Sun.COM  * The main NDMP daemon function
1957917SReza.Sabdar@Sun.COM  *
1967917SReza.Sabdar@Sun.COM  * Parameters:
1977917SReza.Sabdar@Sun.COM  *   argc (input) - the argument count
1987917SReza.Sabdar@Sun.COM  *   argv (input) - command line options
1997917SReza.Sabdar@Sun.COM  *
2007917SReza.Sabdar@Sun.COM  * Returns:
2017917SReza.Sabdar@Sun.COM  *   0
2027917SReza.Sabdar@Sun.COM  */
2037917SReza.Sabdar@Sun.COM int
main(int argc,char * argv[])2047917SReza.Sabdar@Sun.COM main(int argc, char *argv[])
2057917SReza.Sabdar@Sun.COM {
2067917SReza.Sabdar@Sun.COM 	char c;
2077917SReza.Sabdar@Sun.COM 	struct sigaction act;
2087917SReza.Sabdar@Sun.COM 	sigset_t set;
2097917SReza.Sabdar@Sun.COM 	void *arg = 0;
2107917SReza.Sabdar@Sun.COM 
2117917SReza.Sabdar@Sun.COM 	openlog(argv[0], LOG_PID | LOG_NDELAY, LOG_DAEMON);
2127917SReza.Sabdar@Sun.COM 
2137917SReza.Sabdar@Sun.COM 	/*
2147917SReza.Sabdar@Sun.COM 	 * Check for existing ndmpd door server (make sure ndmpd is not already
2157917SReza.Sabdar@Sun.COM 	 * running)
2167917SReza.Sabdar@Sun.COM 	 */
2177917SReza.Sabdar@Sun.COM 	if (ndmp_door_check()) {
2187917SReza.Sabdar@Sun.COM 		/* ndmpd is already running, exit. */
2197917SReza.Sabdar@Sun.COM 		return (0);
2207917SReza.Sabdar@Sun.COM 	}
2217917SReza.Sabdar@Sun.COM 
2227917SReza.Sabdar@Sun.COM 	/* load ENVs */
2237917SReza.Sabdar@Sun.COM 	if (ndmpd_load_prop()) {
2247917SReza.Sabdar@Sun.COM 		syslog(LOG_ERR,
2257917SReza.Sabdar@Sun.COM 		    "%s SMF properties initialization failed.", argv[0]);
2267917SReza.Sabdar@Sun.COM 		exit(SMF_EXIT_ERR_CONFIG);
2277917SReza.Sabdar@Sun.COM 	}
2287917SReza.Sabdar@Sun.COM 
2297917SReza.Sabdar@Sun.COM 	/* Global zone check */
2307917SReza.Sabdar@Sun.COM 	if (getzoneid() != GLOBAL_ZONEID) {
2317917SReza.Sabdar@Sun.COM 		syslog(LOG_ERR, "Local zone not supported.");
2327917SReza.Sabdar@Sun.COM 		exit(SMF_EXIT_ERR_FATAL);
2337917SReza.Sabdar@Sun.COM 	}
2347917SReza.Sabdar@Sun.COM 
2357917SReza.Sabdar@Sun.COM 	/* Trusted Solaris check */
2367917SReza.Sabdar@Sun.COM 	if (is_system_labeled()) {
2377917SReza.Sabdar@Sun.COM 		syslog(LOG_ERR, "Trusted Solaris not supported.");
2387917SReza.Sabdar@Sun.COM 		exit(SMF_EXIT_ERR_FATAL);
2397917SReza.Sabdar@Sun.COM 	}
2407917SReza.Sabdar@Sun.COM 
2417917SReza.Sabdar@Sun.COM 	opterr = 0;
2427917SReza.Sabdar@Sun.COM 	while ((c = getopt(argc, argv, ":d")) != -1) {
2437917SReza.Sabdar@Sun.COM 		switch (c) {
2447917SReza.Sabdar@Sun.COM 		case 'd':
2457917SReza.Sabdar@Sun.COM 			(void) set_debug_level(TRUE);
2467917SReza.Sabdar@Sun.COM 			break;
2477917SReza.Sabdar@Sun.COM 		default:
2487917SReza.Sabdar@Sun.COM 			syslog(LOG_ERR, "%s: Invalid option -%c.",
2497917SReza.Sabdar@Sun.COM 			    argv[0], optopt);
2507917SReza.Sabdar@Sun.COM 			syslog(LOG_ERR, "Usage: %s [-d]", argv[0]);
2517917SReza.Sabdar@Sun.COM 			exit(SMF_EXIT_ERR_CONFIG);
2527917SReza.Sabdar@Sun.COM 		}
2537917SReza.Sabdar@Sun.COM 
2547917SReza.Sabdar@Sun.COM 	}
2557917SReza.Sabdar@Sun.COM 
2567917SReza.Sabdar@Sun.COM 	closelog();
2577917SReza.Sabdar@Sun.COM 	/*
2587917SReza.Sabdar@Sun.COM 	 * close any open file descriptors which are greater
2597917SReza.Sabdar@Sun.COM 	 * than STDERR_FILENO
2607917SReza.Sabdar@Sun.COM 	 */
2617917SReza.Sabdar@Sun.COM 	closefrom(STDERR_FILENO + 1);
2627917SReza.Sabdar@Sun.COM 
2637917SReza.Sabdar@Sun.COM 	/* set up signal handler */
2647917SReza.Sabdar@Sun.COM 	(void) sigfillset(&set);
2657917SReza.Sabdar@Sun.COM 	(void) sigdelset(&set, SIGABRT); /* always unblocked for ASSERT() */
2667917SReza.Sabdar@Sun.COM 	(void) sigfillset(&act.sa_mask);
2677917SReza.Sabdar@Sun.COM 	act.sa_handler = ndmpd_sig_handler;
2687917SReza.Sabdar@Sun.COM 	act.sa_flags = 0;
2697917SReza.Sabdar@Sun.COM 
2707917SReza.Sabdar@Sun.COM 	(void) sigaction(SIGTERM, &act, NULL);
2717917SReza.Sabdar@Sun.COM 	(void) sigaction(SIGHUP, &act, NULL);
2727917SReza.Sabdar@Sun.COM 	(void) sigaction(SIGINT, &act, NULL);
2737917SReza.Sabdar@Sun.COM 	(void) sigaction(SIGUSR1, &act, NULL);
2749012SReza.Sabdar@Sun.COM 	(void) sigaction(SIGPIPE, &act, NULL);
2757917SReza.Sabdar@Sun.COM 	(void) sigdelset(&set, SIGTERM);
2767917SReza.Sabdar@Sun.COM 	(void) sigdelset(&set, SIGHUP);
2777917SReza.Sabdar@Sun.COM 	(void) sigdelset(&set, SIGINT);
2787917SReza.Sabdar@Sun.COM 	(void) sigdelset(&set, SIGUSR1);
2799012SReza.Sabdar@Sun.COM 	(void) sigdelset(&set, SIGPIPE);
2807917SReza.Sabdar@Sun.COM 
2817917SReza.Sabdar@Sun.COM 	(void) daemonize_init(argv[0]);
2827917SReza.Sabdar@Sun.COM 
2837917SReza.Sabdar@Sun.COM 	openlog(argv[0], LOG_PID | LOG_NDELAY, LOG_DAEMON);
2847917SReza.Sabdar@Sun.COM 	(void) mutex_init(&log_lock, 0, NULL);
28512186SJanice.Chang@Sun.COM 	(void) mutex_init(&ndmpd_zfs_fd_lock, 0, NULL);
2867917SReza.Sabdar@Sun.COM 
2877917SReza.Sabdar@Sun.COM 	if (mod_init() != 0) {
2887917SReza.Sabdar@Sun.COM 		syslog(LOG_ERR, "Failed to load the plugin module.");
2897917SReza.Sabdar@Sun.COM 		exit(SMF_EXIT_ERR_CONFIG);
2907917SReza.Sabdar@Sun.COM 	}
2917917SReza.Sabdar@Sun.COM 
2927917SReza.Sabdar@Sun.COM 	/* libzfs init */
2937917SReza.Sabdar@Sun.COM 	if ((zlibh = libzfs_init()) == NULL) {
2947917SReza.Sabdar@Sun.COM 		syslog(LOG_ERR, "Failed to initialize ZFS library.");
2957917SReza.Sabdar@Sun.COM 		exit(SMF_EXIT_ERR_CONFIG);
2967917SReza.Sabdar@Sun.COM 	}
2977917SReza.Sabdar@Sun.COM 
2987917SReza.Sabdar@Sun.COM 	/* initialize and start the door server */
2997917SReza.Sabdar@Sun.COM 	if (ndmp_door_init()) {
3007917SReza.Sabdar@Sun.COM 		syslog(LOG_ERR, "Can not start ndmpd door server.");
3017917SReza.Sabdar@Sun.COM 		exit(SMF_EXIT_ERR_CONFIG);
3027917SReza.Sabdar@Sun.COM 	}
3037917SReza.Sabdar@Sun.COM 
304*13051SJanice.Chang@Sun.COM 	if (tlm_init() == -1) {
305*13051SJanice.Chang@Sun.COM 		syslog(LOG_ERR, "Failed to initialize tape manager.");
306*13051SJanice.Chang@Sun.COM 		exit(SMF_EXIT_ERR_CONFIG);
307*13051SJanice.Chang@Sun.COM 	}
3087917SReza.Sabdar@Sun.COM 
3097917SReza.Sabdar@Sun.COM 	/*
3107917SReza.Sabdar@Sun.COM 	 * Prior to this point, we are single-threaded. We will be
3117917SReza.Sabdar@Sun.COM 	 * multi-threaded from this point on.
3127917SReza.Sabdar@Sun.COM 	 */
3137917SReza.Sabdar@Sun.COM 	(void) pthread_create(NULL, NULL, (funct_t)ndmpd_main,
3147917SReza.Sabdar@Sun.COM 	    (void *)&arg);
3157917SReza.Sabdar@Sun.COM 
3167917SReza.Sabdar@Sun.COM 	while (!ndmpd.s_shutdown_flag) {
3177917SReza.Sabdar@Sun.COM 		(void) sigsuspend(&set);
3187917SReza.Sabdar@Sun.COM 
3197917SReza.Sabdar@Sun.COM 		switch (ndmpd.s_sigval) {
3207917SReza.Sabdar@Sun.COM 		case 0:
3217917SReza.Sabdar@Sun.COM 			break;
3227917SReza.Sabdar@Sun.COM 
3239012SReza.Sabdar@Sun.COM 		case SIGPIPE:
3249012SReza.Sabdar@Sun.COM 			break;
3259012SReza.Sabdar@Sun.COM 
3267917SReza.Sabdar@Sun.COM 		case SIGHUP:
3277917SReza.Sabdar@Sun.COM 			/* Refresh SMF properties */
3287917SReza.Sabdar@Sun.COM 			if (ndmpd_load_prop())
3297917SReza.Sabdar@Sun.COM 				syslog(LOG_ERR,
3307917SReza.Sabdar@Sun.COM 				    "Service properties initialization "
3317917SReza.Sabdar@Sun.COM 				    "failed.");
3327917SReza.Sabdar@Sun.COM 			break;
3337917SReza.Sabdar@Sun.COM 
3347917SReza.Sabdar@Sun.COM 		default:
3357917SReza.Sabdar@Sun.COM 			/*
3367917SReza.Sabdar@Sun.COM 			 * Typically SIGINT or SIGTERM.
3377917SReza.Sabdar@Sun.COM 			 */
3387917SReza.Sabdar@Sun.COM 			ndmpd.s_shutdown_flag = 1;
3397917SReza.Sabdar@Sun.COM 			break;
3407917SReza.Sabdar@Sun.COM 		}
3417917SReza.Sabdar@Sun.COM 
3427917SReza.Sabdar@Sun.COM 		ndmpd.s_sigval = 0;
3437917SReza.Sabdar@Sun.COM 	}
3447917SReza.Sabdar@Sun.COM 
34512186SJanice.Chang@Sun.COM 	(void) mutex_destroy(&ndmpd_zfs_fd_lock);
3467917SReza.Sabdar@Sun.COM 	(void) mutex_destroy(&log_lock);
3477917SReza.Sabdar@Sun.COM 	libzfs_fini(zlibh);
3487917SReza.Sabdar@Sun.COM 	mod_fini();
3497917SReza.Sabdar@Sun.COM 	ndmp_door_fini();
3507917SReza.Sabdar@Sun.COM 	daemonize_fini();
3517917SReza.Sabdar@Sun.COM 	return (SMF_EXIT_OK);
3527917SReza.Sabdar@Sun.COM }
3537917SReza.Sabdar@Sun.COM 
3547917SReza.Sabdar@Sun.COM static void
ndmpd_sig_handler(int sig)3557917SReza.Sabdar@Sun.COM ndmpd_sig_handler(int sig)
3567917SReza.Sabdar@Sun.COM {
3577917SReza.Sabdar@Sun.COM 	if (ndmpd.s_sigval == 0)
3587917SReza.Sabdar@Sun.COM 		ndmpd.s_sigval = sig;
3597917SReza.Sabdar@Sun.COM }
3607917SReza.Sabdar@Sun.COM 
3617917SReza.Sabdar@Sun.COM /*
3627917SReza.Sabdar@Sun.COM  * Enable libumem debugging by default on DEBUG builds.
3637917SReza.Sabdar@Sun.COM  */
3647917SReza.Sabdar@Sun.COM #ifdef DEBUG
3657917SReza.Sabdar@Sun.COM const char *
_umem_debug_init(void)3667917SReza.Sabdar@Sun.COM _umem_debug_init(void)
3677917SReza.Sabdar@Sun.COM {
3687917SReza.Sabdar@Sun.COM 	return ("default,verbose"); /* $UMEM_DEBUG setting */
3697917SReza.Sabdar@Sun.COM }
3707917SReza.Sabdar@Sun.COM 
3717917SReza.Sabdar@Sun.COM const char *
_umem_logging_init(void)3727917SReza.Sabdar@Sun.COM _umem_logging_init(void)
3737917SReza.Sabdar@Sun.COM {
3747917SReza.Sabdar@Sun.COM 	return ("fail,contents"); /* $UMEM_LOGGING setting */
3757917SReza.Sabdar@Sun.COM }
3767917SReza.Sabdar@Sun.COM #endif
377