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