Blame SOURCES/nfs-utils-1.3.0-server-generator.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-31 15:55:05.544831618 -0400
e19a30
+++ nfs-utils-1.3.0/configure.ac	2017-03-31 15:58:38.833955546 -0400
e19a30
@@ -64,8 +64,14 @@ unitdir=/usr/lib/systemd/system
e19a30
 AC_ARG_WITH(systemd,
e19a30
 	[AC_HELP_STRING([--with-systemd@<:@=unit-dir-path@:>@],
e19a30
 			[install systemd unit files @<:@Default: no, and path defaults to /usr/lib/systemd/system if not given@:>@])],
e19a30
-	test "$withval" = "no" && use_systemd=0 || unitdir=$withval use_systemd=1
e19a30
-	use_systemd=0
e19a30
+	if test "$withval" != "no" ; then 
e19a30
+		use_systemd=1
e19a30
+		if test "$withval" != "yes" ; then 
e19a30
+			unitdir=$withval
e19a30
+		fi
e19a30
+	else
e19a30
+		use_systemd=0
e19a30
+	fi
e19a30
 	)
e19a30
 	AM_CONDITIONAL(INSTALL_SYSTEMD, [test "$use_systemd" = 1])
e19a30
 	AC_SUBST(unitdir)
e19a30
diff -up nfs-utils-1.3.0/.gitignore.orig nfs-utils-1.3.0/.gitignore
e19a30
--- nfs-utils-1.3.0/.gitignore.orig	2014-03-25 11:12:07.000000000 -0400
e19a30
+++ nfs-utils-1.3.0/.gitignore	2017-03-31 15:55:47.123245655 -0400
e19a30
@@ -69,6 +69,7 @@ tests/nsm_client/nlm_sm_inter_clnt.c
e19a30
 tests/nsm_client/nlm_sm_inter_svc.c
e19a30
 tests/nsm_client/nlm_sm_inter_xdr.c
e19a30
 utils/nfsidmap/nfsidmap
e19a30
+systemd/nfs-server-generator
e19a30
 # cscope database files
e19a30
 cscope.*
e19a30
 # generic editor backup et al
e19a30
diff -up nfs-utils-1.3.0/support/export/export.c.orig nfs-utils-1.3.0/support/export/export.c
e19a30
--- nfs-utils-1.3.0/support/export/export.c.orig	2017-03-31 15:55:05.528831459 -0400
e19a30
+++ nfs-utils-1.3.0/support/export/export.c	2017-03-31 15:55:47.124245665 -0400
e19a30
@@ -15,6 +15,8 @@
e19a30
 #include <sys/param.h>
e19a30
 #include <netinet/in.h>
e19a30
 #include <stdlib.h>
e19a30
+#include <dirent.h>
e19a30
+#include <errno.h>
e19a30
 #include "xmalloc.h"
e19a30
 #include "nfslib.h"
e19a30
 #include "exportfs.h"
e19a30
@@ -68,11 +70,15 @@ static void warn_duplicated_exports(nfs_
e19a30
 /**
e19a30
  * export_read - read entries from /etc/exports
e19a30
  * @fname: name of file to read from
e19a30
+ * @ignore_hosts: don't check validity of host names
e19a30
  *
e19a30
  * Returns number of read entries.
e19a30
+ * @ignore_hosts can be set when the host names won't be used
e19a30
+ * and when getting delays or errors due to problems with
e19a30
+ * hostname looking is not acceptable.
e19a30
  */
e19a30
 int
e19a30
-export_read(char *fname)
e19a30
+export_read(char *fname, int ignore_hosts)
e19a30
 {
e19a30
 	struct exportent	*eep;
e19a30
 	nfs_export		*exp;
e19a30
@@ -81,7 +87,7 @@ export_read(char *fname)
e19a30
 
e19a30
 	setexportent(fname, "r");
e19a30
 	while ((eep = getexportent(0,1)) != NULL) {
e19a30
-		exp = export_lookup(eep->e_hostname, eep->e_path, 0);
e19a30
+		exp = export_lookup(eep->e_hostname, eep->e_path, ignore_hosts);
e19a30
 		if (!exp) {
e19a30
 			if (export_create(eep, 0))
e19a30
 				/* possible complaints already logged */
e19a30
@@ -94,6 +100,70 @@ export_read(char *fname)
e19a30
 
e19a30
 	return volumes;
e19a30
 }
e19a30
+
e19a30
+/**
e19a30
+ * export_d_read - read entries from /etc/exports.
e19a30
+ * @fname: name of directory to read from
e19a30
+ * @ignore_hosts: don't check validity of host names
e19a30
+ *
e19a30
+ * Returns number of read entries.
e19a30
+ * Based on mnt_table_parse_dir() in
e19a30
+ *  util-linux-ng/shlibs/mount/src/tab_parse.c
e19a30
+ */
e19a30
+int
e19a30
+export_d_read(const char *dname, int ignore_hosts)
e19a30
+{
e19a30
+	int n = 0, i;
e19a30
+	struct dirent **namelist = NULL;
e19a30
+	int volumes = 0;
e19a30
+
e19a30
+
e19a30
+	n = scandir(dname, &namelist, NULL, versionsort);
e19a30
+	if (n < 0) {
e19a30
+		if (errno == ENOENT)
e19a30
+			/* Silently return */
e19a30
+			return volumes;
e19a30
+		xlog(L_NOTICE, "scandir %s: %s", dname, strerror(errno));
e19a30
+	} else if (n == 0)
e19a30
+		return volumes;
e19a30
+
e19a30
+	for (i = 0; i < n; i++) {
e19a30
+		struct dirent *d = namelist[i];
e19a30
+		size_t namesz;
e19a30
+		char fname[PATH_MAX + 1];
e19a30
+		int fname_len;
e19a30
+
e19a30
+
e19a30
+		if (d->d_type != DT_UNKNOWN
e19a30
+		    && d->d_type != DT_REG
e19a30
+		    && d->d_type != DT_LNK)
e19a30
+			continue;
e19a30
+		if (*d->d_name == '.')
e19a30
+			continue;
e19a30
+
e19a30
+#define _EXT_EXPORT_SIZ   (sizeof(_EXT_EXPORT) - 1)
e19a30
+		namesz = strlen(d->d_name);
e19a30
+		if (!namesz
e19a30
+		    || namesz < _EXT_EXPORT_SIZ + 1
e19a30
+		    || strcmp(d->d_name + (namesz - _EXT_EXPORT_SIZ),
e19a30
+			      _EXT_EXPORT))
e19a30
+			continue;
e19a30
+
e19a30
+		fname_len = snprintf(fname, PATH_MAX +1, "%s/%s", dname, d->d_name);
e19a30
+		if (fname_len > PATH_MAX) {
e19a30
+			xlog(L_WARNING, "Too long file name: %s in %s", d->d_name, dname);
e19a30
+			continue;
e19a30
+		}
e19a30
+
e19a30
+		volumes += export_read(fname, ignore_hosts);
e19a30
+	}
e19a30
+
e19a30
+	for (i = 0; i < n; i++)
e19a30
+		free(namelist[i]);
e19a30
+	free(namelist);
e19a30
+
e19a30
+	return volumes;
e19a30
+}
e19a30
 
e19a30
 /**
e19a30
  * export_create - create an in-core nfs_export record from an export entry
e19a30
diff -up nfs-utils-1.3.0/support/include/exportfs.h.orig nfs-utils-1.3.0/support/include/exportfs.h
e19a30
--- nfs-utils-1.3.0/support/include/exportfs.h.orig	2017-03-31 15:55:05.528831459 -0400
e19a30
+++ nfs-utils-1.3.0/support/include/exportfs.h	2017-03-31 15:55:47.124245665 -0400
e19a30
@@ -133,7 +133,8 @@ struct addrinfo *		client_resolve(const
e19a30
 int 				client_member(const char *client,
e19a30
 						const char *name);
e19a30
 
e19a30
-int				export_read(char *fname);
e19a30
+int				export_read(char *fname, int ignore_hosts);
e19a30
+int				export_d_read(const char *dname, int ignore_hosts);
e19a30
 void				export_reset(nfs_export *);
e19a30
 nfs_export *			export_lookup(char *hname, char *path, int caconical);
e19a30
 nfs_export *			export_find(const struct addrinfo *ai,
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-31 15:55:05.545831628 -0400
e19a30
+++ nfs-utils-1.3.0/systemd/Makefile.am	2017-03-31 15:55:47.124245665 -0400
e19a30
@@ -4,7 +4,6 @@ MAINTAINERCLEANFILES = Makefile.in
e19a30
 
e19a30
 unit_files =  \
e19a30
     nfs-client.target \
e19a30
-    \
e19a30
     auth-rpcgss-module.service \
e19a30
     nfs-blkmap.service \
e19a30
     nfs-config.service \
e19a30
@@ -15,8 +14,6 @@ unit_files =  \
e19a30
     rpc-gssd.service \
e19a30
     rpc-statd-notify.service \
e19a30
     rpc-statd.service \
e19a30
-    rpc-svcgssd.service \
e19a30
-    \
e19a30
     proc-fs-nfsd.mount \
e19a30
     var-lib-nfs-rpc_pipefs.mount
e19a30
 
e19a30
@@ -25,8 +22,16 @@ man7_MANS	= nfs.systemd.man
e19a30
 EXTRA_DIST = $(unit_files) $(man5_MANS) $(man7_MANS)
e19a30
 
e19a30
 unit_dir = /usr/lib/systemd/system
e19a30
+generator_dir = /usr/lib/systemd/system-generators
e19a30
+
e19a30
+EXTRA_PROGRAMS	= nfs-server-generator
e19a30
+genexecdir = $(generator_dir)
e19a30
+nfs_server_generator_LDADD = ../support/export/libexport.a \
e19a30
+			     ../support/nfs/libnfs.a \
e19a30
+			     ../support/misc/libmisc.a
e19a30
 
e19a30
 if INSTALL_SYSTEMD
e19a30
+genexec_PROGRAMS = nfs-server-generator
e19a30
 install-data-hook: $(unit_files)
e19a30
 	mkdir -p $(DESTDIR)/$(unitdir)
e19a30
 	cp $(unit_files) $(DESTDIR)/$(unitdir)
e19a30
diff -up nfs-utils-1.3.0/systemd/nfs-server-generator.c.orig nfs-utils-1.3.0/systemd/nfs-server-generator.c
e19a30
--- nfs-utils-1.3.0/systemd/nfs-server-generator.c.orig	2017-03-31 15:55:47.124245665 -0400
e19a30
+++ nfs-utils-1.3.0/systemd/nfs-server-generator.c	2017-03-31 15:55:47.124245665 -0400
e19a30
@@ -0,0 +1,179 @@
e19a30
+/*
e19a30
+ * nfs-server-generator:
e19a30
+ *   systemd generator to create ordering dependencies between
e19a30
+ *   nfs-server and various filesystem mounts
e19a30
+ *
e19a30
+ * 1/ nfs-server should start Before any 'nfs' mountpoints are
e19a30
+ *    mounted, in case they are loop-back mounts.  This ordering is particularly
e19a30
+ *    important for the shutdown side, so the nfs-server is stopped
e19a30
+ *    after the filesystems are unmounted.
e19a30
+ * 2/ nfs-server should start After all exported filesystems are mounted
e19a30
+ *    so there is no risk of exporting the underlying directory.
e19a30
+ *    This is particularly important for _net mounts which
e19a30
+ *    are not caught by "local-fs.target".
e19a30
+ */
e19a30
+
e19a30
+#ifdef HAVE_CONFIG_H
e19a30
+#include <config.h>
e19a30
+#endif
e19a30
+
e19a30
+#include <sys/stat.h>
e19a30
+#include <sys/types.h>
e19a30
+#include <unistd.h>
e19a30
+#include <stdlib.h>
e19a30
+#include <string.h>
e19a30
+#include <ctype.h>
e19a30
+#include <stdio.h>
e19a30
+#include <mntent.h>
e19a30
+
e19a30
+#include "misc.h"
e19a30
+#include "nfslib.h"
e19a30
+#include "exportfs.h"
e19a30
+
e19a30
+/* A simple "set of strings" to remove duplicates
e19a30
+ * found in /etc/exports
e19a30
+ */
e19a30
+struct list {
e19a30
+	struct list *next;
e19a30
+	char *name;
e19a30
+};
e19a30
+static int is_unique(struct list **lp, char *path)
e19a30
+{
e19a30
+	struct list *l = *lp;
e19a30
+
e19a30
+	while (l) {
e19a30
+		if (strcmp(l->name, path) == 0)
e19a30
+			return 0;
e19a30
+		l = l->next;
e19a30
+	}
e19a30
+	l = malloc(sizeof(*l));
e19a30
+	if (l == NULL)
e19a30
+		return 0;
e19a30
+	l->name = path;
e19a30
+	l->next = *lp;
e19a30
+	*lp = l;
e19a30
+	return 1;
e19a30
+}
e19a30
+
e19a30
+/* We need to convert a path name to a systemd unit
e19a30
+ * name.  This requires some translation ('/' -> '-')
e19a30
+ * and some escaping.
e19a30
+ */
e19a30
+static void systemd_escape(FILE *f, char *path)
e19a30
+{
e19a30
+	while (*path == '/')
e19a30
+		path++;
e19a30
+	if (!*path) {
e19a30
+		/* "/" becomes "-", otherwise leading "/" is ignored */
e19a30
+		fputs("-", f);
e19a30
+		return;
e19a30
+	}
e19a30
+	while (*path) {
e19a30
+		char c = *path++;
e19a30
+
e19a30
+		if (c == '/') {
e19a30
+			/* multiple non-trailing slashes become '-' */
e19a30
+			while (*path == '/')
e19a30
+				path++;
e19a30
+			if (*path)
e19a30
+				fputs("-", f);
e19a30
+		} else if (isalnum(c) || c == ':' || c == '.')
e19a30
+			fputc(c, f);
e19a30
+		else
e19a30
+			fprintf(f, "\\x%02x", c & 0xff);
e19a30
+	}
e19a30
+}
e19a30
+
e19a30
+static int has_noauto_flag(char *path)
e19a30
+{
e19a30
+	FILE		*fstab;
e19a30
+	struct mntent	*mnt;
e19a30
+
e19a30
+	fstab = setmntent("/etc/fstab", "r");
e19a30
+	if (!fstab)
e19a30
+		return 0;
e19a30
+
e19a30
+	while ((mnt = getmntent(fstab)) != NULL) {
e19a30
+		int l = strlen(mnt->mnt_dir);
e19a30
+		if (strncmp(mnt->mnt_dir, path, l) != 0)
e19a30
+			continue;
e19a30
+		if (path[l] && path[l] != '/')
e19a30
+			continue;
e19a30
+		if (hasmntopt(mnt, "noauto"))
e19a30
+			break;
e19a30
+	}
e19a30
+	fclose(fstab);
e19a30
+	return mnt != NULL;
e19a30
+}
e19a30
+
e19a30
+int main(int argc, char *argv[])
e19a30
+{
e19a30
+	char		*path;
e19a30
+	char		dirbase[] = "/nfs-server.service.d";
e19a30
+	char		filebase[] = "/order-with-mounts.conf";
e19a30
+	nfs_export	*exp;
e19a30
+	int		i;
e19a30
+	struct list	*list = NULL;
e19a30
+	FILE		*f, *fstab;
e19a30
+	struct mntent	*mnt;
e19a30
+
e19a30
+	/* Avoid using any external services */
e19a30
+	xlog_syslog(0);
e19a30
+
e19a30
+	if (argc != 4 || argv[1][0] != '/') {
e19a30
+		fprintf(stderr, "nfs-server-generator: create systemd dependencies for nfs-server\n");
e19a30
+		fprintf(stderr, "Usage: normal-dir early-dir late-dir\n");
e19a30
+		exit(1);
e19a30
+	}
e19a30
+
e19a30
+	path = malloc(strlen(argv[1]) + sizeof(dirbase) + sizeof(filebase));
e19a30
+	if (!path)
e19a30
+		exit(2);
e19a30
+	if (export_read(_PATH_EXPORTS, 1) +
e19a30
+	    export_d_read(_PATH_EXPORTS_D, 1) == 0)
e19a30
+		/* Nothing is exported, so nothing to do */
e19a30
+		exit(0);
e19a30
+
e19a30
+	strcat(strcpy(path, argv[1]), dirbase);
e19a30
+	mkdir(path, 0755);
e19a30
+	strcat(path, filebase);
e19a30
+	f = fopen(path, "w");
e19a30
+	if (!f)
e19a30
+		exit(1);
e19a30
+	fprintf(f, "# Automatically generated by nfs-server-generator\n\n[Unit]\n");
e19a30
+
e19a30
+	for (i = 0; i < MCL_MAXTYPES; i++) {
e19a30
+		for (exp = exportlist[i].p_head; exp; exp = exp->m_next) {
e19a30
+			if (!is_unique(&list, exp->m_export.e_path))
e19a30
+				continue;
e19a30
+			if (exp->m_export.e_mountpoint)
e19a30
+				continue;
e19a30
+			if (has_noauto_flag(exp->m_export.e_path))
e19a30
+				continue;
e19a30
+			if (strchr(exp->m_export.e_path, ' '))
e19a30
+				fprintf(f, "RequiresMountsFor=\"%s\"\n",
e19a30
+					exp->m_export.e_path);
e19a30
+			else
e19a30
+				fprintf(f, "RequiresMountsFor=%s\n",
e19a30
+					exp->m_export.e_path);
e19a30
+		}
e19a30
+	}
e19a30
+
e19a30
+	fstab = setmntent("/etc/fstab", "r");
e19a30
+	if (!fstab)
e19a30
+		exit(1);
e19a30
+
e19a30
+	while ((mnt = getmntent(fstab)) != NULL) {
e19a30
+		if (strcmp(mnt->mnt_type, "nfs") != 0 &&
e19a30
+		    strcmp(mnt->mnt_type, "nfs4") != 0)
e19a30
+			continue;
e19a30
+		fprintf(f, "Before= ");
e19a30
+		systemd_escape(f, mnt->mnt_dir);
e19a30
+		fprintf(f, ".mount\n");
e19a30
+	}
e19a30
+
e19a30
+	fclose(fstab);
e19a30
+	fclose(f);
e19a30
+
e19a30
+	exit(0);
e19a30
+}
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-31 15:55:05.553831708 -0400
e19a30
+++ nfs-utils-1.3.0/utils/exportfs/exportfs.c	2017-03-31 15:55:47.125245675 -0400
e19a30
@@ -26,7 +26,6 @@
e19a30
 #include <fcntl.h>
e19a30
 #include <netdb.h>
e19a30
 #include <errno.h>
e19a30
-#include <dirent.h>
e19a30
 #include <limits.h>
e19a30
 #include <time.h>
e19a30
 
e19a30
@@ -48,7 +47,6 @@ static void	error(nfs_export *exp, int e
e19a30
 static void	usage(const char *progname, int n);
e19a30
 static void	validate_export(nfs_export *exp);
e19a30
 static int	matchhostname(const char *hostname1, const char *hostname2);
e19a30
-static int	export_d_read(const char *dname);
e19a30
 static void grab_lockfile(void);
e19a30
 static void release_lockfile(void);
e19a30
 
e19a30
@@ -190,8 +188,8 @@ main(int argc, char **argv)
e19a30
 	atexit(release_lockfile);
e19a30
 
e19a30
 	if (f_export && ! f_ignore) {
e19a30
-		if (! (export_read(_PATH_EXPORTS) +
e19a30
-		       export_d_read(_PATH_EXPORTS_D))) {
e19a30
+		if (! (export_read(_PATH_EXPORTS, 0) +
e19a30
+		       export_d_read(_PATH_EXPORTS_D, 0))) {
e19a30
 			if (f_verbose)
e19a30
 				xlog(L_WARNING, "No file systems exported!");
e19a30
 		}
e19a30
@@ -705,63 +703,6 @@ out:
e19a30
 	return result;
e19a30
 }
e19a30
 
e19a30
-/* Based on mnt_table_parse_dir() in
e19a30
-   util-linux-ng/shlibs/mount/src/tab_parse.c */
e19a30
-static int
e19a30
-export_d_read(const char *dname)
e19a30
-{
e19a30
-	int n = 0, i;
e19a30
-	struct dirent **namelist = NULL;
e19a30
-	int volumes = 0;
e19a30
-
e19a30
-
e19a30
-	n = scandir(dname, &namelist, NULL, versionsort);
e19a30
-	if (n < 0) {
e19a30
-		if (errno == ENOENT)
e19a30
-			/* Silently return */
e19a30
-			return volumes;
e19a30
-		xlog(L_NOTICE, "scandir %s: %s", dname, strerror(errno));
e19a30
-	} else if (n == 0)
e19a30
-		return volumes;
e19a30
-
e19a30
-	for (i = 0; i < n; i++) {
e19a30
-		struct dirent *d = namelist[i];
e19a30
-		size_t namesz;
e19a30
-		char fname[PATH_MAX + 1];
e19a30
-		int fname_len;
e19a30
-
e19a30
-
e19a30
-		if (d->d_type != DT_UNKNOWN
e19a30
-		    && d->d_type != DT_REG
e19a30
-		    && d->d_type != DT_LNK)
e19a30
-			continue;
e19a30
-		if (*d->d_name == '.')
e19a30
-			continue;
e19a30
-
e19a30
-#define _EXT_EXPORT_SIZ   (sizeof(_EXT_EXPORT) - 1)
e19a30
-		namesz = strlen(d->d_name);
e19a30
-		if (!namesz
e19a30
-		    || namesz < _EXT_EXPORT_SIZ + 1
e19a30
-		    || strcmp(d->d_name + (namesz - _EXT_EXPORT_SIZ),
e19a30
-			      _EXT_EXPORT))
e19a30
-			continue;
e19a30
-
e19a30
-		fname_len = snprintf(fname, PATH_MAX +1, "%s/%s", dname, d->d_name);
e19a30
-		if (fname_len > PATH_MAX) {
e19a30
-			xlog(L_WARNING, "Too long file name: %s in %s", d->d_name, dname);
e19a30
-			continue;
e19a30
-		}
e19a30
-
e19a30
-		volumes += export_read(fname);
e19a30
-	}
e19a30
-
e19a30
-	for (i = 0; i < n; i++)
e19a30
-		free(namelist[i]);
e19a30
-	free(namelist);
e19a30
-
e19a30
-	return volumes;
e19a30
-}
e19a30
-
e19a30
 static char
e19a30
 dumpopt(char c, char *fmt, ...)
e19a30
 {