From 48754f91f3b01f3d680fe5684027e6e9501a14ea Mon Sep 17 00:00:00 2001 From: DistroBaker Date: Tue, 30 Mar 2021 16:20:16 +0000 Subject: [PATCH] Merged update from upstream sources This is an automated DistroBaker update from upstream sources. If you do not know what this is about or would like to opt out, contact the OSCI team. Source: https://src.fedoraproject.org/rpms/nfs-utils.git#56aa42541981fc94866058c8f588dd29e556bdda --- 10-nfsv4.conf | 9 + nfs-utils-2.5.3-rdma-on.patch | 16 + nfs-utils-2.5.4-rc1.patch | 1244 +++++++++++++++++++++++++++++++++ nfs-utils.spec | 102 ++- 4 files changed, 1370 insertions(+), 1 deletion(-) create mode 100644 10-nfsv4.conf create mode 100644 nfs-utils-2.5.3-rdma-on.patch create mode 100644 nfs-utils-2.5.4-rc1.patch diff --git a/10-nfsv4.conf b/10-nfsv4.conf new file mode 100644 index 0000000..03510d9 --- /dev/null +++ b/10-nfsv4.conf @@ -0,0 +1,9 @@ +[ NFSMount_Global_Options ] +# This statically named section defines global mount +# options that can be applied on all NFS mount. +# +# Setting this option makes it mandatory the server supports the +# given version. The mount will fail if the given version is +# not support by the server. +Nfsvers=4 + diff --git a/nfs-utils-2.5.3-rdma-on.patch b/nfs-utils-2.5.3-rdma-on.patch new file mode 100644 index 0000000..7f8268a --- /dev/null +++ b/nfs-utils-2.5.3-rdma-on.patch @@ -0,0 +1,16 @@ +diff -up nfs-utils-2.5.3/nfs.conf.orig nfs-utils-2.5.3/nfs.conf +--- nfs-utils-2.5.3/nfs.conf.orig 2021-03-16 13:38:43.922161313 -0400 ++++ nfs-utils-2.5.3/nfs.conf 2021-03-16 13:39:24.560299448 -0400 +@@ -72,9 +72,9 @@ use-gss-proxy=1 + # vers4.0=y + # vers4.1=y + # vers4.2=y +-# rdma=n +-# rdma-port=20049 +-# ++rdma=y ++rdma-port=20049 ++ + [statd] + # debug=0 + # port=0 diff --git a/nfs-utils-2.5.4-rc1.patch b/nfs-utils-2.5.4-rc1.patch new file mode 100644 index 0000000..5d190da --- /dev/null +++ b/nfs-utils-2.5.4-rc1.patch @@ -0,0 +1,1244 @@ +diff --git a/nfs.conf b/nfs.conf +index bebb2e3d..9042d27d 100644 +--- a/nfs.conf ++++ b/nfs.conf +@@ -24,6 +24,7 @@ + # keytab-file=/etc/krb5.keytab + # cred-cache-directory= + # preferred-realm= ++# set-home=1 + # + [lockd] + # port=0 +@@ -31,8 +32,11 @@ + # + [exportd] + # debug="all|auth|call|general|parse" ++# manage-gids=n + # state-directory-path=/var/lib/nfs + # threads=1 ++# cache-use-ipaddr=n ++# ttl=1800 + [mountd] + # debug="all|auth|call|general|parse" + # manage-gids=n +@@ -42,6 +46,8 @@ + # reverse-lookup=n + # state-directory-path=/var/lib/nfs + # ha-callout= ++# cache-use-ipaddr=n ++# ttl=1800 + # + [nfsdcld] + # debug=0 +diff --git a/support/export/Makefile.am b/support/export/Makefile.am +index a9e710c0..eec737f6 100644 +--- a/support/export/Makefile.am ++++ b/support/export/Makefile.am +@@ -12,7 +12,8 @@ EXTRA_DIST = mount.x + noinst_LIBRARIES = libexport.a + libexport_a_SOURCES = client.c export.c hostname.c \ + xtab.c mount_clnt.c mount_xdr.c \ +- cache.c auth.c v4root.c fsloc.c ++ cache.c auth.c v4root.c fsloc.c \ ++ v4clients.c + BUILT_SOURCES = $(GENFILES) + + noinst_HEADERS = mount.h +diff --git a/support/export/auth.c b/support/export/auth.c +index 0bfa77d1..cea37630 100644 +--- a/support/export/auth.c ++++ b/support/export/auth.c +@@ -66,6 +66,10 @@ check_useipaddr(void) + int old_use_ipaddr = use_ipaddr; + unsigned int len = 0; + ++ if (use_ipaddr > 1) ++ /* fixed - don't check */ ++ return; ++ + /* add length of m_hostname + 1 for the comma */ + for (clp = clientlist[MCL_NETGROUP]; clp; clp = clp->m_next) + len += (strlen(clp->m_hostname) + 1); +diff --git a/support/export/cache.c b/support/export/cache.c +index f1569afb..3e4f53c0 100644 +--- a/support/export/cache.c ++++ b/support/export/cache.c +@@ -42,13 +42,6 @@ + #include "blkid/blkid.h" + #endif + +-/* +- * Invoked by RPC service loop +- */ +-void cache_set_fds(fd_set *fdset); +-int cache_process_req(fd_set *readfds); +-void cache_process_loop(void); +- + enum nfsd_fsid { + FSID_DEV = 0, + FSID_NUM, +@@ -96,7 +89,6 @@ static bool path_lookup_error(int err) + * Record is terminated with newline. + * + */ +-static int cache_export_ent(char *buf, int buflen, char *domain, struct exportent *exp, char *path); + + #define INITIAL_MANAGED_GROUPS 100 + +@@ -114,6 +106,7 @@ static void auth_unix_ip(int f) + char class[20]; + char ipaddr[INET6_ADDRSTRLEN + 1]; + char *client = NULL; ++ struct addrinfo *ai = NULL; + struct addrinfo *tmp = NULL; + char buf[RPC_CHAN_BUF_SIZE], *bp; + int blen; +@@ -139,21 +132,26 @@ static void auth_unix_ip(int f) + + auth_reload(); + +- /* addr is a valid, interesting address, find the domain name... */ +- if (!use_ipaddr) { +- struct addrinfo *ai = NULL; +- +- ai = client_resolve(tmp->ai_addr); +- if (ai) { +- client = client_compose(ai); +- nfs_freeaddrinfo(ai); +- } ++ /* addr is a valid address, find the domain name... */ ++ ai = client_resolve(tmp->ai_addr); ++ if (ai) { ++ client = client_compose(ai); ++ nfs_freeaddrinfo(ai); + } ++ if (!client) ++ xlog(D_AUTH, "failed authentication for IP %s", ipaddr); ++ else if (!use_ipaddr) ++ xlog(D_AUTH, "successful authentication for IP %s as %s", ++ ipaddr, *client ? client : "DEFAULT"); ++ else ++ xlog(D_AUTH, "successful authentication for IP %s", ++ ipaddr); ++ + bp = buf; blen = sizeof(buf); + qword_add(&bp, &blen, "nfsd"); + qword_add(&bp, &blen, ipaddr); +- qword_adduint(&bp, &blen, time(0) + DEFAULT_TTL); +- if (use_ipaddr) { ++ qword_adduint(&bp, &blen, time(0) + default_ttl); ++ if (use_ipaddr && client) { + memmove(ipaddr + 1, ipaddr, strlen(ipaddr) + 1); + ipaddr[0] = '$'; + qword_add(&bp, &blen, ipaddr); +@@ -225,7 +223,7 @@ static void auth_unix_gid(int f) + + bp = buf; blen = sizeof(buf); + qword_adduint(&bp, &blen, uid); +- qword_adduint(&bp, &blen, time(0) + DEFAULT_TTL); ++ qword_adduint(&bp, &blen, time(0) + default_ttl); + if (rv >= 0) { + qword_adduint(&bp, &blen, ngroups); + for (i=0; ie_mountpoint[0]? + found->e_mountpoint: + found->e_path)) { +- /* Cannot export this yet ++ /* Cannot export this yet + * should log a warning, but need to rate limit + xlog(L_WARNING, "%s not exported as %d not a mountpoint", + found->e_path, found->e_mountpoint); + */ + /* FIXME we need to make sure we re-visit this later */ + goto out; +- } else if (cache_export_ent(buf, sizeof(buf), dom, found, found_path) < 0) { +- if (!path_lookup_error(errno)) +- goto out; +- /* The kernel is saying the path is unexportable */ +- found = NULL; + } + + bp = buf; blen = sizeof(buf); +@@ -905,6 +898,8 @@ static void nfsd_fh(int f) + qword_addeol(&bp, &blen); + if (blen <= 0 || cache_write(f, buf, bp - buf) != bp - buf) + xlog(L_ERROR, "nfsd_fh: error writing reply"); ++ if (!found) ++ xlog(D_AUTH, "denied access to %s", *dom == '$' ? dom+1 : dom); + out: + if (found_path) + free(found_path); +@@ -966,7 +961,7 @@ static int dump_to_cache(int f, char *buf, int blen, char *domain, + ssize_t err; + + if (ttl <= 1) +- ttl = DEFAULT_TTL; ++ ttl = default_ttl; + + qword_add(&bp, &blen, domain); + qword_add(&bp, &blen, path); +@@ -996,8 +991,13 @@ static int dump_to_cache(int f, char *buf, int blen, char *domain, + qword_add(&bp, &blen, "uuid"); + qword_addhex(&bp, &blen, u, 16); + } +- } else ++ xlog(D_AUTH, "granted access to %s for %s", ++ path, *domain == '$' ? domain+1 : domain); ++ } else { + qword_adduint(&bp, &blen, now + ttl); ++ xlog(D_AUTH, "denied access to %s for %s", ++ path, *domain == '$' ? domain+1 : domain); ++ } + qword_addeol(&bp, &blen); + if (blen <= 0) { + errno = ENOBUFS; +@@ -1530,6 +1530,7 @@ void cache_process_loop(void) + for (;;) { + + cache_set_fds(&readfds); ++ v4clients_set_fds(&readfds); + + selret = select(FD_SETSIZE, &readfds, + (void *) 0, (void *) 0, (struct timeval *) 0); +@@ -1545,6 +1546,7 @@ void cache_process_loop(void) + + default: + cache_process_req(&readfds); ++ v4clients_process(&readfds); + } + } + } +diff --git a/support/export/export.h b/support/export/export.h +index 4296db1a..8d5a0d30 100644 +--- a/support/export/export.h ++++ b/support/export/export.h +@@ -3,13 +3,14 @@ + * + * support/export/export.h + * +- * Declarations for export support ++ * Declarations for export support + */ + + #ifndef EXPORT_H + #define EXPORT_H + + #include "nfslib.h" ++#include "exportfs.h" + + unsigned int auth_reload(void); + nfs_export * auth_authenticate(const char *what, +@@ -17,8 +18,14 @@ nfs_export * auth_authenticate(const char *what, + const char *path); + + void cache_open(void); ++void cache_set_fds(fd_set *fdset); ++int cache_process_req(fd_set *readfds); + void cache_process_loop(void); + ++void v4clients_init(void); ++void v4clients_set_fds(fd_set *fdset); ++int v4clients_process(fd_set *fdset); ++ + struct nfs_fh_len * + cache_get_filehandle(nfs_export *exp, int len, char *p); + int cache_export(nfs_export *exp, char *path); +diff --git a/support/export/v4clients.c b/support/export/v4clients.c +new file mode 100644 +index 00000000..056ddc9b +--- /dev/null ++++ b/support/export/v4clients.c +@@ -0,0 +1,179 @@ ++/* ++ * support/export/v4clients.c ++ * ++ * Montior clients appearing in, and disappearing from, /proc/fs/nfsd/clients ++ * and log relevant information. ++ */ ++ ++#include ++#include ++#include ++#include ++#include "export.h" ++ ++/* search.h declares 'struct entry' and nfs_prot.h ++ * does too. Easiest fix is to trick search.h into ++ * calling its struct "struct Entry". ++ */ ++#define entry Entry ++#include ++#undef entry ++ ++static int clients_fd = -1; ++ ++void v4clients_init(void) ++{ ++ if (clients_fd >= 0) ++ return; ++ clients_fd = inotify_init1(IN_NONBLOCK); ++ if (clients_fd < 0) { ++ xlog_err("Unable to initialise v4clients watcher: %s\n", ++ strerror(errno)); ++ return; ++ } ++ if (inotify_add_watch(clients_fd, "/proc/fs/nfsd/clients", ++ IN_CREATE | IN_DELETE) < 0) { ++ xlog_err("Unable to watch /proc/fs/nfsd/clients: %s\n", ++ strerror(errno)); ++ close(clients_fd); ++ clients_fd = -1; ++ return; ++ } ++} ++ ++void v4clients_set_fds(fd_set *fdset) ++{ ++ if (clients_fd >= 0) ++ FD_SET(clients_fd, fdset); ++} ++ ++static void *tree_root; ++ ++struct ent { ++ unsigned long num; ++ char *clientid; ++ char *addr; ++ int vers; ++}; ++ ++static int ent_cmp(const void *av, const void *bv) ++{ ++ const struct ent *a = av; ++ const struct ent *b = bv; ++ ++ if (a->num < b->num) ++ return -1; ++ if (a->num > b->num) ++ return 1; ++ return 0; ++} ++ ++static void free_ent(struct ent *ent) ++{ ++ free(ent->clientid); ++ free(ent->addr); ++ free(ent); ++} ++ ++static char *dup_line(char *line) ++{ ++ char *ret; ++ char *e = strchr(line, '\n'); ++ if (!e) ++ e = line + strlen(line); ++ ret = malloc(e - line + 1); ++ if (ret) { ++ memcpy(ret, line, e - line); ++ ret[e-line] = 0; ++ } ++ return ret; ++} ++ ++static void add_id(int id) ++{ ++ char buf[2048]; ++ struct ent **ent; ++ struct ent *key; ++ char *path; ++ FILE *f; ++ ++ if (asprintf(&path, "/proc/fs/nfsd/clients/%d/info", id) < 0) ++ return; ++ ++ f = fopen(path, "r"); ++ if (!f) { ++ free(path); ++ return; ++ } ++ key = calloc(1, sizeof(*key)); ++ if (!key) { ++ fclose(f); ++ free(path); ++ return; ++ } ++ key->num = id; ++ while (fgets(buf, sizeof(buf), f)) { ++ if (strncmp(buf, "clientid: ", 10) == 0) ++ key->clientid = dup_line(buf+10); ++ if (strncmp(buf, "address: ", 9) == 0) ++ key->addr = dup_line(buf+9); ++ if (strncmp(buf, "minor version: ", 15) == 0) ++ key->vers = atoi(buf+15); ++ } ++ fclose(f); ++ free(path); ++ ++ xlog(L_NOTICE, "v4.%d client attached: %s from %s", ++ key->vers, key->clientid, key->addr); ++ ++ ent = tsearch(key, &tree_root, ent_cmp); ++ ++ if (!ent || *ent != key) ++ /* Already existed, or insertion failed */ ++ free_ent(key); ++} ++ ++static void del_id(int id) ++{ ++ struct ent key = {.num = id}; ++ struct ent **e, *ent; ++ ++ e = tfind(&key, &tree_root, ent_cmp); ++ if (!e || !*e) ++ return; ++ ent = *e; ++ tdelete(ent, &tree_root, ent_cmp); ++ xlog(L_NOTICE, "v4.%d client detached: %s from %s", ++ ent->vers, ent->clientid, ent->addr); ++ free_ent(ent); ++} ++ ++int v4clients_process(fd_set *fdset) ++{ ++ char buf[4096] __attribute__((aligned(__alignof__(struct inotify_event)))); ++ const struct inotify_event *ev; ++ ssize_t len; ++ char *ptr; ++ ++ if (clients_fd < 0 || ++ !FD_ISSET(clients_fd, fdset)) ++ return 0; ++ ++ while ((len = read(clients_fd, buf, sizeof(buf))) > 0) { ++ for (ptr = buf; ptr < buf + len; ++ ptr += sizeof(struct inotify_event) + ev->len) { ++ int id; ++ ev = (const struct inotify_event *)ptr; ++ ++ id = atoi(ev->name); ++ if (id <= 0) ++ continue; ++ if (ev->mask & IN_CREATE) ++ add_id(id); ++ if (ev->mask & IN_DELETE) ++ del_id(id); ++ } ++ } ++ return 1; ++} ++ +diff --git a/support/export/v4root.c b/support/export/v4root.c +index 6f640aa9..3654bd7c 100644 +--- a/support/export/v4root.c ++++ b/support/export/v4root.c +@@ -45,7 +45,7 @@ static nfs_export pseudo_root = { + .e_nsqgids = 0, + .e_fsid = 0, + .e_mountpoint = NULL, +- .e_ttl = DEFAULT_TTL, ++ .e_ttl = 0, + }, + .m_exported = 0, + .m_xtabent = 1, +@@ -84,6 +84,7 @@ v4root_create(char *path, nfs_export *export) + struct exportent *curexp = &export->m_export; + + dupexportent(&eep, &pseudo_root.m_export); ++ eep.e_ttl = default_ttl; + eep.e_hostname = curexp->e_hostname; + strncpy(eep.e_path, path, sizeof(eep.e_path)-1); + if (strcmp(path, "/") != 0) +diff --git a/support/include/exportfs.h b/support/include/exportfs.h +index daa7e2a0..81d13721 100644 +--- a/support/include/exportfs.h ++++ b/support/include/exportfs.h +@@ -105,7 +105,8 @@ typedef struct mexport { + } nfs_export; + + #define HASH_TABLE_SIZE 1021 +-#define DEFAULT_TTL (30 * 60) ++ ++extern int default_ttl; + + typedef struct _exp_hash_entry { + nfs_export * p_first; +diff --git a/support/nfs/exports.c b/support/nfs/exports.c +index 037febd0..2c8f0752 100644 +--- a/support/nfs/exports.c ++++ b/support/nfs/exports.c +@@ -47,6 +47,8 @@ struct flav_info flav_map[] = { + + const int flav_map_size = sizeof(flav_map)/sizeof(flav_map[0]); + ++int default_ttl = 30 * 60; ++ + static char *efname = NULL; + static XFILE *efp = NULL; + static int first; +@@ -100,7 +102,7 @@ static void init_exportent (struct exportent *ee, int fromkernel) + ee->e_nsquids = 0; + ee->e_nsqgids = 0; + ee->e_uuid = NULL; +- ee->e_ttl = DEFAULT_TTL; ++ ee->e_ttl = default_ttl; + } + + struct exportent * +diff --git a/systemd/nfs.conf.man b/systemd/nfs.conf.man +index d2187f8a..4436a38a 100644 +--- a/systemd/nfs.conf.man ++++ b/systemd/nfs.conf.man +@@ -132,12 +132,22 @@ but on the server, this will resolve to the path + .B exportd + Recognized values: + .BR threads , ++.BR cache-use-upaddr , ++.BR ttl , + .BR state-directory-path + + See + .BR exportd (8) + for details. + ++Note that setting ++.B "\[dq]debug = auth\[dq]" ++for ++.B exportd ++is equivalent to providing the ++.B \-\-log\-auth ++option. ++ + .TP + .B nfsdcltrack + Recognized values: +@@ -188,6 +198,8 @@ Recognized values: + .BR port , + .BR threads , + .BR reverse-lookup , ++.BR cache-use-upaddr , ++.BR ttl , + .BR state-directory-path , + .BR ha-callout . + +@@ -197,6 +209,14 @@ section, are used to configure mountd. See + .BR rpc.mountd (8) + for details. + ++Note that setting ++.B "\[dq]debug = auth\[dq]" ++for ++.B mountd ++is equivalent to providing the ++.B \-\-log\-auth ++option. ++ + The + .B state-directory-path + value in the +@@ -253,7 +273,8 @@ Recognized values: + .BR rpc-timeout , + .BR keytab-file , + .BR cred-cache-directory , +-.BR preferred-realm . ++.BR preferred-realm , ++.BR set-home . + + See + .BR rpc.gssd (8) +diff --git a/tools/nfsdclnts/nfsdclnts.py b/tools/nfsdclnts/nfsdclnts.py +index 5e7e03c2..b7280f2c 100755 +--- a/tools/nfsdclnts/nfsdclnts.py ++++ b/tools/nfsdclnts/nfsdclnts.py +@@ -223,6 +223,7 @@ def nfsd4_show(): + + global verbose + verbose = False ++ signal.signal(signal.SIGPIPE, signal.SIG_DFL) + if args.verbose: + verbose = True + +diff --git a/utils/exportd/exportd.c b/utils/exportd/exportd.c +index 7130bcbf..f36f51d2 100644 +--- a/utils/exportd/exportd.c ++++ b/utils/exportd/exportd.c +@@ -42,9 +42,14 @@ static struct option longopts[] = + { "foreground", 0, 0, 'F' }, + { "debug", 1, 0, 'd' }, + { "help", 0, 0, 'h' }, ++ { "manage-gids", 0, 0, 'g' }, + { "num-threads", 1, 0, 't' }, ++ { "log-auth", 0, 0, 'l' }, ++ { "cache-use-ipaddr", 0, 0, 'i' }, ++ { "ttl", 0, 0, 'T' }, + { NULL, 0, 0, 0 } + }; ++static char shortopts[] = "d:fghs:t:liT:"; + + /* + * Signal handlers. +@@ -174,33 +179,43 @@ usage(const char *prog, int n) + { + fprintf(stderr, + "Usage: %s [-f|--foreground] [-h|--help] [-d kind|--debug kind]\n" ++" [-g|--manage-gids] [-l|--log-auth] [-i|--cache-use-ipaddr] [-T|--ttl ttl]\n" + " [-s|--state-directory-path path]\n" + " [-t num|--num-threads=num]\n", prog); + exit(n); + } + +-inline static void ++inline static void + read_exportd_conf(char *progname, char **argv) + { + char *s; ++ int ttl; + + conf_init_file(NFS_CONFFILE); + + xlog_set_debug(progname); + ++ manage_gids = conf_get_bool("exportd", "manage-gids", manage_gids); + num_threads = conf_get_num("exportd", "threads", num_threads); ++ if (conf_get_bool("mountd", "cache-use-ipaddr", 0)) ++ use_ipaddr = 2; + + s = conf_get_str("exportd", "state-directory-path"); + if (s && !state_setup_basedir(argv[0], s)) + exit(1); ++ ++ ttl = conf_get_num("mountd", "ttl", default_ttl); ++ if (ttl > 0) ++ default_ttl = ttl; + } + + int + main(int argc, char **argv) + { + char *progname; +- int foreground = 0; +- int c; ++ int foreground = 0; ++ int c; ++ int ttl; + + /* Set the basename */ + if ((progname = strrchr(argv[0], '/')) != NULL) +@@ -214,17 +229,35 @@ main(int argc, char **argv) + /* Read in config setting */ + read_exportd_conf(progname, argv); + +- while ((c = getopt_long(argc, argv, "d:fhs:t:", longopts, NULL)) != EOF) { ++ while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != EOF) { + switch (c) { + case 'd': + xlog_sconfig(optarg, 1); + break; ++ case 'l': ++ xlog_sconfig("auth", 1); ++ break; + case 'f': + foreground++; + break; ++ case 'g': ++ manage_gids = 1; ++ break; + case 'h': + usage(progname, 0); + break; ++ case 'i': ++ use_ipaddr = 2; ++ break; ++ case 'T': ++ ttl = atoi(optarg); ++ if (ttl <= 0) { ++ fprintf(stderr, "%s: bad ttl number of seconds: %s\n", ++ argv[0], optarg); ++ usage(argv[0], 1); ++ } ++ default_ttl = ttl; ++ break; + case 's': + if (!state_setup_basedir(argv[0], optarg)) + exit(1); +@@ -241,8 +274,8 @@ main(int argc, char **argv) + + if (!setup_state_path_names(progname, ETAB, ETABTMP, ETABLCK, &etab)) + return 1; +- +- if (!foreground) ++ ++ if (!foreground) + xlog_stderr(0); + + daemon_init(foreground); +@@ -264,6 +297,7 @@ main(int argc, char **argv) + + /* Open files now to avoid sharing descriptors among forked processes */ + cache_open(); ++ v4clients_init(); + + /* Process incoming upcalls */ + cache_process_loop(); +diff --git a/utils/exportd/exportd.man b/utils/exportd/exportd.man +index 1d65b5e0..b238ff05 100644 +--- a/utils/exportd/exportd.man ++++ b/utils/exportd/exportd.man +@@ -10,35 +10,74 @@ nfsv4.exportd \- NFSv4 Server Mount Daemon + .SH DESCRIPTION + The + .B nfsv4.exportd +-is used to manage NFSv4 exports. The NFSv4 server +-receives a mount request from a client and pass it up to +-.B nfsv4.exportd. +-.B nfsv4.exportd +-then uses the exports(5) export +-table to verify the validity of the mount request. +-.PP +-An NFS server maintains a table of local physical file systems +-that are accessible to NFS clients. +-Each file system in this table is referred to as an +-.IR "exported file system" , +-or +-.IR export , +-for short. +-.PP +-Each file system in the export table has an access control list. ++is used to manage NFSv4 exports. ++The NFS server ++.RI ( nfsd ) ++maintains a cache of authentication and authorization information which ++is used to identify the source of each requent, and then what access ++permissions that source has to any local filesystem. When required ++information is not found in the cache, the server sends a request to + .B nfsv4.exportd +-uses these access control lists to determine +-whether an NFS client is permitted to access a given file system. +-For details on how to manage your NFS server's export table, see the +-.BR exports (5) +-and +-.BR exportfs (8) +-man pages. ++to fill in the missing information. ++.B nfsv4.exportd ++uses a table of information stored in ++.B /var/lib/nfs/etab ++and maintained by ++.BR exportfs (8), ++possibly based on the contents of ++.BR exports (5), ++to respond to each request. + .SH OPTIONS + .TP + .B \-d kind " or " \-\-debug kind + Turn on debugging. Valid kinds are: all, auth, call, general and parse. + .TP ++.BR \-l " or " \-\-log\-auth ++Enable logging of responses to authentication and access requests from ++nfsd. Each response is then cached by the kernel for 30 minutes (or as set by ++.B \-\-ttl ++below), and will be refreshed after 15 minutes (half the ttl time) if ++the relevant client remains active. ++Note that ++.B -l ++is equivalent to ++.B "-d auth" ++and so can be enabled in ++.B /etc/nfs.conf ++with ++.B "\[dq]debug = auth\[dq]" ++in the ++.B "[exportd]" ++section. ++.TP ++.BR \-i " or " \-\-cache\-use\-ipaddr ++Normally each client IP address is matched against each host identifier ++(name, wildcard, netgroup etc) found in ++.B /etc/exports ++and a combined identity is formed from all matching identifiers. ++Often many clients will map to the same combined identity so performing ++this mapping reduces the number of distinct access details that the ++kernel needs to store. ++Specifying the ++.B \-i ++option suppresses this mapping so that access to each filesystem is ++requested and cached separately for each client IP address. Doing this ++can increase the burden of updating the cache slightly, but can make the ++log messages produced by the ++.B -l ++option easier to read. ++.TP ++.B \-T " or " \-\-ttl ++Provide a time-to-live (TTL) for cached information given to the kernel. ++The kernel will normally request an update if the information is needed ++after half of this time has expired. Increasing the provided number, ++which is in seconds, reduces the rate of cache update requests, and this ++is particularly noticeable when these requests are logged with ++.BR \-l . ++However increasing also means that changes to hostname to address ++mappings can take longer to be noticed. ++The default TTL is 1800 (30 minutes). ++.TP + .B \-F " or " \-\-foreground + Run in foreground (do not daemonize) + .TP +@@ -46,11 +85,27 @@ Run in foreground (do not daemonize) + Display usage message. + .TP + .BR "\-t N" " or " "\-\-num\-threads=N " or " \-\-num\-threads N " +-This option specifies the number of worker threads that rpc.mountd ++This option specifies the number of worker threads that ++.B nfsv4.exports + spawns. The default is 1 thread, which is probably enough. More + threads are usually only needed for NFS servers which need to handle + mount storms of hundreds of NFS mounts in a few seconds, or when + your DNS server is slow or unreliable. ++.TP ++.BR \-g " or " \-\-manage-gids ++Accept requests from the kernel to map user id numbers into lists of ++group id numbers for use in access control. An NFS request will ++normally (except when using Kerberos or other cryptographic ++authentication) contain a user-id and a list of group-ids. Due to a ++limitation in the NFS protocol, at most 16 groups ids can be listed. ++If you use the ++.B \-g ++flag, then the list of group ids received from the client will be ++replaced by a list of group ids determined by an appropriate lookup on ++the server. Note that the 'primary' group id is not affected so a ++.B newgroup ++command on the client will still be effective. This function requires ++a Linux Kernel with version at least 2.6.21. + .SH CONFIGURATION FILE + Many of the options that can be set on the command line can also be + controlled through values set in the +@@ -63,6 +118,9 @@ configuration file. + Values recognized in the + .B [exportd] + section include ++.B cache\-use\-ipaddr , ++.BR ttl , ++.BR manage-gids ", and" + .B debug + which each have the same effect as the option with the same name. + .SH FILES +@@ -78,4 +136,6 @@ listing exports, export options, and access control lists + .BR nfs.conf (5), + .BR firwall-cmd (1), + .sp +-RFC 3530 - "Network File System (NFS) version 4 Protocol" ++RFC 7530 - "Network File System (NFS) Version 4 Protocol" ++.br ++RFC 8881 - "Network File System (NFS) Version 4 Minor Version 1 Protocol" +diff --git a/utils/gssd/gssd.c b/utils/gssd/gssd.c +index 85bc4b07..1541d371 100644 +--- a/utils/gssd/gssd.c ++++ b/utils/gssd/gssd.c +@@ -87,6 +87,8 @@ unsigned int context_timeout = 0; + unsigned int rpc_timeout = 5; + char *preferred_realm = NULL; + char *ccachedir = NULL; ++/* set $HOME to "/" by default */ ++static bool set_home = true; + /* Avoid DNS reverse lookups on server names */ + static bool avoid_dns = true; + static bool use_gssproxy = false; +@@ -900,7 +902,7 @@ sig_die(int signal) + static void + usage(char *progname) + { +- fprintf(stderr, "usage: %s [-f] [-l] [-M] [-n] [-v] [-r] [-p pipefsdir] [-k keytab] [-d ccachedir] [-t timeout] [-R preferred realm] [-D]\n", ++ fprintf(stderr, "usage: %s [-f] [-l] [-M] [-n] [-v] [-r] [-p pipefsdir] [-k keytab] [-d ccachedir] [-t timeout] [-R preferred realm] [-D] [-H]\n", + progname); + exit(1); + } +@@ -941,6 +943,7 @@ read_gss_conf(void) + preferred_realm = s; + + use_gssproxy = conf_get_bool("gssd", "use-gss-proxy", use_gssproxy); ++ set_home = conf_get_bool("gssd", "set-home", set_home); + } + + int +@@ -961,7 +964,7 @@ main(int argc, char *argv[]) + verbosity = conf_get_num("gssd", "verbosity", verbosity); + rpc_verbosity = conf_get_num("gssd", "rpc-verbosity", rpc_verbosity); + +- while ((opt = getopt(argc, argv, "DfvrlmnMp:k:d:t:T:R:")) != -1) { ++ while ((opt = getopt(argc, argv, "HDfvrlmnMp:k:d:t:T:R:")) != -1) { + switch (opt) { + case 'f': + fg = 1; +@@ -1009,6 +1012,9 @@ main(int argc, char *argv[]) + case 'D': + avoid_dns = false; + break; ++ case 'H': ++ set_home = false; ++ break; + default: + usage(argv[0]); + break; +@@ -1018,13 +1024,19 @@ main(int argc, char *argv[]) + /* + * Some krb5 routines try to scrape info out of files in the user's + * home directory. This can easily deadlock when that homedir is on a +- * kerberized NFS mount. By setting $HOME unconditionally to "/", we +- * prevent this behavior in routines that use $HOME in preference to +- * the results of getpw*. ++ * kerberized NFS mount. By setting $HOME to "/" by default, we prevent ++ * this behavior in routines that use $HOME in preference to the results ++ * of getpw*. ++ * ++ * Some users do not use Kerberized home dirs and need $HOME to remain ++ * unchanged. Those users can leave $HOME unchanged by setting set_home ++ * to false. + */ +- if (setenv("HOME", "/", 1)) { +- printerr(0, "gssd: Unable to set $HOME: %s\n", strerror(errno)); +- exit(1); ++ if (set_home) { ++ if (setenv("HOME", "/", 1)) { ++ printerr(0, "gssd: Unable to set $HOME: %s\n", strerror(errno)); ++ exit(1); ++ } + } + + if (use_gssproxy) { +diff --git a/utils/gssd/gssd.man b/utils/gssd/gssd.man +index 26095a89..9ae6def9 100644 +--- a/utils/gssd/gssd.man ++++ b/utils/gssd/gssd.man +@@ -8,7 +8,7 @@ + rpc.gssd \- RPCSEC_GSS daemon + .SH SYNOPSIS + .B rpc.gssd +-.RB [ \-DfMnlvr ] ++.RB [ \-DfMnlvrH ] + .RB [ \-k + .IR keytab ] + .RB [ \-p +@@ -282,6 +282,16 @@ The default timeout is set to 5 seconds. + If you get messages like "WARNING: can't create tcp rpc_clnt to server + %servername% for user with uid %uid%: RPC: Remote system error - + Connection timed out", you should consider an increase of this timeout. ++.TP ++.B -H ++Avoids setting $HOME to "/". This allows rpc.gssd to read per user k5identity ++files versus trying to read /.k5identity for each user. ++ ++If ++.B \-H ++is not set, rpc.gssd will use the first match found in ++/var/kerberos/krb5/user/$EUID/client.keytab and will not use a principal based on ++host and/or service parameters listed in $HOME/.k5identity. + .SH CONFIGURATION FILE + Many of the options that can be set on the command line can also be + controlled through values set in the +@@ -339,6 +349,13 @@ Equivalent to + .B preferred-realm + Equivalent to + .BR -R . ++.TP ++.B set-home ++Setting to ++.B false ++is equivalent to providing the ++.B -H ++flag. + .P + In addtion, the following value is recognized from the + .B [general] +diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c +index 612063ba..39e85fd5 100644 +--- a/utils/mountd/mountd.c ++++ b/utils/mountd/mountd.c +@@ -31,6 +31,7 @@ + #include "pseudoflavors.h" + #include "nfsd_path.h" + #include "nfslib.h" ++#include "export.h" + + extern void my_svc_run(void); + +@@ -74,8 +75,12 @@ static struct option longopts[] = + { "reverse-lookup", 0, 0, 'r' }, + { "manage-gids", 0, 0, 'g' }, + { "no-udp", 0, 0, 'u' }, ++ { "log-auth", 0, 0, 'l'}, ++ { "cache-use-ipaddr", 0, 0, 'i'}, ++ { "ttl", 1, 0, 'T'}, + { NULL, 0, 0, 0 } + }; ++static char shortopts[] = "o:nFd:p:P:hH:N:V:vurs:t:gliT:"; + + #define NFSVERSBIT(vers) (0x1 << (vers - 1)) + #define NFSVERSBIT_ALL (NFSVERSBIT(2) | NFSVERSBIT(3) | NFSVERSBIT(4)) +@@ -669,6 +674,7 @@ inline static void + read_mountd_conf(char **argv) + { + char *s; ++ int ttl; + + conf_init_file(NFS_CONFFILE); + +@@ -679,6 +685,8 @@ read_mountd_conf(char **argv) + num_threads = conf_get_num("mountd", "threads", num_threads); + reverse_resolve = conf_get_bool("mountd", "reverse-lookup", reverse_resolve); + ha_callout_prog = conf_get_str("mountd", "ha-callout"); ++ if (conf_get_bool("mountd", "cache-use-ipaddr", 0)) ++ use_ipaddr = 2; + + s = conf_get_str("mountd", "state-directory-path"); + if (s && !state_setup_basedir(argv[0], s)) +@@ -701,6 +709,10 @@ read_mountd_conf(char **argv) + else + NFSCTL_VERUNSET(nfs_version, vers); + } ++ ++ ttl = conf_get_num("mountd", "ttl", default_ttl); ++ if (ttl > 0) ++ default_ttl = ttl; + } + + int +@@ -710,6 +722,7 @@ main(int argc, char **argv) + unsigned int listeners = 0; + int foreground = 0; + int c; ++ int ttl; + struct sigaction sa; + struct rlimit rlim; + +@@ -727,7 +740,7 @@ main(int argc, char **argv) + + /* Parse the command line options and arguments. */ + opterr = 0; +- while ((c = getopt_long(argc, argv, "o:nFd:p:P:hH:N:V:vurs:t:g", longopts, NULL)) != EOF) ++ while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != EOF) + switch (c) { + case 'g': + manage_gids = 1; +@@ -798,6 +811,21 @@ main(int argc, char **argv) + case 'u': + NFSCTL_UDPUNSET(_rpcprotobits); + break; ++ case 'l': ++ xlog_sconfig("auth", 1); ++ break; ++ case 'i': ++ use_ipaddr = 2; ++ break; ++ case 'T': ++ ttl = atoi(optarg); ++ if (ttl <= 0) { ++ fprintf(stderr, "%s: bad ttl number of seconds: %s\n", ++ argv[0], optarg); ++ usage(argv[0], 1); ++ } ++ default_ttl = ttl; ++ break; + case 0: + break; + case '?': +@@ -897,6 +925,7 @@ main(int argc, char **argv) + nfsd_path_init(); + /* Open files now to avoid sharing descriptors among forked processes */ + cache_open(); ++ v4clients_init(); + + xlog(L_NOTICE, "Version " VERSION " starting"); + my_svc_run(); +@@ -913,6 +942,7 @@ usage(const char *prog, int n) + { + fprintf(stderr, + "Usage: %s [-F|--foreground] [-h|--help] [-v|--version] [-d kind|--debug kind]\n" ++" [-l|--log-auth] [-i|--cache-use-ipaddr] [-T|--ttl ttl]\n" + " [-o num|--descriptors num]\n" + " [-p|--port port] [-V version|--nfs-version version]\n" + " [-N version|--no-nfs-version version] [-n|--no-tcp]\n" +diff --git a/utils/mountd/mountd.h b/utils/mountd/mountd.h +index f058f01d..d3077531 100644 +--- a/utils/mountd/mountd.h ++++ b/utils/mountd/mountd.h +@@ -60,9 +60,4 @@ bool ipaddr_client_matches(nfs_export *exp, struct addrinfo *ai); + bool namelist_client_matches(nfs_export *exp, char *dom); + bool client_matches(nfs_export *exp, char *dom, struct addrinfo *ai); + +-static inline bool is_ipaddr_client(char *dom) +-{ +- return dom[0] == '$'; +-} +- + #endif /* MOUNTD_H */ +diff --git a/utils/mountd/mountd.man b/utils/mountd/mountd.man +index 9978afcd..1155cf94 100644 +--- a/utils/mountd/mountd.man ++++ b/utils/mountd/mountd.man +@@ -13,24 +13,24 @@ The + .B rpc.mountd + daemon implements the server side of the NFS MOUNT protocol, + an NFS side protocol used by NFS version 2 [RFC1094] and NFS version 3 [RFC1813]. ++It also responds to requests from the Linux kernel to authenticate ++clients and provides details of access permissions. + .PP +-An NFS server maintains a table of local physical file systems +-that are accessible to NFS clients. +-Each file system in this table is referred to as an +-.IR "exported file system" , +-or +-.IR export , +-for short. +-.PP +-Each file system in the export table has an access control list. +-.B rpc.mountd +-uses these access control lists to determine +-whether an NFS client is permitted to access a given file system. +-For details on how to manage your NFS server's export table, see the +-.BR exports (5) +-and +-.BR exportfs (8) +-man pages. ++The NFS server ++.RI ( nfsd ) ++maintains a cache of authentication and authorization information which ++is used to identify the source of each requent, and then what access ++permissions that source has to any local filesystem. When required ++information is not found in the cache, the server sends a request to ++.B mountd ++to fill in the missing information. Mountd uses a table of information ++stored in ++.B /var/lib/nfs/etab ++and maintained by ++.BR exportfs (8), ++possibly based on the contents of ++.BR exports (5), ++to respond to each request. + .SS Mounting exported NFS File Systems + The NFS MOUNT protocol has several procedures. + The most important of these are +@@ -78,11 +78,69 @@ A client may continue accessing an export even after invoking UMNT. + If the client reboots without sending a UMNT request, stale entries + remain for that client in + .IR /var/lib/nfs/rmtab . ++.SS Mounting File Systems with NFSv4 ++Version 4 (and later) of NFS does not use a separate NFS MOUNT ++protocol. Instead mounting is performed using regular NFS requests ++handled by the NFS server in the Linux kernel ++.RI ( nfsd ). ++Consequently ++.I /var/lib/nfs/rmtab ++is not updated to reflect any NFSv4 activity. + .SH OPTIONS + .TP + .B \-d kind " or " \-\-debug kind + Turn on debugging. Valid kinds are: all, auth, call, general and parse. + .TP ++.BR \-l " or " \-\-log\-auth ++Enable logging of responses to authentication and access requests from ++nfsd. Each response is then cached by the kernel for 30 minutes (or as set by ++.B \-\-ttl ++below), and will be refreshed after 15 minutes (half the ttl time) if ++the relevant client remains active. ++Note that ++.B -l ++is equivalent to ++.B "-d auth" ++and so can be enabled in ++.B /etc/nfs.conf ++with ++.B "\[dq]debug = auth\[dq]" ++in the ++.B "[mountd]" ++section. ++.IP ++.B rpc.mountd ++will always log authentication responses to MOUNT requests when NFSv3 is ++used, but to get similar logs for NFSv4, this option is required. ++.TP ++.BR \-i " or " \-\-cache\-use\-ipaddr ++Normally each client IP address is matched against each host identifier ++(name, wildcard, netgroup etc) found in ++.B /etc/exports ++and a combined identity is formed from all matching identifiers. ++Often many clients will map to the same combined identity so performing ++this mapping reduces the number of distinct access details that the ++kernel needs to store. ++Specifying the ++.B \-i ++option suppresses this mapping so that access to each filesystem is ++requested and cached separately for each client IP address. Doing this ++can increase the burden of updating the cache slightly, but can make the ++log messages produced by the ++.B -l ++option easier to read. ++.TP ++.B \-T " or " \-\-ttl ++Provide a time-to-live (TTL) for cached information given to the kernel. ++The kernel will normally request an update if the information is needed ++after half of this time has expired. Increasing the provided number, ++which is in seconds, reduces the rate of cache update requests, and this ++is particularly noticeable when these requests are logged with ++.BR \-l . ++However increasing also means that changes to hostname to address ++mappings can take longer to be noticed. ++The default TTL is 1800 (30 minutes). ++.TP + .B \-F " or " \-\-foreground + Run in foreground (do not daemonize) + .TP +@@ -213,9 +271,11 @@ Values recognized in the + .B [mountd] + section include + .BR manage-gids , ++.BR cache\-use\-ipaddr , + .BR descriptors , + .BR port , + .BR threads , ++.BR ttl , + .BR reverse-lookup ", and" + .BR state-directory-path , + .B ha-callout +@@ -295,5 +355,9 @@ table of clients accessing server's exports + RFC 1094 - "NFS: Network File System Protocol Specification" + .br + RFC 1813 - "NFS Version 3 Protocol Specification" ++.br ++RFC 7530 - "Network File System (NFS) Version 4 Protocol" ++.br ++RFC 8881 - "Network File System (NFS) Version 4 Minor Version 1 Protocol" + .SH AUTHOR + Olaf Kirch, H. J. Lu, G. Allan Morris III, and a host of others. +diff --git a/utils/mountd/svc_run.c b/utils/mountd/svc_run.c +index 41b96d7f..167b9757 100644 +--- a/utils/mountd/svc_run.c ++++ b/utils/mountd/svc_run.c +@@ -56,10 +56,9 @@ + #ifdef HAVE_LIBTIRPC + #include + #endif ++#include "export.h" + + void my_svc_run(void); +-void cache_set_fds(fd_set *fdset); +-int cache_process_req(fd_set *readfds); + + #if defined(__GLIBC__) && LONG_MAX != INT_MAX + /* bug in glibc 2.3.6 and earlier, we need +@@ -101,6 +100,7 @@ my_svc_run(void) + + readfds = svc_fdset; + cache_set_fds(&readfds); ++ v4clients_set_fds(&readfds); + + selret = select(FD_SETSIZE, &readfds, + (void *) 0, (void *) 0, (struct timeval *) 0); +@@ -116,6 +116,7 @@ my_svc_run(void) + + default: + selret -= cache_process_req(&readfds); ++ selret -= v4clients_process(&readfds); + if (selret) + svc_getreqset(&readfds); + } diff --git a/nfs-utils.spec b/nfs-utils.spec index 8b892f1..7ea0e58 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://linux-nfs.org/ Version: 2.5.3 -Release: 0%{?dist} +Release: 2.rc1%{?dist} Epoch: 1 # group all 32bit related archs @@ -15,6 +15,10 @@ Source3: 24-nfs-server.conf Source4: nfsconvert.py Source5: nfsconvert.sh Source6: nfs-convert.service +Source7: 10-nfsv4.conf + +Patch001: nfs-utils-2.5.4-rc1.patch +Patch002: nfs-utils-2.5.3-rdma-on.patch Patch100: nfs-utils-1.2.1-statdpath-man.patch Patch101: nfs-utils-1.2.1-exp-subtree-warn-off.patch @@ -80,6 +84,28 @@ Requires: rpcbind %description -n nfs-utils-coreos Minimal NFS utilities for supporting clients +%package -n nfs-stats-utils +Summary: NFS utilities for supporting clients +Provides: nfsstat = %{epoch}:%{version}-%{release} +Provides: mountstats = %{epoch}:%{version}-%{release} +Provides: nfsiostat = %{epoch}:%{version}-%{release} + +%description -n nfs-stats-utils +Show NFS client Statistics + +%package -n nfsv4-client-utils +Summary: NFSv4 utilities for supporting client +Provides: rpc.gssd = %{epoch}:%{version}-%{release} +Provides: mount.nfs = %{epoch}:%{version}-%{release} +Provides: mount.nfs4 = %{epoch}:%{version}-%{release} +Provides: umount.nfs = %{epoch}:%{version}-%{release} +Provides: umount.nfs4 = %{epoch}:%{version}-%{release} +Provides: nfsidmap = %{epoch}:%{version}-%{release} +Requires: gssproxy => 0.7.0-3 + +%description -n nfsv4-client-utils +The nfsv4-client-utils packages provided NFSv4 client support + %package -n libnfsidmap Summary: NFSv4 User and Group ID Mapping Library Provides: libnfsidmap%{?_isa} = %{epoch}:%{version}-%{release} @@ -182,6 +208,9 @@ mkdir -p $RPM_BUILD_ROOT%{_sharedstatedir}/nfs/statd/sm.bak mkdir -p $RPM_BUILD_ROOT%{_sharedstatedir}/nfs/v4recovery mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/exports.d +mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/nfsmount.conf.d +install -m 644 %{SOURCE7} $RPM_BUILD_ROOT%{_sysconfdir}/nfsmount.conf.d + %pre # move files so the running service will have this applied as well @@ -240,6 +269,13 @@ fi %systemd_post nfs-server +%post -n nfsv4-client-utils +if [ $1 -eq 1 ] ; then + # Initial installation + /bin/systemctl enable nfs-client.target >/dev/null 2>&1 || : + /bin/systemctl start nfs-client.target >/dev/null 2>&1 || : +fi + %preun if [ $1 -eq 0 ]; then %systemd_preun nfs-client.target @@ -249,10 +285,21 @@ if [ $1 -eq 0 ]; then rm -rf /var/lib/nfs/v4recovery fi +%preun -n nfsv4-client-utils +if [ $1 -eq 0 ]; then + %systemd_preun nfs-client.target + + rm -rf /etc/nfsmount.conf.d + rm -rf /var/lib/nfs/v4recovery +fi + %postun %systemd_postun_with_restart nfs-client.target %systemd_postun_with_restart nfs-server +%postun -n nfsv4-client-utils +%systemd_postun_with_restart nfs-client.target + /bin/systemctl --system daemon-reload >/dev/null 2>&1 || : %triggerin -- nfs-utils > 1:2.1.1-3 @@ -363,7 +410,60 @@ fi %{_pkgdir}/*/rpc_pipefs.target %{_pkgdir}/*/var-lib-nfs-rpc_pipefs.mount +%files -n nfsv4-client-utils +%config(noreplace) /etc/nfsmount.conf +%dir %{_sharedstatedir}/nfs/v4recovery +%dir %attr(555, root, root) %{_sharedstatedir}/nfs/rpc_pipefs +%dir %{_libexecdir}/nfs-utils +%config(noreplace) %{_sysconfdir}/request-key.d/id_resolver.conf +%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/gssproxy/24-nfs-server.conf +%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/nfsmount.conf.d/10-nfsv4.conf +%{_sbindir}/rpc.gssd +%{_sbindir}/nfsidmap +%{_sbindir}/nfsconvert +%{_sbindir}/nfsstat +%attr(755,root,root) %{_libexecdir}/nfs-utils/nfsconvert.sh +%attr(4755,root,root) /sbin/mount.nfs +/sbin/mount.nfs4 +/sbin/umount.nfs +/sbin/umount.nfs4 +%{_mandir}/*/nfs.5.gz +%{_mandir}/*/nfs.conf.5.gz +%{_mandir}/*/nfsmount.conf.5.gz +%{_mandir}/*/gssd.8.gz +%{_mandir}/*/mount.nfs.8.gz +%{_mandir}/*/nfsconf.8.gz +%{_mandir}/*/nfsidmap.8.gz +%{_mandir}/*/rpc.gssd.8.gz +%{_mandir}/*/mount.nfs.8.gz +%{_mandir}/*/umount.nfs.8.gz +%{_mandir}/*/nfsidmap.8.gz +%{_mandir}/*/nfsstat.8.gz +%{_pkgdir}/*/rpc-pipefs-generator +%{_pkgdir}/*/auth-rpcgss-module.service +%{_pkgdir}/*/nfs-client.target +%{_pkgdir}/*/nfs-convert.service +%{_pkgdir}/*/rpc-gssd.service +%{_pkgdir}/*/rpc_pipefs.target +%{_pkgdir}/*/var-lib-nfs-rpc_pipefs.mount + +%files -n nfs-stats-utils +%{_sbindir}/mountstats +%{_sbindir}/nfsiostat +%{_mandir}/*/mountstats.8.gz +%{_mandir}/*/nfsiostat.8.gz + %changelog +* Tue Mar 16 2021 Steve Dickson 2.5.3-3.rc1 +- Enable NFS server RDMA by default (bz 1931565) + +* Mon Mar 15 2021 Steve Dickson 2.5.3-2.rc1 +- Updated to the latest RC release: nfs-utils-2-5-4-rc1 (bz 1939257) + +* Sat Mar 13 2021 Steve Dickson 2.5.3-1 +- Created a V4 only client package +- Broke out the stat cmds using python into a separate package + * Sun Feb 21 2021 Steve Dickson 2.5.3-0 - Updated to latest upstream release: nfs-utils-2-5-3 (bz 1931101)