fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER START
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The contents of this file are subject to the terms of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Common Development and Distribution License (the "License").
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You may not use this file except in compliance with the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See the License for the specific language governing permissions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and limitations under the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If applicable, add the following below this CDDL HEADER, with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER END
570de38f63910201fdd77246630b7aa8f9dc5661Surya Prakki * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Use is subject to license terms.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Define a minimal user stack size in bytes over and above the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * libthread THR_STACK_MIN minimum value.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This stack size needs to be sufficient to run _newlwp() and then
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ioctl() down into the kernel.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * LWP scheduling control switches.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * allow_pri - set to non-zero to enable priocntl() manipulations of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * created LWPs.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * allow_rt - set to non-zero to use the RT rather than the TS
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * scheduling class when manipulating the schduling
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * parameters for an LWP. Only used if allow_pri is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int allow_rt = 0; /* disallow - bad interactions with timeout() */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int nthreads; /* number of threads in the kernel */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int exiting; /* shutdown in progress flag */
570de38f63910201fdd77246630b7aa8f9dc5661Surya Prakki (void) fprintf(stderr, gettext("usage: nskernd\n"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns: 1 - can enter kernel; 0 - shutdown in progress, do not enter kernel
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* cannot enter kernel as nskernd is being shutdown - exit */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * returns: 1 - can shutdown; 0 - unable to shutdown
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (nthreads > 0 && (time(0) - start_delay) < delay_time) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* flag shutdown in progress */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * returns: 1 - shutdown successful; 0 - unable to shutdown
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * First function run by a NSKERND_NEWLWP thread.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Determines if it needs to change the scheduling priority of the LWP,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and then calls back into the kernel.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* copy arguments onto stack and free heap memory */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* increase the scheduling priority of this LWP */
570de38f63910201fdd77246630b7aa8f9dc5661Surya Prakki (void) strcpy(pcinfo.pc_clname, allow_rt ? "RT" : "TS");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (priocntl(0, 0, PC_GETCID, (char *)&pcinfo) < 0) {
570de38f63910201fdd77246630b7aa8f9dc5661Surya Prakki "nskernd: priocntl(PC_GETCID) failed: %s\n"),
570de38f63910201fdd77246630b7aa8f9dc5661Surya Prakki "nskernd: priocntl(PC_SETPARMS) failed: %s\n"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Start a new thread bound to an LWP.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This is the user level side of nsc_create_process().
570de38f63910201fdd77246630b7aa8f9dc5661Surya Prakki (void) fprintf(stderr, gettext("nskernd: malloc(%d) failed\n"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* copy args for child */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = thr_create(NULL, (THR_MIN_STACK + NSK_STACK_SIZE),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* thr_create failed */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* success - _newlwp() will free nskp */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *mst, *shd, *bmp, *mode, *ovr, *cnode, *opt, *grp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "nskernd: Error forking\n"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (pid > 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "nskernd: Attempting deferred bitmap error\n"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "nskernd: Failed cfg_open, deferred bitmap\n"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Sooner or later, this lock will be free */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* find the proper set number */
570de38f63910201fdd77246630b7aa8f9dc5661Surya Prakki (void) snprintf(key, CFG_MAX_KEY, "ii.set%d", setno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cfg_get_cstring(cfg, key, buf, CFG_MAX_BUF) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* were there flags in the options field already? */
570de38f63910201fdd77246630b7aa8f9dc5661Surya Prakki (void) snprintf(newflags, CFG_MAX_BUF, "%s=0x%x",
570de38f63910201fdd77246630b7aa8f9dc5661Surya Prakki (void) snprintf(key, CFG_MAX_KEY, "ii.set%d", setno);
570de38f63910201fdd77246630b7aa8f9dc5661Surya Prakki (void) snprintf(outbuf, CFG_MAX_BUF, "%s %s %s %s %s %s %s %s",
570de38f63910201fdd77246630b7aa8f9dc5661Surya Prakki mst, shd, bmp, mode, ovr, cnode, newflags, grp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cfg_put_cstring(cfg, key, outbuf, CFG_MAX_BUF) < 0) {
570de38f63910201fdd77246630b7aa8f9dc5661Surya Prakki "nskernd: Failed deferred bitmap [%s]\n"), set);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if we are the fork'ed client, just exit, if parent just return
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*NOTREACHED*/
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * First function run by a NSKERND_LOCK thread.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Opens dscfg and locks it,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and then calls back into the kernel.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * data1 is the kernel address of the sync structure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * data2 is read(0)/write(1) lock mode.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * data1 as incoming.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * data2 errno.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* copy arguments onto stack and free heap memory */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* return to kernel */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* cleanup */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Inter-node lock thread.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This is the user level side of nsc_rmlock().
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* create a new thread to do the lock and return to kernel */
570de38f63910201fdd77246630b7aa8f9dc5661Surya Prakki gettext("nskernd:dolock: malloc(%d) failed\n"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* copy args for child */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = thr_create(NULL, (THR_MIN_STACK + NSK_STACK_SIZE),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* thr_create failed */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* success - _dolock() will free nskp */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Convenience code for engineering test of multi-terabyte volumes.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * zvol (part of zfs) does not support DKIOCPARTITION but does use EFI
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * labels. This code allocates a simple efi label structure and ioctls
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to extract the size of a zvol. It only handles the minimal EFI ioctl
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * implementation in zvol.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortezvol_bsize(char *path, uint64_t *size, const int pnum)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (stat64("/devices/pseudo/zfs@0:zfs", &stb1) != 0 ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc >= 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteget_bsize(uint64_t raw_fd, uint64_t *size, int *partitionp, char *path)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bsize.dki_info = (uint64_t)(unsigned long)&dki_info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* assume part# is ok and just the size failed */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* see if this is an EFI label */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* see if this is a zvol */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* DKIOCPARTITION */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (vtoc.v_version != V_VERSION && vtoc.v_version != 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *size = (uint64_t)vtoc.v_part[(int)dki_info.dki_partition].p_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Find out if we are running in a cluster
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (cl_nodeid == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gettext("nskernd: unable to ascertain environment"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* NOTREACHED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Runtime Solaris release checking - build release == runtime release
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is always considered success, so only keep entries in the map for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the special cases.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* { "5.10", "5.10" }, */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED1 */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = nsc_check_release(BUILD_REV_STR, nskernd_rel_map, &reqd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gettext("nskernd: unable to determine the current "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Usage: <progname> [-g] [-d <seconds to delay>]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (i) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Usage: nskernd [-g] [-d <seconds to delay>]");
570de38f63910201fdd77246630b7aa8f9dc5661Surya Prakki (void) fprintf(stderr, gettext("nskernd: chroot failed: %s\n"),
570de38f63910201fdd77246630b7aa8f9dc5661Surya Prakki (void) fprintf(stderr, gettext("nskernd: chdir failed: %s\n"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Determine if we are in a Sun Cluster or not, before fork'ing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * create a pipe to synchronise the parent with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * child just before it enters its service loop.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Fork off a child that becomes the daemon.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * wait for the close of the pipe.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If we get a char back, indicates good
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * status from child, so exit 0.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If we get a zero length read, then the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * child has failed, so we do too.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (rc < 0) {
570de38f63910201fdd77246630b7aa8f9dc5661Surya Prakki (void) fprintf(stderr, gettext("nskernd: cannot fork: %s\n"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * In child - become daemon.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* use closefrom(3C) from PSARC/2000/193 when possible */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Ignore all signals apart from SIGTERM.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Increase the number of fd's that can be open.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gettext("nskernd: could not increase RLIMIT_NOFILE: %s\n"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gettext("nskernd: the maximum number of nsctl open "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "devices may be reduced\n"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Open /dev/nsctl and startup.
570de38f63910201fdd77246630b7aa8f9dc5661Surya Prakki (void) fprintf(stderr, gettext("nskernd: unable to open %s\n"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* try and do kernel cleanup and exit */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (sigterm) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* SIGTERM received - terminate */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* need to do kernel cleanup */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* just quit */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* cannot shutdown - threads active */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case NSKERND_STOP: /* kernel telling daemon to stop */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * kernel requesting partsize
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * data1 - size return
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * data2 - raw_fd (entry)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * - partition number (return)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case NSKERND_NEWLWP: /* kernel requesting a new LWP */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the kernel thread can be woken by the dr config
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * utilities (ie cfgadm) therefore we just reissue