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

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