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