From owner-svn-src-head@FreeBSD.ORG Tue Nov 27 22:34:46 2012 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id C6B7B5BD; Tue, 27 Nov 2012 22:34:46 +0000 (UTC) (envelope-from alfred@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id ADBFD8FC15; Tue, 27 Nov 2012 22:34:46 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id qARMYkTs074157; Tue, 27 Nov 2012 22:34:46 GMT (envelope-from alfred@svn.freebsd.org) Received: (from alfred@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id qARMYk0D074156; Tue, 27 Nov 2012 22:34:46 GMT (envelope-from alfred@svn.freebsd.org) Message-Id: <201211272234.qARMYk0D074156@svn.freebsd.org> From: Alfred Perlstein Date: Tue, 27 Nov 2012 22:34:46 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r243637 - head/usr.sbin/nfsd X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 27 Nov 2012 22:34:46 -0000 Author: alfred Date: Tue Nov 27 22:34:46 2012 New Revision: 243637 URL: http://svnweb.freebsd.org/changeset/base/243637 Log: Autoconfigure nfsd threads based on ncpu. Rick Macklem and I discussed the default number of nfsd threads and concluded that it is too low to perform adiquitely on today's hardware. We decided to auto tune the number of nfsds based on the number of cpus in the system. While I'm here I've also added: 1) ability to set the minthreads/maxthreads from userland. 2) ability to run nfsd in debug mode via the cli. Reviewed by: rmacklem MFC after: 2 weeks Modified: head/usr.sbin/nfsd/nfsd.c Modified: head/usr.sbin/nfsd/nfsd.c ============================================================================== --- head/usr.sbin/nfsd/nfsd.c Tue Nov 27 22:14:22 2012 (r243636) +++ head/usr.sbin/nfsd/nfsd.c Tue Nov 27 22:34:46 2012 (r243637) @@ -53,6 +53,7 @@ static const char rcsid[] = #include #include #include +#include #include #include @@ -71,14 +72,11 @@ static const char rcsid[] = #include #include #include +#include + +#include -/* 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(); @@ -209,6 +232,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, @@ -356,7 +380,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 +398,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 +425,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 counta 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 +889,7 @@ setbindhost(struct addrinfo **ai, const void usage(void) { - (void)fprintf(stderr, "usage: nfsd %s\n", USAGE); + (void)fprintf(stderr, "%s", getopt_usage); exit(1); } @@ -923,6 +957,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 +1009,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) { /*