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
next prev 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