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
Subject: Re: [PATCH nfs-utils 17/17] mountd/exportd/exportfs: add --no-netlink option to disable netlink
Date: Mon, 16 Mar 2026 11:26:19 -0400 [thread overview]
Message-ID: <827711a4da6eb44e71dd855904313c49a25939a7.camel@kernel.org> (raw)
In-Reply-To: <20260316-exportd-netlink-v1-17-9a408a0b389d@kernel.org>
On Mon, 2026-03-16 at 11:16 -0400, Jeff Layton wrote:
> 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.
Correction: exportfs doesn't have a section. It will look for the
setting in the mountd and exportd sections. I'll fix up the commit log
in my tree.
>
> 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 ,
--
Jeff Layton <jlayton@kernel.org>
prev parent reply other threads:[~2026-03-16 15:26 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 ` [PATCH nfs-utils 17/17] mountd/exportd/exportfs: add --no-netlink option to disable netlink Jeff Layton
2026-03-16 15:26 ` Jeff Layton [this message]
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=827711a4da6eb44e71dd855904313c49a25939a7.camel@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