--- old/usr/src/cmd/avs/nsctl/nskernd.c	Fri Jul 27 15:35:33 2018
+++ /dev/null	Fri Jul 27 15:07:21 2018
@@ -1,1000 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/resource.h>
-#include <sys/priocntl.h>
-#include <sys/rtpriocntl.h>
-#include <sys/tspriocntl.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-
-#include <strings.h>
-#include <thread.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <errno.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <locale.h>
-#include <unistd.h>
-#include <syslog.h>
-
-#include <sys/nsctl/cfg.h>
-#include <sys/nsctl/nsctl.h>
-#include <sys/nsctl/nsc_ioctl.h>
-#include <sys/nskernd.h>
-#include <nsctl.h>
-
-#include <sys/mkdev.h>
-#include <sys/nsctl/sv_efi.h>
-
-static const char *rdev = "/dev/nsctl";
-
-/*
- * Define a minimal user stack size in bytes over and above the
- * libthread THR_STACK_MIN minimum value.
- *
- * This stack size needs to be sufficient to run _newlwp() and then
- * ioctl() down into the kernel.
- */
-#define	NSK_STACK_SIZE	512
-
-/*
- * LWP scheduling control switches.
- *
- * allow_pri	- set to non-zero to enable priocntl() manipulations of
- *		created LWPs.
- * allow_rt	- set to non-zero to use the RT rather than the TS
- *		scheduling class when manipulating the schduling
- *		parameters for an LWP.  Only used if allow_pri is
- *		non-zero.
- */
-static int allow_pri = 1;
-static int allow_rt = 0;	/* disallow - bad interactions with timeout() */
-
-static int nsctl_fd = -1;
-static int sigterm;
-
-static int nthreads;		/* number of threads in the kernel */
-static int exiting;		/* shutdown in progress flag */
-static mutex_t thr_mutex = DEFAULTMUTEX;
-static mutex_t cfg_mutex = DEFAULTMUTEX;
-
-static int cl_nodeid = -1;
-
-static int display_msg = 0;
-static int delay_time = 30;
-
-static void
-usage(void)
-{
-	(void) fprintf(stderr, gettext("usage: nskernd\n"));
-	exit(255);
-}
-
-
-static void
-sighand(int sig)
-{
-	if (sig == SIGTERM) {
-		sigterm++;
-	}
-}
-
-
-/*
- * Returns: 1 - can enter kernel; 0 - shutdown in progress, do not enter kernel
- */
-int
-nthread_inc(void)
-{
-	(void) mutex_lock(&thr_mutex);
-	if (exiting) {
-		/* cannot enter kernel as nskernd is being shutdown - exit */
-		(void) mutex_unlock(&thr_mutex);
-		return (0);
-	}
-	nthreads++;
-	(void) mutex_unlock(&thr_mutex);
-	return (1);
-}
-
-
-void
-nthread_dec(void)
-{
-	(void) mutex_lock(&thr_mutex);
-	nthreads--;
-	(void) mutex_unlock(&thr_mutex);
-}
-
-
-/*
- * returns: 1 - can shutdown; 0 - unable to shutdown
- */
-int
-canshutdown(void)
-{
-	int rc = 1;
-	time_t	start_delay;
-
-	(void) mutex_lock(&thr_mutex);
-	if (nthreads > 0) {
-		if (display_msg) {
-			(void) fprintf(stderr,
-			    gettext("nskernd: unable to shutdown: "
-			    "%d kernel threads in use\n"), nthreads);
-		}
-		start_delay = time(0);
-		while (nthreads > 0 && (time(0) - start_delay) < delay_time) {
-			(void) mutex_unlock(&thr_mutex);
-			(void) sleep(1);
-			(void) mutex_lock(&thr_mutex);
-			(void) fprintf(stderr,
-			    gettext("nskernd:   delay shutdown: "
-			    "%d kernel threads in use\n"), nthreads);
-		}
-		if (nthreads > 0) {
-			rc = 0;
-		} else {
-			exiting = 1;
-		}
-	} else {
-		/* flag shutdown in progress */
-		exiting = 1;
-	}
-	(void) mutex_unlock(&thr_mutex);
-
-	return (rc);
-}
-
-
-/*
- * returns: 1 - shutdown successful; 0 - unable to shutdown
- */
-int
-shutdown(void)
-{
-	struct nskernd data;
-	int rc;
-
-	if (nsctl_fd < 0)
-		return (1);
-
-	bzero(&data, sizeof (data));
-	data.command = NSKERND_STOP;
-
-	if (!canshutdown()) {
-		return (0);
-	}
-
-	rc = ioctl(nsctl_fd, NSCIOC_NSKERND, &data);
-	if (rc < 0) {
-		if (errno != EINTR || !sigterm) {
-			(void) fprintf(stderr,
-			    gettext("nskernd: NSKERND_STOP failed\n"));
-		}
-	}
-
-	return (1);
-}
-
-
-/*
- * First function run by a NSKERND_NEWLWP thread.
- *
- * Determines if it needs to change the scheduling priority of the LWP,
- * and then calls back into the kernel.
- */
-static void *
-_newlwp(void *arg)
-{
-	struct nskernd nsk;
-	pcparms_t pcparms;
-	pcinfo_t pcinfo;
-
-	/* copy arguments onto stack and free heap memory */
-	bcopy(arg, &nsk, sizeof (nsk));
-	free(arg);
-
-	if (nsk.data2 && allow_pri) {
-		/* increase the scheduling priority of this LWP */
-
-		bzero(&pcinfo, sizeof (pcinfo));
-		(void) strcpy(pcinfo.pc_clname, allow_rt ? "RT" : "TS");
-
-		if (priocntl(0, 0, PC_GETCID, (char *)&pcinfo) < 0) {
-			(void) fprintf(stderr,
-			    gettext(
-			    "nskernd: priocntl(PC_GETCID) failed: %s\n"),
-			    strerror(errno));
-			goto pri_done;
-		}
-
-		bzero(&pcparms, sizeof (pcparms));
-		pcparms.pc_cid = pcinfo.pc_cid;
-
-		if (allow_rt) {
-			((rtparms_t *)pcparms.pc_clparms)->rt_pri =
-				(pri_t)0; /* minimum RT priority */
-			((rtparms_t *)pcparms.pc_clparms)->rt_tqsecs =
-				(uint_t)RT_TQDEF;
-			((rtparms_t *)pcparms.pc_clparms)->rt_tqnsecs =
-				RT_TQDEF;
-		} else {
-			((tsparms_t *)pcparms.pc_clparms)->ts_uprilim =
-				((tsinfo_t *)&pcinfo.pc_clinfo)->ts_maxupri;
-			((tsparms_t *)pcparms.pc_clparms)->ts_upri =
-				((tsinfo_t *)&pcinfo.pc_clinfo)->ts_maxupri;
-		}
-
-		if (priocntl(P_LWPID, P_MYID,
-		    PC_SETPARMS, (char *)&pcparms) < 0) {
-			(void) fprintf(stderr,
-			    gettext(
-			    "nskernd: priocntl(PC_SETPARMS) failed: %s\n"),
-			    strerror(errno));
-		}
-	}
-
-pri_done:
-	if (nthread_inc()) {
-		(void) ioctl(nsctl_fd, NSCIOC_NSKERND, &nsk);
-		nthread_dec();
-	}
-	return (NULL);
-}
-
-
-/*
- * Start a new thread bound to an LWP.
- *
- * This is the user level side of nsc_create_process().
- */
-static void
-newlwp(struct nskernd *req)
-{
-	struct nskernd *nskp;
-	thread_t tid;
-	int rc;
-
-	nskp = malloc(sizeof (*nskp));
-	if (!nskp) {
-#ifdef DEBUG
-		(void) fprintf(stderr, gettext("nskernd: malloc(%d) failed\n"),
-		    sizeof (*nskp));
-#endif
-		req->data1 = (uint64_t)ENOMEM;
-		return;
-	}
-
-	/* copy args for child */
-	bcopy(req, nskp, sizeof (*nskp));
-
-	rc = thr_create(NULL, (THR_MIN_STACK + NSK_STACK_SIZE),
-		_newlwp, nskp, THR_BOUND|THR_DETACHED, &tid);
-
-	if (rc != 0) {
-		/* thr_create failed */
-#ifdef DEBUG
-		(void) fprintf(stderr,
-		    gettext("nskernd: thr_create failed: %s\n"),
-		    strerror(errno));
-#endif
-		req->data1 = (uint64_t)errno;
-		free(nskp);
-	} else {
-		/* success - _newlwp() will free nskp */
-		req->data1 = (uint64_t)0;
-	}
-}
-
-static int
-log_iibmp_err(char *set, int flags)
-{
-	CFGFILE *cfg;
-	char key[CFG_MAX_KEY];
-	char buf[CFG_MAX_BUF];
-	char newflags[CFG_MAX_BUF];
-	char outbuf[CFG_MAX_BUF];
-	char *mst, *shd, *bmp, *mode, *ovr, *cnode, *opt, *grp;
-	int setno, found = 0;
-	int setlen;
-	int rc = 0;
-	pid_t pid = -1;
-
-	if (set && *set) {
-		setlen = strlen(set);
-	} else {
-		return (EINVAL);
-	}
-
-	(void) mutex_lock(&cfg_mutex);
-	cfg = cfg_open("");
-	if (!cfg) {
-		(void) mutex_unlock(&cfg_mutex);
-		return (ENXIO);
-	}
-
-	if (!cfg_lock(cfg, CFG_WRLOCK)) {
-
-		(void) mutex_unlock(&cfg_mutex);
-		cfg_close(cfg);
-
-		pid = fork();
-
-		if (pid == -1) {
-			(void) fprintf(stderr, gettext(
-			    "nskernd: Error forking\n"));
-			return (errno);
-		} else if (pid > 0) {
-			(void) fprintf(stdout, gettext(
-			    "nskernd: Attempting deferred bitmap error\n"));
-			return (0);
-		}
-
-		(void) mutex_lock(&cfg_mutex);
-		cfg = cfg_open("");
-		if (!cfg) {
-			(void) mutex_unlock(&cfg_mutex);
-			(void) fprintf(stderr, gettext(
-			    "nskernd: Failed cfg_open, deferred bitmap\n"));
-			return (ENXIO);
-		}
-
-		/* Sooner or later, this lock will be free */
-		while (!cfg_lock(cfg, CFG_WRLOCK))
-			(void) sleep(2);
-	}
-
-	/* find the proper set number */
-	for (setno = 1; !found; setno++) {
-		(void) snprintf(key, CFG_MAX_KEY, "ii.set%d", setno);
-		if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) {
-			break;
-		}
-
-		mst = strtok(buf, " ");
-		shd = strtok(NULL, " ");
-		if (strncmp(shd, set, setlen) == 0) {
-			found = 1;
-
-			bmp = strtok(NULL, " ");
-			mode = strtok(NULL, " ");
-			ovr = strtok(NULL, " ");
-			cnode = strtok(NULL, " ");
-			opt = strtok(NULL, " ");
-			grp = strtok(NULL, " ");
-			break;
-		}
-	}
-
-	if (found) {
-		/* were there flags in the options field already? */
-		(void) snprintf(newflags, CFG_MAX_BUF, "%s=0x%x",
-		    NSKERN_II_BMP_OPTION, flags);
-		if (opt && strcmp(opt, "-") != 0) {
-			bzero(newflags, CFG_MAX_BUF);
-			opt = strtok(opt, ";");
-			while (opt) {
-				if (strncmp(opt, NSKERN_II_BMP_OPTION,
-				    strlen(NSKERN_II_BMP_OPTION)) != 0) {
-					(void) strcat(newflags, ";");
-					(void) strcat(newflags, opt);
-				}
-			}
-		}
-		(void) snprintf(key, CFG_MAX_KEY, "ii.set%d", setno);
-		(void) snprintf(outbuf, CFG_MAX_BUF, "%s %s %s %s %s %s %s %s",
-		    mst, shd, bmp, mode, ovr, cnode, newflags, grp);
-		if (cfg_put_cstring(cfg, key, outbuf, CFG_MAX_BUF) < 0) {
-			(void) printf("Failed to put [%s]\n", outbuf);
-			rc = ENXIO;
-		} else {
-			(void) cfg_commit(cfg);
-			rc = 0;
-		}
-	} else {
-		(void) fprintf(stderr, gettext(
-		    "nskernd: Failed deferred bitmap [%s]\n"), set);
-		rc = EINVAL;
-	}
-	cfg_unlock(cfg);
-	cfg_close(cfg);
-	(void) mutex_unlock(&cfg_mutex);
-
-	/*
-	 * if we are the fork'ed client, just exit, if parent just return
-	 */
-	if (pid == 0) {
-		exit(rc);
-		/*NOTREACHED*/
-	} else {
-		return (rc);
-	}
-}
-
-/*
- * First function run by a NSKERND_LOCK thread.
- *
- * Opens dscfg and locks it,
- * and then calls back into the kernel.
- *
- * Incoming:
- *	data1 is the kernel address of the sync structure.
- *	data2 is read(0)/write(1) lock mode.
- *
- * Returns:
- *	data1 as incoming.
- *	data2 errno.
- */
-static void *
-_dolock(void *arg)
-{
-	struct nskernd nsk;
-	CFGFILE *cfg;
-	int locked;
-	int mode;
-	int rc = 0;
-
-	/* copy arguments onto stack and free heap memory */
-	bcopy(arg, &nsk, sizeof (nsk));
-	free(arg);
-
-	(void) mutex_lock(&cfg_mutex);
-	cfg = cfg_open("");
-	if (cfg == NULL) {
-#ifdef DEBUG
-		(void) fprintf(stderr,
-		    gettext("nskernd: cfg_open failed: %s\n"),
-		    strerror(errno));
-#endif
-		rc = ENXIO;
-	}
-
-	if (nsk.data2 == 0) {
-		mode = CFG_RDLOCK;
-	} else {
-		mode = CFG_WRLOCK;
-	}
-
-	locked = 0;
-	if (rc == 0) {
-		if (cfg_lock(cfg, mode)) {
-			locked = 1;
-		} else {
-#ifdef DEBUG
-			(void) fprintf(stderr,
-			    gettext("nskernd: cfg_lock failed: %s\n"),
-			    strerror(errno));
-#endif
-			rc = EINVAL;
-		}
-	}
-
-	/* return to kernel */
-
-	nsk.data2 = (uint64_t)rc;
-	if (nthread_inc()) {
-		(void) ioctl(nsctl_fd, NSCIOC_NSKERND, &nsk);
-		nthread_dec();
-	}
-
-	/* cleanup */
-
-	if (locked) {
-		cfg_unlock(cfg);
-		locked = 0;
-	}
-
-	if (cfg != NULL) {
-		cfg_close(cfg);
-		cfg = NULL;
-	}
-	(void) mutex_unlock(&cfg_mutex);
-
-	return (NULL);
-}
-
-
-/*
- * Inter-node lock thread.
- *
- * This is the user level side of nsc_rmlock().
- */
-static void
-dolock(struct nskernd *req)
-{
-	struct nskernd *nskp;
-	thread_t tid;
-	int rc;
-
-	/* create a new thread to do the lock and return to kernel */
-
-	nskp = malloc(sizeof (*nskp));
-	if (!nskp) {
-#ifdef DEBUG
-		(void) fprintf(stderr,
-		    gettext("nskernd:dolock: malloc(%d) failed\n"),
-		    sizeof (*nskp));
-#endif
-		req->data1 = (uint64_t)ENOMEM;
-		return;
-	}
-
-	/* copy args for child */
-	bcopy(req, nskp, sizeof (*nskp));
-
-	rc = thr_create(NULL, (THR_MIN_STACK + NSK_STACK_SIZE),
-	    _dolock, nskp, THR_BOUND|THR_DETACHED, &tid);
-
-	if (rc != 0) {
-		/* thr_create failed */
-#ifdef DEBUG
-		(void) fprintf(stderr,
-		    gettext("nskernd: thr_create failed: %s\n"),
-		    strerror(errno));
-#endif
-		req->data1 = (uint64_t)errno;
-		free(nskp);
-	} else {
-		/* success - _dolock() will free nskp */
-		req->data1 = (uint64_t)0;
-	}
-}
-
-
-/*
- * Convenience code for engineering test of multi-terabyte volumes.
- *
- * zvol (part of zfs) does not support DKIOCPARTITION but does use EFI
- * labels.  This code allocates a simple efi label structure and ioctls
- * to extract the size of a zvol.  It only handles the minimal EFI ioctl
- * implementation in zvol.
- */
-
-static void
-zvol_bsize(char *path, uint64_t *size, const int pnum)
-{
-	struct stat64 stb1, stb2;
-	struct dk_minfo dkm;
-	int fd = -1;
-	int rc;
-
-	if (cl_nodeid || pnum != 0)
-		return;
-
-	if ((fd = open(path, O_RDONLY)) < 0) {
-		return;
-	}
-
-	if (stat64("/devices/pseudo/zfs@0:zfs", &stb1) != 0 ||
-	    fstat64(fd, &stb2) != 0 ||
-	    !S_ISCHR(stb1.st_mode) ||
-	    !S_ISCHR(stb2.st_mode) ||
-	    major(stb1.st_rdev) != major(stb2.st_rdev)) {
-		(void) close(fd);
-		return;
-	}
-
-	rc = ioctl(fd, DKIOCGMEDIAINFO, (void *)&dkm);
-	if (rc >= 0) {
-		*size = LE_64(dkm.dki_capacity) *
-			(dkm.dki_lbsize) / 512;
-	}
-
-	(void) close(fd);
-}
-
-/* ARGSUSED */
-static void
-get_bsize(uint64_t raw_fd, uint64_t *size, int *partitionp, char *path)
-{
-	struct nscioc_bsize bsize;
-#ifdef DKIOCPARTITION
-	struct partition64 p64;
-#endif
-	struct dk_cinfo dki_info;
-	struct vtoc vtoc;
-	int fd;
-
-	*partitionp = -1;
-	*size = (uint64_t)0;
-
-	dki_info.dki_partition = (ushort_t)-1;
-	bsize.dki_info = (uint64_t)(unsigned long)&dki_info;
-	bsize.vtoc = (uint64_t)(unsigned long)&vtoc;
-	bsize.raw_fd = raw_fd;
-	bsize.efi = 0;
-
-	fd = open(rdev, O_RDONLY);
-	if (fd < 0)
-		return;
-
-	if (ioctl(fd, NSCIOC_BSIZE, &bsize) < 0) {
-		if (dki_info.dki_partition != (ushort_t)-1) {
-			/* assume part# is ok and just the size failed */
-			*partitionp = (int)dki_info.dki_partition;
-
-#ifdef DKIOCPARTITION
-			/* see if this is an EFI label */
-			bzero(&p64, sizeof (p64));
-			p64.p_partno = (uint_t)*partitionp;
-			if ((ioctl(fd, DKIOCPARTITION, &p64)) > 0) {
-				*size = (uint64_t)p64.p_size;
-			} else {
-				bsize.p64 = (uint64_t)(unsigned long)&p64;
-				bsize.efi = 1;
-
-				if (ioctl(fd, NSCIOC_BSIZE, &bsize) < 0) {
-					/* see if this is a zvol */
-					zvol_bsize(path, size, *partitionp);
-				} else {
-					*size = (uint64_t)p64.p_size;
-				}
-			}
-#endif	/* DKIOCPARTITION */
-		}
-
-		(void) close(fd);
-		return;
-	}
-
-	(void) close(fd);
-
-	*partitionp = (int)dki_info.dki_partition;
-
-	if (vtoc.v_sanity != VTOC_SANE)
-		return;
-
-	if (vtoc.v_version != V_VERSION && vtoc.v_version != 0)
-		return;
-
-	if (dki_info.dki_partition > V_NUMPAR)
-		return;
-
-	*size = (uint64_t)vtoc.v_part[(int)dki_info.dki_partition].p_size;
-}
-
-
-static int
-iscluster(void)
-{
-	/*
-	 * Find out if we are running in a cluster
-	 */
-	cl_nodeid = cfg_iscluster();
-	if (cl_nodeid > 0) {
-		return (TRUE);
-	} else if (cl_nodeid == 0) {
-		return (FALSE);
-	}
-
-	(void) fprintf(stderr, "%s\n",
-	    gettext("nskernd: unable to ascertain environment"));
-	exit(1);
-	/* NOTREACHED */
-}
-
-/*
- * Runtime Solaris release checking - build release == runtime release
- * is always considered success, so only keep entries in the map for
- * the special cases.
- */
-static nsc_release_t nskernd_rel_map[] = {
-/*	{ "5.10", "5.10" },			*/
-	{ "5.11", "5.10" },
-	{ NULL, NULL }
-};
-
-
-#ifdef lint
-#define	main	nskernd_main
-#endif
-/* ARGSUSED1 */
-int
-main(int argc, char *argv[])
-{
-	const char *dir = "/";
-	struct nskernd data;
-	struct rlimit rl;
-	int i, run, rc;
-	int partition;
-	char *reqd;
-	int syncpipe[2];
-	int startup;
-
-	(void) setlocale(LC_ALL, "");
-	(void) textdomain("nskernd");
-
-	rc = nsc_check_release(BUILD_REV_STR, nskernd_rel_map, &reqd);
-	if (rc < 0) {
-		(void) fprintf(stderr,
-		    gettext("nskernd: unable to determine the current "
-		    "Solaris release: %s\n"), strerror(errno));
-		exit(1);
-	} else if (rc == FALSE) {
-		(void) fprintf(stderr,
-		    gettext("nskernd: incorrect Solaris release "
-		    "(requires %s)\n"), reqd);
-		exit(1);
-	}
-
-	rc = 0;
-
-	if (argc != 1)
-		usage();
-
-	/*
-	 * Usage: <progname> [-g] [-d <seconds to delay>]
-	 */
-	while ((i = getopt(argc, argv, "gd:")) != EOF) {
-		switch (i) {
-			case 'g':
-				display_msg = 1;
-				break;
-			case 'd':
-				delay_time = atoi(optarg);
-				if (delay_time <= 0) {
-					delay_time = 30;
-				}
-				break;
-			default:
-				syslog(LOG_ERR,
-				"Usage: nskernd [-g] [-d <seconds to delay>]");
-				exit(1);
-				break;
-		}
-	}
-
-	if (chroot(dir) < 0) {
-		(void) fprintf(stderr, gettext("nskernd: chroot failed: %s\n"),
-		    strerror(errno));
-		exit(1);
-	}
-
-	if (chdir(dir) < 0) {
-		(void) fprintf(stderr, gettext("nskernd: chdir failed: %s\n"),
-		    strerror(errno));
-		exit(1);
-	}
-
-	/*
-	 * Determine if we are in a Sun Cluster or not, before fork'ing
-	 */
-	(void) iscluster();
-
-	/*
-	 * create a pipe to synchronise the parent with the
-	 * child just before it enters its service loop.
-	 */
-	if (pipe(syncpipe) < 0) {
-		(void) fprintf(stderr,
-		    gettext("nskernd: cannot create pipe: %s\n"),
-		    strerror(errno));
-		exit(1);
-	}
-	/*
-	 * Fork off a child that becomes the daemon.
-	 */
-
-	if ((rc = fork()) > 0) {
-		char c;
-		int n;
-		(void) close(syncpipe[1]);
-		/*
-		 * wait for the close of the pipe.
-		 * If we get a char back, indicates good
-		 * status from child, so exit 0.
-		 * If we get a zero length read, then the
-		 * child has failed, so we do too.
-		 */
-		n = read(syncpipe[0], &c, 1);
-		exit((n <= 0) ? 1 : 0);
-	} else if (rc < 0) {
-		(void) fprintf(stderr, gettext("nskernd: cannot fork: %s\n"),
-		    strerror(errno));
-		exit(1);
-	}
-
-	/*
-	 * In child - become daemon.
-	 */
-
-	/* use closefrom(3C) from PSARC/2000/193 when possible */
-	for (i = 0; i < syncpipe[1]; i++) {
-		(void) close(i);
-	}
-	closefrom(syncpipe[1] + 1);
-
-	(void) open("/dev/console", O_WRONLY|O_APPEND);
-	(void) dup(0);
-	(void) dup(0);
-	(void) close(0);
-
-	(void) setpgrp();
-
-	/*
-	 * Ignore all signals apart from SIGTERM.
-	 */
-
-	for (i = 1; i < _sys_nsig; i++)
-		(void) sigset(i, SIG_IGN);
-
-	(void) sigset(SIGTERM, sighand);
-
-	/*
-	 * Increase the number of fd's that can be open.
-	 */
-
-	rl.rlim_cur = RLIM_INFINITY;
-	rl.rlim_max = RLIM_INFINITY;
-	if (setrlimit(RLIMIT_NOFILE, &rl) < 0) {
-		(void) fprintf(stderr,
-		    gettext("nskernd: could not increase RLIMIT_NOFILE: %s\n"),
-		    strerror(errno));
-		(void) fprintf(stderr,
-		    gettext("nskernd: the maximum number of nsctl open "
-		    "devices may be reduced\n"));
-	}
-
-	/*
-	 * Open /dev/nsctl and startup.
-	 */
-
-	nsctl_fd = open(rdev, O_RDONLY);
-	if (nsctl_fd < 0) {
-		(void) fprintf(stderr, gettext("nskernd: unable to open %s\n"),
-		    rdev);
-		exit(1);
-	}
-
-	bzero(&data, sizeof (data));
-
-	data.command = NSKERND_START;
-	data.data1 = (uint64_t)cl_nodeid;
-	run = 1;
-
-	startup = 1;
-	while (run) {
-		rc = ioctl(nsctl_fd, NSCIOC_NSKERND, &data);
-		if (rc < 0) {
-			/* try and do kernel cleanup and exit */
-			if (shutdown()) {
-				run = 0;
-			} else {
-				sigterm = 0;
-			}
-
-			(void) fprintf(stderr,
-			    gettext("nskernd: NSCIOC_NSKERND failed: %s\n"),
-			    strerror(errno));
-			continue;
-		} else if (sigterm) {
-			/* SIGTERM received - terminate */
-			if (data.command != NSKERND_START &&
-			    (data.command != NSKERND_STOP ||
-			    data.data1 != (uint64_t)1)) {
-				/* need to do kernel cleanup */
-				if (shutdown()) {
-					run = 0;
-				} else {
-					sigterm = 0;
-					data.command = NSKERND_START;
-					data.data1 = (uint64_t)cl_nodeid;
-				}
-			} else {
-				/* just quit */
-				if (canshutdown()) {
-					run = 0;
-				} else {
-					/* cannot shutdown - threads active */
-					sigterm = 0;
-					data.command = NSKERND_START;
-					data.data1 = (uint64_t)cl_nodeid;
-				}
-			}
-			continue;
-		}
-		if (startup) {
-			char c = 0;
-			(void) write(syncpipe[1], &c, 1);
-			(void) close(syncpipe[1]);
-			startup = 0;
-		}
-		switch (data.command) {
-		case NSKERND_START:	/* (re)start completion */
-			if (rc == 1) {
-				(void) fprintf(stderr,
-				    gettext("nskernd: already started\n"));
-				run = 0;
-			} else if (rc == 2) {
-				(void) fprintf(stderr,
-				    gettext("nskernd: stopped by kernel\n"));
-				run = 0;
-			}
-			data.command = NSKERND_WAIT;
-			break;
-
-		case NSKERND_STOP:	/* kernel telling daemon to stop */
-			if (data.data1 != (uint64_t)1) {
-				(void) shutdown();
-				run = 0;
-			}
-			break;
-
-		case NSKERND_BSIZE:
-			/*
-			 * kernel requesting partsize
-			 * data1 - size return
-			 * data2 - raw_fd (entry)
-			 *	 - partition number (return)
-			 */
-			partition = -1;
-			get_bsize(data.data2, &data.data1,
-			    &partition, data.char1);
-			data.data2 = (uint64_t)partition;
-			data.command = NSKERND_WAIT;
-			break;
-
-		case NSKERND_NEWLWP:	/* kernel requesting a new LWP */
-			newlwp(&data);
-			data.command = NSKERND_WAIT;
-			break;
-
-		case NSKERND_LOCK:  	/* kernel requesting lock */
-			dolock(&data);
-			data.command = NSKERND_WAIT;
-			break;
-
-		case NSKERND_WAIT:	/* kernel retrying wait */
-			/*
-			 * the kernel thread can be woken by the dr config
-			 * utilities (ie cfgadm) therefore we just reissue
-			 * the wait.
-			 */
-			break;
-
-		case NSKERND_IIBITMAP:
-			rc = log_iibmp_err(data.char1, (int)data.data1);
-			data.data1 = (uint64_t)rc;
-			data.command = NSKERND_WAIT;
-			break;
-
-		default:
-			(void) fprintf(stderr,
-				gettext("nskernd: unknown command %d"),
-				data.command);
-			data.command = NSKERND_WAIT;
-			break;
-		}
-	}
-
-	(void) close(nsctl_fd);
-
-	return (rc);
-}
