nfsd.c revision ed629aef897f4494e9359e52811ca81d4b278489
* 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. * See the License for the specific language governing permissions * and limitations under the License. * When distributing Covered Code, include this CDDL HEADER in each * 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] * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ * University Copyright- Copyright (c) 1982, 1986, 1988 * The Regents of the University of California * University Acknowledgment- Portions of this document are derived from * software developed by the University of California, Berkeley, and its /* quiesce requests will be ignored if nfs_server_vers_max < QUIESCE_VERSMIN */ /* DSS: distributed stable storage */ /* static NETSELDECL(defaultprotos)[] = { NC_UDP, NC_TCP, NULL }; */ * The following are all globals used by routines in nfs_tbind.c. /* used by cots_listen_event() */ * Keep track of min/max versions of NFS protocol to be started. * Start with the defaults (min == 2, max == 3). We have the * capability of starting vers=4 but only if the user requests it. * Set the default for server delegation enablement and set per int maxservers =
1;
/* zero allows inifinte number of threads */ * Initializations that require more privileges than we need to run. " sufficient privileges\n",
av[0]);
* Read in the values from config file first before we check * command line options so the options override the file. /* close defaults file */ * Conflict options error messages. "the following options can be specified\n" "\tNFSD_PROTOCOL=protocol\n" "\tNFSD_DEVICE=device\n\n");
* 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. /* first "-s" option encountered? */ * Allocate maximum possible space * required given cmdline arg count; * "-s <path>" consumes two args. "dss paths malloc failed\n",
"%s: -s pathname too long.\n",
av[0]);
* Conflict options error messages. "the following options can be specified\n" "NFS version 4 is not supported " "with the UDP protocol. Exiting\n");
"NFS version 4 is not supported " "with the UDP protocol.\n");
* If there is exactly one more argument, it is the number of * If there are two or more arguments, then this is a usage error. * Check the ranges for min/max version specified * 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. * 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 * Set current dir to server root * 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 /* daemon was already running */ * 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. * Block all signals till we spawn other "Number of servers not specified. Using default of %d.",
* Make sure to unregister any previous versions in case the * user is reconfiguring the server in interesting ways. * Set up kernel RPC thread pool for the NFS server. * Set up blocked thread to do LWP creation on behalf of the kernel. * RDMA start and stop thread. * Per pool RDMA listener creation and * start rdma services and block in the kernel. * (only if proto or provider is not set to TCP or UDP) "Can't set up RDMA creator thread : %s",
* Now open up for signal delivery * Build a protocol block list for registration. /* XXX - this needs work to get the version just right */ /* there's more than one match for the same protocol */ "couldn't find netconfig entry for protocol %s",
* nfsd is up and running as far as we are concerned. * Get rid of unneeded privileges. * Poll for non-data control events on the transport descriptors. * If we get here, something failed in poll_for_action(). * Establish NFS service thread. * If no version left, silently do nothing, previous * checks will have assured at least TCP is available. "usage: %s [ -a ] [ -c max_conns ] [ -p protocol ] [ -t transport ] ",
MyName);
(
void)
fprintf(
stderr,
"\n[ -l listen_backlog ] [ nservers ]\n");
"\twhere -a causes <nservers> to be started on each appropriate transport,\n");
"\tmax_conns is the maximum number of concurrent connections allowed,\n");
(
void)
fprintf(
stderr,
"\t\tand max_conns must be a decimal number");
(
void)
fprintf(
stderr,
"\tprotocol is a protocol identifier,\n");
"\ttransport is a transport provider name (i.e. device),\n");
"\tlisten_backlog is the TCP listen backlog,\n");
"\tand <nservers> must be a decimal number > zero.\n");
* Issue nfssys system call to flush all logging buffers asynchronously. * NOTICE: It is extremely important to flush NFS logging buffers when * nfsd exits. When the system is halted or rebooted nfslogd * may not have an opportunity to flush the buffers. * Flush logging buffers and exit. * Request that server quiesce, then (nfsd) exit. For subsequent warm start. * This is a Contracted Project Private interface, for the sole use * of Sun Cluster HA-NFS. See PSARC/2004/497. * Equivalent to SIGTERM handler if nfs_server_vers_max < QUIESCE_VERSMIN. /* Request server quiesce at next shutdown */ * ENOENT is returned if there is no matching SVC pool * for the id. Possibly because the pool is not yet setup. * In this case, just exit as if no error. For all other errors, * just return and allow caller to retry. "_nfssys(NFS4_SVC_REQUEST_QUIESCE) failed: %s",
/* Flush logging buffers */ * DSS: distributed stable storage. * Create leaf directories as required, keeping an eye on path * lengths. Calls exit(1) on failure. * The pathnames passed in must already exist, and must be writeable by nfsd. * Note: the leaf directories under NFS4_VAR_DIR are not created here; * they're created at pkg install. * Create the temporary storage used by dss_mkleafdir() here, * rather than in that function, so that it only needs to be * done once, rather than once for each call. Too big to put * on the function's stack. for (i = 0; i <
npaths; i++) {
* Create "leaf" in "dir" (which must already exist). * leaf: should start with a '/' /* MAXPATHLEN includes the terminating NUL */ /* the directory may already exist: that's OK */ * Create the storage dirs, and pass the path list to the kernel. * This requires the nfssrv module to be loaded; the _nfssys() syscall * will fail ENOTSUP if it is not. * Use libnvpair(3LIB) to pass the data to the kernel. * We need to remove duplicate paths; this might be user error * in the general case, but HA-NFSv4 can also cause this. * Sort the pathnames array, and NULL out duplicates, * then write the non-NULL entries to a new array. * Sorting will also allow the kernel to optimise its searches. /* now NULL out any duplicates */ /* skip i over any of its NULLed duplicates */ /* finally, write the non-NULL entries to a new array */ for (i = 0, j = 0; i <
npaths; i++)
/* Create directories to store the distributed state files */ /* Create the name-value pair list */ /* Add the pathnames array as a single name-value pair */ * Pack list into contiguous memory, for passing to kernel. * nvlist_pack() will allocate the memory for the buffer, * which we should free() when no longer needed. * NV_ENCODE_XDR for safety across ILP32/LP64 kernel boundary. /* Now we have the packed buffer, we no longer need the list */ * Let the kernel know in advance how big the buffer is. * NOTE: we cannot just pass buflen, since size_t is a long, and * thus a different size between ILP32 userland and LP64 kernel. * Use an int for the transfer, since that should be big enough; * this is a no-op at the moment, here, since nfsd is 32-bit, but "_nfssys(NFS4_DSS_SETPATHS_SIZE) failed: %s. ",
/* Pass the packed buffer to the kernel */ * The kernel has now unpacked the buffer and extracted the * pathnames array, we no longer need the buffer. * Quick sort string compare routine, for qsort. * Needed to make arg types correct. char *
s1 = *((
char **)
p1);
char *
s2 = *((
char **)
p2);