public inbox for linux-nfs@vger.kernel.org
 help / color / mirror / Atom feed
From: Jeff Layton <jlayton@kernel.org>
To: Steve Dickson <steved@redhat.com>
Cc: Chuck Lever <chuck.lever@oracle.com>, NeilBrown <neil@brown.name>,
	 Olga Kornievskaia <okorniev@redhat.com>,
	Dai Ngo <Dai.Ngo@oracle.com>,  Tom Talpey <tom@talpey.com>,
	Trond Myklebust <trondmy@kernel.org>,
	 Anna Schumaker <anna@kernel.org>,
	linux-nfs@vger.kernel.org,  Jeff Layton <jlayton@kernel.org>
Subject: [PATCH nfs-utils 17/17] mountd/exportd/exportfs: add --no-netlink option to disable netlink
Date: Mon, 16 Mar 2026 11:16:55 -0400	[thread overview]
Message-ID: <20260316-exportd-netlink-v1-17-9a408a0b389d@kernel.org> (raw)
In-Reply-To: <20260316-exportd-netlink-v1-0-9a408a0b389d@kernel.org>

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. For exportfs, it's in the
[exportfs] section.

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 <netlink/genl/genl.h>
 #include <netlink/genl/ctrl.h>
 #include <netlink/msg.h>
@@ -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 04753fa169f97c6b07893613197739ff36e0d09b..9eedb750e316a2ef42bb541d4df4925deeee4874 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


  parent reply	other threads:[~2026-03-16 15:17 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-16 15:16 [PATCH nfs-utils 00/17] exportfs/exportd/mountd: allow them to use netlink for up/downcalls Jeff Layton
2026-03-16 15:16 ` [PATCH nfs-utils 01/17] nfsdctl: move *_netlink.h to support/include/ Jeff Layton
2026-03-16 15:16 ` [PATCH nfs-utils 02/17] support/export: remove unnecessary static variables in nfsd_fh expkey lookup Jeff Layton
2026-03-16 15:16 ` [PATCH nfs-utils 03/17] exportfs: remove obsolete legacy mode documentation from manpage Jeff Layton
2026-03-16 15:16 ` [PATCH nfs-utils 04/17] support/include: update netlink headers for all cache upcalls Jeff Layton
2026-03-16 15:16 ` [PATCH nfs-utils 05/17] build: add libnl3 and netlink header support for exportd and mountd Jeff Layton
2026-03-16 15:16 ` [PATCH nfs-utils 06/17] xlog: claim D_FAC3 as D_NETLINK Jeff Layton
2026-03-16 15:16 ` [PATCH nfs-utils 07/17] exportd/mountd: add netlink support for svc_export cache Jeff Layton
2026-03-16 15:16 ` [PATCH nfs-utils 08/17] exportd/mountd: add netlink support for the nfsd.fh cache Jeff Layton
2026-03-16 15:16 ` [PATCH nfs-utils 09/17] exportd/mountd: add netlink support for the auth.unix.ip cache Jeff Layton
2026-03-16 15:16 ` [PATCH nfs-utils 10/17] exportd/mountd: add netlink support for the auth.unix.gid cache Jeff Layton
2026-03-16 15:16 ` [PATCH nfs-utils 11/17] mountd/exportd: only use /proc interfaces if netlink setup fails Jeff Layton
2026-03-16 15:16 ` [PATCH nfs-utils 12/17] support/export: check for pending requests after opening netlink sockets Jeff Layton
2026-03-16 15:16 ` [PATCH nfs-utils 13/17] exportd/mountd: use cache type from notifications to target scanning Jeff Layton
2026-03-16 15:16 ` [PATCH nfs-utils 14/17] nfsd/sunrpc: add cache flush command and attribute enums Jeff Layton
2026-03-16 15:16 ` [PATCH nfs-utils 15/17] exportfs: add netlink support for cache flush with /proc fallback Jeff Layton
2026-03-16 15:16 ` [PATCH nfs-utils 16/17] exportfs: use netlink to probe kernel support, skip export_test Jeff Layton
2026-03-16 15:16 ` Jeff Layton [this message]
2026-03-16 15:26   ` [PATCH nfs-utils 17/17] mountd/exportd/exportfs: add --no-netlink option to disable netlink Jeff Layton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260316-exportd-netlink-v1-17-9a408a0b389d@kernel.org \
    --to=jlayton@kernel.org \
    --cc=Dai.Ngo@oracle.com \
    --cc=anna@kernel.org \
    --cc=chuck.lever@oracle.com \
    --cc=linux-nfs@vger.kernel.org \
    --cc=neil@brown.name \
    --cc=okorniev@redhat.com \
    --cc=steved@redhat.com \
    --cc=tom@talpey.com \
    --cc=trondmy@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox