diff options
author | obrien <obrien@FreeBSD.org> | 2013-02-08 16:10:16 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2013-02-08 16:10:16 +0000 |
commit | 3028e3f8aba938dfd0bf9fda987b8a72140b8027 (patch) | |
tree | b2f038222ff8a70f687652441df00d2b564c8abe /usr.sbin/nfsd | |
parent | 952a6d5a7cd3d3f9007acfa06805262fc04a105f (diff) | |
parent | 1d08d5f677c1dfa810e381073590adbae19cc69f (diff) | |
download | FreeBSD-src-3028e3f8aba938dfd0bf9fda987b8a72140b8027.zip FreeBSD-src-3028e3f8aba938dfd0bf9fda987b8a72140b8027.tar.gz |
Sync with HEAD.
Diffstat (limited to 'usr.sbin/nfsd')
-rw-r--r-- | usr.sbin/nfsd/nfsd.8 | 15 | ||||
-rw-r--r-- | usr.sbin/nfsd/nfsd.c | 123 | ||||
-rw-r--r-- | usr.sbin/nfsd/nfsv4.4 | 4 |
3 files changed, 118 insertions, 24 deletions
diff --git a/usr.sbin/nfsd/nfsd.8 b/usr.sbin/nfsd/nfsd.8 index ea99640..19e5644 100644 --- a/usr.sbin/nfsd/nfsd.8 +++ b/usr.sbin/nfsd/nfsd.8 @@ -41,6 +41,8 @@ server .Op Fl arduteo .Op Fl n Ar num_servers .Op Fl h Ar bindip +.Op Fl maxthreads Ar max_threads +.Op Fl minthreads Ar min_threads .Sh DESCRIPTION The .Nm @@ -74,8 +76,17 @@ Unregister the service with .Xr rpcbind 8 without creating any servers. -.It Fl n -Specifies how many servers to create. +.It Fl n Ar threads +Specifies how many servers to create. This option is equivalent to specifying +.Fl maxthreads +and +.Fl minthreads +with their respective arguments to +.Ar threads . +.It Fl maxthreads Ar threads +Specifies the maximum servers that will be kept around to service requests. +.It Fl minthreads Ar threads +Specifies the minimum servers that will be kept around to service requests. .It Fl h Ar bindip Specifies which IP address or hostname to bind to on the local host. This option is recommended when a host has multiple interfaces. diff --git a/usr.sbin/nfsd/nfsd.c b/usr.sbin/nfsd/nfsd.c index c269e47..0e39138 100644 --- a/usr.sbin/nfsd/nfsd.c +++ b/usr.sbin/nfsd/nfsd.c @@ -53,6 +53,7 @@ static const char rcsid[] = #include <sys/module.h> #include <sys/types.h> #include <sys/stat.h> +#include <sys/sysctl.h> #include <sys/ucred.h> #include <rpc/rpc.h> @@ -71,14 +72,11 @@ static const char rcsid[] = #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <sysexits.h> + +#include <getopt.h> -/* Global defs */ -#ifdef DEBUG -#define syslog(e, s...) fprintf(stderr,s) -static int debug = 1; -#else static int debug = 0; -#endif #define NFSD_STABLERESTART "/var/db/nfs-stablerestart" #define NFSD_STABLEBACKUP "/var/db/nfs-stablerestart.bak" @@ -86,11 +84,26 @@ static int debug = 0; #define DEFNFSDCNT 4 static pid_t children[MAXNFSDCNT]; /* PIDs of children */ static int nfsdcnt; /* number of children */ +static int nfsdcnt_set; +static int minthreads; +static int maxthreads; static int new_syscall; static int run_v4server = 1; /* Force running of nfsv4 server */ static int nfssvc_nfsd; /* Set to correct NFSSVC_xxx flag */ static int stablefd = -1; /* Fd for the stable restart file */ static int backupfd; /* Fd for the backup stable restart file */ +static const char *getopt_shortopts; +static const char *getopt_usage; + +static int minthreads_set; +static int maxthreads_set; + +static struct option longopts[] = { + { "debug", no_argument, &debug, 1 }, + { "minthreads", required_argument, &minthreads_set, 1 }, + { "maxthreads", required_argument, &maxthreads_set, 1 }, + { NULL, 0, NULL, 0} +}; void cleanup(int); void child_cleanup(int); @@ -145,26 +158,28 @@ main(int argc, char **argv) int udpflag, ecode, error, s, srvcnt; int bindhostc, bindanyflag, rpcbreg, rpcbregcnt; int nfssvc_addsock; + int longindex = 0; + const char *lopt; char **bindhost = NULL; pid_t pid; nfsdcnt = DEFNFSDCNT; unregister = reregister = tcpflag = maxsock = 0; bindanyflag = udpflag = connect_type_cnt = bindhostc = 0; -#define GETOPT "ah:n:rdtueo" -#define USAGE "[-ardtueo] [-n num_servers] [-h bindip]" - while ((ch = getopt(argc, argv, GETOPT)) != -1) + getopt_shortopts = "ah:n:rdtueo"; + getopt_usage = + "usage:\n" + " nfsd [-ardtueo] [-h bindip]\n" + " [-n numservers] [--minthreads #] [--maxthreads #]\n"; + while ((ch = getopt_long(argc, argv, getopt_shortopts, longopts, + &longindex)) != -1) switch (ch) { case 'a': bindanyflag = 1; break; case 'n': + nfsdcnt_set = 1; nfsdcnt = atoi(optarg); - if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) { - warnx("nfsd count %d; reset to %d", nfsdcnt, - DEFNFSDCNT); - nfsdcnt = DEFNFSDCNT; - } break; case 'h': bindhostc++; @@ -193,6 +208,14 @@ main(int argc, char **argv) case 'o': run_v4server = 0; break; + case 0: + lopt = longopts[longindex].name; + if (!strcmp(lopt, "minthreads")) { + minthreads = atoi(optarg); + } else if (!strcmp(lopt, "maxthreads")) { + maxthreads = atoi(optarg); + } + break; default: case '?': usage(); @@ -201,6 +224,10 @@ main(int argc, char **argv) udpflag = 1; argv += optind; argc -= optind; + if (minthreads_set && maxthreads_set && minthreads > maxthreads) + errx(EX_USAGE, + "error: minthreads(%d) can't be greater than " + "maxthreads(%d)", minthreads, maxthreads); /* * XXX @@ -209,6 +236,7 @@ main(int argc, char **argv) if (argc > 1) usage(); if (argc == 1) { + nfsdcnt_set = 1; nfsdcnt = atoi(argv[0]); if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) { warnx("nfsd count %d; reset to %d", nfsdcnt, @@ -236,7 +264,7 @@ main(int argc, char **argv) ip6flag = 1; s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); if (s == -1) { - if (errno != EPROTONOSUPPORT) + if (errno != EPROTONOSUPPORT && errno != EAFNOSUPPORT) err(1, "socket"); ip6flag = 0; } else if (getnetconfigent("udp6") == NULL || @@ -356,7 +384,7 @@ main(int argc, char **argv) (void)signal(SIGCHLD, reapchild); (void)signal(SIGUSR2, backup_stable); - openlog("nfsd", LOG_PID, LOG_DAEMON); + openlog("nfsd", LOG_PID | (debug ? LOG_PERROR : 0), LOG_DAEMON); /* * For V4, we open the stablerestart file and call nfssvc() @@ -374,13 +402,13 @@ main(int argc, char **argv) if (run_v4server > 0) { open_stable(&stablefd, &backupfd); if (stablefd < 0) { - syslog(LOG_ERR, "Can't open %s\n", NFSD_STABLERESTART); + syslog(LOG_ERR, "Can't open %s: %m\n", NFSD_STABLERESTART); exit(1); } /* This system call will fail for old kernels, but that's ok. */ nfssvc(NFSSVC_BACKUPSTABLE, NULL); if (nfssvc(NFSSVC_STABLERESTART, (caddr_t)&stablefd) < 0) { - syslog(LOG_ERR, "Can't read stable storage file\n"); + syslog(LOG_ERR, "Can't read stable storage file: %m\n"); exit(1); } nfssvc_addsock = NFSSVC_NFSDADDSOCK; @@ -401,6 +429,16 @@ main(int argc, char **argv) } if (!new_syscall) { + if (nfsdcnt < 1) { + warnx("nfsd count too low %d; reset to %d", nfsdcnt, + DEFNFSDCNT); + nfsdcnt = DEFNFSDCNT; + } + if (nfsdcnt > MAXNFSDCNT) { + warnx("nfsd count too high %d; reset to %d", nfsdcnt, + DEFNFSDCNT); + nfsdcnt = MAXNFSDCNT; + } /* If we use UDP only, we start the last server below. */ srvcnt = tcpflag ? nfsdcnt : nfsdcnt - 1; for (i = 0; i < srvcnt; i++) { @@ -855,7 +893,7 @@ setbindhost(struct addrinfo **ai, const char *bindhost, struct addrinfo hints) void usage(void) { - (void)fprintf(stderr, "usage: nfsd %s\n", USAGE); + (void)fprintf(stderr, "%s", getopt_usage); exit(1); } @@ -923,6 +961,29 @@ nfsd_exit(int status) exit(status); } +static int +get_tuned_nfsdcount(void) +{ + int ncpu, error, tuned_nfsdcnt; + size_t ncpu_size; + + ncpu_size = sizeof(ncpu); + error = sysctlbyname("hw.ncpu", &ncpu, &ncpu_size, NULL, 0); + if (error) { + warnx("sysctlbyname(hw.ncpu) failed defaulting to %d nfs servers", + DEFNFSDCNT); + tuned_nfsdcnt = DEFNFSDCNT; + } else { + tuned_nfsdcnt = ncpu * 8; + } + if (!new_syscall && tuned_nfsdcnt > MAXNFSDCNT) { + warnx("nfsd count %d; truncated to %d", tuned_nfsdcnt, + MAXNFSDCNT); + tuned_nfsdcnt = MAXNFSDCNT; + } + return tuned_nfsdcnt; +} + void start_server(int master) { @@ -952,8 +1013,28 @@ start_server(int master) } } nfsdargs.principal = principal; - nfsdargs.minthreads = nfsdcnt; - nfsdargs.maxthreads = nfsdcnt; + + if (minthreads_set) { + nfsdargs.minthreads = minthreads; + if (!maxthreads_set) + nfsdargs.maxthreads = minthreads; + } + if (maxthreads_set) { + nfsdargs.maxthreads = maxthreads; + if (!minthreads_set) + nfsdargs.minthreads = maxthreads; + } + if (nfsdcnt_set) { + nfsdargs.minthreads = nfsdcnt; + nfsdargs.maxthreads = nfsdcnt; + } + if (!minthreads_set && !maxthreads_set && !nfsdcnt_set) { + int tuned_nfsdcnt; + + tuned_nfsdcnt = get_tuned_nfsdcount(); + nfsdargs.minthreads = tuned_nfsdcnt; + nfsdargs.maxthreads = tuned_nfsdcnt; + } error = nfssvc(nfssvc_nfsd, &nfsdargs); if (error < 0 && errno == EAUTH) { /* diff --git a/usr.sbin/nfsd/nfsv4.4 b/usr.sbin/nfsd/nfsv4.4 index d2c19ed..679bb69 100644 --- a/usr.sbin/nfsd/nfsv4.4 +++ b/usr.sbin/nfsd/nfsv4.4 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 15, 2011 +.Dd December 23, 2012 .Dt NFSV4 4 .Os .Sh NAME @@ -98,6 +98,8 @@ allows a limited subset of operations to be performed on non-exported subtrees of the local file system, so that traversal of the tree to the exported subtrees is possible. As such, the ``<rootdir>'' can be in a non-exported file system. +The exception is ZFS, which checks exports and, as such, all ZFS file systems +below the ``<rootdir>'' must be exported. However, the entire tree that is rooted at that point must be in local file systems that are of types that can be NFS exported. |