diff -up nfs-utils-1.3.0/configure.ac.orig nfs-utils-1.3.0/configure.ac --- nfs-utils-1.3.0/configure.ac.orig 2017-03-28 13:43:36.000000000 -0400 +++ nfs-utils-1.3.0/configure.ac 2017-03-28 13:43:53.000000000 -0400 @@ -23,6 +23,12 @@ AC_ARG_WITH(statedir, statedir=$withval, statedir=/var/lib/nfs) AC_SUBST(statedir) +AC_ARG_WITH(nfsconfig, + [AC_HELP_STRING([--with-nfsconfig=/config/file], + [use general config file /config/file @<:@default=/etc/nfs.conf@:>@])], + nfsconfig=$withval, + nfsconfig=/etc/nfs.conf) + AC_SUBST(nfsconfig) AC_ARG_WITH(statdpath, [AC_HELP_STRING([--with-statdpath=/foo], [define the statd state dir as /foo instead of the NFS statedir @<:@default=/var/lib/nfs@:>@])], @@ -442,6 +448,7 @@ dnl Export some path names to config.h dnl ************************************************************* AC_DEFINE_UNQUOTED(NFS_STATEDIR, "$statedir", [This defines the location of the NFS state files. Warning: this must match definitions in config.mk!]) AC_DEFINE_UNQUOTED(NSM_DEFAULT_STATEDIR, "$statdpath", [Define this to the pathname where statd keeps its state file]) +AC_DEFINE_UNQUOTED(NFS_CONFFILE, "$nfsconfig", [This defines the location of NFS daemon config file]) if test "x$cross_compiling" = "xno"; then CFLAGS_FOR_BUILD=${CFLAGS_FOR_BUILD-"$CFLAGS"} diff -up nfs-utils-1.3.0/support/include/conffile.h.orig nfs-utils-1.3.0/support/include/conffile.h --- nfs-utils-1.3.0/support/include/conffile.h.orig 2014-03-25 11:12:07.000000000 -0400 +++ nfs-utils-1.3.0/support/include/conffile.h 2017-03-28 13:43:53.000000000 -0400 @@ -35,6 +35,8 @@ #include #include +#include +#include struct conf_list_node { TAILQ_ENTRY(conf_list_node) link; @@ -56,6 +58,7 @@ extern struct sockaddr *conf_get_address extern struct conf_list *conf_get_list(char *, char *); extern struct conf_list *conf_get_tag_list(char *, char *); extern int conf_get_num(char *, char *, int); +extern _Bool conf_get_bool(char *, char *, _Bool); extern char *conf_get_str(char *, char *); extern char *conf_get_section(char *, char *, char *); extern void conf_init(void); diff -up nfs-utils-1.3.0/support/include/xlog.h.orig nfs-utils-1.3.0/support/include/xlog.h --- nfs-utils-1.3.0/support/include/xlog.h.orig 2014-03-25 11:12:07.000000000 -0400 +++ nfs-utils-1.3.0/support/include/xlog.h 2017-03-28 13:43:53.000000000 -0400 @@ -41,6 +41,7 @@ void xlog_stderr(int on); void xlog_syslog(int on); void xlog_config(int fac, int on); void xlog_sconfig(char *, int on); +void xlog_from_conffile(char *); int xlog_enabled(int fac); void xlog(int fac, const char *fmt, ...); void xlog_warn(const char *fmt, ...); diff -up nfs-utils-1.3.0/support/nfs/conffile.c.orig nfs-utils-1.3.0/support/nfs/conffile.c --- nfs-utils-1.3.0/support/nfs/conffile.c.orig 2014-03-25 11:12:07.000000000 -0400 +++ nfs-utils-1.3.0/support/nfs/conffile.c 2017-03-28 13:43:53.000000000 -0400 @@ -52,6 +52,7 @@ #pragma GCC visibility push(hidden) static void conf_load_defaults(void); +static int conf_load(int trans, char *path); static int conf_set(int , char *, char *, char *, char *, int , int ); @@ -107,8 +108,6 @@ struct conf_binding { char *conf_path; LIST_HEAD (conf_bindings, conf_binding) conf_bindings[256]; -static char *conf_addr; - static __inline__ u_int8_t conf_hash(char *s) { @@ -213,7 +212,7 @@ static void conf_parse_line(int trans, char *line, size_t sz) { char *val, *ptr; - size_t i, valsize; + size_t i; size_t j; static char *section = 0; static char *arg = 0; @@ -300,18 +299,32 @@ conf_parse_line(int trans, char *line, s } line[strcspn (line, " \t=")] = '\0'; val = line + i + 1 + strspn (line + i + 1, " \t"); - valsize = 0; - while (val[valsize++]); - /* Skip trailing spaces and comments */ - for (j = 0; j < valsize; j++) { - if (val[j] == '#' || val[j] == ';' || isspace(val[j])) { - val[j] = '\0'; - break; + if (val[0] == '"') { + val ++; + j = strcspn(val, "\""); + val[j] = 0; + } else if (val[0] == '\'') { + val ++; + j = strcspn(val, "'"); + val[j] = 0; + } else { + /* Skip trailing spaces and comments */ + for (j = 0; val[j]; j++) { + if ((val[j] == '#' || val[j] == ';') + && (j == 0 || isspace(val[j-1]))) { + val[j] = '\0'; + break; + } } + while (j && isspace(val[j-1])) + val[--j] = '\0'; } - /* XXX Perhaps should we not ignore errors? */ - conf_set(trans, section, arg, line, val, 0, 0); + if (strcasecmp(line, "include") == 0) + conf_load(trans, val); + else + /* XXX Perhaps should we not ignore errors? */ + conf_set(trans, section, arg, line, val, 0, 0); return; } } @@ -368,23 +381,18 @@ conf_init (void) conf_reinit(); } -/* Open the config file and map it into our address space, then parse it. */ -void -conf_reinit(void) +static int +conf_load(int trans, char *path) { - struct conf_binding *cb = 0; - int fd, trans; - unsigned int i; - size_t sz; - char *new_conf_addr = 0; struct stat sb; + if ((stat (path, &sb) == 0) || (errno != ENOENT)) { + char *new_conf_addr; + size_t sz = sb.st_size; + int fd = open (path, O_RDONLY, 0); - if ((stat (conf_path, &sb) == 0) || (errno != ENOENT)) { - sz = sb.st_size; - fd = open (conf_path, O_RDONLY, 0); if (fd == -1) { - xlog_warn("conf_reinit: open (\"%s\", O_RDONLY) failed", conf_path); - return; + xlog_warn("conf_reinit: open (\"%s\", O_RDONLY) failed", path); + return -1; } new_conf_addr = malloc(sz); @@ -396,39 +404,46 @@ conf_reinit(void) /* XXX I assume short reads won't happen here. */ if (read (fd, new_conf_addr, sz) != (int)sz) { xlog_warn("conf_reinit: read (%d, %p, %lu) failed", - fd, new_conf_addr, (unsigned long)sz); + fd, new_conf_addr, (unsigned long)sz); goto fail; } close(fd); - trans = conf_begin(); /* XXX Should we not care about errors and rollback? */ conf_parse(trans, new_conf_addr, sz); + free(new_conf_addr); + return 0; + fail: + close(fd); + free(new_conf_addr); } - else - trans = conf_begin(); + return -1; +} + +/* Open the config file and map it into our address space, then parse it. */ +void +conf_reinit(void) +{ + struct conf_binding *cb = 0; + int trans; + unsigned int i; + + trans = conf_begin(); + if (conf_load(trans, conf_path) < 0) + return; /* Load default configuration values. */ conf_load_defaults(); /* Free potential existing configuration. */ - if (conf_addr) { - for (i = 0; i < sizeof conf_bindings / sizeof conf_bindings[0]; i++) { - cb = LIST_FIRST (&conf_bindings[i]); - for (; cb; cb = LIST_FIRST (&conf_bindings[i])) - conf_remove_now(cb->section, cb->tag); - } - free (conf_addr); + for (i = 0; i < sizeof conf_bindings / sizeof conf_bindings[0]; i++) { + cb = LIST_FIRST (&conf_bindings[i]); + for (; cb; cb = LIST_FIRST (&conf_bindings[i])) + conf_remove_now(cb->section, cb->tag); } conf_end(trans, 1); - conf_addr = new_conf_addr; return; - -fail: - if (new_conf_addr) - free(new_conf_addr); - close (fd); } /* @@ -446,6 +461,38 @@ conf_get_num(char *section, char *tag, i return def; } +/* + * Return the Boolean value denoted by TAG in section SECTION, or DEF + * if that tags does not exist. + * FALSE is returned for case-insensitve comparisons with 0, f, false, n, no, off + * TRUE is returned for 1, t, true, y, yes, on + * A failure to match one of these results in DEF + */ +_Bool +conf_get_bool(char *section, char *tag, _Bool def) +{ + char *value = conf_get_str(section, tag); + + if (!value) + return def; + if (strcasecmp(value, "1") == 0 || + strcasecmp(value, "t") == 0 || + strcasecmp(value, "true") == 0 || + strcasecmp(value, "y") == 0 || + strcasecmp(value, "yes") == 0 || + strcasecmp(value, "on") == 0) + return true; + + if (strcasecmp(value, "0") == 0 || + strcasecmp(value, "f") == 0 || + strcasecmp(value, "false") == 0 || + strcasecmp(value, "n") == 0 || + strcasecmp(value, "no") == 0 || + strcasecmp(value, "off") == 0) + return false; + return def; +} + /* Validate X according to the range denoted by TAG in section SECTION. */ int conf_match_num(char *section, char *tag, int x) @@ -476,12 +523,24 @@ char * conf_get_str(char *section, char *tag) { struct conf_binding *cb; - +retry: cb = LIST_FIRST (&conf_bindings[conf_hash (section)]); for (; cb; cb = LIST_NEXT (cb, link)) { if (strcasecmp (section, cb->section) == 0 - && strcasecmp (tag, cb->tag) == 0) + && strcasecmp (tag, cb->tag) == 0) { + if (cb->value[0] == '$') { + /* expand $name from [environment] section, + * or from environment + */ + char *env = getenv(cb->value+1); + if (env && *env) + return env; + section = "environment"; + tag = cb->value + 1; + goto retry; + } return cb->value; + } } return 0; } @@ -705,6 +764,8 @@ conf_set(int transaction, char *section, { struct conf_trans *node; + if (!value || !*value) + return 0; node = conf_trans_node(transaction, CONF_SET); if (!node) return 1; diff -up nfs-utils-1.3.0/support/nfs/xlog.c.orig nfs-utils-1.3.0/support/nfs/xlog.c --- nfs-utils-1.3.0/support/nfs/xlog.c.orig 2014-03-25 11:12:07.000000000 -0400 +++ nfs-utils-1.3.0/support/nfs/xlog.c 2017-03-28 13:43:53.000000000 -0400 @@ -29,6 +29,7 @@ #include #include #include "nfslib.h" +#include "conffile.h" #undef VERBOSE_PRINTF @@ -125,6 +126,19 @@ xlog_sconfig(char *kind, int on) xlog_config(tbl->df_fac, on); } +void +xlog_from_conffile(char *service) +{ + struct conf_list *kinds; + struct conf_list_node *n; + + kinds = conf_get_list(service, "debug"); + if (!kinds || !kinds->cnt) + return; + TAILQ_FOREACH(n, &(kinds->fields), link) + xlog_sconfig(n->field, 1); +} + int xlog_enabled(int fac) { diff -up nfs-utils-1.3.0/systemd/Makefile.am.orig nfs-utils-1.3.0/systemd/Makefile.am --- nfs-utils-1.3.0/systemd/Makefile.am.orig 2017-03-28 13:43:36.000000000 -0400 +++ nfs-utils-1.3.0/systemd/Makefile.am 2017-03-28 13:43:53.000000000 -0400 @@ -20,7 +20,9 @@ unit_files = \ proc-fs-nfsd.mount \ var-lib-nfs-rpc_pipefs.mount -EXTRA_DIST = $(unit_files) +man5_MANS = nfs.conf.man +man7_MANS = nfs.systemd.man +EXTRA_DIST = $(unit_files) $(man5_MANS) $(man7_MANS) unit_dir = /usr/lib/systemd/system diff -up nfs-utils-1.3.0/systemd/nfs.conf.man.orig nfs-utils-1.3.0/systemd/nfs.conf.man --- nfs-utils-1.3.0/systemd/nfs.conf.man.orig 2017-03-28 13:43:53.000000000 -0400 +++ nfs-utils-1.3.0/systemd/nfs.conf.man 2017-03-28 13:43:53.000000000 -0400 @@ -0,0 +1,231 @@ +.TH NFS.CONF 5 +.SH NAME +nfs.conf \- general configuration for NFS daemons and tools +.SH SYNOPSIS +.I /etc/nfs.conf +.SH DESCRIPTION +.PP +This file contains site-specific configuration for various NFS daemons +and other processes. Most configuration can also be passed to +processes via command line arguments, but it can be more convenient to +have a central file. In particular, this encourages consistent +configuration across different processes. +.PP +When command line options are provided, they override values set in +this file. When this file does not specify a particular parameter, +and no command line option is provided, each tool provides its own +default values. +.PP +The file format supports multiple sections, each of which can contain +multiple value assignments. A section is introduced by a line +containing the section name enclosed in square brackets, so +.RS +.B [global] +.RE +would introduce a section called +.BR global . +A value assignment is a single line that has the name of the value, an +equals sign, and a setting for the value, so +.RS +.B threads = 4 +.RE +would set the value named +.B threads +in the current section to +.BR 4 . +Leading and trailing spaces and tab +are ignored, as are spaces and tabs surrounding the equals sign. +Single and double quotes surrounding the assigned value are also +removed. If the resulting string is empty, the whole assignment +is ignored. +.PP +Any line starting with +.RB \*(lq # \*(rq +or +.RB \*(lq ; \*(rq +is ignored, as is any blank line. +.PP +If the assigned value started with a +.RB \*(lq $ \*(rq +then the remainder is treated as a name and looked for in the section +.B [environment] +or in the processes environment (see +.BR environ (7)). +The value found is used for this value. +.PP +The value name +.B include +is special. If a section contains +.RS +.B include = /some/file/name +.RE +then the named file will be read, and any value assignments found +there-in will be added to the current section. If the file contains +section headers, then new sections will be created just as if the +included file appeared in place of the +.B include +line. +.PP +Lookup of section and value names is case-insensitive. + +Where a Boolean value is expected, any of +.BR true , +.BR t , +.BR yes , +.BR y , +.BR on ", or" +.B 1 +can be used for "true", while +.BR false , +.BR f , +.BR no , +.BR n , +.BR off ", or" +.B 0 +can be used for "false". Comparisons are case-insensitive. + +.SH SECTIONS +The following sections are known to various programs, and can contain +the given named values. Most sections can also contain a +.B debug +value, which can be one or more from the list +.BR general , +.BR call , +.BR auth , +.BR parse , +.BR all . +When a list is given, the members should be comma-separated. +.TP +.B nfsdcltrack +Recognized values: +.BR storagedir . + +The +.B nfsdcltrack +program is run directly by the Linux kernel and there is no +opportunity to provide command line arguments, so the configuration +file is the only way to configure this program. See +.BR nfsdcltrack (8) +for details. + +.TP +.B nfsd +Recognized values: +.BR threads , +.BR host , +.BR port , +.BR grace-time , +.BR lease-time , +.BR udp , +.BR tcp , +.BR vers2 , +.BR vers3 , +.BR vers4 , +.BR vers4.0 , +.BR vers4.1 , +.BR vers4.2 , +.BR rdma . + +Version and protocol values are Boolean values as described above, +and are also used by +.BR rpc.mountd . +Threads and the two times are integers. +.B port +and +.B rdma +are service names or numbers. See +.BR rpc.nfsd (8) +for details. + +.TP +.B mountd +Recognized values: +.BR manage-gids , +.BR descriptors , +.BR port , +.BR threads , +.BR reverse-lookup , +.BR state-directory-path , +.BR ha-callout . + +These, together with the protocol and version values in the +.B [nfsd] +section, are used to configure mountd. See +.BR rpc.mountd (8) +for details. + +.TP +.B statd +Recognized values: +.BR port , +.BR outgoing-port , +.BR name , +.BR state-directory-path , +.BR ha-callout . + +See +.BR rpc.statd (8) +for details. + +.TP +.B lockd +Recognized values: +.B port +and +.BR udp-port . + +See +.BR rpc.statd (8) +for details. + +.TP +.B sm-notify +Recognized values: +.BR retry-time , +.BR outgoing-port ", and" +.BR outgoing-addr . + +See +.BR sm-notify (8) +for details. + +.TP +.B gssd +Recognized values: +.BR use-memcache , +.BR use-machine-creds , +.BR avoid-dns , +.BR limit-to-legacy-enctypes , +.BR context-timeout , +.BR rpc-timeout , +.BR pipefs-directory , +.BR keytab-file , +.BR cred-cache-directory , +.BR preferred-realm . + +See +.BR rpc.gssd (8) +for details. + +.TP +.B svcgssd +Recognized values: +.BR principal . + +See +.BR rpc.svcgssd (8) +for details. + +.TP +.B exportfs +Only +.B debug= +is recognized. + +.SH FILES +.I /etc/nfs.conf +.SH SEE ALSO +.BR nfsdcltrack (8), +.BR rpc.nfsd (8), +.BR rpc.mountd (8), +.BR nfsmount.conf (5). diff -up nfs-utils-1.3.0/systemd/nfs.systemd.man.orig nfs-utils-1.3.0/systemd/nfs.systemd.man --- nfs-utils-1.3.0/systemd/nfs.systemd.man.orig 2017-03-28 13:45:11.000000000 -0400 +++ nfs-utils-1.3.0/systemd/nfs.systemd.man 2017-03-28 13:45:11.000000000 -0400 @@ -0,0 +1,167 @@ +.TH NFS.SYSTEMD 7 +.SH NAME +nfs.systemd \- managing NFS services through systemd. +.SH SYNOPSIS +nfs-utils.service +.br +nfs-server.service +.br +nfs-client.target +.br +.I etc +.SH DESCRIPTION +The +.I nfs-utils +package provides a suite of +.I systemd +unit files which allow the various services to be started and +managed. These unit files ensure that the services are started in the +correct order, and the prerequisites are active before dependant +services start. As there are quite few unit files, it is not +immediately obvious how best to achieve certain results. The +following subsections attempt to cover the issues that are most likely +to come up. +.SS Configuration +The standard systemd unit files do not provide any easy way to pass +any command line arguments to daemons so as to configure their +behavior. In many case such configuration can be performed by making +changes to +.I /etc/nfs.conf +or other configuration files. When that is not convenient, a +distribution might provide systemd "drop-in" files which replace the +.B ExecStart= +setting to start the program with different arguments. For example a +drop-in file +.B systemd/system/nfs-mountd.service.d/local.conf +containing +.RS +.nf +[Service] +EnvironmentFile=/etc/sysconfig/nfs +ExecStart= +ExecStart= /usr/sbin/rpc.mountd $RPCMOUNTDOPTS +.fi +.RE +would cause the +.B nfs-mountd.service +unit to run the +.I rpc.mountd +program using, for arguments, the value given for +.B RPCMOUNTDOPTS +in +.IR /etc/sysconfig/nfs . +This allows for seamless integration with existing configuration +tools. +.SS Enabling unit files +There are three unit files which are designed to be manually enabled. +All others are automatically run as required. The three are: +.TP +.B nfs-client.target +This should be enabled on any host which ever serves as an NFS client. +There is little cost in transparently enabling it whenever NFS client +software is installed. +.TP +.B nfs-server.service +This must be enabled to provide NFS service to clients. It starts and +configures the required daemons in the required order. +.TP +.B nfs-blkmap.service +The +.B blkmapd +daemon is only required on NFS clients which are using pNFS (parallel +NFS), and particularly using the +.B blocklayout +layout protocol. If you might use this particular extension to NFS, +the +.B nfs-blkmap.service +unit should be enabled. +.PP +Several other units which might be considered to be optional, such as +.I rpc-gssd.service +are careful to only start if the required configuration file exists. +.I rpc-gsdd.service +will not start if the +.I krb5.keytab +file does not exist (typically in +.IR /etc ). +.SS Restarting NFS services +Most NFS daemons can be restarted at any time. They will reload any +state that they need, and continue servicing requests. This is rarely +necessary though. +.PP +When configuration changesare make, it can be hard to know exactly +which services need to be restarted to ensure that the configuration +takes effect. The simplest approach, which is often the best, is to +restart everything. To help with this, the +.B nfs-utils.service +unit is provided. It declares appropriate dependencies with other +unit files so that +.RS +.B systemctl restart nfs-utils +.RE +will restart all NFS daemons that are running. This will cause all +configuration changes to take effect +.I except +for changes to mount options lists in +.I /etc/fstab +or +.IR /etc/nfsmount.conf . +Mount options can only be changed by unmounting and remounting +filesystem. This can be a disruptive operation so it should only be +done when the value justifies the cost. The command +.RS +.B umount -a -t nfs; mount -a -t nfs +.RE +should unmount and remount all NFS filesystems. +.SS Masking unwanted services +Rarely there may be a desire to prohibit some services from running +even though there are normally part of a working NFS system. This may +be needed to reduce system load to an absolute minimum, or to reduce +attack surface by not running daemons that are not absolutely +required. +.PP +Two particular services which this can apply to are +.I rpcbind +and +.IR idmapd . +.I rpcbind +is not part of the +.I nfs-utils +package, but it used by several NFS services. However it is +.B not +needed when only NFSv4 is in use. If a site will never use NFSv3 (or +NFSv2) and does not want +.I rpcbind +to be running, the correct approach is to run +.RS +.B systemctl mask rpcbind +.RE +This will disable +.IR rpcbind , +and the various NFS services which depend on it (and are only needed +for NFSv3) will refuse to start, without interfering with the +operation of NFSv4 services. In particular, +.I rpc.statd +will not run when +.I rpcbind +is masked. +.PP +.I idmapd +is only needed for NFSv4, and even then is not needed when the client +and server agree to use user-ids rather than user-names to identify the +owners of files. If +.I idmapd +is not needed and not wanted, it can be masked with +.RS +.B systemctl mask idmapd +.RE +.SH FILES +/etc/nfs.conf +.br +/etc/nfsmount.conf +.br +/etc/idmapd.conf +.SH SEE ALSO +.BR systemd.unit (5), +.BR nfs.conf (5), +.BR nfsmount.conf (5). diff -up nfs-utils-1.3.0/systemd/rpc-statd.service.orig nfs-utils-1.3.0/systemd/rpc-statd.service --- nfs-utils-1.3.0/systemd/rpc-statd.service.orig 2017-03-28 13:43:36.000000000 -0400 +++ nfs-utils-1.3.0/systemd/rpc-statd.service 2017-03-28 13:43:53.000000000 -0400 @@ -11,7 +11,8 @@ Wants=nfs-config.service After=nfs-config.service [Service] +Environment=RPC_STATD_NO_NOTIFY=1 EnvironmentFile=-/run/sysconfig/nfs-utils Type=forking PIDFile=/var/run/rpc.statd.pid -ExecStart=/usr/sbin/rpc.statd --no-notify $STATDARGS +ExecStart=/usr/sbin/rpc.statd $STATDARGS diff -up nfs-utils-1.3.0/utils/exportfs/exportfs.c.orig nfs-utils-1.3.0/utils/exportfs/exportfs.c --- nfs-utils-1.3.0/utils/exportfs/exportfs.c.orig 2017-03-28 13:43:36.000000000 -0400 +++ nfs-utils-1.3.0/utils/exportfs/exportfs.c 2017-03-28 13:43:53.000000000 -0400 @@ -37,6 +37,7 @@ #include "nfslib.h" #include "exportfs.h" #include "xlog.h" +#include "conffile.h" static void export_all(int verbose); static void exportfs(char *arg, char *options, int verbose); @@ -53,6 +54,7 @@ static void release_lockfile(void); static const char *lockfile = EXP_LOCKFILE; static int _lockfd = -1; +char *conf_path = NFS_CONFFILE; /* * If we aren't careful, changes made by exportfs can be lost @@ -108,6 +110,9 @@ main(int argc, char **argv) xlog_stderr(1); xlog_syslog(0); + conf_init(); + xlog_from_conffile("exportfs"); + while ((c = getopt(argc, argv, "ad:fhio:ruvs")) != EOF) { switch(c) { case 'a': diff -up nfs-utils-1.3.0/utils/exportfs/exportfs.man.orig nfs-utils-1.3.0/utils/exportfs/exportfs.man --- nfs-utils-1.3.0/utils/exportfs/exportfs.man.orig 2017-03-28 13:43:36.000000000 -0400 +++ nfs-utils-1.3.0/utils/exportfs/exportfs.man 2017-03-28 13:43:53.000000000 -0400 @@ -90,6 +90,13 @@ to be added to the kernel's export table .TP .B \-d kind " or " \-\-debug kind Turn on debugging. Valid kinds are: all, auth, call, general and parse. +Debugging can also be turned on by setting +.B debug= +in the +.B [exportfs] +section of +.IR /etc/nfs.conf . + .TP .B -a Export or unexport all directories. @@ -295,6 +302,7 @@ master table of exports table of clients accessing server's exports .SH SEE ALSO .BR exports (5), +.BR nfs.conf (5), .BR rpc.mountd (8), .BR netgroup (5) .SH AUTHORS diff -up nfs-utils-1.3.0/utils/gssd/gssd.c.orig nfs-utils-1.3.0/utils/gssd/gssd.c --- nfs-utils-1.3.0/utils/gssd/gssd.c.orig 2017-03-28 13:43:36.000000000 -0400 +++ nfs-utils-1.3.0/utils/gssd/gssd.c 2017-03-28 13:43:53.000000000 -0400 @@ -71,6 +71,7 @@ #include "gss_util.h" #include "krb5_util.h" #include "nfslib.h" +#include "conffile.h" static char *pipefs_path = GSSD_PIPEFS_DIR; static DIR *pipefs_dir; @@ -78,6 +79,7 @@ static int pipefs_fd; static int inotify_fd; struct event inotify_ev; +char *conf_path = NFS_CONFFILE; char *keytabfile = GSSD_DEFAULT_KEYTAB_FILE; char **ccachesearch; int use_memcache = 0; @@ -831,6 +833,33 @@ main(int argc, char *argv[]) char *progname; char *ccachedir = NULL; struct event sighup_ev; + char *s; + + conf_init(); + use_memcache = conf_get_bool("gssd", "use-memcache", use_memcache); + root_uses_machine_creds = conf_get_bool("gssd", "use-machine-creds", + root_uses_machine_creds); + avoid_dns = conf_get_bool("gssd", "avoid-dns", avoid_dns); +#ifdef HAVE_SET_ALLOWABLE_ENCTYPES + limit_to_legacy_enctypes = conf_get_bool("gssd", "limit-to-legacy-enctypes", + limit_to_legacy_enctypes); +#endif + context_timeout = conf_get_num("gssd", "context-timeout", context_timeout); + rpc_timeout = conf_get_num("gssd", "rpc-timeout", rpc_timeout); + s = conf_get_str("gssd", "pipefs-directory"); + if (!s) + s = conf_get_str("general", "pipefs-directory"); + if (s) + pipefs_path = s; + s = conf_get_str("gssd", "keytab-file"); + if (s) + keytabfile = s; + s = conf_get_str("gssd", "cred-cache-directory"); + if (s) + ccachedir = s; + s = conf_get_str("gssd", "preferred-realm"); + if (s) + preferred_realm = s; while ((opt = getopt(argc, argv, "DfvrlmnMp:k:d:t:T:R:")) != -1) { switch (opt) { diff -up nfs-utils-1.3.0/utils/gssd/gssd.man.orig nfs-utils-1.3.0/utils/gssd/gssd.man --- nfs-utils-1.3.0/utils/gssd/gssd.man.orig 2017-03-28 13:43:36.000000000 -0400 +++ nfs-utils-1.3.0/utils/gssd/gssd.man 2017-03-28 13:43:53.000000000 -0400 @@ -297,6 +297,60 @@ The default timeout is set to 5 seconds. If you get messages like "WARNING: can't create tcp rpc_clnt to server %servername% for user with uid %uid%: RPC: Remote system error - Connection timed out", you should consider an increase of this timeout. +.SH CONFIGURATION FILE +Many of the options that can be set on the command line can also be +controlled through values set in the +.B [gssd] +section of the +.I /etc/nfs.conf +configuration file. Values recognized include: +.TP +.B use-memcache +A Boolean flag equivalent to +.BR -M . +.TP +.B use-machine-creds +A Boolean flag. Setting to +.B false +is equivalent to giving the +.B -n +flag. +.TP +.B avoid-dns +Setting to +.B false +is equivalent to providing the +.B -D +flag. +.TP +.B limit-to-legacy-enctypes +Equivalent to +.BR -l . +.TP +.B context-timeout +Equivalent to +.BR -T . +.TP +.B rpc-timeout +Equivalent to +.BR -t . +.TP +.B pipefs-directory +Equivalent to +.BR -p . +.TP +.B keytab-file +Equivalent to +.BR -k . +.TP +.BR cred-cache-directory +Equivalent to +.BR -d . +.TP +.B preferred-realm +Equivalent to +.BR -R . + .SH SEE ALSO .BR rpc.svcgssd (8), .BR kerberos (1), diff -up nfs-utils-1.3.0/utils/gssd/svcgssd.c.orig nfs-utils-1.3.0/utils/gssd/svcgssd.c --- nfs-utils-1.3.0/utils/gssd/svcgssd.c.orig 2017-03-28 13:43:36.000000000 -0400 +++ nfs-utils-1.3.0/utils/gssd/svcgssd.c 2017-03-28 13:43:53.000000000 -0400 @@ -61,6 +61,9 @@ #include "svcgssd.h" #include "gss_util.h" #include "err_util.h" +#include "conffile.h" + +char *conf_path = NFS_CONFFILE; void sig_die(int signal) @@ -98,6 +101,17 @@ main(int argc, char *argv[]) extern char *optarg; char *progname; char *principal = NULL; + char *s; + + conf_init(); + + s = conf_get_str("svcgssd", "principal"); + if (!s) + ; + else if (strcmp(s, "system")== 0) + get_creds = 0; + else + principal = s; while ((opt = getopt(argc, argv, "fivrnp:")) != -1) { switch (opt) { diff -up nfs-utils-1.3.0/utils/gssd/svcgssd.man.orig nfs-utils-1.3.0/utils/gssd/svcgssd.man --- nfs-utils-1.3.0/utils/gssd/svcgssd.man.orig 2014-03-25 11:12:07.000000000 -0400 +++ nfs-utils-1.3.0/utils/gssd/svcgssd.man 2017-03-28 13:43:53.000000000 -0400 @@ -45,6 +45,23 @@ Use the system default credentials .RI (host/ FQDN @ REALM ) rather than the default .RI nfs/ FQDN @ REALM . +.SH CONFIGURATION FILE +Some of the options that can be set on the command line can also be +controlled through values set in the +.B [svcgssd] +section of the +.I /etc/nfs.conf +configuration file. Values recognized include: +.TP +.B principal +If set to +.B system +this is equivalent to the +.B -n +option. If set to any other value, that is used like the +.B -p +option. + .SH SEE ALSO .BR rpc.gssd(8), .SH AUTHORS diff -up nfs-utils-1.3.0/utils/mountd/mountd.c.orig nfs-utils-1.3.0/utils/mountd/mountd.c --- nfs-utils-1.3.0/utils/mountd/mountd.c.orig 2017-03-28 13:43:36.000000000 -0400 +++ nfs-utils-1.3.0/utils/mountd/mountd.c 2017-03-28 13:43:53.000000000 -0400 @@ -22,6 +22,8 @@ #include #include #include + +#include "conffile.h" #include "xmalloc.h" #include "misc.h" #include "mountd.h" @@ -39,6 +41,8 @@ int new_cache = 0; int manage_gids; int use_ipaddr = -1; +char *conf_path = NFS_CONFFILE; + /* PRC: a high-availability callout program can be specified with -H * When this is done, the program will receive callouts whenever clients * send mount or unmount requests -- the callout is not needed for 2.6 kernel */ @@ -692,6 +696,7 @@ main(int argc, char **argv) char *export_file = _PATH_EXPORTS; char *state_dir = NFS_STATEDIR; char *progname; + char *s; unsigned int listeners = 0; int foreground = 0; int port = 0; @@ -707,6 +712,38 @@ main(int argc, char **argv) else progname = argv[0]; + conf_init(); + xlog_from_conffile("mountd"); + manage_gids = conf_get_bool("mountd", "manage-gids", manage_gids); + descriptors = conf_get_num("mountd", "descriptors", descriptors); + port = conf_get_num("mountd", "port", port); + num_threads = conf_get_num("mountd", "threads", num_threads); + reverse_resolve = conf_get_bool("mountd", "reverse-lookup", reverse_resolve); + ha_callout_prog = conf_get_str("mountd", "ha-callout"); + + s = conf_get_str("mountd", "state-directory-path"); + if (s) + state_dir = s; + + /* NOTE: following uses "nfsd" section of nfs.conf !!!! */ + if (conf_get_bool("nfsd", "udp", NFSCTL_UDPISSET(_rpcprotobits))) + NFSCTL_UDPSET(_rpcprotobits); + else + NFSCTL_UDPUNSET(_rpcprotobits); + if (conf_get_bool("nfsd", "tcp", NFSCTL_TCPISSET(_rpcprotobits))) + NFSCTL_TCPSET(_rpcprotobits); + else + NFSCTL_TCPUNSET(_rpcprotobits); + for (vers = 2; vers <= 4; vers++) { + char tag[10]; + sprintf(tag, "vers%d", vers); + if (conf_get_bool("nfsd", tag, NFSCTL_VERISSET(nfs_version, vers))) + NFSCTL_VERSET(nfs_version, vers); + else + NFSCTL_VERUNSET(nfs_version, vers); + } + + /* Parse the command line options and arguments. */ opterr = 0; while ((c = getopt_long(argc, argv, "o:nFd:f:p:P:hH:N:V:vurs:t:g", longopts, NULL)) != EOF) diff -up nfs-utils-1.3.0/utils/mountd/mountd.man.orig nfs-utils-1.3.0/utils/mountd/mountd.man --- nfs-utils-1.3.0/utils/mountd/mountd.man.orig 2017-03-28 13:43:36.000000000 -0400 +++ nfs-utils-1.3.0/utils/mountd/mountd.man 2017-03-28 13:43:53.000000000 -0400 @@ -207,6 +207,39 @@ the server. Note that the 'primary' grou .B newgroup command on the client will still be effective. This function requires a Linux Kernel with version at least 2.6.21. + +.SH CONFIGURATION FILE +Many of the options that can be set on the command line can also be +controlled through values set in the +.B [mountd] +or, in some cases, the +.B [nfsd] +sections of the +.I /etc/nfs.conf +configuration file. +Values recognized in the +.B [mountd] +section include +.BR manage-gids , +.BR descriptors , +.BR port , +.BR threads , +.BR reverse-lookup ", and" +.BR state-directory-path , +.B ha-callout +which each have the same effect as the option with the same name. + +The values recognized in the +.B [nfsd] +section include +.BR TCP , +.BR UDP , +.BR vers2 , +.BR vers3 ", and" +.B vers4 +which each have same same meaning as given by +.BR rpc.nfsd (8). + .SH TCP_WRAPPERS SUPPORT You can protect your .B rpc.mountd @@ -261,6 +294,7 @@ table of clients accessing server's expo .BR rpc.nfsd (8), .BR rpc.rquotad (8), .BR nfs (5), +.BR nfs.conf (5), .BR tcpd (8), .BR hosts_access (5), .BR iptables (8), diff -up nfs-utils-1.3.0/utils/nfsdcltrack/nfsdcltrack.c.orig nfs-utils-1.3.0/utils/nfsdcltrack/nfsdcltrack.c --- nfs-utils-1.3.0/utils/nfsdcltrack/nfsdcltrack.c.orig 2017-03-28 13:43:36.000000000 -0400 +++ nfs-utils-1.3.0/utils/nfsdcltrack/nfsdcltrack.c 2017-03-28 13:43:53.000000000 -0400 @@ -43,6 +43,7 @@ #include #endif +#include "conffile.h" #include "xlog.h" #include "sqlite.h" @@ -55,6 +56,8 @@ /* defined by RFC 3530 */ #define NFS4_OPAQUE_LIMIT 1024 +char *conf_path = NFS_CONFFILE; + /* private data structures */ struct cltrack_cmd { char *name; @@ -553,6 +556,7 @@ int main(int argc, char **argv) { char arg; + char *val; int rc = 0; char *progname, *cmdarg = NULL; struct cltrack_cmd *cmd; @@ -562,6 +566,15 @@ main(int argc, char **argv) xlog_syslog(1); xlog_stderr(0); + conf_init(); + xlog_from_conffile("nfsdcltrack"); + val = conf_get_str("nfsdcltrack", "storagedir"); + if (val) + storagedir = val; + rc = conf_get_num("nfsdcltrack", "debug", 0); + if (rc > 0) + xlog_config(D_ALL, 1); + /* process command-line options */ while ((arg = getopt_long(argc, argv, "hdfs:", longopts, NULL)) != EOF) { diff -up nfs-utils-1.3.0/utils/nfsdcltrack/nfsdcltrack.man.orig nfs-utils-1.3.0/utils/nfsdcltrack/nfsdcltrack.man --- nfs-utils-1.3.0/utils/nfsdcltrack/nfsdcltrack.man.orig 2014-03-25 11:12:07.000000000 -0400 +++ nfs-utils-1.3.0/utils/nfsdcltrack/nfsdcltrack.man 2017-03-28 13:43:53.000000000 -0400 @@ -66,6 +66,20 @@ Check to see if a nfs_client_id4 is allo .IP "\fBgracedone\fR" 4 .IX Item "gracedone" Remove any unreclaimed client records from the database. This command requires a epoch boot time as an argument. +.SH "EXTERNAL CONFIGURATION" +The directory for stable storage information can be set via the file +.B /etc/nfs.conf +by setting the +.B storagedir +value in the +.B nfsdcltrack +section. For example: +.in +5 +[nfsdcltrack] +.br + storagedir = /shared/nfs/nfsdcltrack +.in -5 +Debuging to syslog can also be enabled by setting "debug = 1" in this file. .SH "LEGACY TRANSITION MECHANISM" .IX Header "LEGACY TRANSITION MECHANISM" The Linux kernel NFSv4 server has historically tracked this information diff -up nfs-utils-1.3.0/utils/nfsd/nfsd.c.orig nfs-utils-1.3.0/utils/nfsd/nfsd.c --- nfs-utils-1.3.0/utils/nfsd/nfsd.c.orig 2017-03-28 13:43:36.000000000 -0400 +++ nfs-utils-1.3.0/utils/nfsd/nfsd.c 2017-03-28 13:43:53.000000000 -0400 @@ -23,14 +23,18 @@ #include #include +#include "conffile.h" #include "nfslib.h" #include "nfssvc.h" #include "xlog.h" +#include "xcommon.h" #ifndef NFSD_NPROC #define NFSD_NPROC 8 #endif +char *conf_path = NFS_CONFFILE; + static void usage(const char *); static struct option longopts[] = @@ -51,50 +55,6 @@ static struct option longopts[] = { NULL, 0, 0, 0 } }; -/* given a family and ctlbits, disable any that aren't listed in netconfig */ -#ifdef HAVE_LIBTIRPC -static void -nfsd_enable_protos(unsigned int *proto4, unsigned int *proto6) -{ - struct netconfig *nconf; - unsigned int *famproto; - void *handle; - - xlog(D_GENERAL, "Checking netconfig for visible protocols."); - - handle = setnetconfig(); - while((nconf = getnetconfig(handle))) { - if (!(nconf->nc_flag & NC_VISIBLE)) - continue; - - if (!strcmp(nconf->nc_protofmly, NC_INET)) - famproto = proto4; - else if (!strcmp(nconf->nc_protofmly, NC_INET6)) - famproto = proto6; - else - continue; - - if (!strcmp(nconf->nc_proto, NC_TCP)) - NFSCTL_TCPSET(*famproto); - else if (!strcmp(nconf->nc_proto, NC_UDP)) - NFSCTL_UDPSET(*famproto); - - xlog(D_GENERAL, "Enabling %s %s.", nconf->nc_protofmly, - nconf->nc_proto); - } - endnetconfig(handle); - return; -} -#else /* HAVE_LIBTIRPC */ -static void -nfsd_enable_protos(unsigned int *proto4, unsigned int *proto6) -{ - /* Enable all IPv4 protocols if no TIRPC support */ - *proto4 = NFSCTL_ALLBITS; - *proto6 = 0; -} -#endif /* HAVE_LIBTIRPC */ - int main(int argc, char **argv) { @@ -102,44 +62,91 @@ main(int argc, char **argv) char *p, *progname, *port, *rdma_port = NULL; char **haddr = NULL; int hcounter = 0; + struct conf_list *hosts; int socket_up = 0; unsigned int minorvers = 0; unsigned int minorversset = 0; unsigned int versbits = NFSCTL_VERDEFAULT; unsigned int protobits = NFSCTL_ALLBITS; - unsigned int proto4 = 0; - unsigned int proto6 = 0; int grace = -1; int lease = -1; - progname = strdup(basename(argv[0])); - if (!progname) { - fprintf(stderr, "%s: unable to allocate memory.\n", argv[0]); - exit(1); - } - - port = strdup("nfs"); - if (!port) { - fprintf(stderr, "%s: unable to allocate memory.\n", progname); - exit(1); - } - - haddr = malloc(sizeof(char *)); - if (!haddr) { - fprintf(stderr, "%s: unable to allocate memory.\n", progname); - exit(1); - } + progname = basename(argv[0]); + haddr = xmalloc(sizeof(char *)); haddr[0] = NULL; xlog_syslog(0); xlog_stderr(1); + conf_init(); + xlog_from_conffile("nfsd"); + count = conf_get_num("nfsd", "threads", count); + grace = conf_get_num("nfsd", "grace-time", grace); + lease = conf_get_num("nfsd", "lease-time", lease); + port = conf_get_str("nfsd", "port"); + if (!port) + port = "nfs"; + rdma_port = conf_get_str("nfsd", "rdma"); + if (conf_get_bool("nfsd", "udp", NFSCTL_UDPISSET(protobits))) + NFSCTL_UDPSET(protobits); + else + NFSCTL_UDPUNSET(protobits); + if (conf_get_bool("nfsd", "tcp", NFSCTL_TCPISSET(protobits))) + NFSCTL_TCPSET(protobits); + else + NFSCTL_TCPUNSET(protobits); + for (i = 2; i <= 4; i++) { + char tag[10]; + sprintf(tag, "vers%d", i); + if (conf_get_bool("nfsd", tag, NFSCTL_VERISSET(versbits, i))) + NFSCTL_VERSET(versbits, i); + else + NFSCTL_VERUNSET(versbits, i); + } + /* We assume the kernel will default all minor versions to 'on', + * and allow the config file to disable some. + */ + for (i = NFS4_MINMINOR; i <= NFS4_MAXMINOR; i++) { + char tag[20]; + sprintf(tag, "vers4.%d", i); + /* The default for minor version support is to let the + * kernel decide. We could ask the kernel what that choice + * will be, but that is needlessly complex. + * Instead, perform a config-file lookup using each of the + * two possible default. If the result is different from the + * default, then impose that value, else don't make a change + * (i.e. don't set the bit in minorversset). + */ + if (!conf_get_bool("nfsd", tag, 1)) { + NFSCTL_VERSET(minorversset, i); + NFSCTL_VERUNSET(minorvers, i); + } + if (conf_get_bool("nfsd", tag, 0)) { + NFSCTL_VERSET(minorversset, i); + NFSCTL_VERSET(minorvers, i); + } + } + + hosts = conf_get_list("nfsd", "host"); + if (hosts && hosts->cnt) { + struct conf_list_node *n; + haddr = realloc(haddr, sizeof(char*) * hosts->cnt); + TAILQ_FOREACH(n, &(hosts->fields), link) { + haddr[hcounter] = n->field; + hcounter++; + } + } + while ((c = getopt_long(argc, argv, "dH:hN:V:p:P:sTUrG:L:", longopts, NULL)) != EOF) { switch(c) { case 'd': xlog_config(D_ALL, 1); break; case 'H': + if (hosts) { + hosts = NULL; + hcounter = 0; + } if (hcounter) { haddr = realloc(haddr, sizeof(char*) * hcounter+1); if(!haddr) { @@ -148,30 +155,13 @@ main(int argc, char **argv) exit(1); } } - haddr[hcounter] = strdup(optarg); - if (!haddr[hcounter]) { - fprintf(stderr, "%s: unable to allocate " - "memory.\n", progname); - exit(1); - } + haddr[hcounter] = optarg; hcounter++; break; case 'P': /* XXX for nfs-server compatibility */ case 'p': /* only the last -p option has any effect */ - portnum = atoi(optarg); - if (portnum <= 0 || portnum > 65535) { - fprintf(stderr, "%s: bad port number: %s\n", - progname, optarg); - usage(progname); - } - free(port); - port = strdup(optarg); - if (!port) { - fprintf(stderr, "%s: unable to allocate " - "memory.\n", progname); - exit(1); - } + port = optarg; break; case 'r': rdma_port = "nfsrdma"; @@ -188,7 +178,7 @@ main(int argc, char **argv) case 4: if (*p == '.') { int i = atoi(p+1); - if (i > NFS4_MAXMINOR) { + if (i < NFS4_MINMINOR || i > NFS4_MAXMINOR) { fprintf(stderr, "%s: unsupported minor version\n", optarg); exit(1); } @@ -210,7 +200,7 @@ main(int argc, char **argv) case 4: if (*p == '.') { int i = atoi(p+1); - if (i > NFS4_MAXMINOR) { + if (i < NFS4_MINMINOR || i > NFS4_MAXMINOR) { fprintf(stderr, "%s: unsupported minor version\n", optarg); exit(1); } @@ -277,18 +267,6 @@ main(int argc, char **argv) xlog_open(progname); - nfsd_enable_protos(&proto4, &proto6); - - if (!NFSCTL_TCPISSET(protobits)) { - NFSCTL_TCPUNSET(proto4); - NFSCTL_TCPUNSET(proto6); - } - - if (!NFSCTL_UDPISSET(protobits)) { - NFSCTL_UDPUNSET(proto4); - NFSCTL_UDPUNSET(proto6); - } - /* make sure that at least one version is enabled */ found_one = 0; for (c = NFSD_MINVERS; c <= NFSD_MAXVERS; c++) { @@ -301,8 +279,7 @@ main(int argc, char **argv) } if (NFSCTL_VERISSET(versbits, 4) && - !NFSCTL_TCPISSET(proto4) && - !NFSCTL_TCPISSET(proto6)) { + !NFSCTL_TCPISSET(protobits)) { xlog(L_ERROR, "version 4 requires the TCP protocol"); exit(1); } @@ -336,15 +313,10 @@ main(int argc, char **argv) i = 0; do { - error = nfssvc_set_sockets(AF_INET, proto4, haddr[i], port); - if (!error) - socket_up = 1; -#ifdef IPV6_SUPPORTED - error = nfssvc_set_sockets(AF_INET6, proto6, haddr[i], port); + error = nfssvc_set_sockets(protobits, haddr[i], port); if (!error) socket_up = 1; -#endif /* IPV6_SUPPORTED */ - } while (++i < hcounter); + } while (++i < hcounter); if (rdma_port) { error = nfssvc_set_rdmaport(rdma_port); @@ -381,11 +353,7 @@ set_threads: if ((error = nfssvc_threads(portnum, count)) < 0) xlog(L_ERROR, "error starting threads: errno %d (%m)", errno); out: - free(port); - for(i=0; i < hcounter; i++) - free(haddr[i]); free(haddr); - free(progname); return (error != 0); } diff -up nfs-utils-1.3.0/utils/nfsd/nfsd.man.orig nfs-utils-1.3.0/utils/nfsd/nfsd.man --- nfs-utils-1.3.0/utils/nfsd/nfsd.man.orig 2014-03-25 11:12:07.000000000 -0400 +++ nfs-utils-1.3.0/utils/nfsd/nfsd.man 2017-03-28 13:43:53.000000000 -0400 @@ -57,7 +57,7 @@ This option can be used to request that .B rpc.nfsd does not offer certain versions of NFS. The current version of .B rpc.nfsd -can support NFS versions 2,3,4 and the newer version 4.1. +can support major NFS versions 2,3,4 and the minor versions 4.1 and 4.2. .TP .B \-s " or " \-\-syslog By default, @@ -82,7 +82,7 @@ This option can be used to request that .B rpc.nfsd offer certain versions of NFS. The current version of .B rpc.nfsd -can support NFS versions 2,3,4 and the newer version 4.1. +can support major NFS versions 2,3,4 and the minor versions 4.1 and 4.2. .TP .B \-L " or " \-\-lease-time seconds Set the lease-time used for NFSv4. This corresponds to how often @@ -95,11 +95,11 @@ New file open requests (NFSv4) and new f allowed until after this time has passed to allow clients to recover state. .TP .I nproc -specify the number of NFS server threads. By default, just one -thread is started. However, for optimum performance several threads +specify the number of NFS server threads. By default, eight +threads are started. However, for optimum performance several threads should be used. The actual figure depends on the number of and the work load created by the NFS clients, but a useful starting point is -8 threads. Effects of modifying that number can be checked using +eight threads. Effects of modifying that number can be checked using the .BR nfsstat (8) program. @@ -114,6 +114,58 @@ In particular .B rpc.nfsd 0 will stop all threads and thus close any open connections. +.SH CONFIGURATION FILE +Many of the options that can be set on the command line can also be +controlled through values set in the +.B [nfsd] +section of the +.I /etc/nfs.conf +configuration file. Values recognized include: +.TP +.B threads +The number of threads to start. +.TP +.B host +A host name, or comma separated list of host names, that +.I rpc.nfsd +will listen on. Use of the +.B --host +option replaces all host names listed here. +.TP +.B grace-time +The grace time, for both NFSv4 and NLM, in seconds. +.TP +.B lease-time +The lease time for NFSv4, in seconds. +.TP +.B port +Set the port for TCP/UDP to bind to. +.TP +.B rdma +Set RDMA port. Use "rdma=nfsrdma" to enable standard port. +.TP +.B UDP +Enable (with "on" or "yes" etc) or disable ("off", "no") UDP support. +.TP +.B TCP +Enable or disable TCP support. +.TP +.B vers2 +.TP +.B vers3 +.TP +.B vers4 +Enable or disable a major NFS version. 3 and 4 are normally enabled +by default. +.TP +.B vers4.1 +.TP +.B vers4.2 +Setting these to "off" or similar will disable the selected minor +versions. Setting to "on" will enable them. The default values +are determined by the kernel, and usually minor versions default to +being enabled once the implementation is sufficiently complete. + .SH NOTES If the program is built with TI-RPC support, it will enable any protocol and address family combinations that are marked visible in the @@ -124,6 +176,7 @@ database. .BR rpc.mountd (8), .BR exports (5), .BR exportfs (8), +.BR nfs.conf (5), .BR rpc.rquotad (8), .BR nfsstat (8), .BR netconfig(5). diff -up nfs-utils-1.3.0/utils/nfsd/nfssvc.c.orig nfs-utils-1.3.0/utils/nfsd/nfssvc.c --- nfs-utils-1.3.0/utils/nfsd/nfssvc.c.orig 2017-03-28 13:43:36.000000000 -0400 +++ nfs-utils-1.3.0/utils/nfsd/nfssvc.c 2017-03-28 13:43:53.000000000 -0400 @@ -23,6 +23,7 @@ #include "nfslib.h" #include "xlog.h" +#include "nfssvc.h" #ifndef NFSD_FS_DIR #define NFSD_FS_DIR "/proc/fs/nfsd" @@ -123,22 +124,6 @@ nfssvc_setfds(const struct addrinfo *hin if (fd < 0) return 0; - switch(hints->ai_family) { - case AF_INET: - family = "inet"; - break; -#ifdef IPV6_SUPPORTED - case AF_INET6: - family = "inet6"; - break; -#endif /* IPV6_SUPPORTED */ - default: - xlog(L_ERROR, "Unknown address family specified: %d\n", - hints->ai_family); - rc = EAFNOSUPPORT; - goto error; - } - rc = getaddrinfo(node, port, hints, &addrhead); if (rc == EAI_NONAME && !strcmp(port, "nfs")) { snprintf(buf, sizeof(buf), "%d", NFS_PORT); @@ -146,10 +131,10 @@ nfssvc_setfds(const struct addrinfo *hin } if (rc != 0) { - xlog(L_ERROR, "unable to resolve %s:%s to %s address: " - "%s", node ? node : "ANYADDR", port, family, - rc == EAI_SYSTEM ? strerror(errno) : - gai_strerror(rc)); + xlog(L_ERROR, "unable to resolve %s:%s: %s", + node ? node : "ANYADDR", port, + rc == EAI_SYSTEM ? strerror(errno) : + gai_strerror(rc)); goto error; } @@ -168,6 +153,20 @@ nfssvc_setfds(const struct addrinfo *hin continue; } + switch(addr->ai_addr->sa_family) { + case AF_INET: + family = "AF_INET"; + break; +#ifdef IPV6_SUPPORTED + case AF_INET6: + family = "AF_INET6"; + break; +#endif /* IPV6_SUPPORTED */ + default: + addr = addr->ai_next; + continue; + } + xlog(D_GENERAL, "Creating %s %s socket.", family, proto); /* open socket and prepare to hand it off to kernel */ @@ -251,12 +250,16 @@ error: } int -nfssvc_set_sockets(const int family, const unsigned int protobits, +nfssvc_set_sockets(const unsigned int protobits, const char *host, const char *port) { struct addrinfo hints = { .ai_flags = AI_PASSIVE }; - hints.ai_family = family; +#ifdef IPV6_SUPPORTED + hints.ai_family = AF_UNSPEC; +#else /* IPV6_SUPPORTED */ + hints.ai_family = AF_INET; +#endif /* IPV6_SUPPORTED */ if (!NFSCTL_ANYPROTO(protobits)) return EPROTOTYPE; diff -up nfs-utils-1.3.0/utils/nfsd/nfssvc.h.orig nfs-utils-1.3.0/utils/nfsd/nfssvc.h --- nfs-utils-1.3.0/utils/nfsd/nfssvc.h.orig 2014-03-25 11:12:07.000000000 -0400 +++ nfs-utils-1.3.0/utils/nfsd/nfssvc.h 2017-03-28 13:43:53.000000000 -0400 @@ -22,7 +22,7 @@ void nfssvc_mount_nfsdfs(char *progname); int nfssvc_inuse(void); -int nfssvc_set_sockets(const int family, const unsigned int protobits, +int nfssvc_set_sockets(const unsigned int protobits, const char *host, const char *port); void nfssvc_set_time(const char *type, const int seconds); int nfssvc_set_rdmaport(const char *port); diff -up nfs-utils-1.3.0/utils/statd/sm-notify.c.orig nfs-utils-1.3.0/utils/statd/sm-notify.c --- nfs-utils-1.3.0/utils/statd/sm-notify.c.orig 2014-03-25 11:12:07.000000000 -0400 +++ nfs-utils-1.3.0/utils/statd/sm-notify.c 2017-03-28 13:43:53.000000000 -0400 @@ -29,6 +29,7 @@ #include #include +#include "conffile.h" #include "sockaddr.h" #include "xlog.h" #include "nsm.h" @@ -64,6 +65,7 @@ static _Bool opt_update_state = true; static unsigned int opt_max_retry = 15 * 60; static char * opt_srcaddr = NULL; static char * opt_srcport = NULL; +char * conf_path = NFS_CONFFILE; static void notify(const int sock); static int notify_host(int, struct nsm_host *); @@ -455,6 +457,7 @@ main(int argc, char **argv) { int c, sock, force = 0; char * progname; + char * s; progname = strrchr(argv[0], '/'); if (progname != NULL) @@ -462,6 +465,15 @@ main(int argc, char **argv) else progname = argv[0]; + conf_init(); + xlog_from_conffile("sm-notify"); + opt_max_retry = conf_get_num("sm-notify", "retry-time", opt_max_retry / 60) * 60; + opt_srcport = conf_get_str("sm-notify", "outgoing-port"); + opt_srcaddr = conf_get_str("sm-notify", "outgoing-addr"); + s = conf_get_str("statd", "state-directory-path"); + if (s && !nsm_setup_pathnames(argv[0], s)) + exit(1); + while ((c = getopt(argc, argv, "dm:np:v:P:f")) != -1) { switch (c) { case 'f': diff -up nfs-utils-1.3.0/utils/statd/sm-notify.man.orig nfs-utils-1.3.0/utils/statd/sm-notify.man --- nfs-utils-1.3.0/utils/statd/sm-notify.man.orig 2014-03-25 11:12:07.000000000 -0400 +++ nfs-utils-1.3.0/utils/statd/sm-notify.man 2017-03-28 13:43:53.000000000 -0400 @@ -219,6 +219,33 @@ argument when sending SM_NOTIFY requests .IP This option can be useful in multi-homed configurations where the remote requires notification from a specific network address. +.SH CONFIGURATION FILE +Many of the options that can be set on the command line can also be +controlled through values set in the +.B [sm-notify] +or, in one case, the +.B [statd] +section of the +.I /etc/nfs.conf +configuration file. + +Values recognized in the +.B [sm-notify] +section include: +.BR retry-time , +.BR outgoing-port ", and" +.BR outgoing-addr . +These have the same effect as the command line options +.BR m , +.BR p ", and" +.B v +respectively. + +The value recognized in the +.B [statd] +section is +.BR state-directory-path . + .SH SECURITY The .B sm-notify diff -up nfs-utils-1.3.0/utils/statd/statd.c.orig nfs-utils-1.3.0/utils/statd/statd.c --- nfs-utils-1.3.0/utils/statd/statd.c.orig 2017-03-28 13:43:36.000000000 -0400 +++ nfs-utils-1.3.0/utils/statd/statd.c 2017-03-28 13:43:53.000000000 -0400 @@ -26,6 +26,7 @@ #include #include +#include "conffile.h" #include "statd.h" #include "nfslib.h" #include "nfsrpc.h" @@ -36,6 +37,7 @@ #include int run_mode = 0; /* foreground logging mode */ +char *conf_path = NFS_CONFFILE; /* LH - I had these local to main, but it seemed silly to have * two copies of each - one in main(), one static in log.c... @@ -242,15 +244,21 @@ static void set_nlm_port(char *type, int int main (int argc, char **argv) { extern char *optarg; + char *s; int pid; int arg; int port = 0, out_port = 0; int nlm_udp = 0, nlm_tcp = 0; struct rlimit rlim; + char *env; /* Default: daemon mode, no other options */ run_mode = 0; + env = getenv("RPC_STATD_NO_NOTIFY"); + if (env && atoi(env) > 0) + run_mode |= MODE_NO_NOTIFY; + /* Log to stderr if there's an error during startup */ xlog_stderr(1); xlog_syslog(0); @@ -265,6 +273,24 @@ int main (int argc, char **argv) /* Set hostname */ MY_NAME = NULL; + conf_init(); + xlog_from_conffile("statd"); + out_port = conf_get_num("statd", "outgoing-port", out_port); + port = conf_get_num("statd", "port", port); + MY_NAME = conf_get_str("statd", "name"); + if (MY_NAME) + run_mode |= STATIC_HOSTNAME; + s = conf_get_str("statd", "state-directory-path"); + if (s && !nsm_setup_pathnames(argv[0], s)) + exit(1); + s = conf_get_str("statd", "ha-callout"); + if (s) + ha_callout_prog = s; + + nlm_tcp = conf_get_num("lockd", "port", nlm_tcp); + /* udp defaults to the same as tcp ! */ + nlm_udp = conf_get_num("lockd", "udp-port", nlm_tcp); + /* Process command line switches */ while ((arg = getopt_long(argc, argv, "h?vVFNH:dn:p:o:P:LT:U:", longopts, NULL)) != EOF) { switch (arg) { diff -up nfs-utils-1.3.0/utils/statd/statd.man.orig nfs-utils-1.3.0/utils/statd/statd.man --- nfs-utils-1.3.0/utils/statd/statd.man.orig 2017-03-28 13:43:36.000000000 -0400 +++ nfs-utils-1.3.0/utils/statd/statd.man 2017-03-28 13:43:53.000000000 -0400 @@ -8,7 +8,7 @@ .\" Rewritten by Chuck Lever , 2009. .\" Copyright 2009 Oracle. All rights reserved. .\" -.TH RPC.STATD 8 "1 November 2009 +.TH RPC.STATD 8 "1 November 2009" .SH NAME rpc.statd \- NSM service daemon .SH SYNOPSIS @@ -247,7 +247,7 @@ should listen on for .B NLM requests. .TP -.BI "\-P, " "" \-\-state\-directory\-path " pathname +.BI "\-P, " "" \-\-state\-directory\-path " pathname" Specifies the pathname of the parent directory where NSM state information resides. If this option is not specified, @@ -267,6 +267,37 @@ Causes to display version information on .I stderr and then exit. +.SH CONFIGURATION FILE +Many of the options that can be set on the command line can also be +controlled through values set in the +.B [statd] +or, in some cases, the +.B [lockd] +sections of the +.I /etc/nfs.conf +configuration file. +Values recognized in the +.B [statd] +section include +.BR port , +.BR outgoing-port , +.BR name , +.BR state-directory-path ", and" +.B ha-callout +which each have the same effect as the option with the same name. + +The values recognized in the +.B [lockd] +section include +.B port +and +.B udp-port +which have the same effect as the +.B --nlm-port +and +.B --nlm-udp-port +options, respectively. + .SH SECURITY The .B rpc.statd @@ -387,6 +418,11 @@ it attempts to start listeners on networ As long as at least one network transport listener starts successfully, .B rpc.statd will operate. +.SH ENVIRONMENT +.TP +.B RPC_STATD_NO_NOTIFY= +If set to a positive integer, has the same effect as +.IR \-\-no\-notify . .SH FILES .TP 2.5i .I /var/lib/nfs/sm