summaryrefslogtreecommitdiffstats
path: root/usr.sbin/nfsd
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2013-02-08 16:10:16 +0000
committerobrien <obrien@FreeBSD.org>2013-02-08 16:10:16 +0000
commit3028e3f8aba938dfd0bf9fda987b8a72140b8027 (patch)
treeb2f038222ff8a70f687652441df00d2b564c8abe /usr.sbin/nfsd
parent952a6d5a7cd3d3f9007acfa06805262fc04a105f (diff)
parent1d08d5f677c1dfa810e381073590adbae19cc69f (diff)
downloadFreeBSD-src-3028e3f8aba938dfd0bf9fda987b8a72140b8027.zip
FreeBSD-src-3028e3f8aba938dfd0bf9fda987b8a72140b8027.tar.gz
Sync with HEAD.
Diffstat (limited to 'usr.sbin/nfsd')
-rw-r--r--usr.sbin/nfsd/nfsd.815
-rw-r--r--usr.sbin/nfsd/nfsd.c123
-rw-r--r--usr.sbin/nfsd/nfsv4.44
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.
OpenPOWER on IntegriCloud