/* ARGSUSED */ int main(int argc, char **argv) { MyName = argv[0]; (void) setlocale(LC_ALL, ""); (void) textdomain(TEXT_DOMAIN); (void) _create_daemon_lock(SPED, DAEMON_UID, DAEMON_GID); /* * Initialize the daemon to basic + sys_nfs */ if (__init_daemon_priv(PU_RESETGROUPS|PU_CLEARLIMITSET, DAEMON_UID, DAEMON_GID, PRIV_SYS_NFS, (char *)NULL) == -1) { (void) fprintf(stderr, gettext("%s PRIV_SYS_NFS privilege " "missing\n"), MyName); exit(1); } daemonize(); /* Basic privileges we don't need, remove from E/P. */ __fini_daemon_priv(PRIV_PROC_EXEC, PRIV_PROC_FORK, PRIV_FILE_LINK_ANY, PRIV_PROC_SESSION, PRIV_PROC_INFO, (char *)NULL); switch (_enter_daemon_lock(SPED)) { case 0: break; case -1: syslog(LOG_ERR, "error locking for %s: %s", SPED, strerror(errno)); exit(3); default: /* daemon was already running */ exit(0); } openlog(MyName, LOG_PID | LOG_NDELAY, LOG_DAEMON); /* Initialize daemon subsystems */ daemon_init(); /* start services */ return (start_svcs()); }
int main(int ac, char *av[]) { char *dir = "/"; int allflag = 0; int df_allflag = 0; int opt_cnt = 0; int maxservers = 1; /* zero allows inifinte number of threads */ int maxservers_set = 0; int logmaxservers = 0; int pid; int i; char *provider = (char *)NULL; char *df_provider = (char *)NULL; struct protob *protobp0, *protobp; NETSELDECL(proto) = NULL; NETSELDECL(df_proto) = NULL; NETSELPDECL(providerp); char *defval; boolean_t can_do_mlp; uint_t dss_npaths = 0; char **dss_pathnames = NULL; sigset_t sgset; char name[PATH_MAX], value[PATH_MAX]; int ret, bufsz; int pipe_fd = -1; MyName = *av; /* * Initializations that require more privileges than we need to run. */ (void) _create_daemon_lock(NFSD, DAEMON_UID, DAEMON_GID); svcsetprio(); can_do_mlp = priv_ineffect(PRIV_NET_BINDMLP); if (__init_daemon_priv(PU_RESETGROUPS|PU_CLEARLIMITSET, DAEMON_UID, DAEMON_GID, PRIV_SYS_NFS, can_do_mlp ? PRIV_NET_BINDMLP : NULL, NULL) == -1) { (void) fprintf(stderr, "%s should be run with" " sufficient privileges\n", av[0]); exit(1); } (void) enable_extended_FILE_stdio(-1, -1); /* * Read in the values from SMF first before we check * command line options so the options override SMF values. */ bufsz = PATH_MAX; ret = nfs_smf_get_prop("max_connections", value, DEFAULT_INSTANCE, SCF_TYPE_INTEGER, NFSD, &bufsz); if (ret == SA_OK) { errno = 0; max_conns_allowed = strtol(value, (char **)NULL, 10); if (errno != 0) max_conns_allowed = -1; } bufsz = PATH_MAX; ret = nfs_smf_get_prop("listen_backlog", value, DEFAULT_INSTANCE, SCF_TYPE_INTEGER, NFSD, &bufsz); if (ret == SA_OK) { errno = 0; listen_backlog = strtol(value, (char **)NULL, 10); if (errno != 0) { listen_backlog = 32; } } bufsz = PATH_MAX; ret = nfs_smf_get_prop("protocol", value, DEFAULT_INSTANCE, SCF_TYPE_ASTRING, NFSD, &bufsz); if ((ret == SA_OK) && strlen(value) > 0) { df_proto = strdup(value); opt_cnt++; if (strncasecmp("ALL", value, 3) == 0) { free(df_proto); df_proto = NULL; df_allflag = 1; } } bufsz = PATH_MAX; ret = nfs_smf_get_prop("device", value, DEFAULT_INSTANCE, SCF_TYPE_ASTRING, NFSD, &bufsz); if ((ret == SA_OK) && strlen(value) > 0) { df_provider = strdup(value); opt_cnt++; } bufsz = PATH_MAX; ret = nfs_smf_get_prop("servers", value, DEFAULT_INSTANCE, SCF_TYPE_INTEGER, NFSD, &bufsz); if (ret == SA_OK) { errno = 0; maxservers = strtol(value, (char **)NULL, 10); if (errno != 0) maxservers = 1; else maxservers_set = 1; } bufsz = 4; ret = nfs_smf_get_prop("server_versmin", value, DEFAULT_INSTANCE, SCF_TYPE_INTEGER, NFSD, &bufsz); if (ret == SA_OK) nfs_server_vers_min = strtol(value, (char **)NULL, 10); bufsz = 4; ret = nfs_smf_get_prop("server_versmax", value, DEFAULT_INSTANCE, SCF_TYPE_INTEGER, NFSD, &bufsz); if (ret == SA_OK) nfs_server_vers_max = strtol(value, (char **)NULL, 10); bufsz = PATH_MAX; ret = nfs_smf_get_prop("server_delegation", value, DEFAULT_INSTANCE, SCF_TYPE_ASTRING, NFSD, &bufsz); if (ret == SA_OK) if (strncasecmp(value, "off", 3) == 0) nfs_server_delegation = FALSE; /* * Conflict options error messages. */ if (opt_cnt > 1) { (void) fprintf(stderr, "\nConflicting options, only one of " "the following options can be specified\n" "in SMF:\n" "\tprotocol=ALL\n" "\tprotocol=protocol\n" "\tdevice=devicename\n\n"); usage(); } opt_cnt = 0; while ((i = getopt(ac, av, "ac:p:s:t:l:")) != EOF) { switch (i) { case 'a': free(df_proto); df_proto = NULL; free(df_provider); df_provider = NULL; allflag = 1; opt_cnt++; break; case 'c': max_conns_allowed = atoi(optarg); break; case 'p': proto = optarg; df_allflag = 0; opt_cnt++; break; /* * DSS: NFSv4 distributed stable storage. * * This is a Contracted Project Private interface, for * the sole use of Sun Cluster HA-NFS. See PSARC/2006/313. */ case 's': if (strlen(optarg) < MAXPATHLEN) { /* first "-s" option encountered? */ if (dss_pathnames == NULL) { /* * Allocate maximum possible space * required given cmdline arg count; * "-s <path>" consumes two args. */ size_t sz = (ac / 2) * sizeof (char *); dss_pathnames = (char **)malloc(sz); if (dss_pathnames == NULL) { (void) fprintf(stderr, "%s: " "dss paths malloc failed\n", av[0]); exit(1); } (void) memset(dss_pathnames, 0, sz); } dss_pathnames[dss_npaths] = optarg; dss_npaths++; } else { (void) fprintf(stderr, "%s: -s pathname too long.\n", av[0]); } break; case 't': provider = optarg; df_allflag = 0; opt_cnt++; break; case 'l': listen_backlog = atoi(optarg); break; case '?': usage(); /* NOTREACHED */ } } allflag = df_allflag; if (proto == NULL) proto = df_proto; if (provider == NULL) provider = df_provider; /* * Conflict options error messages. */ if (opt_cnt > 1) { (void) fprintf(stderr, "\nConflicting options, only one of " "the following options can be specified\n" "on the command line:\n" "\t-a\n" "\t-p protocol\n" "\t-t transport\n\n"); usage(); } if (proto != NULL && strncasecmp(proto, NC_UDP, strlen(NC_UDP)) == 0) { if (nfs_server_vers_max == NFS_V4) { if (nfs_server_vers_min == NFS_V4) { fprintf(stderr, "NFS version 4 is not supported " "with the UDP protocol. Exiting\n"); exit(3); } else { fprintf(stderr, "NFS version 4 is not supported " "with the UDP protocol.\n"); } } } /* * If there is exactly one more argument, it is the number of * servers. */ if (optind == ac - 1) { maxservers = atoi(av[optind]); maxservers_set = 1; } /* * If there are two or more arguments, then this is a usage error. */ else if (optind < ac - 1) usage(); /* * Check the ranges for min/max version specified */ else if ((nfs_server_vers_min > nfs_server_vers_max) || (nfs_server_vers_min < NFS_VERSMIN) || (nfs_server_vers_max > NFS_VERSMAX)) usage(); /* * There are no additional arguments, and we haven't set maxservers * explicitly via the config file, we use a default number of * servers. We will log this. */ else if (maxservers_set == 0) logmaxservers = 1; /* * Basic Sanity checks on options * * max_conns_allowed must be positive, except for the special * value of -1 which is used internally to mean unlimited, -1 isn't * documented but we allow it anyway. * * maxservers must be positive * listen_backlog must be positive or zero */ if (((max_conns_allowed != -1) && (max_conns_allowed <= 0)) || (listen_backlog < 0) || (maxservers <= 0)) { usage(); } /* * Set current dir to server root */ if (chdir(dir) < 0) { (void) fprintf(stderr, "%s: ", MyName); perror(dir); exit(1); } #ifndef DEBUG pipe_fd = daemonize_init(); #endif openlog(MyName, LOG_PID | LOG_NDELAY, LOG_DAEMON); /* * establish our lock on the lock file and write our pid to it. * exit if some other process holds the lock, or if there's any * error in writing/locking the file. */ pid = _enter_daemon_lock(NFSD); switch (pid) { case 0: break; case -1: fprintf(stderr, "error locking for %s: %s\n", NFSD, strerror(errno)); exit(2); default: /* daemon was already running */ exit(0); } /* * If we've been given a list of paths to be used for distributed * stable storage, and provided we're going to run a version * that supports it, setup the DSS paths. */ if (dss_pathnames != NULL && nfs_server_vers_max >= DSS_VERSMIN) { if (dss_init(dss_npaths, dss_pathnames) != 0) { fprintf(stderr, "%s", "dss_init failed. Exiting.\n"); exit(1); } } /* * Block all signals till we spawn other * threads. */ (void) sigfillset(&sgset); (void) thr_sigsetmask(SIG_BLOCK, &sgset, NULL); if (logmaxservers) { fprintf(stderr, "Number of servers not specified. Using default of %d.\n", maxservers); } /* * Make sure to unregister any previous versions in case the * user is reconfiguring the server in interesting ways. */ svc_unreg(NFS_PROGRAM, NFS_VERSION); svc_unreg(NFS_PROGRAM, NFS_V3); svc_unreg(NFS_PROGRAM, NFS_V4); svc_unreg(NFS_ACL_PROGRAM, NFS_ACL_V2); svc_unreg(NFS_ACL_PROGRAM, NFS_ACL_V3); /* * Set up kernel RPC thread pool for the NFS server. */ if (nfssvcpool(maxservers)) { fprintf(stderr, "Can't set up kernel NFS service: %s. " "Exiting.\n", strerror(errno)); exit(1); } /* * Set up blocked thread to do LWP creation on behalf of the kernel. */ if (svcwait(NFS_SVCPOOL_ID)) { fprintf(stderr, "Can't set up NFS pool creator: %s. Exiting.\n", strerror(errno)); exit(1); } /* * RDMA start and stop thread. * Per pool RDMA listener creation and * destructor thread. * * start rdma services and block in the kernel. * (only if proto or provider is not set to TCP or UDP) */ if ((proto == NULL) && (provider == NULL)) { if (svcrdma(NFS_SVCPOOL_ID, nfs_server_vers_min, nfs_server_vers_max, nfs_server_delegation)) { fprintf(stderr, "Can't set up RDMA creator thread : %s\n", strerror(errno)); } } /* * Now open up for signal delivery */ (void) thr_sigsetmask(SIG_UNBLOCK, &sgset, NULL); sigset(SIGTERM, sigflush); sigset(SIGUSR1, quiesce); /* * Build a protocol block list for registration. */ protobp0 = protobp = (struct protob *)malloc(sizeof (struct protob)); protobp->serv = "NFS"; protobp->versmin = nfs_server_vers_min; protobp->versmax = nfs_server_vers_max; protobp->program = NFS_PROGRAM; protobp->next = (struct protob *)malloc(sizeof (struct protob)); protobp = protobp->next; protobp->serv = "NFS_ACL"; /* not used */ protobp->versmin = nfs_server_vers_min; /* XXX - this needs work to get the version just right */ protobp->versmax = (nfs_server_vers_max > NFS_ACL_V3) ? NFS_ACL_V3 : nfs_server_vers_max; protobp->program = NFS_ACL_PROGRAM; protobp->next = (struct protob *)NULL; if (allflag) { if (do_all(protobp0, nfssvc) == -1) { fprintf(stderr, "setnetconfig failed : %s\n", strerror(errno)); exit(1); } } else if (proto) { /* there's more than one match for the same protocol */ struct netconfig *nconf; NCONF_HANDLE *nc; bool_t protoFound = FALSE; if ((nc = setnetconfig()) == (NCONF_HANDLE *) NULL) { fprintf(stderr, "setnetconfig failed : %s\n", strerror(errno)); goto done; } while (nconf = getnetconfig(nc)) { if (strcmp(nconf->nc_proto, proto) == 0) { protoFound = TRUE; do_one(nconf->nc_device, NULL, protobp0, nfssvc); } } (void) endnetconfig(nc); if (protoFound == FALSE) { fprintf(stderr, "couldn't find netconfig entry for protocol %s\n", proto); } } else if (provider) do_one(provider, proto, protobp0, nfssvc); else { for (providerp = defaultproviders; *providerp != NULL; providerp++) { provider = *providerp; do_one(provider, NULL, protobp0, nfssvc); } } done: free(protobp); free(protobp0); if (num_fds == 0) { fprintf(stderr, "Could not start NFS service for any protocol." " Exiting.\n"); exit(1); } end_listen_fds = num_fds; /* * nfsd is up and running as far as we are concerned. */ daemonize_fini(pipe_fd); /* * Get rid of unneeded privileges. */ __fini_daemon_priv(PRIV_PROC_FORK, PRIV_PROC_EXEC, PRIV_PROC_SESSION, PRIV_FILE_LINK_ANY, PRIV_PROC_INFO, (char *)NULL); /* * Poll for non-data control events on the transport descriptors. */ poll_for_action(); /* * If we get here, something failed in poll_for_action(). */ return (1); }
int main(int argc, char *argv[]) { int pid; int c; int rpc_svc_mode = RPC_SVC_MT_AUTO; int maxthreads; int maxrecsz = RPC_MAXDATASIZE; bool_t exclbind = TRUE; bool_t can_do_mlp; long thr_flags = (THR_NEW_LWP|THR_DAEMON); /* * Mountd requires uid 0 for: * /etc/rmtab updates (we could chown it to daemon) * /etc/dfs/dfstab reading (it wants to lock out share which * doesn't do any locking before first truncate; * NFS share does; should use fcntl locking instead) * Needed privileges: * auditing * nfs syscall * file dac search (so it can stat all files) * Optional privileges: * MLP */ can_do_mlp = priv_ineffect(PRIV_NET_BINDMLP); if (__init_daemon_priv(PU_RESETGROUPS|PU_CLEARLIMITSET, -1, -1, PRIV_SYS_NFS, PRIV_PROC_AUDIT, PRIV_FILE_DAC_SEARCH, can_do_mlp ? PRIV_NET_BINDMLP : NULL, NULL) == -1) { (void) fprintf(stderr, "%s must be run as with sufficient privileges\n", argv[0]); exit(1); } maxthreads = 0; while ((c = getopt(argc, argv, "vrm:")) != EOF) { switch (c) { case 'v': verbose++; break; case 'r': rejecting = 1; break; case 'm': maxthreads = atoi(optarg); if (maxthreads < 1) { (void) fprintf(stderr, "%s: must specify positive maximum threads count, using default\n", argv[0]); maxthreads = 0; } break; } } /* * Read in the NFS version values from config file. */ if ((defopen(NFSADMIN)) == 0) { char *defval; int defvers; if ((defval = defread("NFS_SERVER_VERSMIN=")) != NULL) { errno = 0; defvers = strtol(defval, (char **)NULL, 10); if (errno == 0) { mount_vers_min = defvers; /* * special because NFSv2 is * supported by mount v1 & v2 */ if (defvers == NFS_VERSION) mount_vers_min = MOUNTVERS; } } if ((defval = defread("NFS_SERVER_VERSMAX=")) != NULL) { errno = 0; defvers = strtol(defval, (char **)NULL, 10); if (errno == 0) { mount_vers_max = defvers; } } /* close defaults file */ defopen(NULL); } /* * Sanity check versions, * even though we may get versions > MOUNTVERS3, we still need * to start nfsauth service, so continue on regardless of values. */ if (mount_vers_min > mount_vers_max) { syslog(LOG_NOTICE, "NFS_SERVER_VERSMIN > NFS_SERVER_VERSMAX"); mount_vers_max = mount_vers_min; } (void) setlocale(LC_ALL, ""); (void) rwlock_init(&sharetab_lock, USYNC_THREAD, NULL); (void) mutex_init(&mnttab_lock, USYNC_THREAD, NULL); netgroup_init(); #if !defined(TEXT_DOMAIN) #define TEXT_DOMAIN "SYS_TEST" #endif (void) textdomain(TEXT_DOMAIN); /* Don't drop core if the NFS module isn't loaded. */ (void) signal(SIGSYS, SIG_IGN); (void) signal(SIGHUP, sigexit); (void) signal(SIGCLD, sigexit); switch (fork()) { case 0: /* child */ break; case -1: perror("mountd: can't fork"); exit(1); default: /* parent */ for (;;) (void) pause(); /* NOTREACHED */ } (void) signal(SIGHUP, SIG_DFL); (void) signal(SIGCLD, SIG_DFL); /* * If we coredump it'll be in /core */ if (chdir("/") < 0) syslog(LOG_ERR, "chdir /: %m"); /* * Close existing file descriptors, open "/dev/null" as * standard input, output, and error, and detach from * controlling terminal. */ closefrom(0); (void) open("/dev/null", O_RDONLY); (void) open("/dev/null", O_WRONLY); (void) dup(1); (void) setsid(); openlog("mountd", LOG_PID, LOG_DAEMON); /* * establish our lock on the lock file and write our pid to it. * exit if some other process holds the lock, or if there's any * error in writing/locking the file. */ pid = _enter_daemon_lock(MOUNTD); switch (pid) { case 0: break; case -1: syslog(LOG_ERR, "error locking for %s: %s", MOUNTD, strerror(errno)); exit(2); default: /* daemon was already running */ exit(0); } audit_mountd_setup(); /* BSM */ /* * Tell RPC that we want automatic thread mode. * A new thread will be spawned for each request. */ if (!rpc_control(RPC_SVC_MTMODE_SET, &rpc_svc_mode)) { syslog(LOG_ERR, "unable to set automatic MT mode"); exit(1); } /* * Enable non-blocking mode and maximum record size checks for * connection oriented transports. */ if (!rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrecsz)) { syslog(LOG_INFO, "unable to set RPC max record size"); } /* * Prevent our non-priv udp and tcp ports bound w/wildcard addr * from being hijacked by a bind to a more specific addr. */ if (!rpc_control(__RPC_SVC_EXCLBIND_SET, &exclbind)) { syslog(LOG_INFO, "warning: unable to set udp/tcp EXCLBIND"); } /* * If the -m argument was specified, then set the * maximum number of threads to the value specified. */ if (maxthreads > 0 && !rpc_control(RPC_SVC_THRMAX_SET, &maxthreads)) { syslog(LOG_ERR, "unable to set maxthreads"); exit(1); } /* * Make sure to unregister any previous versions in case the * user is reconfiguring the server in interesting ways. */ svc_unreg(MOUNTPROG, MOUNTVERS); svc_unreg(MOUNTPROG, MOUNTVERS_POSIX); svc_unreg(MOUNTPROG, MOUNTVERS3); /* * Create the nfsauth thread with same signal disposition * as the main thread. We need to create a separate thread * since mountd() will be both an RPC server (for remote * traffic) _and_ a doors server (for kernel upcalls). */ if (thr_create(NULL, 0, nfsauth_svc, 0, thr_flags, &nfsauth_thread)) { syslog(LOG_ERR, gettext("Failed to create NFSAUTH svc thread")); exit(2); } /* * Create datagram and connection oriented services */ if (mount_vers_max >= MOUNTVERS) { if (svc_create(mnt, MOUNTPROG, MOUNTVERS, "datagram_v") == 0) { syslog(LOG_ERR, "couldn't register datagram_v MOUNTVERS"); exit(1); } if (svc_create(mnt, MOUNTPROG, MOUNTVERS, "circuit_v") == 0) { syslog(LOG_ERR, "couldn't register circuit_v MOUNTVERS"); exit(1); } } if (mount_vers_max >= MOUNTVERS_POSIX) { if (svc_create(mnt, MOUNTPROG, MOUNTVERS_POSIX, "datagram_v") == 0) { syslog(LOG_ERR, "couldn't register datagram_v MOUNTVERS_POSIX"); exit(1); } if (svc_create(mnt, MOUNTPROG, MOUNTVERS_POSIX, "circuit_v") == 0) { syslog(LOG_ERR, "couldn't register circuit_v MOUNTVERS_POSIX"); exit(1); } } if (mount_vers_max >= MOUNTVERS3) { if (svc_create(mnt, MOUNTPROG, MOUNTVERS3, "datagram_v") == 0) { syslog(LOG_ERR, "couldn't register datagram_v MOUNTVERS3"); exit(1); } if (svc_create(mnt, MOUNTPROG, MOUNTVERS3, "circuit_v") == 0) { syslog(LOG_ERR, "couldn't register circuit_v MOUNTVERS3"); exit(1); } } /* * Start serving */ rmtab_load(); (void) kill(getppid(), SIGHUP); /* Get rid of the most dangerous basic privileges. */ __fini_daemon_priv(PRIV_PROC_EXEC, PRIV_PROC_INFO, PRIV_PROC_SESSION, (char *)NULL); svc_run(); syslog(LOG_ERR, "Error: svc_run shouldn't have returned"); abort(); /* NOTREACHED */ return (0); }
int main(int argc, char *argv[]) { int pid; int i; struct protob *protobp; struct flock f; pid_t pi; struct svcpool_args cb_svcpool; MyName = "nfs4cbd"; Mysvc4 = nfs4svc; #ifndef DEBUG /* * Close existing file descriptors, open "/dev/null" as * standard input, output, and error, and detach from * controlling terminal. */ closefrom(0); (void) open("/dev/null", O_RDONLY); (void) open("/dev/null", O_WRONLY); (void) dup(1); (void) setsid(); #endif /* * create a child to continue our work * Parent's exit will tell mount command we're ready to go */ if ((pi = fork()) > 0) { exit(0); } if (pi == -1) { (void) syslog(LOG_ERR, "Could not start NFS4_CALLBACK service"); exit(1); } (void) _create_daemon_lock(NFS4CBD, DAEMON_UID, DAEMON_GID); svcsetprio(); if (__init_daemon_priv(PU_RESETGROUPS|PU_CLEARLIMITSET, DAEMON_UID, DAEMON_GID, PRIV_SYS_NFS, (char *)NULL) == -1) { (void) fprintf(stderr, "%s must be run with sufficient" " privileges\n", argv[0]); exit(1); } /* Basic privileges we don't need, remove from E/P. */ __fini_daemon_priv(PRIV_PROC_EXEC, PRIV_PROC_FORK, PRIV_FILE_LINK_ANY, PRIV_PROC_SESSION, PRIV_PROC_INFO, (char *)NULL); /* * establish our lock on the lock file and write our pid to it. * exit if some other process holds the lock, or if there's any * error in writing/locking the file. */ pid = _enter_daemon_lock(NFS4CBD); switch (pid) { case 0: break; case -1: syslog(LOG_ERR, "error locking for %s: %s", NFS4CBD, strerror(errno)); exit(2); default: /* daemon was already running */ exit(0); } openlog(MyName, LOG_PID | LOG_NDELAY, LOG_DAEMON); cb_svcpool.id = NFS_CB_SVCPOOL_ID; cb_svcpool.maxthreads = 0; cb_svcpool.redline = 0; cb_svcpool.qsize = 0; cb_svcpool.timeout = 0; cb_svcpool.stksize = 0; cb_svcpool.max_same_xprt = 0; /* create a SVC_POOL for the nfsv4 callback deamon */ if (_nfssys(SVCPOOL_CREATE, &cb_svcpool)) { (void) syslog(LOG_ERR, "can't setup NFS_CB SVCPOOL: Exiting"); exit(1); } /* * Set up blocked thread to do LWP creation on behalf of the kernel. */ if (svcwait(NFS_CB_SVCPOOL_ID)) { (void) syslog(LOG_ERR, "Can't set up NFS_CB LWP creator: Exiting"); exit(1); } /* * Build a protocol block list for registration. */ protobp = (struct protob *)malloc(sizeof (struct protob)); protobp->serv = "NFS4_CALLBACK"; protobp->versmin = NFS_CB; protobp->versmax = NFS_CB; protobp->program = NFS4_CALLBACK; protobp->next = NULL; if (do_all(protobp, NULL, 0) == -1) { exit(1); } free(protobp); if (num_fds == 0) { (void) syslog(LOG_ERR, "Could not start NFS4_CALLBACK service for any protocol"); exit(1); } end_listen_fds = num_fds; /* * Poll for non-data control events on the transport descriptors. */ poll_for_action(); /* * If we get here, something failed in poll_for_action(). */ return (1); }
int main(int argc, char *argv[]) { pid_t pid; int c, error; struct rlimit rlset; char *defval; /* * There is no check for non-global zone and Trusted Extensions. * Reparsed works in both of these environments as long as the * services that use reparsed are supported. */ MyName = argv[0]; if (geteuid() != 0) { syslog(LOG_ERR, "%s must be run as root", MyName); exit(1); } while ((c = getopt(argc, argv, REPARSED_CMD_OPTS)) != EOF) { switch (c) { case 'v': verbose++; break; default: usage(); } } daemonize(); openlog(MyName, LOG_PID | LOG_NDELAY, LOG_DAEMON); (void) _create_daemon_lock(REPARSED, DAEMON_UID, DAEMON_GID); (void) enable_extended_FILE_stdio(-1, -1); switch (_enter_daemon_lock(REPARSED)) { case 0: break; case -1: syslog(LOG_ERR, "Error locking for %s", REPARSED); exit(2); default: /* daemon was already running */ exit(0); } (void) signal(SIGHUP, warn_hup); /* * Make the process a privilege aware daemon. * Only "basic" privileges are required. * */ if (__init_daemon_priv(PU_RESETGROUPS|PU_CLEARLIMITSET, 0, 0, (char *)NULL) == -1) { syslog(LOG_ERR, "should be run with sufficient privileges"); exit(3); } /* * Clear basic privileges not required by reparsed. */ __fini_daemon_priv(PRIV_PROC_FORK, PRIV_PROC_EXEC, PRIV_PROC_SESSION, PRIV_FILE_LINK_ANY, PRIV_PROC_INFO, (char *)NULL); return (start_reparsed_svcs()); }