Added back the nfs-config service for backwards compatibility

Signed-off-by: Steve Dickson <steved@redhat.com>
This commit is contained in:
Steve Dickson 2017-01-19 14:49:27 -05:00
parent c6baeee084
commit 368cd44bb6
8 changed files with 209 additions and 7946 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,583 +0,0 @@
diff --git a/.gitignore b/.gitignore
index 5164637..126d12c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -69,6 +69,9 @@ 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
+systemd/nfs-config.service
+systemd/rpc-gssd.service
# cscope database files
cscope.*
# generic editor backup et al
diff --git a/configure.ac b/configure.ac
index 1daf5b8..d60f3a2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -511,8 +511,20 @@ AC_SUBST([AM_CFLAGS], ["$my_am_cflags"])
# Make sure that $ACLOCAL_FLAGS are used during a rebuild
AC_SUBST([ACLOCAL_AMFLAGS], ["-I $ac_macro_dir \$(ACLOCAL_FLAGS)"])
+# make libexecdir available for substituion in config files
+# 2 "evals" needed late to expand variable names.
+AC_SUBST([_libexecdir])
+AC_CONFIG_COMMANDS_PRE([eval eval _libexecdir=$libexecdir])
+
+# make _sysconfdir available for substituion in config files
+# 2 "evals" needed late to expand variable names.
+AC_SUBST([_sysconfdir])
+AC_CONFIG_COMMANDS_PRE([eval eval _sysconfdir=$sysconfdir])
+
AC_CONFIG_FILES([
Makefile
+ systemd/nfs-config.service
+ systemd/rpc-gssd.service
linux-nfs/Makefile
support/Makefile
support/export/Makefile
diff --git a/support/export/export.c b/support/export/export.c
index e1bebce..0b8a858 100644
--- a/support/export/export.c
+++ b/support/export/export.c
@@ -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"
@@ -96,6 +98,69 @@ export_read(char *fname)
}
/**
+ * export_d_read - read entries from /etc/exports.
+ * @fname: name of directory to read from
+ *
+ * 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 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;
+}
+
+/**
* export_create - create an in-core nfs_export record from an export entry
* @xep: export entry to lookup
* @canonical: if set, e_hostname is known to be canonical DNS name
diff --git a/support/include/exportfs.h b/support/include/exportfs.h
index 4cac203..f033329 100644
--- a/support/include/exportfs.h
+++ b/support/include/exportfs.h
@@ -135,6 +135,7 @@ int client_member(const char *client,
const char *name);
int export_read(char *fname);
+int export_d_read(const char *dname);
void export_reset(nfs_export *);
nfs_export * export_lookup(char *hname, char *path, int caconical);
nfs_export * export_find(const struct addrinfo *ai,
diff --git a/systemd/Makefile.am b/systemd/Makefile.am
index 03f96e9..49c9b8d 100644
--- a/systemd/Makefile.am
+++ b/systemd/Makefile.am
@@ -39,8 +39,16 @@ endif
EXTRA_DIST = $(unit_files)
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 --git a/systemd/nfs-config.service b/systemd/nfs-config.service
deleted file mode 100644
index bd69e84..0000000
--- a/systemd/nfs-config.service
+++ /dev/null
@@ -1,13 +0,0 @@
-[Unit]
-Description=Preprocess NFS configuration
-After=local-fs.target
-DefaultDependencies=no
-
-[Service]
-Type=oneshot
-# This service needs to run any time any nfs service
-# is started, so changes to local config files get
-# incorporated. Having "RemainAfterExit=no" (the default)
-# ensures this happens.
-RemainAfterExit=no
-ExecStart=/usr/libexec/nfs-utils/nfs-utils_env.sh
diff --git a/systemd/nfs-config.service.in b/systemd/nfs-config.service.in
new file mode 100644
index 0000000..e89dc54
--- /dev/null
+++ b/systemd/nfs-config.service.in
@@ -0,0 +1,13 @@
+[Unit]
+Description=Preprocess NFS configuration
+After=local-fs.target
+DefaultDependencies=no
+
+[Service]
+Type=oneshot
+# This service needs to run any time any nfs service
+# is started, so changes to local config files get
+# incorporated. Having "RemainAfterExit=no" (the default)
+# ensures this happens.
+RemainAfterExit=no
+ExecStart=@_libexecdir@/nfs-utils/nfs-utils_env.sh
diff --git a/systemd/nfs-server-generator.c b/systemd/nfs-server-generator.c
new file mode 100644
index 0000000..f47718e
--- /dev/null
+++ b/systemd/nfs-server-generator.c
@@ -0,0 +1,150 @@
+/*
+ * 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);
+ }
+}
+
+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;
+
+ 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) +
+ export_d_read(_PATH_EXPORTS_D) == 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 (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 --git a/systemd/nfs-server.service b/systemd/nfs-server.service
index 2ccdc63..196c818 100644
--- a/systemd/nfs-server.service
+++ b/systemd/nfs-server.service
@@ -16,9 +16,6 @@ Before= rpc-statd-notify.service
Wants=auth-rpcgss-module.service
After=rpc-gssd.service gssproxy.service rpc-svcgssd.service
-# start/stop server before/after client
-Before=remote-fs-pre.target
-
Wants=nfs-config.service
After=nfs-config.service
diff --git a/systemd/rpc-gssd.service b/systemd/rpc-gssd.service
deleted file mode 100644
index d4a3819..0000000
--- a/systemd/rpc-gssd.service
+++ /dev/null
@@ -1,19 +0,0 @@
-[Unit]
-Description=RPC security service for NFS client and server
-DefaultDependencies=no
-Conflicts=umount.target
-Requires=var-lib-nfs-rpc_pipefs.mount
-After=var-lib-nfs-rpc_pipefs.mount
-
-ConditionPathExists=/etc/krb5.keytab
-
-PartOf=nfs-utils.service
-
-Wants=nfs-config.service
-After=nfs-config.service
-
-[Service]
-EnvironmentFile=-/run/sysconfig/nfs-utils
-
-Type=forking
-ExecStart=/usr/sbin/rpc.gssd $GSSDARGS
diff --git a/systemd/rpc-gssd.service.in b/systemd/rpc-gssd.service.in
new file mode 100644
index 0000000..1a7911c
--- /dev/null
+++ b/systemd/rpc-gssd.service.in
@@ -0,0 +1,19 @@
+[Unit]
+Description=RPC security service for NFS client and server
+DefaultDependencies=no
+Conflicts=umount.target
+Requires=var-lib-nfs-rpc_pipefs.mount
+After=var-lib-nfs-rpc_pipefs.mount
+
+ConditionPathExists=@_sysconfdir@/krb5.keytab
+
+PartOf=nfs-utils.service
+
+Wants=nfs-config.service
+After=nfs-config.service
+
+[Service]
+EnvironmentFile=-/run/sysconfig/nfs-utils
+
+Type=forking
+ExecStart=/usr/sbin/rpc.gssd $GSSDARGS
diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c
index a00b5ea..4ac2c15 100644
--- a/utils/exportfs/exportfs.c
+++ b/utils/exportfs/exportfs.c
@@ -26,7 +26,6 @@
#include <fcntl.h>
#include <netdb.h>
#include <errno.h>
-#include <dirent.h>
#include <limits.h>
#include <time.h>
@@ -47,7 +46,6 @@ static void error(nfs_export *exp, int err);
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);
@@ -700,63 +698,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, ...)
{
diff --git a/utils/idmapd/idmapd.man b/utils/idmapd/idmapd.man
index b9200c7..d4ab894 100644
--- a/utils/idmapd/idmapd.man
+++ b/utils/idmapd/idmapd.man
@@ -23,6 +23,29 @@ is the NFSv4 ID <-> name mapping daemon. It provides functionality to
the NFSv4 kernel client and server, to which it communicates via
upcalls, by translating user and group IDs to names, and vice versa.
.Pp
+The system derives the
+.I user
+part of the string by performing a password or group lookup.
+The lookup mechanism is configured in
+.Pa /etc/idmapd.conf
+.Pp
+By default, the
+.I domain
+part of the string is the system's DNS domain name.
+It can also be specified in
+.Pa /etc/idmapd.conf
+if the system is multi-homed,
+or if the system's DNS domain name does
+not match the name of the system's Kerberos realm.
+.Pp
+When the domain is not specified in /etc/idmapd.conf
+the local DNS server will be queried for the
+.Sy _nfsv4idmapdomain
+text record. If the record exists
+that will be used as the domain. When the record
+does not exist, the domain part of the DNS domain
+will used.
+.Pp
Note that on more recent kernels only the NFSv4 server uses
.Nm .
The NFSv4 client instead uses
diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c
index 9de6794..d5dfb5e 100644
--- a/utils/mount/stropts.c
+++ b/utils/mount/stropts.c
@@ -948,6 +948,7 @@ static int nfs_is_permanent_error(int error)
case ETIMEDOUT:
case ECONNREFUSED:
case EHOSTUNREACH:
+ case EOPNOTSUPP: /* aka RPC_PROGNOTREGISTERED */
case EAGAIN:
return 0; /* temporary */
default:
@@ -1019,8 +1020,7 @@ static int nfsmount_parent(struct nfsmount_info *mi)
if (nfs_try_mount(mi))
return EX_SUCCESS;
- /* retry background mounts when the server is not up */
- if (nfs_is_permanent_error(errno) && errno != EOPNOTSUPP) {
+ if (nfs_is_permanent_error(errno)) {
mount_error(mi->spec, mi->node, errno);
return EX_FAIL;
}
@@ -1055,8 +1055,7 @@ static int nfsmount_child(struct nfsmount_info *mi)
if (nfs_try_mount(mi))
return EX_SUCCESS;
- /* retry background mounts when the server is not up */
- if (nfs_is_permanent_error(errno) && errno != EOPNOTSUPP)
+ if (nfs_is_permanent_error(errno))
break;
if (time(NULL) > timeout)
diff --git a/utils/nfsidmap/nfsidmap.man b/utils/nfsidmap/nfsidmap.man
index 2f17cf2..2af16f3 100644
--- a/utils/nfsidmap/nfsidmap.man
+++ b/utils/nfsidmap/nfsidmap.man
@@ -39,6 +39,15 @@ if the system is multi-homed,
or if the system's DNS domain name does
not match the name of the system's Kerberos realm.
.PP
+When the domain is not specified in
+.I /etc/idmapd.conf
+the local DNS server will be queried for the
+.I _nfsv4idmapdomain
+text record. If the record exists
+that will be used as the domain. When the record
+does not exist, the domain part of the DNS domain
+will used.
+.PP
The
.I /usr/sbin/nfsidmap
program performs translations on behalf of the kernel.

View File

@ -1,929 +0,0 @@
diff --git a/.gitignore b/.gitignore
index 5164637..126d12c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -69,6 +69,9 @@ 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
+systemd/nfs-config.service
+systemd/rpc-gssd.service
# cscope database files
cscope.*
# generic editor backup et al
diff --git a/Makefile.am b/Makefile.am
index 4a2edc6..e1f39aa 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -23,7 +23,6 @@ ACLOCAL_AMFLAGS = -I aclocal
install-data-hook:
if [ ! -d $(DESTDIR)$(statedir) ]; then mkdir -p $(DESTDIR)$(statedir); fi
- touch $(DESTDIR)$(statedir)/xtab; chmod 644 $(DESTDIR)$(statedir)/xtab
touch $(DESTDIR)$(statedir)/etab; chmod 644 $(DESTDIR)$(statedir)/etab
touch $(DESTDIR)$(statedir)/rmtab; chmod 644 $(DESTDIR)$(statedir)/rmtab
mkdir -p $(DESTDIR)$(statdpath)/sm $(DESTDIR)$(statdpath)/sm.bak
@@ -32,7 +31,7 @@ install-data-hook:
-chown $(statduser) $(DESTDIR)$(statdpath)/sm $(DESTDIR)$(statdpath)/sm.bak $(DESTDIR)$(statdpath)/state
uninstall-hook:
- rm $(DESTDIR)$(statedir)/xtab
+ rm -f $(DESTDIR)$(statedir)/xtab
rm $(DESTDIR)$(statedir)/etab
rm $(DESTDIR)$(statedir)/rmtab
rm $(DESTDIR)$(statdpath)/state
diff --git a/configure.ac b/configure.ac
index 1daf5b8..8a5aa2e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -24,6 +24,12 @@ AC_ARG_WITH(statedir,
statedir=$withval,
statedir=/var/lib/nfs)
AC_SUBST(statedir)
+AC_ARG_WITH(nfsconfig,
+ [AC_HELP_STRING([--with-nfsconfig=/config/file],
+ [use general config file /config/file @<:@default=/etc/nfs.conf@:>@])],
+ nfsconfig=$withval,
+ nfsconfig=/etc/nfs.conf)
+ AC_SUBST(nfsconfig)
AC_ARG_WITH(statdpath,
[AC_HELP_STRING([--with-statdpath=/foo],
[define the statd state dir as /foo instead of the NFS statedir @<:@default=/var/lib/nfs@:>@])],
@@ -468,6 +474,7 @@ dnl Export some path names to config.h
dnl *************************************************************
AC_DEFINE_UNQUOTED(NFS_STATEDIR, "$statedir", [This defines the location of the NFS state files. Warning: this must match definitions in config.mk!])
AC_DEFINE_UNQUOTED(NSM_DEFAULT_STATEDIR, "$statdpath", [Define this to the pathname where statd keeps its state file])
+AC_DEFINE_UNQUOTED(NFS_CONFFILE, "$nfsconfig", [This defines the location of NFS daemon config file])
if test "x$cross_compiling" = "xno"; then
CFLAGS_FOR_BUILD=${CFLAGS_FOR_BUILD-"$CFLAGS"}
@@ -511,8 +518,20 @@ AC_SUBST([AM_CFLAGS], ["$my_am_cflags"])
# Make sure that $ACLOCAL_FLAGS are used during a rebuild
AC_SUBST([ACLOCAL_AMFLAGS], ["-I $ac_macro_dir \$(ACLOCAL_FLAGS)"])
+# make libexecdir available for substituion in config files
+# 2 "evals" needed late to expand variable names.
+AC_SUBST([_libexecdir])
+AC_CONFIG_COMMANDS_PRE([eval eval _libexecdir=$libexecdir])
+
+# make _sysconfdir available for substituion in config files
+# 2 "evals" needed late to expand variable names.
+AC_SUBST([_sysconfdir])
+AC_CONFIG_COMMANDS_PRE([eval eval _sysconfdir=$sysconfdir])
+
AC_CONFIG_FILES([
Makefile
+ systemd/nfs-config.service
+ systemd/rpc-gssd.service
linux-nfs/Makefile
support/Makefile
support/export/Makefile
diff --git a/support/export/export.c b/support/export/export.c
index e1bebce..15e91cb 100644
--- a/support/export/export.c
+++ b/support/export/export.c
@@ -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 *exp, struct exportent *eep)
/**
* 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 */
@@ -96,6 +102,70 @@ export_read(char *fname)
}
/**
+ * 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
* @xep: export entry to lookup
* @canonical: if set, e_hostname is known to be canonical DNS name
diff --git a/support/export/xtab.c b/support/export/xtab.c
index e953071..10d9dbc 100644
--- a/support/export/xtab.c
+++ b/support/export/xtab.c
@@ -1,7 +1,7 @@
/*
* support/export/xtab.c
*
- * Interface to the xtab file.
+ * Interface to the etab/exports file.
*
* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
*/
@@ -29,7 +29,6 @@ xtab_read(char *xtab, char *lockfn, int is_export)
{
/* is_export == 0 => reading /proc/fs/nfs/exports - we know these things are exported to kernel
* is_export == 1 => reading /var/lib/nfs/etab - these things are allowed to be exported
- * is_export == 2 => reading /var/lib/nfs/xtab - these things might be known to kernel
*/
struct exportent *xp;
nfs_export *exp;
@@ -55,9 +54,6 @@ xtab_read(char *xtab, char *lockfn, int is_export)
if ((xp->e_flags & NFSEXP_FSID) && xp->e_fsid == 0)
v4root_needed = 0;
break;
- case 2:
- exp->m_exported = -1;/* may be exported */
- break;
}
}
endexportent();
@@ -79,7 +75,7 @@ xtab_mount_read(void)
return xtab_read(_PATH_PROC_EXPORTS_ALT,
_PATH_PROC_EXPORTS_ALT, 0);
} else
- return xtab_read(_PATH_XTAB, _PATH_XTABLCK, 2);
+ return 0;
}
int
@@ -135,29 +131,6 @@ xtab_export_write()
return xtab_write(_PATH_ETAB, _PATH_ETABTMP, _PATH_ETABLCK, 1);
}
-int
-xtab_mount_write()
-{
- return xtab_write(_PATH_XTAB, _PATH_XTABTMP, _PATH_XTABLCK, 0);
-}
-
-void
-xtab_append(nfs_export *exp)
-{
- struct exportent xe;
- int lockid;
-
- if ((lockid = xflock(_PATH_XTABLCK, "w")) < 0)
- return;
- setexportent(_PATH_XTAB, "a");
- xe = exp->m_export;
- xe.e_hostname = exp->m_client->m_hostname;
- putexportent(&xe);
- endexportent();
- xfunlock(lockid);
- exp->m_xtabent = 1;
-}
-
/*
* rename newfile onto oldfile unless
* they are identical
diff --git a/support/include/exportfs.h b/support/include/exportfs.h
index 4cac203..08ef30a 100644
--- a/support/include/exportfs.h
+++ b/support/include/exportfs.h
@@ -96,7 +96,7 @@ typedef struct mexport {
struct mexport * m_next;
struct mclient * m_client;
struct exportent m_export;
- int m_exported; /* known to knfsd. -1 means not sure */
+ int m_exported; /* known to knfsd. */
int m_xtabent : 1, /* xtab entry exists */
m_mayexport: 1, /* derived from xtabbed */
m_changed : 1, /* options (may) have changed */
@@ -134,7 +134,8 @@ struct addrinfo * client_resolve(const struct sockaddr *sap);
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,
@@ -149,9 +150,7 @@ int export_unexport(nfs_export *);
int xtab_mount_read(void);
int xtab_export_read(void);
-int xtab_mount_write(void);
int xtab_export_write(void);
-void xtab_append(nfs_export *);
int secinfo_addflavor(struct flav_info *, struct exportent *);
diff --git a/support/include/nfslib.h b/support/include/nfslib.h
index ddd71ac..777f398 100644
--- a/support/include/nfslib.h
+++ b/support/include/nfslib.h
@@ -35,15 +35,6 @@
#ifndef _PATH_IDMAPDCONF
#define _PATH_IDMAPDCONF "/etc/idmapd.conf"
#endif
-#ifndef _PATH_XTAB
-#define _PATH_XTAB NFS_STATEDIR "/xtab"
-#endif
-#ifndef _PATH_XTABTMP
-#define _PATH_XTABTMP NFS_STATEDIR "/xtab.tmp"
-#endif
-#ifndef _PATH_XTABLCK
-#define _PATH_XTABLCK NFS_STATEDIR "/.xtab.lock"
-#endif
#ifndef _PATH_ETAB
#define _PATH_ETAB NFS_STATEDIR "/etab"
#endif
diff --git a/systemd/Makefile.am b/systemd/Makefile.am
index 03f96e9..49c9b8d 100644
--- a/systemd/Makefile.am
+++ b/systemd/Makefile.am
@@ -39,8 +39,16 @@ endif
EXTRA_DIST = $(unit_files)
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 --git a/systemd/nfs-config.service b/systemd/nfs-config.service
deleted file mode 100644
index bd69e84..0000000
--- a/systemd/nfs-config.service
+++ /dev/null
@@ -1,13 +0,0 @@
-[Unit]
-Description=Preprocess NFS configuration
-After=local-fs.target
-DefaultDependencies=no
-
-[Service]
-Type=oneshot
-# This service needs to run any time any nfs service
-# is started, so changes to local config files get
-# incorporated. Having "RemainAfterExit=no" (the default)
-# ensures this happens.
-RemainAfterExit=no
-ExecStart=/usr/libexec/nfs-utils/nfs-utils_env.sh
diff --git a/systemd/nfs-config.service.in b/systemd/nfs-config.service.in
new file mode 100644
index 0000000..e89dc54
--- /dev/null
+++ b/systemd/nfs-config.service.in
@@ -0,0 +1,13 @@
+[Unit]
+Description=Preprocess NFS configuration
+After=local-fs.target
+DefaultDependencies=no
+
+[Service]
+Type=oneshot
+# This service needs to run any time any nfs service
+# is started, so changes to local config files get
+# incorporated. Having "RemainAfterExit=no" (the default)
+# ensures this happens.
+RemainAfterExit=no
+ExecStart=@_libexecdir@/nfs-utils/nfs-utils_env.sh
diff --git a/systemd/nfs-server-generator.c b/systemd/nfs-server-generator.c
new file mode 100644
index 0000000..7c40b3f
--- /dev/null
+++ b/systemd/nfs-server-generator.c
@@ -0,0 +1,150 @@
+/*
+ * 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);
+ }
+}
+
+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;
+
+ 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 (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 --git a/systemd/nfs-server.service b/systemd/nfs-server.service
index 2ccdc63..196c818 100644
--- a/systemd/nfs-server.service
+++ b/systemd/nfs-server.service
@@ -16,9 +16,6 @@ Before= rpc-statd-notify.service
Wants=auth-rpcgss-module.service
After=rpc-gssd.service gssproxy.service rpc-svcgssd.service
-# start/stop server before/after client
-Before=remote-fs-pre.target
-
Wants=nfs-config.service
After=nfs-config.service
diff --git a/systemd/rpc-gssd.service b/systemd/rpc-gssd.service
deleted file mode 100644
index d4a3819..0000000
--- a/systemd/rpc-gssd.service
+++ /dev/null
@@ -1,19 +0,0 @@
-[Unit]
-Description=RPC security service for NFS client and server
-DefaultDependencies=no
-Conflicts=umount.target
-Requires=var-lib-nfs-rpc_pipefs.mount
-After=var-lib-nfs-rpc_pipefs.mount
-
-ConditionPathExists=/etc/krb5.keytab
-
-PartOf=nfs-utils.service
-
-Wants=nfs-config.service
-After=nfs-config.service
-
-[Service]
-EnvironmentFile=-/run/sysconfig/nfs-utils
-
-Type=forking
-ExecStart=/usr/sbin/rpc.gssd $GSSDARGS
diff --git a/systemd/rpc-gssd.service.in b/systemd/rpc-gssd.service.in
new file mode 100644
index 0000000..1a7911c
--- /dev/null
+++ b/systemd/rpc-gssd.service.in
@@ -0,0 +1,19 @@
+[Unit]
+Description=RPC security service for NFS client and server
+DefaultDependencies=no
+Conflicts=umount.target
+Requires=var-lib-nfs-rpc_pipefs.mount
+After=var-lib-nfs-rpc_pipefs.mount
+
+ConditionPathExists=@_sysconfdir@/krb5.keytab
+
+PartOf=nfs-utils.service
+
+Wants=nfs-config.service
+After=nfs-config.service
+
+[Service]
+EnvironmentFile=-/run/sysconfig/nfs-utils
+
+Type=forking
+ExecStart=/usr/sbin/rpc.gssd $GSSDARGS
diff --git a/tools/mountstats/mountstats.py b/tools/mountstats/mountstats.py
index 4ca4bc4..88ccdae 100644
--- a/tools/mountstats/mountstats.py
+++ b/tools/mountstats/mountstats.py
@@ -412,6 +412,8 @@ class DeviceData:
print(' short reads: %d short writes: %d' % \
(self.__nfs_data['shortreads'], self.__nfs_data['shortwrites']))
print(' NFSERR_DELAYs from server: %d' % self.__nfs_data['delay'])
+ print(' pNFS READs: %d' % self.__nfs_data['pnfsreads'])
+ print(' pNFS WRITEs: %d' % self.__nfs_data['pnfswrites'])
def display_nfs_bytes(self):
"""Pretty-print the NFS event counters
diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c
index a00b5ea..98368a5 100644
--- a/utils/exportfs/exportfs.c
+++ b/utils/exportfs/exportfs.c
@@ -26,7 +26,6 @@
#include <fcntl.h>
#include <netdb.h>
#include <errno.h>
-#include <dirent.h>
#include <limits.h>
#include <time.h>
@@ -47,7 +46,6 @@ static void error(nfs_export *exp, int err);
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);
@@ -185,8 +183,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!");
}
@@ -221,8 +219,6 @@ main(int argc, char **argv)
xtab_export_write();
if (new_cache)
cache_flush(force_flush);
- if (!new_cache)
- xtab_mount_write();
return export_errno;
}
@@ -240,7 +236,7 @@ exports_update_one(nfs_export *exp, int verbose)
exp->m_export.e_path, exp->m_export.e_mountpoint);
exp->m_mayexport = 0;
}
- if (exp->m_mayexport && ((exp->m_exported<1) || exp->m_changed)) {
+ if (exp->m_mayexport && exp->m_changed) {
if (verbose)
printf("%sexporting %s:%s to kernel\n",
exp->m_exported ?"re":"",
@@ -700,63 +696,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, ...)
{
diff --git a/utils/idmapd/idmapd.man b/utils/idmapd/idmapd.man
index b9200c7..d4ab894 100644
--- a/utils/idmapd/idmapd.man
+++ b/utils/idmapd/idmapd.man
@@ -23,6 +23,29 @@ is the NFSv4 ID <-> name mapping daemon. It provides functionality to
the NFSv4 kernel client and server, to which it communicates via
upcalls, by translating user and group IDs to names, and vice versa.
.Pp
+The system derives the
+.I user
+part of the string by performing a password or group lookup.
+The lookup mechanism is configured in
+.Pa /etc/idmapd.conf
+.Pp
+By default, the
+.I domain
+part of the string is the system's DNS domain name.
+It can also be specified in
+.Pa /etc/idmapd.conf
+if the system is multi-homed,
+or if the system's DNS domain name does
+not match the name of the system's Kerberos realm.
+.Pp
+When the domain is not specified in /etc/idmapd.conf
+the local DNS server will be queried for the
+.Sy _nfsv4idmapdomain
+text record. If the record exists
+that will be used as the domain. When the record
+does not exist, the domain part of the DNS domain
+will used.
+.Pp
Note that on more recent kernels only the NFSv4 server uses
.Nm .
The NFSv4 client instead uses
diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c
index 9de6794..d5dfb5e 100644
--- a/utils/mount/stropts.c
+++ b/utils/mount/stropts.c
@@ -948,6 +948,7 @@ static int nfs_is_permanent_error(int error)
case ETIMEDOUT:
case ECONNREFUSED:
case EHOSTUNREACH:
+ case EOPNOTSUPP: /* aka RPC_PROGNOTREGISTERED */
case EAGAIN:
return 0; /* temporary */
default:
@@ -1019,8 +1020,7 @@ static int nfsmount_parent(struct nfsmount_info *mi)
if (nfs_try_mount(mi))
return EX_SUCCESS;
- /* retry background mounts when the server is not up */
- if (nfs_is_permanent_error(errno) && errno != EOPNOTSUPP) {
+ if (nfs_is_permanent_error(errno)) {
mount_error(mi->spec, mi->node, errno);
return EX_FAIL;
}
@@ -1055,8 +1055,7 @@ static int nfsmount_child(struct nfsmount_info *mi)
if (nfs_try_mount(mi))
return EX_SUCCESS;
- /* retry background mounts when the server is not up */
- if (nfs_is_permanent_error(errno) && errno != EOPNOTSUPP)
+ if (nfs_is_permanent_error(errno))
break;
if (time(NULL) > timeout)
diff --git a/utils/mountd/auth.c b/utils/mountd/auth.c
index 0881d9a..b612d88 100644
--- a/utils/mountd/auth.c
+++ b/utils/mountd/auth.c
@@ -46,7 +46,6 @@ void
auth_init(void)
{
auth_reload();
- xtab_mount_write();
}
/*
diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c
index 7a51b09..981abd4 100644
--- a/utils/mountd/mountd.c
+++ b/utils/mountd/mountd.c
@@ -107,7 +107,6 @@ unregister_services (void)
static void
cleanup_lockfiles (void)
{
- unlink(_PATH_XTABLCK);
unlink(_PATH_ETABLCK);
unlink(_PATH_RMTABLCK);
}
@@ -289,7 +288,7 @@ mount_umntall_1_svc(struct svc_req *rqstp, void *UNUSED(argp),
xlog(D_CALL, "Received UMNTALL request from %s",
host_ntop(sap, buf, sizeof(buf)));
- /* Reload /etc/xtab if necessary */
+ /* Reload /etc/exports if necessary */
auth_reload();
mountlist_del_all(nfs_getrpccaller(rqstp->rq_xprt));
@@ -350,7 +349,7 @@ mount_pathconf_2_svc(struct svc_req *rqstp, dirpath *path, ppathcnf *res)
if (*p == '\0')
p = "/";
- /* Reload /etc/xtab if necessary */
+ /* Reload /etc/exports if necessary */
auth_reload();
/* Resolve symlinks */
@@ -531,12 +530,6 @@ get_rootfh(struct svc_req *rqstp, dirpath *path, nfs_export **expret,
} else {
int did_export = 0;
retry:
- if (exp->m_exported<1) {
- export_export(exp);
- did_export = 1;
- }
- if (!exp->m_xtabent)
- xtab_append(exp);
if (v3)
fh = getfh_size((struct sockaddr_in *)sap, p, 64);
diff --git a/utils/nfsdcltrack/nfsdcltrack.c b/utils/nfsdcltrack/nfsdcltrack.c
index fcdda7f..e6e514b 100644
--- a/utils/nfsdcltrack/nfsdcltrack.c
+++ b/utils/nfsdcltrack/nfsdcltrack.c
@@ -43,6 +43,7 @@
#include <sys/capability.h>
#endif
+#include "conffile.h"
#include "xlog.h"
#include "sqlite.h"
@@ -55,6 +56,8 @@
/* defined by RFC 3530 */
#define NFS4_OPAQUE_LIMIT 1024
+char *conf_path = NFS_CONFFILE;
+
/* private data structures */
struct cltrack_cmd {
char *name;
@@ -553,6 +556,7 @@ int
main(int argc, char **argv)
{
char arg;
+ char *val;
int rc = 0;
char *progname, *cmdarg = NULL;
struct cltrack_cmd *cmd;
@@ -562,6 +566,14 @@ main(int argc, char **argv)
xlog_syslog(1);
xlog_stderr(0);
+ conf_init();
+ val = conf_get_str("nfsdcltrack", "storagedir");
+ if (val)
+ storagedir = val;
+ rc = conf_get_num("nfsdcltrack", "debug", 0);
+ if (rc > 0)
+ xlog_config(D_ALL, 1);
+
/* process command-line options */
while ((arg = getopt_long(argc, argv, "hdfs:", longopts,
NULL)) != EOF) {
diff --git a/utils/nfsdcltrack/nfsdcltrack.man b/utils/nfsdcltrack/nfsdcltrack.man
index 4b8f4d7..cc24b7a 100644
--- a/utils/nfsdcltrack/nfsdcltrack.man
+++ b/utils/nfsdcltrack/nfsdcltrack.man
@@ -67,6 +67,20 @@ Check to see if a nfs_client_id4 is allowed to reclaim. This command requires a
.IP "\fBgracedone\fR" 4
.IX Item "gracedone"
Remove any unreclaimed client records from the database. This command requires a epoch boot time as an argument.
+.SH "EXTERNAL CONFIGURATION"
+The directory for stable storage information can be set via the file
+.B /etc/nfs.conf
+by setting the
+.B storagedir
+value in the
+.B nfsdcltrack
+section. For example:
+.in +5
+[nfsdcltrack]
+.br
+ storagedir = /shared/nfs/nfsdcltrack
+.in -5
+Debuging to syslog can also be enabled by setting "debug = 1" in this file.
.SH "LEGACY TRANSITION MECHANISM"
.IX Header "LEGACY TRANSITION MECHANISM"
The Linux kernel NFSv4 server has historically tracked this information
diff --git a/utils/nfsidmap/nfsidmap.man b/utils/nfsidmap/nfsidmap.man
index 2f17cf2..2af16f3 100644
--- a/utils/nfsidmap/nfsidmap.man
+++ b/utils/nfsidmap/nfsidmap.man
@@ -39,6 +39,15 @@ if the system is multi-homed,
or if the system's DNS domain name does
not match the name of the system's Kerberos realm.
.PP
+When the domain is not specified in
+.I /etc/idmapd.conf
+the local DNS server will be queried for the
+.I _nfsv4idmapdomain
+text record. If the record exists
+that will be used as the domain. When the record
+does not exist, the domain part of the DNS domain
+will used.
+.PP
The
.I /usr/sbin/nfsidmap
program performs translations on behalf of the kernel.

View File

@ -0,0 +1,202 @@
diff -up nfs-utils-2.1.1/configure.ac.orig nfs-utils-2.1.1/configure.ac
--- nfs-utils-2.1.1/configure.ac.orig 2017-01-12 10:21:39.000000000 -0500
+++ nfs-utils-2.1.1/configure.ac 2017-01-16 14:24:01.691124185 -0500
@@ -518,6 +518,11 @@ AC_SUBST([AM_CFLAGS], ["$my_am_cflags"])
# Make sure that $ACLOCAL_FLAGS are used during a rebuild
AC_SUBST([ACLOCAL_AMFLAGS], ["-I $ac_macro_dir \$(ACLOCAL_FLAGS)"])
+# make libexecdir available for substituion in config files
+# 2 "evals" needed late to expand variable names.
+AC_SUBST([_libexecdir])
+AC_CONFIG_COMMANDS_PRE([eval eval _libexecdir=$libexecdir])
+
# make _sysconfdir available for substituion in config files
# 2 "evals" needed late to expand variable names.
AC_SUBST([_sysconfdir])
@@ -525,6 +530,7 @@ AC_CONFIG_COMMANDS_PRE([eval eval _sysco
AC_CONFIG_FILES([
Makefile
+ systemd/nfs-config.service
systemd/rpc-gssd.service
linux-nfs/Makefile
support/Makefile
diff -up nfs-utils-2.1.1/systemd/Makefile.am.orig nfs-utils-2.1.1/systemd/Makefile.am
--- nfs-utils-2.1.1/systemd/Makefile.am.orig 2017-01-12 10:21:39.000000000 -0500
+++ nfs-utils-2.1.1/systemd/Makefile.am 2017-01-16 14:24:01.691124185 -0500
@@ -5,6 +5,7 @@ MAINTAINERCLEANFILES = Makefile.in
unit_files = \
nfs-client.target \
\
+ nfs-config.service \
nfs-mountd.service \
nfs-server.service \
nfs-utils.service \
diff -up nfs-utils-2.1.1/systemd/nfs-blkmap.service.orig nfs-utils-2.1.1/systemd/nfs-blkmap.service
--- nfs-utils-2.1.1/systemd/nfs-blkmap.service.orig 2017-01-12 10:21:39.000000000 -0500
+++ nfs-utils-2.1.1/systemd/nfs-blkmap.service 2017-01-16 14:24:01.691124185 -0500
@@ -10,7 +10,8 @@ PartOf=nfs-utils.service
[Service]
Type=forking
PIDFile=/var/run/blkmapd.pid
-ExecStart=/usr/sbin/blkmapd
+EnvironmentFile=-/run/sysconfig/nfs-utils
+ExecStart=/usr/sbin/blkmapd $BLKMAPDARGS
[Install]
WantedBy=nfs-client.target
diff -up nfs-utils-2.1.1/systemd/nfs-config.service.in.orig nfs-utils-2.1.1/systemd/nfs-config.service.in
--- nfs-utils-2.1.1/systemd/nfs-config.service.in.orig 2017-01-16 14:24:01.691124185 -0500
+++ nfs-utils-2.1.1/systemd/nfs-config.service.in 2017-01-16 14:24:01.691124185 -0500
@@ -0,0 +1,13 @@
+[Unit]
+Description=Preprocess NFS configuration
+After=local-fs.target
+DefaultDependencies=no
+
+[Service]
+Type=oneshot
+# This service needs to run any time any nfs service
+# is started, so changes to local config files get
+# incorporated. Having "RemainAfterExit=no" (the default)
+# ensures this happens.
+RemainAfterExit=no
+ExecStart=@_libexecdir@/nfs-utils/nfs-utils_env.sh
diff -up nfs-utils-2.1.1/systemd/nfs-idmapd.service.orig nfs-utils-2.1.1/systemd/nfs-idmapd.service
--- nfs-utils-2.1.1/systemd/nfs-idmapd.service.orig 2017-01-12 10:21:39.000000000 -0500
+++ nfs-utils-2.1.1/systemd/nfs-idmapd.service 2017-01-16 14:24:01.691124185 -0500
@@ -6,6 +6,10 @@ After=var-lib-nfs-rpc_pipefs.mount local
BindsTo=nfs-server.service
+Wants=nfs-config.service
+After=nfs-config.service
+
[Service]
+EnvironmentFile=-/run/sysconfig/nfs-utils
Type=forking
-ExecStart=/usr/sbin/rpc.idmapd
+ExecStart=/usr/sbin/rpc.idmapd $RPCIDMAPDARGS
diff -up nfs-utils-2.1.1/systemd/nfs-mountd.service.orig nfs-utils-2.1.1/systemd/nfs-mountd.service
--- nfs-utils-2.1.1/systemd/nfs-mountd.service.orig 2017-01-12 10:21:39.000000000 -0500
+++ nfs-utils-2.1.1/systemd/nfs-mountd.service 2017-01-16 14:24:01.691124185 -0500
@@ -6,6 +6,10 @@ After=proc-fs-nfsd.mount
After=network.target local-fs.target
BindsTo=nfs-server.service
+Wants=nfs-config.service
+After=nfs-config.service
+
[Service]
+EnvironmentFile=-/run/sysconfig/nfs-utils
Type=forking
-ExecStart=/usr/sbin/rpc.mountd
+ExecStart=/usr/sbin/rpc.mountd $RPCMOUNTDARGS
diff -up nfs-utils-2.1.1/systemd/nfs-server.service.orig nfs-utils-2.1.1/systemd/nfs-server.service
--- nfs-utils-2.1.1/systemd/nfs-server.service.orig 2017-01-12 10:21:39.000000000 -0500
+++ nfs-utils-2.1.1/systemd/nfs-server.service 2017-01-16 14:24:01.692124186 -0500
@@ -16,11 +16,16 @@ Before= rpc-statd-notify.service
Wants=auth-rpcgss-module.service
After=rpc-gssd.service gssproxy.service rpc-svcgssd.service
+Wants=nfs-config.service
+After=nfs-config.service
+
[Service]
+EnvironmentFile=-/run/sysconfig/nfs-utils
+
Type=oneshot
RemainAfterExit=yes
ExecStartPre=/usr/sbin/exportfs -r
-ExecStart=/usr/sbin/rpc.nfsd
+ExecStart=/usr/sbin/rpc.nfsd $RPCNFSDARGS
ExecStop=/usr/sbin/rpc.nfsd 0
ExecStopPost=/usr/sbin/exportfs -au
ExecStopPost=/usr/sbin/exportfs -f
diff -up nfs-utils-2.1.1/systemd/README.orig nfs-utils-2.1.1/systemd/README
--- nfs-utils-2.1.1/systemd/README.orig 2017-01-12 10:21:39.000000000 -0500
+++ nfs-utils-2.1.1/systemd/README 2017-01-16 14:24:01.691124185 -0500
@@ -19,8 +19,8 @@ by a suitable 'preset' setting:
can work (if no type is given, ".service" is assumed).
nfs-client.target
- If enabled, daemons needed for an nfs client are enabled.
- This does *not* include rpc.statd. The rpc-statd.service unit
+ If enabled, daemons needs for an nfs client are enabled.
+ This does *not* include rpc.statd. the rpc-statd.service unit
is started by /usr/sbin/start-statd which mount.nfs will run
if statd is needed.
@@ -52,19 +52,11 @@ It cannot stop rpc.statd or rpc.gssd as
client and systemd cannot specify is two-pronged reverse dependency.
(i.e. stop this unit if none of these units are running)
-Distro specific configuration can be included in /etc/nfs.conf, or
-by providing drop-in files which replace the ExecStart line for a given
-service, and possibly add an EnvironmentFile line.
-
-For example, if systemd/system/nfs-mountd.service.d/local.conf
-contained
- [Service]
- EnvironmentFile=/etc/sysconfig/nfs
- ExecStart=
- ExecStart=/usr/sbin/rpc.mountd $RPCMOUNTDOPTS
-
-then the setting of RPCMOUNTDOPTS in /etc/sysconfig/nfs would be
-passed to rpc.mountd.
+Distro specific commandline configuration can be provided by
+installing a script /usr/libexec/nfs-utils/nfs-utils_env.sh
+This should write /run/sysconfig/nfs-utils based on configuration
+information such as in /etc/sysconfig/nfs or /etc/defaults/nfs.
+It is run once by nfs-config.service.
rpc.gssd and rpc.svcgssd are assumed to be needed if /etc/krb5.keytab
is present.
diff -up nfs-utils-2.1.1/systemd/rpc-gssd.service.in.orig nfs-utils-2.1.1/systemd/rpc-gssd.service.in
--- nfs-utils-2.1.1/systemd/rpc-gssd.service.in.orig 2017-01-12 10:21:39.000000000 -0500
+++ nfs-utils-2.1.1/systemd/rpc-gssd.service.in 2017-01-16 14:24:01.692124186 -0500
@@ -9,6 +9,11 @@ ConditionPathExists=@_sysconfdir@/krb5.k
PartOf=nfs-utils.service
+Wants=nfs-config.service
+After=nfs-config.service
+
[Service]
+EnvironmentFile=-/run/sysconfig/nfs-utils
+
Type=forking
-ExecStart=/usr/sbin/rpc.gssd
+ExecStart=/usr/sbin/rpc.gssd $RPCGSSDARGS
diff -up nfs-utils-2.1.1/systemd/rpc-statd-notify.service.orig nfs-utils-2.1.1/systemd/rpc-statd-notify.service
--- nfs-utils-2.1.1/systemd/rpc-statd-notify.service.orig 2017-01-12 10:21:39.000000000 -0500
+++ nfs-utils-2.1.1/systemd/rpc-statd-notify.service 2017-01-16 14:24:01.692124186 -0500
@@ -10,6 +10,10 @@ After=nfs-server.service
PartOf=nfs-utils.service
+Wants=nfs-config.service
+After=nfs-config.service
+
[Service]
+EnvironmentFile=-/run/sysconfig/nfs-utils
Type=forking
-ExecStart=-/usr/sbin/sm-notify
+ExecStart=-/usr/sbin/sm-notify $SMNOTIFYARGS
diff -up nfs-utils-2.1.1/systemd/rpc-statd.service.orig nfs-utils-2.1.1/systemd/rpc-statd.service
--- nfs-utils-2.1.1/systemd/rpc-statd.service.orig 2017-01-12 10:21:39.000000000 -0500
+++ nfs-utils-2.1.1/systemd/rpc-statd.service 2017-01-16 14:24:01.692124186 -0500
@@ -7,8 +7,12 @@ After=network.target nss-lookup.target r
PartOf=nfs-utils.service
+Wants=nfs-config.service
+After=nfs-config.service
+
[Service]
Environment=RPC_STATD_NO_NOTIFY=1
+EnvironmentFile=-/run/sysconfig/nfs-utils
Type=forking
PIDFile=/var/run/rpc.statd.pid
-ExecStart=/usr/sbin/rpc.statd
+ExecStart=/usr/sbin/rpc.statd $STATDARGS

View File

@ -2,7 +2,7 @@ Summary: NFS utilities and supporting clients and daemons for the kernel NFS ser
Name: nfs-utils
URL: http://sourceforge.net/projects/nfs
Version: 2.1.1
Release: 0%{?dist}
Release: 1%{?dist}
Epoch: 1
# group all 32bit related archs
@ -18,6 +18,7 @@ Patch100: nfs-utils-1.2.1-statdpath-man.patch
Patch101: nfs-utils-1.2.1-exp-subtree-warn-off.patch
Patch102: nfs-utils-1.2.3-sm-notify-res_init.patch
Patch103: nfs-utils-1.2.5-idmap-errmsg.patch
Patch104: nfs-utils-2.1.1-nfs-config.patch
Group: System Environment/Daemons
Provides: exportfs = %{epoch}:%{version}-%{release}
@ -74,6 +75,7 @@ This package also contains the mount.nfs and umount.nfs program.
%patch101 -p1
%patch102 -p1
%patch103 -p1
%patch104 -p1
# Remove .orig files
find . -name "*.orig" | xargs rm -f
@ -128,9 +130,6 @@ install -m 644 nfs.conf $RPM_BUILD_ROOT%{_sysconfdir}
install -m 644 %{SOURCE1} $RPM_BUILD_ROOT%{_sysconfdir}/request-key.d
install -m 644 %{SOURCE2} $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/nfs
# rpc.svcgssd is no longer supported.
rm -rf $RPM_BUILD_ROOT%{_unitdir}/rpc-svcgssd.service
mkdir -p $RPM_BUILD_ROOT/run/sysconfig
mkdir -p $RPM_BUILD_ROOT/usr/lib/systemd/scripts
install -m 755 %{SOURCE3} $RPM_BUILD_ROOT/usr/libexec/nfs-utils/nfs-utils_env.sh
@ -278,8 +277,11 @@ fi
/sbin/umount.nfs4
%changelog
* Thu Jan 19 2017 Steve Dickson <steved@redhat.com> 2.1.1-1
- Added back the nfs-config service for backwards compatibility
* Thu Jan 19 2017 Steve Dickson <steved@redhat.com> 2.1.1-0
- Updated to latest upstream release: nfs-utils-2-1-1
- Updated to latest upstream release: nfs-utils-2-1-1 (bz 1413232)
* Mon Dec 19 2016 Miro Hrončok <mhroncok@redhat.com> - 1:1.3.4-1.rc3.1
- Rebuild for Python 3.6

View File

@ -35,8 +35,5 @@ RPCGSSDARGS=""
# Enable usage of gssproxy. See gssproxy-mech(8).
GSS_USE_PROXY="yes"
#
# Optional arguments passed to rpc.svcgssd. See rpc.svcgssd(8)
RPCSVCGSSDARGS=""
#
# Optional arguments passed to blkmapd. See blkmapd(8)
BLKMAPDARGS=""