From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3478E3D47BF for ; Mon, 30 Mar 2026 13:39:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774877941; cv=none; b=ki0UgN191xeTj0xSLQcFTJgl140UVad23IJP4z7XHIZ/huUjmPFaXsXncS3x7l7hw0zfq4MOo/vF9ZHHiHQfjbZQq5ZrFhZyi+gERlWIXKJCdpJyzZDcdE5b7cmrqpATmMVUVntXzHfQLnwYs3Vid74MpGImxOINJuaZw2Ox/cc= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774877941; c=relaxed/simple; bh=+aWAb97mZVh6HH7pPbEHCb51YhCysPLtJWzPNztzH5I=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=g5cB3KoB9k8rkH0DgDTtu49uSxYq9uyWzg+rf8D7kLpbtaJYXDtXyeRepzIhXU2NWifnLmUeaJ8YqTim6Eteyn1E8SDwDkY+r+IFL3x20cOxzAucaxGqvLdXGQjLznhgjUA25RJgITcyjJ+c5rZa4Ar0PvzYqXm4dQ5kb6qh15w= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=jGyESMpx; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="jGyESMpx" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 233B7C4CEF7; Mon, 30 Mar 2026 13:39:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1774877941; bh=+aWAb97mZVh6HH7pPbEHCb51YhCysPLtJWzPNztzH5I=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=jGyESMpx0YQHLSNFSkEbbukb5gf99XQ3gwrcC0pPoIoj0PbIF0aEXu0qY1I4+q19L JIoJqVLtBJIs9mt5glJY7oQ7j8R+oQarugtZFGZiBKRSxgp9KVYxmdh4UsxvJGWG7n iHmj4jYK+s6WQIJ9p+I7IkSabyoQDuDvNNTDYbxZz0g+MWS6KjdbJ2CIVqxZHpxJQY hqEra2JPL1tVXpz5kaE1g7W+5FwFE+xVLBrjH1JBsfq6DJCFFGMEPeimPRhO985ENv mrrOWQj55NUqpOz+NATr9YPliawfA7//ObshvWRKZoewiwVfrW9YZNtJ9/ZXXuLp6r ptCPVRuX9uVFQ== From: Jeff Layton Date: Mon, 30 Mar 2026 09:38:36 -0400 Subject: [PATCH nfs-utils v2 16/16] mountd/exportd/exportfs: add --no-netlink option to disable netlink Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20260330-exportd-netlink-v2-16-cc9bd5db2408@kernel.org> References: <20260330-exportd-netlink-v2-0-cc9bd5db2408@kernel.org> In-Reply-To: <20260330-exportd-netlink-v2-0-cc9bd5db2408@kernel.org> To: Steve Dickson Cc: Chuck Lever , NeilBrown , Olga Kornievskaia , Dai Ngo , Tom Talpey , Trond Myklebust , Anna Schumaker , linux-nfs@vger.kernel.org, Jeff Layton X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=11999; i=jlayton@kernel.org; h=from:subject:message-id; bh=+aWAb97mZVh6HH7pPbEHCb51YhCysPLtJWzPNztzH5I=; b=owEBbQKS/ZANAwAKAQAOaEEZVoIVAcsmYgBpynzhd8GXMk2U/QDXuNlKzIPSdivajSLFXDJpu 8WNSm1X6eGJAjMEAAEKAB0WIQRLwNeyRHGyoYTq9dMADmhBGVaCFQUCacp84QAKCRAADmhBGVaC FRFFD/9viXjrTJGXDGd1P/Lh5bF0DjVkvTwBGToZsLt14EDKASnm58htMJKP7YcN2st7QkCHZ4p NSRbRVJoik5Uv+ZL8pKrM+fQGNFaceebGzLpKkJoQ6ET5enqKCl3ntMBqWNn4PJXx1ojoqJe9Fy rA7mDHGKfmPF/xrAgz8LZ5DFHvBODy84DvboWORtt2vcfxd3cPXMlaMwswvnUPAdcPTynnhCHal yz72r5vQGvZ2xbY2dFz3FrDa0u9xwuSXjYsR85mbQpyWoURQGrn7Xp1r9DuyN4Crv3Ese8TQFu8 nwQPD9ulhuZ8CwY7rZytVyR0EHsq+8YOo75R8kBoeePOUdaUAmC9BC6gLHYKV2xS1J/U97Hm9em XNrQCe7h/8akBxc3tBqBOl8AbWlnZO+Zb1IlsKeBQhMTWN35TpMsmZc96IA98Lm/5C4nIng6Elr j+/Mxgfr6ZqPieATq/xhOk0ha0+vnP54wplHbuKR3KeHvEiH+dfQfRezz8tLOwwd4G3f+dfCZbm bi7/3+XDABvFqGoUKdgSwZs3NQbdX9fqc+ynMASZz2vat3OPIwv7c9pZ9Sdk3jdMCvd3z3ch4Z2 FnnmWXQWNBbJEB64Qi0AfQO8f+GU/LcqvJYZ6BdAX8Ivx0WELOX3JgSe1iiqVXnDYZDNZGnRVvW Cvb4Gv1MezMu+Ow== X-Developer-Key: i=jlayton@kernel.org; a=openpgp; fpr=4BC0D7B24471B2A184EAF5D3000E684119568215 Add a --no-netlink command-line option (short: -L) and no-netlink= config file setting that disables netlink support, forcing the use of /proc interfaces instead. For mountd and exportd, the setting lives in their respective [mountd] and [exportd] sections of nfs.conf. exportfs will look in either stanza for the setting. This is useful for debugging, testing the /proc fallback path, or working around kernel netlink issues. --- support/export/cache.c | 3 ++- support/export/cache_flush.c | 4 ++- utils/exportd/exportd.c | 10 ++++++-- utils/exportd/exportd.man | 12 +++++++-- utils/exportfs/exportfs.c | 13 +++++++++- utils/exportfs/exportfs.man | 58 ++++++++++++++++++++++++++++++++++++++------ utils/mountd/mountd.c | 9 ++++++- utils/mountd/mountd.man | 9 +++++++ 8 files changed, 102 insertions(+), 16 deletions(-) diff --git a/support/export/cache.c b/support/export/cache.c index 5a2c5760cb5410845971ba831a9ae779d17a6d87..2f128d7db7bd63d86530f0c4003af58327db2c70 100644 --- a/support/export/cache.c +++ b/support/export/cache.c @@ -111,6 +111,7 @@ static bool path_lookup_error(int err) extern int use_ipaddr; extern int manage_gids; +extern int no_netlink; static void auth_unix_ip(int f) { @@ -3064,7 +3065,7 @@ void cache_open(void) { int i; - if (cache_nfsd_nl_open() == 0) { + if (!no_netlink && cache_nfsd_nl_open() == 0) { if (cache_sunrpc_nl_open() == 0) { /* * Check for pending requests, in case any diff --git a/support/export/cache_flush.c b/support/export/cache_flush.c index 7d7f12b212967e5b3d1a2357de07bc3ba5f0b674..ed7b964f9d5372f4accba21254ee9c5f40ffd44d 100644 --- a/support/export/cache_flush.c +++ b/support/export/cache_flush.c @@ -20,6 +20,8 @@ #include "nfslib.h" #include "xlog.h" +extern int no_netlink; + #include #include #include @@ -155,7 +157,7 @@ static void cache_proc_flush(void) void cache_flush(void) { - if (cache_nl_flush() == 0) { + if (!no_netlink && cache_nl_flush() == 0) { xlog(D_NETLINK, "cache flush via netlink succeeded"); return; } diff --git a/utils/exportd/exportd.c b/utils/exportd/exportd.c index a2e370ac506f56d0feab306bd252c32ef58ba009..a08aaaccbc2f2ec8504c53bbf07daf1ac2be0c32 100644 --- a/utils/exportd/exportd.c +++ b/utils/exportd/exportd.c @@ -32,6 +32,7 @@ static int num_threads = 1; #define MAX_THREADS 64 int manage_gids; +int no_netlink; int use_ipaddr = -1; static struct option longopts[] = @@ -40,13 +41,14 @@ static struct option longopts[] = { "debug", 1, 0, 'd' }, { "help", 0, 0, 'h' }, { "manage-gids", 0, 0, 'g' }, + { "no-netlink", 0, 0, 'L' }, { "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:"; +static char shortopts[] = "d:fghs:t:liLT:"; /* * Signal handlers. @@ -109,7 +111,7 @@ usage(const char *prog, int n) "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); +" [-t num|--num-threads=num] [-L|--no-netlink]\n", prog); exit(n); } @@ -124,6 +126,7 @@ read_exportd_conf(char *progname, char **argv) xlog_set_debug(progname); manage_gids = conf_get_bool("exportd", "manage-gids", manage_gids); + no_netlink = conf_get_bool("exportd", "no-netlink", no_netlink); num_threads = conf_get_num("exportd", "threads", num_threads); if (conf_get_bool("mountd", "cache-use-ipaddr", 0)) use_ipaddr = 2; @@ -171,6 +174,9 @@ main(int argc, char **argv) case 'g': manage_gids = 1; break; + case 'L': + no_netlink = 1; + break; case 'h': usage(progname, 0); break; diff --git a/utils/exportd/exportd.man b/utils/exportd/exportd.man index fae434b5f03bfb5a252f1e5c6d7fc8fc2a3f5567..d024868c6471c60f6804f427317a2627cbddb0af 100644 --- a/utils/exportd/exportd.man +++ b/utils/exportd/exportd.man @@ -106,6 +106,13 @@ 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. +.TP +.B \-L " or " \-\-no-netlink +Disable the use of netlink for kernel communication and force the use +of the legacy +.I /proc/net/rpc +interfaces instead. This can be useful for debugging or working around +kernel netlink issues. .SH CONFIGURATION FILE Many of the options that can be set on the command line can also be controlled through values set in the @@ -120,8 +127,9 @@ Values recognized in the section include .B cache\-use\-ipaddr , .BR ttl , -.BR manage-gids ", and" -.B debug +.BR manage-gids , +.BR no\-netlink ", and" +.B debug which each have the same effect as the option with the same name. .SH FILES .TP 2.5i diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c index 1f726746ebc5185ef00a177760fc7a7fa44126c5..93f0bcd7ad56ab7fb57f7a2955687fa8ec7592b4 100644 --- a/utils/exportfs/exportfs.c +++ b/utils/exportfs/exportfs.c @@ -49,6 +49,8 @@ #include "sunrpc_netlink.h" #endif +int no_netlink; + static void export_all(int verbose); static void exportfs(char *arg, char *options, int verbose); static void unexportfs(char *arg, int verbose); @@ -109,8 +111,11 @@ read_exportfs_conf(char **argv) xlog_set_debug("exportfs"); /* NOTE: following uses "mountd" section of nfs.conf !!!! */ + no_netlink = conf_get_bool("mountd", "no-netlink", no_netlink); s = conf_get_str("mountd", "state-directory-path"); /* Also look in the exportd section */ + if (!no_netlink) + no_netlink = conf_get_bool("exportd", "no-netlink", no_netlink); if (s == NULL) s = conf_get_str("exportd", "state-directory-path"); if (s && !state_setup_basedir(argv[0], s)) @@ -145,7 +150,7 @@ main(int argc, char **argv) nfsd_path_init(); - while ((c = getopt(argc, argv, "ad:fhio:ruvs")) != EOF) { + while ((c = getopt(argc, argv, "ad:fhiLo:ruvs")) != EOF) { switch(c) { case 'a': f_all = 1; @@ -162,6 +167,9 @@ main(int argc, char **argv) case 'i': f_ignore = 1; break; + case 'L': + no_netlink = 1; + break; case 'o': options = optarg; break; @@ -500,6 +508,8 @@ static int can_test(void) size_t bufsiz = sizeof(buf); /* Try netlink first: resolve sunrpc genl family */ + if (no_netlink) + goto try_proc; sock = nl_socket_alloc(); if (sock) { if (genl_connect(sock) == 0) { @@ -513,6 +523,7 @@ static int can_test(void) } /* Fallback: /proc probe */ +try_proc: fd = open("/proc/net/rpc/auth.unix.ip/channel", O_WRONLY); if (fd < 0) return 0; diff --git a/utils/exportfs/exportfs.man b/utils/exportfs/exportfs.man index af0e5571cef83d4f3de6915608b4871690a8853a..3737ee81ab275aa65e942ec1602f33a7abbfc80e 100644 --- a/utils/exportfs/exportfs.man +++ b/utils/exportfs/exportfs.man @@ -53,14 +53,41 @@ by using the command. .PP .B exportfs -does not give any information to the kernel directly, but provides it -only to -.B rpc.mountd -through the +does not communicate with the kernel directly. +It writes export information to .I /var/lib/nfs/etab -file. +and relies on its partner programs +.B rpc.mountd +and +.B nfsv4.exportd +to manage kernel communication. +These daemons work in one of two modes: a netlink mode and a +.I /proc +mode. +.PP +In the netlink mode, available on sufficiently recent kernels, .B rpc.mountd -then manages kernel requests for information about exports, as needed. +(or +.BR nfsv4.exportd ) +communicates with the kernel via generic netlink sockets. +The kernel sends multicast notifications when cache entries need to be +resolved, and the daemon responds with the appropriate export +information. +Cache flushing (via +.BR "exportfs \-f" ) +is also performed over netlink. +This mode can be disabled with the +.B \-L +option. +.PP +In the +.I /proc +mode, used when netlink is unavailable, +.B rpc.mountd +manages kernel requests for information about exports +via the +.I /proc/net/rpc +channel files. .SH OPTIONS .TP .B \-d kind " or " \-\-debug kind @@ -123,6 +150,12 @@ options. .TP .B -s Display the current export list suitable for /etc/exports. +.TP +.B -L +Disable the use of netlink for kernel communication and force the use +of the legacy +.I /proc +interfaces for cache flushing and export validation. .SH CONFIGURATION FILE The @@ -142,11 +175,20 @@ When a list is given, the members should be comma-separated. .B exportfs will also recognize the .B state-directory-path -value from both the +and +.B no\-netlink +values from both the .B [mountd] section and the .B [exportd] -section +section. +When +.B no\-netlink +is set, +.B exportfs +will skip the netlink probe and use the legacy +.I /proc +interfaces for cache flushing and export validation .SH DISCUSSION .SS Exporting Directories diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c index 6e6777cd1daa0227f3ff81f826c1cbc8627b4a8a..92d8c4690efc48fcfa12d9618cac9172c4752f4f 100644 --- a/utils/mountd/mountd.c +++ b/utils/mountd/mountd.c @@ -41,6 +41,7 @@ static struct nfs_fh_len *get_rootfh(struct svc_req *, dirpath *, nfs_export **, int reverse_resolve = 0; int manage_gids; +int no_netlink; int apply_root_cred; int use_ipaddr = -1; @@ -72,6 +73,7 @@ static struct option longopts[] = { "num-threads", 1, 0, 't' }, { "reverse-lookup", 0, 0, 'r' }, { "manage-gids", 0, 0, 'g' }, + { "no-netlink", 0, 0, 'L' }, { "no-udp", 0, 0, 'u' }, { "log-auth", 0, 0, 'l'}, { "cache-use-ipaddr", 0, 0, 'i'}, @@ -667,6 +669,7 @@ read_mountd_conf(char **argv) xlog_set_debug("mountd"); manage_gids = conf_get_bool("mountd", "manage-gids", manage_gids); + no_netlink = conf_get_bool("mountd", "no-netlink", no_netlink); descriptors = conf_get_num("mountd", "descriptors", descriptors); port = conf_get_num("mountd", "port", port); num_threads = conf_get_num("mountd", "threads", num_threads); @@ -734,6 +737,9 @@ main(int argc, char **argv) case 'g': manage_gids = 1; break; + case 'L': + no_netlink = 1; + break; case 'o': descriptors = atoi(optarg); if (descriptors <= 0) { @@ -951,6 +957,7 @@ usage(const char *prog, int n) " [-N version|--no-nfs-version version] [-n|--no-tcp]\n" " [-H prog |--ha-callout prog] [-r |--reverse-lookup]\n" " [-s|--state-directory-path path] [-g|--manage-gids]\n" -" [-t num|--num-threads=num] [-u|--no-udp]\n", prog); +" [-t num|--num-threads=num] [-u|--no-udp]\n" +" [-L|--no-netlink]\n", prog); exit(n); } diff --git a/utils/mountd/mountd.man b/utils/mountd/mountd.man index 2fa396c3288f37b1afa247b54a6166ca4f1b5e06..8bec38db131d9f70d1e04a000133023cca955fe1 100644 --- a/utils/mountd/mountd.man +++ b/utils/mountd/mountd.man @@ -284,6 +284,14 @@ the server. Note that the 'primary' group id is not affected so a command on the client will still be effective. This function requires a Linux Kernel with version at least 2.6.21. +.TP +.B \-L " or " \-\-no-netlink +Disable the use of netlink for kernel communication and force the use +of the legacy +.I /proc/net/rpc +interfaces instead. This can be useful for debugging or working around +kernel netlink issues. + .SH CONFIGURATION FILE Many of the options that can be set on the command line can also be controlled through values set in the @@ -297,6 +305,7 @@ Values recognized in the .B [mountd] section include .BR manage-gids , +.BR no\-netlink , .BR cache\-use\-ipaddr , .BR descriptors , .BR port , -- 2.53.0