From 718f39a8c6bbd998c4d9504c957e194618dc7496 Mon Sep 17 00:00:00 2001 From: Steve Dickson Date: Mon, 22 Aug 2016 11:56:22 -0400 Subject: [PATCH] Updated to the latest RC release: nfs-utils-1-3-5-rc1 Signed-off-by: Steve Dickson --- nfs-utils-1.3.5-rc1.patch | 450 ++++++++++++++++++++++++++++++++++++++ nfs-utils.spec | 30 +-- 2 files changed, 465 insertions(+), 15 deletions(-) create mode 100644 nfs-utils-1.3.5-rc1.patch diff --git a/nfs-utils-1.3.5-rc1.patch b/nfs-utils-1.3.5-rc1.patch new file mode 100644 index 0000000..6188fa9 --- /dev/null +++ b/nfs-utils-1.3.5-rc1.patch @@ -0,0 +1,450 @@ +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 + #include + #include ++#include ++#include + #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-server-generator.c b/systemd/nfs-server-generator.c +new file mode 100644 +index 0000000..af8bb52 +--- /dev/null ++++ b/systemd/nfs-server-generator.c +@@ -0,0 +1,144 @@ ++/* ++ * 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 ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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)); ++ 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) ++ return 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"); ++ 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(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/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 + #include + #include +-#include + #include + #include + +@@ -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. diff --git a/nfs-utils.spec b/nfs-utils.spec index f840bc0..61e2e97 100644 --- a/nfs-utils.spec +++ b/nfs-utils.spec @@ -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: 1.3.4 -Release: 0%{?dist} +Release: 0.rc1%{?dist} Epoch: 1 # group all 32bit related archs @@ -15,6 +15,8 @@ Source2: nfs.sysconfig Source3: nfs-utils_env.sh Source4: lockd.conf +Patch001: nfs-utils-1.3.5-rc1.patch + 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 @@ -72,6 +74,8 @@ This package also contains the mount.nfs and umount.nfs program. %prep %setup -q +%patch001 -p1 + %patch100 -p1 %patch101 -p1 %patch102 -p1 @@ -105,18 +109,21 @@ CFLAGS="`echo $RPM_OPT_FLAGS $ARCH_OPT_FLAGS $PIE -D_FILE_OFFSET_BITS=64`" --enable-mountconfig \ --enable-ipv6 \ --with-statdpath=%{_statdpath} \ - --enable-libmount-mount + --enable-libmount-mount \ + --with-systemd make %{?_smp_mflags} all %install +%define _pkgdir %{_prefix}/lib/systemd + rm -rf $RPM_BUILD_ROOT/* mkdir -p $RPM_BUILD_ROOT%/sbin mkdir -p $RPM_BUILD_ROOT%{_sbindir} mkdir -p $RPM_BUILD_ROOT%{_libexecdir}/nfs-utils/ -mkdir -p $RPM_BUILD_ROOT%{_unitdir} -mkdir -p $RPM_BUILD_ROOT%{_unitdir}/nfs.target.wants +mkdir -p $RPM_BUILD_ROOT%{_pkgdir}/system +mkdir -p $RPM_BUILD_ROOT%{_pkgdir}/system-generators mkdir -p ${RPM_BUILD_ROOT}%{_mandir}/man8 mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/request-key.d @@ -127,16 +134,6 @@ install -m 644 utils/mount/nfsmount.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 -for file in systemd/*.service ; do - install -m 644 $file $RPM_BUILD_ROOT%{_unitdir} -done -for file in systemd/*.target ; do - install -m 644 $file $RPM_BUILD_ROOT%{_unitdir} -done -for file in systemd/*.mount ; do - install -m 644 $file $RPM_BUILD_ROOT%{_unitdir} -done - # rpc.svcgssd is no longer supported. rm -rf $RPM_BUILD_ROOT%{_unitdir}/rpc-svcgssd.service @@ -282,7 +279,7 @@ fi %{_sbindir}/nfsidmap %{_sbindir}/blkmapd %{_mandir}/*/* -%{_unitdir}/* +%{_pkgdir}/*/* %attr(755,root,root) /usr/libexec/nfs-utils/nfs-utils_env.sh %attr(4755,root,root) /sbin/mount.nfs @@ -291,6 +288,9 @@ fi /sbin/umount.nfs4 %changelog +* Sat Aug 20 2016 Steve Dickson 1.3.4-0.rc1 +- Updated to the latest RC release: nfs-utils-1-3-5-rc1 + * Sat Aug 6 2016 Steve Dickson 1.3.4-0 - Updated to latest upstream version 1.3.4