diff options
author | Yuri Pankov <yuri.pankov@nexenta.com> | 2018-08-07 16:46:21 -0700 |
---|---|---|
committer | Joshua M. Clulow <josh@sysmgr.org> | 2018-08-07 16:46:22 -0700 |
commit | cb41b9c565d4eec9e1f06e24d429696f59f2f07d (patch) | |
tree | ee8675f196c2ea84b5ac5c6f0dff8c9e5305f0ee /usr/src/cmd/avs/nsctl | |
parent | 0e986b9d87352cd82909c748e7f684afe0ed579f (diff) | |
download | illumos-joyent-cb41b9c565d4eec9e1f06e24d429696f59f2f07d.tar.gz |
9674 Let's scrap AVS/sdbc
Reviewed by: Dan McDonald <danmcd@joyent.com>
Reviewed by: Peter Tribble <peter.tribble@gmail.com>
Approved by: Joshua M. Clulow <josh@sysmgr.org>
Diffstat (limited to 'usr/src/cmd/avs/nsctl')
-rw-r--r-- | usr/src/cmd/avs/nsctl/Makefile | 87 | ||||
-rw-r--r-- | usr/src/cmd/avs/nsctl/nscadm.c | 275 | ||||
-rw-r--r-- | usr/src/cmd/avs/nsctl/nskernd.c | 1000 |
3 files changed, 0 insertions, 1362 deletions
diff --git a/usr/src/cmd/avs/nsctl/Makefile b/usr/src/cmd/avs/nsctl/Makefile deleted file mode 100644 index f5b19dc7b2..0000000000 --- a/usr/src/cmd/avs/nsctl/Makefile +++ /dev/null @@ -1,87 +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 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -# must be before include of Makefile.cmd -DYNPROG = nscadm nskernd - -include ../../Makefile.cmd -include ../Makefile.com - -PROG = $(DYNPROG) - -OBJS= nscadm.o nskernd.o -SRCS= $(OBJS:%.o=%.c) -POFILES= $(OBJS:%.o=%.po) - -nscadm := POBJS = nscadm.o -nskernd := POBJS = nskernd.o - -CFLAGS += -v -CPPFLAGS += -DBUILD_REV_STR='"5.11"' -NSCADM_LDLIBS = -lnsctl -NSKERND_LDLIBS = -lnsctl -ldscfg -LINTFLAGS += -Xa -n -s -x -m -u -Dlint -errhdr=%user -DDEBUG -LINTDIR = $(KBASE)/lintdir -POFILE = nsctl_all.po -LFILE = $(LINTDIR)/nsctl.ln -ROOTLIBLINK = $(ROOTLIB)/nskernd -ROOTSBINLINK = $(ROOTUSRSBIN)/nscadm - -all := TARGET= all -install := TARGET= install -clean := TARGET= clean -clobber := TARGET= clobber -lint := TARGET= lint - -nscadm := LDLIBS += $(NSCADM_LDLIBS) -nskernd := LDLIBS += $(NSKERND_LDLIBS) - -.KEEP_STATE: - -.PARALLEL: $(OBJS) - -all: $(PROG) $(POFILES) - -install: all $(ROOTPROG) $(ROOTBIN)/nskernd $(ROOTLIBLINK) $(ROOTSBINLINK) - -lint: lint_SRCS - -clean: - $(RM) *.o $(POFILES) - -$(PROG): $$(POBJS) - $(LINK.c) $(POBJS) -o $@ $(LDLIBS) - $(POST_PROCESS) - -$(POFILE): $(POFILES) - $(RM) $@ - $(CAT) $(POFILES) > $@ - -$(ROOTLIBLINK): $(ROOTLIB) $(ROOTBIN)/nskernd - -$(RM) $@; $(LN) $(ROOTBIN)/nskernd $@ - -$(ROOTSBINLINK): $(ROOTUSRSBIN) $(ROOTPROG) - -$(RM) $@; $(LN) $(ROOTBIN)/nscadm $@ - -include ../../Makefile.targ diff --git a/usr/src/cmd/avs/nsctl/nscadm.c b/usr/src/cmd/avs/nsctl/nscadm.c deleted file mode 100644 index 5096dd5b73..0000000000 --- a/usr/src/cmd/avs/nsctl/nscadm.c +++ /dev/null @@ -1,275 +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/stat.h> -#include <strings.h> -#include <stdlib.h> -#include <unistd.h> -#include <errno.h> -#include <stdio.h> -#include <locale.h> - -#include <nsctl.h> -#define __NSC_GEN__ -#include <sys/nsctl/nsc_gen.h> -#include <sys/nsctl/nsc_mem.h> - - -/* - * Private functions from libsd. - */ -extern int nsc_nvclean(int); -extern int nsc_gmem_data(char *); -extern int nsc_gmem_sizes(int *); - -/* - * Local functions. - */ -static int _nsc_gmem(void); -static void show_maps(char *, int); - - -static void -usage(void) -{ - (void) fprintf(stderr, gettext("usage: nscadm [-h] command\n")); - (void) fprintf(stderr, gettext("valid commands:\n")); - (void) fprintf(stderr, gettext(" freeze <device>\n")); - (void) fprintf(stderr, gettext(" unfreeze <device>\n")); - (void) fprintf(stderr, gettext(" isfrozen <device>\n")); -} - -static void -is_chr_dev(char *dev, char *op) -{ - struct stat sbuf; - if (stat(dev, &sbuf) < 0) { - (void) fprintf(stderr, gettext("nscadm: ")); - perror(op); - exit(255); - } - if (!S_ISCHR(sbuf.st_mode)) { - (void) fprintf(stderr, gettext("nscadm: %s: not a valid device " - "<%s>\n"), op, dev); - exit(255); - } -} - -int -main(int argc, char *argv[]) -{ - extern int optind, opterr; - int opt, rc; - - (void) setlocale(LC_ALL, ""); - (void) textdomain("nscadm"); - - rc = 0; - opterr = 0; - - while ((opt = getopt(argc, argv, "h")) != -1) { - switch (opt) { - case 'h': - usage(); - exit(0); - break; - default: - usage(); - exit(255); - break; - } - } - - if (optind == argc) { - usage(); - exit(255); - } - - if (strcoll(argv[optind], gettext("freeze")) == 0 || - strcmp(argv[optind], "freeze") == 0) { - if (argc - optind != 2) { - usage(); - exit(255); - } - - is_chr_dev(argv[optind+1], "freeze"); - rc = nsc_isfrozen(argv[optind+1]); - if (rc < 0) { - perror(gettext("nscadm: freeze")); - exit(255); - } else if (rc != 0) { - rc = nsc_freeze(argv[optind+1]); - if (rc < 0) { - perror(gettext("nscadm: freeze")); - exit(255); - } - } else { - (void) fprintf(stderr, gettext("nscadm: device <%s> is " - "already frozen\n"), argv[optind+1]); - exit(255); - } - - (void) printf(gettext("nscadm: device <%s> frozen\n"), - argv[optind+1]); - } else if (strcoll(argv[optind], gettext("unfreeze")) == 0 || - strcmp(argv[optind], "unfreeze") == 0) { - if (argc - optind != 2) { - usage(); - exit(255); - } - - is_chr_dev(argv[optind+1], "unfreeze"); - rc = nsc_isfrozen(argv[optind+1]); - if (rc < 0) { - perror(gettext("nscadm: unfreeze")); - exit(255); - } else if (rc == 0) { - rc = nsc_unfreeze(argv[optind+1]); - if (rc < 0) { - perror(gettext("nscadm: unfreeze")); - exit(255); - } - } else { - (void) fprintf(stderr, - gettext("nscadm: device <%s> is not " - "frozen\n"), argv[optind+1]); - exit(255); - } - - (void) printf(gettext("nscadm: device <%s> unfrozen\n"), - argv[optind+1]); - } else if (strcoll(argv[optind], gettext("isfrozen")) == 0 || - strcmp(argv[optind], "isfrozen") == 0) { - if (argc - optind != 2) { - usage(); - exit(255); - } - - is_chr_dev(argv[optind+1], "isfrozen"); - rc = nsc_isfrozen(argv[optind+1]); - if (rc < 0) { - perror(gettext("nscadm: isfrozen")); - exit(255); - } - - (void) printf(gettext("nscadm: device <%s> is %sfrozen\n"), - argv[optind+1], rc ? gettext("not ") : ""); -#ifdef DEBUG - } else if (strcoll(argv[optind], gettext("nvclean")) == 0 || - strcmp(argv[optind], "nvclean") == 0) { - rc = nsc_nvclean(0); - if (rc < 0) { - perror(gettext("nscadm: nvclean")); - exit(255); - } - } else if (strcoll(argv[optind], gettext("nvclean_force")) == 0 || - strcmp(argv[optind], "nvclean_force") == 0) { - rc = nsc_nvclean(1); - if (rc < 0) { - perror(gettext("nscadm: nvclean_force")); - exit(255); - } -#endif /* DEBUG */ - } else if (strcoll(argv[optind], gettext("gmem")) == 0 || - strcmp(argv[optind], "gmem") == 0) { - rc = _nsc_gmem(); - if (rc < 0) { - perror(gettext("nscadm: gmem")); - exit(255); - } - } else { - usage(); - exit(255); - } - - return (rc); -} - - -static int -_nsc_gmem(void) -{ - char *addr; - int size; - int rc = 0; - - rc = nsc_gmem_sizes(&size); - - if (rc < 0) - return (rc); - - (void) printf(gettext("size %d\n"), size); - - if ((addr = (char *)malloc(size * 2)) == NULL) { - errno = ENOMEM; - return (-1); - } - - rc = nsc_gmem_data(addr); - - if (rc < 0) { - free(addr); - return (rc); - } - - (void) printf(gettext("Global map entries:\n")); - show_maps(addr, size); - - (void) printf(gettext("\nGlobal NVMEM map entries:\n")); - show_maps(addr + size, size); - - free(addr); - return (0); -} - - -static void -show_maps(char *addr, int len) -{ - /* LINTED alignment of cast ok */ - nsc_rmhdr_t *rhp = (nsc_rmhdr_t *)addr; - nsc_rmmap_t *rmap; - char tname[_NSC_MAXNAME + 1]; - int i; - - (void) printf( - gettext("magic 0x%x ver %d size %d dirty (nvmem systems): %d\n"), - rhp->magic, rhp->ver, rhp->size, rhp->rh_dirty); - - for (i = 0, rmap = rhp->map; - /* LINTED alignment of cast ok */ - rmap < (nsc_rmmap_t *)(addr + len); ++i, ++rmap) { - if (!rmap->name[0]) - continue; - (void) strncpy(tname, rmap->name, _NSC_MAXNAME); - (void) strcpy(&tname[strlen(tname)], " "); - tname[_NSC_MAXNAME] = '\0'; - (void) printf(gettext( - "%d:\tname %s\toffset 0x%x size 0x%x inuse 0x%x\n"), - i, tname, rmap->offset, rmap->size, rmap->inuse); - } -} diff --git a/usr/src/cmd/avs/nsctl/nskernd.c b/usr/src/cmd/avs/nsctl/nskernd.c deleted file mode 100644 index 1a205979d5..0000000000 --- a/usr/src/cmd/avs/nsctl/nskernd.c +++ /dev/null @@ -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); -} |