diff --git a/nfs-utils-2.1.1-nfs-config.patch b/nfs-utils-2.1.1-nfs-config.patch index 18f67a8..6abdf20 100644 --- a/nfs-utils-2.1.1-nfs-config.patch +++ b/nfs-utils-2.1.1-nfs-config.patch @@ -1,6 +1,6 @@ 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 ++++ nfs-utils-2.1.1/configure.ac 2017-02-15 10:53:12.623674876 -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)"]) @@ -23,7 +23,7 @@ diff -up nfs-utils-2.1.1/configure.ac.orig nfs-utils-2.1.1/configure.ac 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 ++++ nfs-utils-2.1.1/systemd/Makefile.am 2017-02-15 10:53:12.623674876 -0500 @@ -5,6 +5,7 @@ MAINTAINERCLEANFILES = Makefile.in unit_files = \ nfs-client.target \ @@ -34,7 +34,7 @@ diff -up nfs-utils-2.1.1/systemd/Makefile.am.orig nfs-utils-2.1.1/systemd/Makefi 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 ++++ nfs-utils-2.1.1/systemd/nfs-blkmap.service 2017-02-15 10:53:12.624674873 -0500 @@ -10,7 +10,8 @@ PartOf=nfs-utils.service [Service] Type=forking @@ -46,8 +46,8 @@ diff -up nfs-utils-2.1.1/systemd/nfs-blkmap.service.orig nfs-utils-2.1.1/systemd [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 +--- nfs-utils-2.1.1/systemd/nfs-config.service.in.orig 2017-02-15 10:53:12.624674873 -0500 ++++ nfs-utils-2.1.1/systemd/nfs-config.service.in 2017-02-15 10:53:12.624674873 -0500 @@ -0,0 +1,13 @@ +[Unit] +Description=Preprocess NFS configuration @@ -64,7 +64,7 @@ diff -up nfs-utils-2.1.1/systemd/nfs-config.service.in.orig nfs-utils-2.1.1/syst +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 ++++ nfs-utils-2.1.1/systemd/nfs-idmapd.service 2017-02-15 10:53:12.625674869 -0500 @@ -6,6 +6,10 @@ After=var-lib-nfs-rpc_pipefs.mount local BindsTo=nfs-server.service @@ -78,10 +78,10 @@ diff -up nfs-utils-2.1.1/systemd/nfs-idmapd.service.orig nfs-utils-2.1.1/systemd -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 +--- nfs-utils-2.1.1/systemd/nfs-mountd.service.orig 2017-02-15 10:52:26.501835762 -0500 ++++ nfs-utils-2.1.1/systemd/nfs-mountd.service 2017-02-15 10:53:12.625674869 -0500 +@@ -7,6 +7,10 @@ After=network.target local-fs.target + After=rpcbind.socket BindsTo=nfs-server.service +Wants=nfs-config.service @@ -94,7 +94,7 @@ diff -up nfs-utils-2.1.1/systemd/nfs-mountd.service.orig nfs-utils-2.1.1/systemd +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 ++++ nfs-utils-2.1.1/systemd/nfs-server.service 2017-02-15 10:53:12.626674866 -0500 @@ -16,11 +16,16 @@ Before= rpc-statd-notify.service Wants=auth-rpcgss-module.service After=rpc-gssd.service gssproxy.service rpc-svcgssd.service @@ -115,7 +115,7 @@ diff -up nfs-utils-2.1.1/systemd/nfs-server.service.orig nfs-utils-2.1.1/systemd 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 ++++ nfs-utils-2.1.1/systemd/README 2017-02-15 10:53:12.626674866 -0500 @@ -19,8 +19,8 @@ by a suitable 'preset' setting: can work (if no type is given, ".service" is assumed). @@ -154,7 +154,7 @@ diff -up nfs-utils-2.1.1/systemd/README.orig nfs-utils-2.1.1/systemd/README 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 ++++ nfs-utils-2.1.1/systemd/rpc-gssd.service.in 2017-02-15 10:53:12.627674862 -0500 @@ -9,6 +9,11 @@ ConditionPathExists=@_sysconfdir@/krb5.k PartOf=nfs-utils.service @@ -170,7 +170,7 @@ diff -up nfs-utils-2.1.1/systemd/rpc-gssd.service.in.orig nfs-utils-2.1.1/system +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 ++++ nfs-utils-2.1.1/systemd/rpc-statd-notify.service 2017-02-15 10:53:12.627674862 -0500 @@ -10,6 +10,10 @@ After=nfs-server.service PartOf=nfs-utils.service @@ -185,7 +185,7 @@ diff -up nfs-utils-2.1.1/systemd/rpc-statd-notify.service.orig nfs-utils-2.1.1/s +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 ++++ nfs-utils-2.1.1/systemd/rpc-statd.service 2017-02-15 10:53:12.627674862 -0500 @@ -7,8 +7,12 @@ After=network.target nss-lookup.target r PartOf=nfs-utils.service diff --git a/nfs-utils-2.1.2-rc1.patch b/nfs-utils-2.1.2-rc1.patch new file mode 100644 index 0000000..cc848bd --- /dev/null +++ b/nfs-utils-2.1.2-rc1.patch @@ -0,0 +1,1040 @@ +diff --git a/support/export/xtab.c b/support/export/xtab.c +index 22cf539..d42eeef 100644 +--- a/support/export/xtab.c ++++ b/support/export/xtab.c +@@ -14,12 +14,20 @@ + #include + #include + #include ++#include ++#include ++#include ++#include + + #include "nfslib.h" + #include "exportfs.h" + #include "xio.h" + #include "xlog.h" + #include "v4root.h" ++#include "misc.h" ++ ++static char state_base_dirname[PATH_MAX] = NFS_STATEDIR; ++extern struct state_paths etab; + + int v4root_needed; + static void cond_rename(char *newfile, char *oldfile); +@@ -65,7 +73,7 @@ xtab_read(char *xtab, char *lockfn, int is_export) + int + xtab_export_read(void) + { +- return xtab_read(_PATH_ETAB, _PATH_ETABLCK, 1); ++ return xtab_read(etab.statefn, etab.lockfn, 1); + } + + /* +@@ -112,7 +120,7 @@ xtab_write(char *xtab, char *xtabtmp, char *lockfn, int is_export) + int + xtab_export_write() + { +- return xtab_write(_PATH_ETAB, _PATH_ETABTMP, _PATH_ETABLCK, 1); ++ return xtab_write(etab.statefn, etab.tmpfn, etab.lockfn, 1); + } + + /* +@@ -158,3 +166,74 @@ static void cond_rename(char *newfile, char *oldfile) + rename(newfile, oldfile); + return; + } ++ ++/* ++ * Returns a dynamically allocated, '\0'-terminated buffer ++ * containing an appropriate pathname, or NULL if an error ++ * occurs. Caller must free the returned result with free(3). ++ */ ++static char * ++state_make_pathname(const char *tabname) ++{ ++ return generic_make_pathname(state_base_dirname, tabname); ++} ++ ++/** ++ * state_setup_basedir - set up basedir ++ * @progname: C string containing name of program, for error messages ++ * @parentdir: C string containing pathname to on-disk state, or NULL ++ * ++ * This runs before logging is set up, so error messages are directed ++ * to stderr. ++ * ++ * Returns true and sets up our basedir, if @parentdir was valid ++ * and usable; otherwise false is returned. ++ */ ++_Bool ++state_setup_basedir(const char *progname, const char *parentdir) ++{ ++ return generic_setup_basedir(progname, parentdir, state_base_dirname, ++ PATH_MAX); ++} ++ ++int ++setup_state_path_names(const char *progname, const char *statefn, ++ const char *tmpfn, const char *lockfn, ++ struct state_paths *paths) ++{ ++ paths->statefn = state_make_pathname(statefn); ++ if (!paths->statefn) { ++ fprintf(stderr, "%s: state_make_pathname(%s) failed\n", ++ progname, statefn); ++ goto out_err; ++ } ++ paths->tmpfn = state_make_pathname(tmpfn); ++ if (!paths->tmpfn) { ++ fprintf(stderr, "%s: state_make_pathname(%s) failed\n", ++ progname, tmpfn); ++ goto out_free_statefn; ++ } ++ paths->lockfn = state_make_pathname(lockfn); ++ if (!paths->lockfn) { ++ fprintf(stderr, "%s: state_make_pathname(%s) failed\n", ++ progname, lockfn); ++ goto out_free_tmpfn; ++ } ++ return 1; ++ ++out_free_tmpfn: ++ free(paths->tmpfn); ++out_free_statefn: ++ free(paths->statefn); ++out_err: ++ return 0; ++ ++} ++ ++void ++free_state_path_names(struct state_paths *paths) ++{ ++ free(paths->statefn); ++ free(paths->tmpfn); ++ free(paths->lockfn); ++} +diff --git a/support/include/misc.h b/support/include/misc.h +index eedc1fe..06e2a0c 100644 +--- a/support/include/misc.h ++++ b/support/include/misc.h +@@ -15,6 +15,9 @@ + int randomkey(unsigned char *keyout, int len); + int weakrandomkey(unsigned char *keyout, int len); + ++char *generic_make_pathname(const char *, const char *); ++_Bool generic_setup_basedir(const char *, const char *, char *, const size_t); ++ + extern int is_mountpoint(char *path); + + /* size of the file pointer buffers for rpc procfs files */ +diff --git a/support/include/nfslib.h b/support/include/nfslib.h +index 1498977..ab8b2bf 100644 +--- a/support/include/nfslib.h ++++ b/support/include/nfslib.h +@@ -35,29 +35,24 @@ + #ifndef _PATH_IDMAPDCONF + #define _PATH_IDMAPDCONF "/etc/idmapd.conf" + #endif +-#ifndef _PATH_ETAB +-#define _PATH_ETAB NFS_STATEDIR "/etab" +-#endif +-#ifndef _PATH_ETABTMP +-#define _PATH_ETABTMP NFS_STATEDIR "/etab.tmp" +-#endif +-#ifndef _PATH_ETABLCK +-#define _PATH_ETABLCK NFS_STATEDIR "/.etab.lock" +-#endif +-#ifndef _PATH_RMTAB +-#define _PATH_RMTAB NFS_STATEDIR "/rmtab" +-#endif +-#ifndef _PATH_RMTABTMP +-#define _PATH_RMTABTMP _PATH_RMTAB ".tmp" +-#endif +-#ifndef _PATH_RMTABLCK +-#define _PATH_RMTABLCK NFS_STATEDIR "/.rmtab.lock" +-#endif + #ifndef _PATH_PROC_EXPORTS + #define _PATH_PROC_EXPORTS "/proc/fs/nfs/exports" + #define _PATH_PROC_EXPORTS_ALT "/proc/fs/nfsd/exports" + #endif + ++#define ETAB "etab" ++#define ETABTMP "etab.tmp" ++#define ETABLCK ".etab.lock" ++#define RMTAB "rmtab" ++#define RMTABTMP "rmtab.tmp" ++#define RMTABLCK ".rmtab.lock" ++ ++struct state_paths { ++ char *statefn; ++ char *tmpfn; ++ char *lockfn; ++}; ++ + /* Maximum number of security flavors on an export: */ + #define SECFLAVOR_COUNT 8 + +@@ -120,6 +115,10 @@ void fputrmtabent(FILE *fp, struct rmtabent *xep, long *pos); + void fendrmtabent(FILE *fp); + void frewindrmtabent(FILE *fp); + ++_Bool state_setup_basedir(const char *, const char *); ++int setup_state_path_names(const char *, const char *, const char *, const char *, struct state_paths *); ++void free_state_path_names(struct state_paths *); ++ + /* mydaemon */ + void daemon_init(bool fg); + void daemon_ready(void); +diff --git a/support/misc/Makefile.am b/support/misc/Makefile.am +index 1048580..8936b0d 100644 +--- a/support/misc/Makefile.am ++++ b/support/misc/Makefile.am +@@ -1,6 +1,6 @@ + ## Process this file with automake to produce Makefile.in + + noinst_LIBRARIES = libmisc.a +-libmisc_a_SOURCES = tcpwrapper.c from_local.c mountpoint.c ++libmisc_a_SOURCES = tcpwrapper.c from_local.c mountpoint.c file.c + + MAINTAINERCLEANFILES = Makefile.in +diff --git a/support/misc/file.c b/support/misc/file.c +new file mode 100644 +index 0000000..63597df +--- /dev/null ++++ b/support/misc/file.c +@@ -0,0 +1,110 @@ ++/* ++ * Copyright 2009 Oracle. All rights reserved. ++ * Copyright 2017 Red Hat, Inc. All rights reserved. ++ * ++ * This file is part of nfs-utils. ++ * ++ * nfs-utils is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * nfs-utils is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with nfs-utils. If not, see . ++ */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "xlog.h" ++#include "misc.h" ++ ++/* ++ * Returns a dynamically allocated, '\0'-terminated buffer ++ * containing an appropriate pathname, or NULL if an error ++ * occurs. Caller must free the returned result with free(3). ++ */ ++__attribute__((__malloc__)) ++char * ++generic_make_pathname(const char *base, const char *leaf) ++{ ++ size_t size; ++ char *path; ++ int len; ++ ++ size = strlen(base) + strlen(leaf) + 2; ++ if (size > PATH_MAX) ++ return NULL; ++ ++ path = malloc(size); ++ if (path == NULL) ++ return NULL; ++ ++ len = snprintf(path, size, "%s/%s", base, leaf); ++ if ((len < 0) || ((size_t)len >= size)) { ++ free(path); ++ return NULL; ++ } ++ ++ return path; ++} ++ ++ ++/** ++ * generic_setup_basedir - set up basedir ++ * @progname: C string containing name of program, for error messages ++ * @parentdir: C string containing pathname to on-disk state, or NULL ++ * @base: character buffer to contain the basedir that is set up ++ * @baselen: size of @base in bytes ++ * ++ * This runs before logging is set up, so error messages are directed ++ * to stderr. ++ * ++ * Returns true and sets up our basedir, if @parentdir was valid ++ * and usable; otherwise false is returned. ++ */ ++_Bool ++generic_setup_basedir(const char *progname, const char *parentdir, char *base, ++ const size_t baselen) ++{ ++ static char buf[PATH_MAX]; ++ struct stat st; ++ char *path; ++ ++ /* First: test length of name and whether it exists */ ++ if ((strlen(parentdir) >= baselen) || (strlen(parentdir) >= PATH_MAX)) { ++ (void)fprintf(stderr, "%s: Directory name too long: %s", ++ progname, parentdir); ++ return false; ++ } ++ if (lstat(parentdir, &st) == -1) { ++ (void)fprintf(stderr, "%s: Failed to stat %s: %s", ++ progname, parentdir, strerror(errno)); ++ return false; ++ } ++ ++ /* Ensure we have a clean directory pathname */ ++ strncpy(buf, parentdir, sizeof(buf)); ++ path = dirname(buf); ++ if (*path == '.') { ++ (void)fprintf(stderr, "%s: Unusable directory %s", ++ progname, parentdir); ++ return false; ++ } ++ ++ xlog(D_CALL, "Using %s as the state directory", parentdir); ++ strcpy(base, parentdir); ++ return true; ++} +diff --git a/support/nfs/cacheio.c b/support/nfs/cacheio.c +index e5e2579..9912afa 100644 +--- a/support/nfs/cacheio.c ++++ b/support/nfs/cacheio.c +@@ -27,6 +27,8 @@ + #include + #include + ++extern struct state_paths etab; ++ + void qword_add(char **bpp, int *lp, char *str) + { + char *bp = *bpp; +@@ -199,7 +201,7 @@ int qword_get_uint(char **bpp, unsigned int *anint) + } + + /* flush the kNFSd caches. +- * Set the flush time to the mtime of _PATH_ETAB or ++ * Set the flush time to the mtime of the etab state file or + * if force, to now. + * the caches to flush are: + * auth.unix.ip nfsd.export nfsd.fh +@@ -228,7 +230,7 @@ cache_flush(int force) + }; + now = time(0); + if (force || +- stat(_PATH_ETAB, &stb) != 0 || ++ stat(etab.statefn, &stb) != 0 || + stb.st_mtime > now) + stb.st_mtime = time(0); + +diff --git a/support/nfs/conffile.c b/support/nfs/conffile.c +index e717c1e..203efd2 100644 +--- a/support/nfs/conffile.c ++++ b/support/nfs/conffile.c +@@ -533,7 +533,7 @@ retry: + * or from environment + */ + char *env = getenv(cb->value+1); +- if (env) ++ if (env && *env) + return env; + section = "environment"; + tag = cb->value + 1; +diff --git a/support/nfs/rmtab.c b/support/nfs/rmtab.c +index 59dfbdf..2ecb2cc 100644 +--- a/support/nfs/rmtab.c ++++ b/support/nfs/rmtab.c +@@ -33,12 +33,14 @@ + + static FILE *rmfp = NULL; + ++extern struct state_paths rmtab; ++ + int + setrmtabent(char *type) + { + if (rmfp) + fclose(rmfp); +- rmfp = fsetrmtabent(_PATH_RMTAB, type); ++ rmfp = fsetrmtabent(rmtab.statefn, type); + return (rmfp != NULL); + } + +diff --git a/support/nsm/file.c b/support/nsm/file.c +index aafa755..52f5401 100644 +--- a/support/nsm/file.c ++++ b/support/nsm/file.c +@@ -88,6 +88,7 @@ + + #include "xlog.h" + #include "nsm.h" ++#include "misc.h" + + #define RPCARGSLEN (4 * (8 + 1)) + #define LINELEN (RPCARGSLEN + SM_PRIV_SIZE * 2 + 1) +@@ -170,25 +171,7 @@ __attribute__((__malloc__)) + static char * + nsm_make_pathname(const char *directory) + { +- size_t size; +- char *path; +- int len; +- +- size = strlen(nsm_base_dirname) + strlen(directory) + 2; +- if (size > PATH_MAX) +- return NULL; +- +- path = malloc(size); +- if (path == NULL) +- return NULL; +- +- len = snprintf(path, size, "%s/%s", nsm_base_dirname, directory); +- if (error_check(len, size)) { +- free(path); +- return NULL; +- } +- +- return path; ++ return generic_make_pathname(nsm_base_dirname, directory); + } + + /* +@@ -293,29 +276,8 @@ out: + _Bool + nsm_setup_pathnames(const char *progname, const char *parentdir) + { +- static char buf[PATH_MAX]; +- struct stat st; +- char *path; +- +- /* First: test length of name and whether it exists */ +- if (lstat(parentdir, &st) == -1) { +- (void)fprintf(stderr, "%s: Failed to stat %s: %s", +- progname, parentdir, strerror(errno)); +- return false; +- } +- +- /* Ensure we have a clean directory pathname */ +- strncpy(buf, parentdir, sizeof(buf)); +- path = dirname(buf); +- if (*path == '.') { +- (void)fprintf(stderr, "%s: Unusable directory %s", +- progname, parentdir); +- return false; +- } +- +- xlog(D_CALL, "Using %s as the state directory", parentdir); +- strncpy(nsm_base_dirname, parentdir, sizeof(nsm_base_dirname)); +- return true; ++ return generic_setup_basedir(progname, parentdir, nsm_base_dirname, ++ PATH_MAX); + } + + /** +diff --git a/systemd/nfs-mountd.service b/systemd/nfs-mountd.service +index 15e828b..b0a8bc0 100644 +--- a/systemd/nfs-mountd.service ++++ b/systemd/nfs-mountd.service +@@ -4,6 +4,7 @@ DefaultDependencies=no + Requires=proc-fs-nfsd.mount + After=proc-fs-nfsd.mount + After=network.target local-fs.target ++After=rpcbind.socket + BindsTo=nfs-server.service + + [Service] +diff --git a/systemd/nfs-server-generator.c b/systemd/nfs-server-generator.c +index cc99969..4aa6509 100644 +--- a/systemd/nfs-server-generator.c ++++ b/systemd/nfs-server-generator.c +@@ -84,6 +84,28 @@ static void systemd_escape(FILE *f, char *path) + } + } + ++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; +@@ -124,6 +146,10 @@ int main(int argc, char *argv[]) + 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); +diff --git a/systemd/nfs.conf.man b/systemd/nfs.conf.man +index 91c49a0..bdc0988 100644 +--- a/systemd/nfs.conf.man ++++ b/systemd/nfs.conf.man +@@ -154,6 +154,13 @@ section, are used to configure mountd. See + .BR rpc.mountd (8) + for details. + ++The ++.B state-directory-path ++value in the ++.B [mountd] ++section is also used by ++.BR exportfs (8). ++ + .TP + .B statd + Recognized values: +diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c +index 61dddfb..02d5b6d 100644 +--- a/utils/exportfs/exportfs.c ++++ b/utils/exportfs/exportfs.c +@@ -52,6 +52,8 @@ static const char *lockfile = EXP_LOCKFILE; + static int _lockfd = -1; + char *conf_path = NFS_CONFFILE; + ++struct state_paths etab; ++ + /* + * If we aren't careful, changes made by exportfs can be lost + * when multiple exports process run at once: +@@ -95,6 +97,7 @@ main(int argc, char **argv) + int f_ignore = 0; + int i, c; + int force_flush = 0; ++ char *s; + + if ((progname = strrchr(argv[0], '/')) != NULL) + progname++; +@@ -108,6 +111,11 @@ main(int argc, char **argv) + conf_init(); + xlog_from_conffile("exportfs"); + ++ /* NOTE: following uses "mountd" section of nfs.conf !!!! */ ++ s = conf_get_str("mountd", "state-directory-path"); ++ if (s && !state_setup_basedir(argv[0], s)) ++ exit(1); ++ + while ((c = getopt(argc, argv, "ad:fhio:ruvs")) != EOF) { + switch(c) { + case 'a': +@@ -159,13 +167,17 @@ main(int argc, char **argv) + xlog(L_ERROR, "-r and -u are incompatible"); + return 1; + } ++ if (!setup_state_path_names(progname, ETAB, ETABTMP, ETABLCK, &etab)) ++ return 1; + if (optind == argc && ! f_all) { + if (force_flush) { + cache_flush(1); ++ free_state_path_names(&etab); + return 0; + } else { + xtab_export_read(); + dump(f_verbose, f_export_format); ++ free_state_path_names(&etab); + return 0; + } + } +@@ -206,6 +218,7 @@ main(int argc, char **argv) + } + xtab_export_write(); + cache_flush(force_flush); ++ free_state_path_names(&etab); + + return export_errno; + } +diff --git a/utils/exportfs/exportfs.man b/utils/exportfs/exportfs.man +index 45b6d83..91d3589 100644 +--- a/utils/exportfs/exportfs.man ++++ b/utils/exportfs/exportfs.man +@@ -148,6 +148,29 @@ options. + .TP + .B -s + Display the current export list suitable for /etc/exports. ++ ++.SH CONFIGURATION FILE ++The ++.B [exportfs] ++section of the ++.I /etc/nfs.conf ++configuration file can contain a ++.B debug ++value, which can be one or more from the list ++.BR general , ++.BR call , ++.BR auth , ++.BR parse , ++.BR all . ++When a list is given, the members should be comma-separated. ++ ++.B exportfs ++will also recognize the ++.B state-directory-path ++value from the ++.B [mountd] ++section. ++ + .SH DISCUSSION + .SS Exporting Directories + The first synopsis shows how to invoke +diff --git a/utils/gssd/gssd.c b/utils/gssd/gssd.c +index 4d18d35..77125f1 100644 +--- a/utils/gssd/gssd.c ++++ b/utils/gssd/gssd.c +@@ -87,6 +87,7 @@ int root_uses_machine_creds = 1; + unsigned int context_timeout = 0; + unsigned int rpc_timeout = 5; + char *preferred_realm = NULL; ++char *ccachedir = NULL; + /* Avoid DNS reverse lookups on server names */ + static bool avoid_dns = true; + int thread_started = false; +@@ -837,18 +838,9 @@ usage(char *progname) + exit(1); + } + +-int +-main(int argc, char *argv[]) ++inline static void ++read_gss_conf(void) + { +- int fg = 0; +- int verbosity = 0; +- int rpc_verbosity = 0; +- int opt; +- int i; +- extern char *optarg; +- char *progname; +- char *ccachedir = NULL; +- struct event sighup_ev; + char *s; + + conf_init(); +@@ -877,6 +869,22 @@ main(int argc, char *argv[]) + if (s) + preferred_realm = s; + ++} ++ ++int ++main(int argc, char *argv[]) ++{ ++ int fg = 0; ++ int verbosity = 0; ++ int rpc_verbosity = 0; ++ int opt; ++ int i; ++ extern char *optarg; ++ char *progname; ++ struct event sighup_ev; ++ ++ read_gss_conf(); ++ + while ((opt = getopt(argc, argv, "DfvrlmnMp:k:d:t:T:R:")) != -1) { + switch (opt) { + case 'f': +diff --git a/utils/gssd/gssd_proc.c b/utils/gssd/gssd_proc.c +index d74d372..4fc81c3 100644 +--- a/utils/gssd/gssd_proc.c ++++ b/utils/gssd/gssd_proc.c +@@ -729,10 +729,18 @@ handle_gssd_upcall(struct clnt_upcall_info *info) + char *target = NULL; + char *service = NULL; + char *enctypes = NULL; ++ char *upcall_str; ++ char *pbuf = info->lbuf; + + printerr(2, "\n%s: '%s' (%s)\n", __func__, info->lbuf, clp->relpath); + +- for (p = strtok(info->lbuf, " "); p; p = strtok(NULL, " ")) { ++ upcall_str = strdup(info->lbuf); ++ if (upcall_str == NULL) { ++ printerr(0, "ERROR: malloc failure\n"); ++ goto out_nomem; ++ } ++ ++ while ((p = strsep(&pbuf, " "))) { + if (!strncmp(p, "mech=", strlen("mech="))) + mech = p + strlen("mech="); + else if (!strncmp(p, "uid=", strlen("uid="))) +@@ -748,7 +756,7 @@ handle_gssd_upcall(struct clnt_upcall_info *info) + if (!mech || strlen(mech) < 1) { + printerr(0, "WARNING: handle_gssd_upcall: " + "failed to find gss mechanism name " +- "in upcall string '%s'\n", info->lbuf); ++ "in upcall string '%s'\n", upcall_str); + goto out; + } + +@@ -761,7 +769,7 @@ handle_gssd_upcall(struct clnt_upcall_info *info) + if (!uidstr) { + printerr(0, "WARNING: handle_gssd_upcall: " + "failed to find uid " +- "in upcall string '%s'\n", info->lbuf); ++ "in upcall string '%s'\n", upcall_str); + goto out; + } + +@@ -774,7 +782,7 @@ handle_gssd_upcall(struct clnt_upcall_info *info) + if (target && strlen(target) < 1) { + printerr(0, "WARNING: handle_gssd_upcall: " + "failed to parse target name " +- "in upcall string '%s'\n", info->lbuf); ++ "in upcall string '%s'\n", upcall_str); + goto out; + } + +@@ -789,7 +797,7 @@ handle_gssd_upcall(struct clnt_upcall_info *info) + if (service && strlen(service) < 1) { + printerr(0, "WARNING: handle_gssd_upcall: " + "failed to parse service type " +- "in upcall string '%s'\n", info->lbuf); ++ "in upcall string '%s'\n", upcall_str); + goto out; + } + +@@ -802,6 +810,8 @@ handle_gssd_upcall(struct clnt_upcall_info *info) + do_error_downcall(clp->gssd_fd, uid, -EACCES); + } + out: ++ free(upcall_str); ++out_nomem: + free(info); + return; + } +diff --git a/utils/mount/network.c b/utils/mount/network.c +index 7dceb2d..281e935 100644 +--- a/utils/mount/network.c ++++ b/utils/mount/network.c +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -804,6 +805,7 @@ int start_statd(void) + pid_t pid = fork(); + switch (pid) { + case 0: /* child */ ++ setgroups(0, NULL); + setgid(0); + setuid(0); + execle(START_STATD, START_STATD, NULL, envp); +@@ -1638,6 +1640,7 @@ int nfs_options2pmap(struct mount_options *options, + struct pmap *nfs_pmap, struct pmap *mnt_pmap) + { + struct nfs_version version; ++ memset(&version, 0, sizeof(version)); + + if (!nfs_nfs_program(options, &nfs_pmap->pm_prog)) + return 0; +diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c +index 387d734..a9ff95d 100644 +--- a/utils/mount/stropts.c ++++ b/utils/mount/stropts.c +@@ -517,6 +517,10 @@ nfs_rewrite_pmap_mount_options(struct mount_options *options, int checkv4) + unsigned long protocol; + struct pmap mnt_pmap; + ++ /* initialize structs */ ++ memset(&nfs_pmap, 0, sizeof(struct pmap)); ++ memset(&mnt_pmap, 0, sizeof(struct pmap)); ++ + /* + * Version and transport negotiation is not required + * and does not work for RDMA mounts. +diff --git a/utils/mountd/auth.c b/utils/mountd/auth.c +index d065830..8299256 100644 +--- a/utils/mountd/auth.c ++++ b/utils/mountd/auth.c +@@ -41,6 +41,8 @@ static nfs_client my_client; + + extern int use_ipaddr; + ++extern struct state_paths etab; ++ + void + auth_init(void) + { +@@ -84,10 +86,10 @@ auth_reload() + static unsigned int counter; + int fd; + +- if ((fd = open(_PATH_ETAB, O_RDONLY)) < 0) { +- xlog(L_FATAL, "couldn't open %s", _PATH_ETAB); ++ if ((fd = open(etab.statefn, O_RDONLY)) < 0) { ++ xlog(L_FATAL, "couldn't open %s", etab.statefn); + } else if (fstat(fd, &stb) < 0) { +- xlog(L_FATAL, "couldn't stat %s", _PATH_ETAB); ++ xlog(L_FATAL, "couldn't stat %s", etab.statefn); + close(fd); + } else if (last_fd != -1 && stb.st_ino == last_inode) { + /* We opened the etab file before, and its inode +diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c +index 61699e6..bbadfaf 100644 +--- a/utils/mountd/mountd.c ++++ b/utils/mountd/mountd.c +@@ -29,6 +29,7 @@ + #include "mountd.h" + #include "rpcmisc.h" + #include "pseudoflavors.h" ++#include "nfslib.h" + + extern void my_svc_run(void); + +@@ -40,6 +41,9 @@ int reverse_resolve = 0; + int manage_gids; + int use_ipaddr = -1; + ++struct state_paths etab; ++struct state_paths rmtab; ++ + char *conf_path = NFS_CONFFILE; + + /* PRC: a high-availability callout program can be specified with -H +@@ -110,8 +114,8 @@ unregister_services (void) + static void + cleanup_lockfiles (void) + { +- unlink(_PATH_ETABLCK); +- unlink(_PATH_RMTABLCK); ++ unlink(etab.lockfn); ++ unlink(rmtab.lockfn); + } + + /* Wait for all worker child processes to exit and reap them */ +@@ -181,6 +185,8 @@ fork_workers(void) + wait_for_workers(); + unregister_services(); + cleanup_lockfiles(); ++ free_state_path_names(&etab); ++ free_state_path_names(&rmtab); + xlog(L_NOTICE, "mountd: no more workers, exiting\n"); + exit(0); + } +@@ -198,6 +204,8 @@ killer (int sig) + wait_for_workers(); + } + cleanup_lockfiles(); ++ free_state_path_names(&etab); ++ free_state_path_names(&rmtab); + xlog (L_NOTICE, "Caught signal %d, un-registering and exiting.", sig); + exit(0); + } +@@ -656,7 +664,6 @@ get_exportlist(void) + int + main(int argc, char **argv) + { +- char *state_dir = NFS_STATEDIR; + char *progname; + char *s; + unsigned int listeners = 0; +@@ -684,8 +691,8 @@ main(int argc, char **argv) + ha_callout_prog = conf_get_str("mountd", "ha-callout"); + + s = conf_get_str("mountd", "state-directory-path"); +- if (s) +- state_dir = s; ++ if (s && !state_setup_basedir(argv[0], s)) ++ exit(1); + + /* NOTE: following uses "nfsd" section of nfs.conf !!!! */ + if (conf_get_bool("nfsd", "udp", NFSCTL_UDPISSET(_rpcprotobits))) +@@ -758,7 +765,8 @@ main(int argc, char **argv) + reverse_resolve = 1; + break; + case 's': +- state_dir = xstrdup(optarg); ++ if (!state_setup_basedir(argv[0], optarg)) ++ exit(1); + break; + case 't': + num_threads = atoi (optarg); +@@ -790,11 +798,10 @@ main(int argc, char **argv) + fprintf(stderr, "%s: No protocol versions specified!\n", progname); + usage(progname, 1); + } +- if (chdir(state_dir)) { +- fprintf(stderr, "%s: chdir(%s) failed: %s\n", +- progname, state_dir, strerror(errno)); +- exit(1); +- } ++ if (!setup_state_path_names(progname, ETAB, ETABTMP, ETABLCK, &etab)) ++ return 1; ++ if (!setup_state_path_names(progname, RMTAB, RMTABTMP, RMTABLCK, &rmtab)) ++ return 1; + + if (getrlimit (RLIMIT_NOFILE, &rlim) != 0) + fprintf(stderr, "%s: getrlimit (RLIMIT_NOFILE) failed: %s\n", +@@ -888,6 +895,8 @@ main(int argc, char **argv) + + xlog(L_ERROR, "RPC service loop terminated unexpectedly. Exiting...\n"); + unregister_services(); ++ free_state_path_names(&etab); ++ free_state_path_names(&rmtab); + exit(1); + } + +diff --git a/utils/mountd/mountd.man b/utils/mountd/mountd.man +index 9f0a51f..9978afc 100644 +--- a/utils/mountd/mountd.man ++++ b/utils/mountd/mountd.man +@@ -144,7 +144,7 @@ Instead, mount the nfsd filesystem on + .IR /proc/fs/nfsd . + .TP + .BI "\-s," "" " \-\-state\-directory\-path " directory +-Specify a directory in which to place statd state information. ++Specify a directory in which to place state information (etab and rmtab). + If this option is not specified the default of + .I /var/lib/nfs + is used. +diff --git a/utils/mountd/rmtab.c b/utils/mountd/rmtab.c +index 527377f..3ae0dbb 100644 +--- a/utils/mountd/rmtab.c ++++ b/utils/mountd/rmtab.c +@@ -28,6 +28,8 @@ + + extern int reverse_resolve; + ++extern struct state_paths rmtab; ++ + /* If new path is a link do not destroy it but place the + * file where the link points. + */ +@@ -59,7 +61,7 @@ mountlist_add(char *host, const char *path) + int lockid; + long pos; + +- if ((lockid = xflock(_PATH_RMTABLCK, "a")) < 0) ++ if ((lockid = xflock(rmtab.lockfn, "a")) < 0) + return; + setrmtabent("r+"); + while ((rep = getrmtabent(1, &pos)) != NULL) { +@@ -99,13 +101,13 @@ mountlist_del(char *hname, const char *path) + int lockid; + int match; + +- if ((lockid = xflock(_PATH_RMTABLCK, "w")) < 0) ++ if ((lockid = xflock(rmtab.lockfn, "w")) < 0) + return; + if (!setrmtabent("r")) { + xfunlock(lockid); + return; + } +- if (!(fp = fsetrmtabent(_PATH_RMTABTMP, "w"))) { ++ if (!(fp = fsetrmtabent(rmtab.tmpfn, "w"))) { + endrmtabent(); + xfunlock(lockid); + return; +@@ -121,9 +123,9 @@ mountlist_del(char *hname, const char *path) + if (!match || rep->r_count) + fputrmtabent(fp, rep, NULL); + } +- if (slink_safe_rename(_PATH_RMTABTMP, _PATH_RMTAB) < 0) { ++ if (slink_safe_rename(rmtab.tmpfn, rmtab.statefn) < 0) { + xlog(L_ERROR, "couldn't rename %s to %s", +- _PATH_RMTABTMP, _PATH_RMTAB); ++ rmtab.tmpfn, rmtab.statefn); + } + endrmtabent(); /* close & unlink */ + fendrmtabent(fp); +@@ -138,7 +140,7 @@ mountlist_del_all(const struct sockaddr *sap) + FILE *fp; + int lockid; + +- if ((lockid = xflock(_PATH_RMTABLCK, "w")) < 0) ++ if ((lockid = xflock(rmtab.lockfn, "w")) < 0) + return; + hostname = host_canonname(sap); + if (hostname == NULL) { +@@ -151,7 +153,7 @@ mountlist_del_all(const struct sockaddr *sap) + if (!setrmtabent("r")) + goto out_free; + +- if (!(fp = fsetrmtabent(_PATH_RMTABTMP, "w"))) ++ if (!(fp = fsetrmtabent(rmtab.tmpfn, "w"))) + goto out_close; + + while ((rep = getrmtabent(1, NULL)) != NULL) { +@@ -160,9 +162,9 @@ mountlist_del_all(const struct sockaddr *sap) + continue; + fputrmtabent(fp, rep, NULL); + } +- if (slink_safe_rename(_PATH_RMTABTMP, _PATH_RMTAB) < 0) { ++ if (slink_safe_rename(rmtab.tmpfn, rmtab.statefn) < 0) { + xlog(L_ERROR, "couldn't rename %s to %s", +- _PATH_RMTABTMP, _PATH_RMTAB); ++ rmtab.tmpfn, rmtab.statefn); + } + fendrmtabent(fp); + out_close: +@@ -195,11 +197,11 @@ mountlist_list(void) + struct stat stb; + int lockid; + +- if ((lockid = xflock(_PATH_RMTABLCK, "r")) < 0) ++ if ((lockid = xflock(rmtab.lockfn, "r")) < 0) + return NULL; +- if (stat(_PATH_RMTAB, &stb) < 0) { ++ if (stat(rmtab.statefn, &stb) < 0) { + xlog(L_ERROR, "can't stat %s: %s", +- _PATH_RMTAB, strerror(errno)); ++ rmtab.statefn, strerror(errno)); + xfunlock(lockid); + return NULL; + } +diff --git a/utils/statd/Makefile.am b/utils/statd/Makefile.am +index 152b680..ea32075 100644 +--- a/utils/statd/Makefile.am ++++ b/utils/statd/Makefile.am +@@ -18,6 +18,7 @@ statd_LDADD = ../../support/nsm/libnsm.a \ + $(LIBWRAP) $(LIBNSL) $(LIBCAP) $(LIBTIRPC) + sm_notify_LDADD = ../../support/nsm/libnsm.a \ + ../../support/nfs/libnfs.a \ ++ ../../support/misc/libmisc.a \ + $(LIBNSL) $(LIBCAP) $(LIBTIRPC) + + EXTRA_DIST = sim_sm_inter.x $(man8_MANS) simulate.c diff --git a/nfs-utils.spec b/nfs-utils.spec index a960a4c..b303e43 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: 2.1.1 -Release: 2%{?dist} +Release: 2.rc1%{?dist} Epoch: 1 # group all 32bit related archs @@ -14,6 +14,8 @@ Source2: nfs.sysconfig Source3: nfs-utils_env.sh Source4: lockd.conf +Patch001: nfs-utils-2.1.2-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 @@ -71,6 +73,8 @@ This package also contains the mount.nfs and umount.nfs program. %prep %setup -q +%patch001 -p1 + %patch100 -p1 %patch101 -p1 %patch102 -p1 @@ -277,6 +281,9 @@ fi /sbin/umount.nfs4 %changelog +* Wed Feb 15 2017 Steve Dickson 2.1.1-2.rc1 +- Updated to the latest RC release: nfs-utils-2-1-2-rc1 + * Fri Feb 10 2017 Fedora Release Engineering - 1:2.1.1-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild @@ -286,10 +293,10 @@ fi * Thu Jan 19 2017 Steve Dickson 2.1.1-0 - Updated to latest upstream release: nfs-utils-2-1-1 (bz 1413232) -* Mon Dec 19 2016 Miro HronĨok - 1:1.3.4-1.rc3.1 +* Mon Dec 19 2016 Miro Hronok - 1:1.3.4-1.rc3.1 - Rebuild for Python 3.6 -* Wed Nov 25 2016 Steve Dickson 1.3.4-1.rc3 +* Fri Nov 25 2016 Steve Dickson 1.3.4-1.rc3 - Updated to the latest RC release: nfs-utils-1-3-5-rc3 * Thu Aug 25 2016 Steve Dickson 1.3.4-1.rc2