From 630156f57293e2cf6bd5f7d6003fd3e1be985b8d Mon Sep 17 00:00:00 2001 From: Scott Mayhew Date: Tue, 4 Feb 2025 15:01:15 -0500 Subject: [PATCH] version handling fixes for nfsdctl and rpc.nfsd commit 8d98abce41e86f41a4a4512a59bfc9ec55b53f7e Author: Scott Mayhew Date: Fri Jan 17 10:47:40 2025 -0500 nfsd: fix version sanity check commit 03b2e2a15041a3dbb07b8ac06d99800087627843 Author: Scott Mayhew Date: Fri Jan 17 10:41:37 2025 -0500 nfsdctl: tweak the nfs.conf version handling commit 1e8acef8665b6ed32fadfaf71d0f22b966728c6b Author: Scott Mayhew Date: Fri Jan 17 10:36:14 2025 -0500 nfsdctl: tweak the version subcommand behavior Resolves: RHEL-72477 Signed-off-by: Scott Mayhew --- ...-nfsdctl-nfsd-version-handling-fixes.patch | 182 ++++++++++++++++++ nfs-utils.spec | 6 +- 2 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 nfs-utils-2.8.2-nfsdctl-nfsd-version-handling-fixes.patch diff --git a/nfs-utils-2.8.2-nfsdctl-nfsd-version-handling-fixes.patch b/nfs-utils-2.8.2-nfsdctl-nfsd-version-handling-fixes.patch new file mode 100644 index 0000000..538cadf --- /dev/null +++ b/nfs-utils-2.8.2-nfsdctl-nfsd-version-handling-fixes.patch @@ -0,0 +1,182 @@ +diff --git a/utils/nfsd/nfsd.c b/utils/nfsd/nfsd.c +index f787583e..a4056499 100644 +--- a/utils/nfsd/nfsd.c ++++ b/utils/nfsd/nfsd.c +@@ -68,7 +68,7 @@ read_nfsd_conf(void) + int + main(int argc, char **argv) + { +- int count = NFSD_NPROC, c, i, error = 0, portnum, fd, found_one; ++ int count = NFSD_NPROC, c, i, j, error = 0, portnum, fd, found_one; + char *p, *progname, *port, *rdma_port = NULL; + char **haddr = NULL; + char *scope = NULL; +@@ -330,11 +330,30 @@ main(int argc, char **argv) + exit(1); + } + +- /* make sure that at least one version is enabled */ ++ /* ++ * Make sure that at least one version is enabled. Note that we might ++ * need to check the minorvers bit field twice - first while handling ++ * major version 4 in versbits, and again if no major verions were ++ * enabled in versbits. ++ */ + found_one = 0; +- for (c = NFSD_MINVERS; c <= NFSD_MAXVERS; c++) { +- if (NFSCTL_VERISSET(versbits, c)) +- found_one = 1; ++ for (i = NFSD_MINVERS; i <= NFSD_MAXVERS; i++) { ++ if (NFSCTL_VERISSET(versbits, i)) { ++ if (i == 4) { ++ for (j = NFS4_MINMINOR; j <= NFS4_MAXMINOR; j++) { ++ if (NFSCTL_MINORISSET(minorvers, j)) ++ found_one = 1; ++ } ++ } else { ++ found_one = 1; ++ } ++ } ++ } ++ if (!found_one) { ++ for (i = NFS4_MINMINOR; i <= NFS4_MAXMINOR; i++) { ++ if (NFSCTL_MINORISSET(minorvers, i)) ++ found_one = 1; ++ } + } + if (!found_one) { + xlog(L_ERROR, "no version specified"); +diff --git a/utils/nfsdctl/nfsdctl.c b/utils/nfsdctl/nfsdctl.c +index ef917ff0..0e93beda 100644 +--- a/utils/nfsdctl/nfsdctl.c ++++ b/utils/nfsdctl/nfsdctl.c +@@ -754,6 +754,19 @@ static int update_nfsd_version(int major, int minor, bool enabled) + return -EINVAL; + } + ++static int get_max_minorversion(void) ++{ ++ int i, max = 0; ++ ++ for (i = 0; i < MAX_NFS_VERSIONS; ++i) { ++ if (nfsd_versions[i].major == 0) ++ break; ++ if (nfsd_versions[i].major == 4 && nfsd_versions[i].minor > max) ++ max = nfsd_versions[i].minor; ++ } ++ return max; ++} ++ + static void version_usage(void) + { + printf("Usage: %s version { {+,-}major.minor } ...\n", taskname); +@@ -771,7 +784,7 @@ static void version_usage(void) + + static int version_func(struct nl_sock *sock, int argc, char ** argv) + { +- int ret, i; ++ int ret, i, j, max_minor; + + /* help is only valid as first argument after command */ + if (argc > 1 && +@@ -785,6 +798,8 @@ static int version_func(struct nl_sock *sock, int argc, char ** argv) + return ret; + + if (argc > 1) { ++ max_minor = get_max_minorversion(); ++ + for (i = 1; i < argc; ++i) { + int ret, major, minor = 0; + char sign = '\0', *str = argv[i]; +@@ -808,9 +823,22 @@ static int version_func(struct nl_sock *sock, int argc, char ** argv) + return -EINVAL; + } + +- ret = update_nfsd_version(major, minor, enabled); +- if (ret) +- return ret; ++ /* ++ * The minorversion field is optional. If omitted, it should ++ * cause all the minor versions for that major version to be ++ * enabled/disabled. ++ */ ++ if (major == 4 && ret == 2) { ++ for (j = 0; j <= max_minor; ++j) { ++ ret = update_nfsd_version(major, j, enabled); ++ if (ret) ++ return ret; ++ } ++ } else { ++ ret = update_nfsd_version(major, minor, enabled); ++ if (ret) ++ return ret; ++ } + } + return set_nfsd_versions(sock); + } +@@ -1275,15 +1303,47 @@ read_nfsd_conf(void) + xlog_set_debug("nfsd"); + } + +-static void configure_versions(void) ++static int configure_versions(void) + { +- bool v4 = conf_get_bool("nfsd", "vers4", true); ++ int i, j, max_minor = get_max_minorversion(); ++ bool found_one = false; ++ char tag[20]; ++ ++ for (i = 2; i <= 4; ++i) { ++ sprintf(tag, "vers%d", i); ++ if (!conf_get_bool("nfsd", tag, true)) { ++ update_nfsd_version(i, 0, false); ++ if (i == 4) ++ for (j = 0; j <= max_minor; ++j) ++ update_nfsd_version(4, j, false); ++ } ++ if (conf_get_bool("nfsd", tag, false)) { ++ update_nfsd_version(i, 0, true); ++ if (i == 4) ++ for (j = 0; j <= max_minor; ++j) ++ update_nfsd_version(4, j, true); ++ } ++ } ++ ++ for (i = 0; i <= max_minor; ++i) { ++ sprintf(tag, "vers4.%d", i); ++ if (!conf_get_bool("nfsd", tag, true)) ++ update_nfsd_version(4, i, false); ++ if (conf_get_bool("nfsd", tag, false)) ++ update_nfsd_version(4, i, true); ++ } + +- update_nfsd_version(2, 0, conf_get_bool("nfsd", "vers2", false)); +- update_nfsd_version(3, 0, conf_get_bool("nfsd", "vers3", true)); +- update_nfsd_version(4, 0, v4 && conf_get_bool("nfsd", "vers4.0", true)); +- update_nfsd_version(4, 1, v4 && conf_get_bool("nfsd", "vers4.1", true)); +- update_nfsd_version(4, 2, v4 && conf_get_bool("nfsd", "vers4.2", true)); ++ for (i = 0; i < MAX_NFS_VERSIONS; ++i) { ++ if (nfsd_versions[i].enabled) { ++ found_one = true; ++ break; ++ } ++ } ++ if (!found_one) { ++ xlog(L_ERROR, "no version specified"); ++ return 1; ++ } ++ return 0; + } + + static void configure_listeners(void) +@@ -1367,7 +1427,9 @@ static int autostart_func(struct nl_sock *sock, int argc, char ** argv) + ret = fetch_nfsd_versions(sock); + if (ret) + return ret; +- configure_versions(); ++ ret = configure_versions(); ++ if (ret) ++ return ret; + ret = set_nfsd_versions(sock); + if (ret) + return ret; diff --git a/nfs-utils.spec b/nfs-utils.spec index 4e36fca..f2d7efb 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.8.2 -Release: 1%{?dist} +Release: 2%{?dist} Epoch: 1 # group all 32bit related archs @@ -18,6 +18,7 @@ Source4: 10-nfsv4.conf # RHEL10.0 # Patch001: nfs-utils-2.8.2-nfsdcltrack-cleanup.patch +Patch002: nfs-utils-2.8.2-nfsdctl-nfsd-version-handling-fixes.patch Patch100: nfs-utils-1.2.1-statdpath-man.patch Patch102: nfs-utils-1.2.5-idmap-errmsg.patch @@ -432,6 +433,9 @@ rm -rf /etc/systemd/system/rpc-*.requires %{_mandir}/*/nfsiostat.8.gz %changelog +* Tue Feb 4 2025 Scott Mayhew 2.8.2-2 +- version handling fixes for nfsdctl and rpc.nfsd (RHEL-72477) + * Thu Jan 16 2025 Steve Dickson 2.8.2-1 - nfsdcltrack related manpage and configure file cleanup (RHEL-73500)