Blame SOURCES/nfs-utils-1.3.0-nfs-conf.patch

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