All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5 V1] exportd: The NFSv4 only mounting daemon.
@ 2021-02-09 21:23 Steve Dickson
  2021-02-09 21:23 ` [PATCH 1/5] exportd: the initial shell of the v4 export support Steve Dickson
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Steve Dickson @ 2021-02-09 21:23 UTC (permalink / raw
  To: Linux NFS Mailing list

exportd is a daemon that will listen for only v4 mount upcalls.
The idea is to allow distros to build a v4 only package
which will have a much smaller footprint than the
entire nfs-utils package.

exportd uses no RPC code, which means none of the 
code or arguments that deal with v3 was ported, 
this again, makes the footprint much smaller. 

The following options were ported:
    * multiple threads
    * state-directory-path option
    * junction support (not tested)

The rest of the mountd options were v3 only options.

Outstanding work that still needs be addressed:
    * Should exportd also process mountd nfs.conf
      sections, that exportd supports? This would 
      make the current nfs.conf sections backward 
      compatible but could cause confusion.

    * How to make the current mountd work injunction
      with exportd. Meaning how to stop mountd from 
      listening for v4 upcalls when exportd is running. 
      This would also allow a v3 only package. It would 
      be nice if this was dynamic verse using a compile 
      switch. Not sure how to do that.

    * Stopping rpc.nfsd from failing when rpc.bind is 
      not running. A nfs.config.d/nfs.conf file was
      used to turned off v3 for testing but that 
      seems a bit clunky.
    
    * The exportd(8) man page could probably used some work.

    * No systemd unit files exists. In theory the only processes
      that would be needed are exportfs, rpc.nfsd and exportd.

Steve Dickson (5):
  exportd: the initial shell of the v4 export support
  exportd: Moved cache upcalls routines into libexport.a
  exportd: multiple threads
  exportd/exportfs: Add the state-directory-path option
  exportd: Enabled junction support

 .gitignore                                |   1 +
 configure.ac                              |   1 +
 nfs.conf                                  |   4 +
 support/export/Makefile.am                |   3 +-
 {utils/mountd => support/export}/auth.c   |   4 +-
 {utils/mountd => support/export}/cache.c  |  46 +++-
 support/export/export.h                   |  34 +++
 {utils/mountd => support/export}/fsloc.c  |   0
 {utils/mountd => support/export}/v4root.c |   0
 {utils/mountd => support/include}/fsloc.h |   0
 systemd/nfs.conf.man                      |  10 +
 utils/Makefile.am                         |   1 +
 utils/exportd/Makefile.am                 |  63 +++++
 utils/exportd/exportd.c                   | 276 ++++++++++++++++++++++
 utils/exportd/exportd.man                 |  81 +++++++
 utils/exportfs/exportfs.c                 |  25 +-
 utils/exportfs/exportfs.man               |   7 +-
 utils/mountd/Makefile.am                  |   5 +-
 18 files changed, 543 insertions(+), 18 deletions(-)
 rename {utils/mountd => support/export}/auth.c (99%)
 rename {utils/mountd => support/export}/cache.c (98%)
 create mode 100644 support/export/export.h
 rename {utils/mountd => support/export}/fsloc.c (100%)
 rename {utils/mountd => support/export}/v4root.c (100%)
 rename {utils/mountd => support/include}/fsloc.h (100%)
 create mode 100644 utils/exportd/Makefile.am
 create mode 100644 utils/exportd/exportd.c
 create mode 100644 utils/exportd/exportd.man

-- 
2.29.2


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/5] exportd: the initial shell of the v4 export support
  2021-02-09 21:23 [PATCH 0/5 V1] exportd: The NFSv4 only mounting daemon Steve Dickson
@ 2021-02-09 21:23 ` Steve Dickson
  2021-02-09 21:23 ` [PATCH 2/5] exportd: Moved cache upcalls routines into libexport.a Steve Dickson
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Steve Dickson @ 2021-02-09 21:23 UTC (permalink / raw
  To: Linux NFS Mailing list

Signed-off-by: Steve Dickson <steved@redhat.com>
---
 .gitignore                |   1 +
 configure.ac              |   1 +
 utils/Makefile.am         |   1 +
 utils/exportd/Makefile.am |  56 ++++++++++++++++++
 utils/exportd/exportd.c   | 121 ++++++++++++++++++++++++++++++++++++++
 utils/exportd/exportd.man |  74 +++++++++++++++++++++++
 6 files changed, 254 insertions(+)
 create mode 100644 utils/exportd/Makefile.am
 create mode 100644 utils/exportd/exportd.c
 create mode 100644 utils/exportd/exportd.man

diff --git a/.gitignore b/.gitignore
index e97b31f..c89d1cd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -47,6 +47,7 @@ utils/idmapd/idmapd
 utils/lockd/lockd
 utils/mount/mount.nfs
 utils/mountd/mountd
+utils/exportd/exportd
 utils/nfsd/nfsd
 utils/nfsstat/nfsstat
 utils/nhfsstone/nhfsstone
diff --git a/configure.ac b/configure.ac
index 50847d8..ffd6247 100644
--- a/configure.ac
+++ b/configure.ac
@@ -706,6 +706,7 @@ AC_CONFIG_FILES([
 	utils/idmapd/Makefile
 	utils/mount/Makefile
 	utils/mountd/Makefile
+	utils/exportd/Makefile
 	utils/nfsd/Makefile
 	utils/nfsref/Makefile
 	utils/nfsstat/Makefile
diff --git a/utils/Makefile.am b/utils/Makefile.am
index 4c930a4..4638e97 100644
--- a/utils/Makefile.am
+++ b/utils/Makefile.am
@@ -34,6 +34,7 @@ endif
 SUBDIRS = \
 	exportfs \
 	mountd \
+	exportd \
 	nfsd \
 	nfsstat \
 	showmount \
diff --git a/utils/exportd/Makefile.am b/utils/exportd/Makefile.am
new file mode 100644
index 0000000..2314d32
--- /dev/null
+++ b/utils/exportd/Makefile.am
@@ -0,0 +1,56 @@
+## Process this file with automake to produce Makefile.in
+
+OPTLIBS     =
+
+man8_MANS   = exportd.man
+EXTRA_DIST  = $(man8_MANS)
+
+sbin_PROGRAMS	=	exportd
+
+exportd_SOURCES = exportd.c 
+exportd_LDADD = ../../support/nfs/libnfs.la
+
+exportd_CPPFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS)
+
+MAINTAINERCLEANFILES = Makefile.in
+
+#######################################################################
+# The following allows the current practice of having
+# daemons renamed during the install to include RPCPREFIX
+# and the KPREFIX
+# This could all be done much easier with program_transform_name
+# ( program_transform_name = s/^/$(RPCPREFIX)$(KPREFIX)/ )
+# but that also renames the man pages, which the current
+# practice does not do.
+install-exec-hook:
+	(cd $(DESTDIR)$(sbindir) && \
+	  for p in $(sbin_PROGRAMS); do \
+	    mv -f $$p$(EXEEXT) $(RPCPREFIX)$(KPREFIX)$$p$(EXEEXT) ;\
+	  done)
+uninstall-hook:
+	(cd $(DESTDIR)$(sbindir) && \
+	  for p in $(sbin_PROGRAMS); do \
+	    rm -f $(RPCPREFIX)$(KPREFIX)$$p$(EXEEXT) ;\
+	  done)
+
+
+# XXX This makes some assumptions about what automake does.
+# XXX But there is no install-man-hook or install-man-local.
+install-man: install-man8 install-man-links
+uninstall-man: uninstall-man8 uninstall-man-links
+
+install-man-links:
+	(cd $(DESTDIR)$(man8dir) && \
+	  for m in $(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS); do \
+	    inst=`echo $$m | sed -e 's/man$$/8/'`; \
+	    rm -f $(RPCPREFIX)$$inst ; \
+	    $(LN_S) $$inst $(RPCPREFIX)$$inst ; \
+	  done)
+
+uninstall-man-links:
+	(cd $(DESTDIR)$(man8dir) && \
+	  for m in $(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS); do \
+	    inst=`echo $$m | sed -e 's/man$$/8/'`; \
+	    rm -f $(RPCPREFIX)$$inst ; \
+	  done)
+
diff --git a/utils/exportd/exportd.c b/utils/exportd/exportd.c
new file mode 100644
index 0000000..53712fa
--- /dev/null
+++ b/utils/exportd/exportd.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2021 Red Hat <nfs@redhat.com>
+ *
+ * support/exportd/exportd.c
+ *
+ * Routines used to support NFSv4 exports
+ *
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stddef.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <getopt.h>
+
+#include "nfslib.h"
+#include "conffile.h"
+
+
+static struct option longopts[] =
+{
+	{ "foreground", 0, 0, 'F' },
+	{ "debug", 1, 0, 'd' },
+	{ "help", 0, 0, 'h' },
+	{ NULL, 0, 0, 0 }
+};
+
+/*
+ * Signal handlers.
+ */
+inline static void set_signals(void);
+
+static void 
+killer (int sig)
+{
+	xlog (L_NOTICE, "Caught signal %d, un-registering and exiting.", sig);
+	exit(0);
+}
+static void
+sig_hup (int UNUSED(sig))
+{
+	/* don't exit on SIGHUP */
+	xlog (L_NOTICE, "Received SIGHUP... Ignoring.\n");
+	return;
+}
+inline static void 
+set_signals(void) 
+{
+	struct sigaction sa;
+
+	sa.sa_handler = SIG_IGN;
+	sa.sa_flags = 0;
+	sigemptyset(&sa.sa_mask);
+	sigaction(SIGPIPE, &sa, NULL);
+	/* WARNING: the following works on Linux and SysV, but not BSD! */
+	sigaction(SIGCHLD, &sa, NULL);
+
+	sa.sa_handler = killer;
+	sigaction(SIGINT, &sa, NULL);
+	sigaction(SIGTERM, &sa, NULL);
+
+	sa.sa_handler = sig_hup;
+	sigaction(SIGHUP, &sa, NULL);
+}
+static void
+usage(const char *prog, int n)
+{
+	fprintf(stderr,
+		"Usage: %s [-f|--foreground] [-h|--help] [-d kind|--debug kind]\n", prog);
+	exit(n);
+}
+
+int
+main(int argc, char **argv)
+{
+	char *progname;
+	int	foreground = 0;
+	int	 c;
+
+	/* Set the basename */
+	if ((progname = strrchr(argv[0], '/')) != NULL)
+		progname++;
+	else
+		progname = argv[0];
+
+	/* Initialize logging. */
+	xlog_open(progname);
+
+	conf_init_file(NFS_CONFFILE);
+	xlog_from_conffile(progname);
+
+	while ((c = getopt_long(argc, argv, "d:fh", longopts, NULL)) != EOF) {
+		switch (c) {
+		case 'd':
+			xlog_sconfig(optarg, 1);
+			break;
+		case 'f':
+			foreground++;
+			break;
+		case 'h':
+			usage(progname, 0);
+			break;
+		case '?':
+		default:
+			usage(progname, 1);
+		}
+
+	}
+
+	if (!foreground) 
+		xlog_stderr(0);
+
+	daemon_init(foreground);
+
+	set_signals();
+	
+	daemon_ready();
+}
diff --git a/utils/exportd/exportd.man b/utils/exportd/exportd.man
new file mode 100644
index 0000000..96e133c
--- /dev/null
+++ b/utils/exportd/exportd.man
@@ -0,0 +1,74 @@
+.\"@(#)exportd.8"
+.\"
+.\" Copyright (C) 2021 Red Hat <nfs@redhat.com>
+.\"
+.TH exportd 8 "02 Feb 2021"
+.SH NAME
+exportd \- NFSv4 Server Mount Daemon
+.SH SYNOPSIS
+.BI "/usr/sbin/exportd [" options "]"
+.SH DESCRIPTION
+The
+.B exportd
+is used to manage NFSv4 exports. The NFSv4 server
+receives a mount request from a client and pass it up to 
+.B exportd. 
+.B exportd 
+then uses the exports(5) export
+table to verify the validity of the mount request.
+.PP
+An NFS server maintains a table of local physical file systems
+that are accessible to NFS clients.
+Each file system in this table is referred to as an
+.IR "exported file system" ,
+or
+.IR export ,
+for short.
+.PP
+Each file system in the export table has an access control list.
+.B exportd
+uses these access control lists to determine
+whether an NFS client is permitted to access a given file system.
+For details on how to manage your NFS server's export table, see the
+.BR exports (5)
+and
+.BR exportfs (8)
+man pages.
+.SH OPTIONS
+.TP
+.B \-d kind " or " \-\-debug kind
+Turn on debugging. Valid kinds are: all, auth, call, general and parse.
+.TP
+.B \-F " or " \-\-foreground
+Run in foreground (do not daemonize)
+.TP
+.B \-h " or " \-\-help
+Display usage message.
+.SH CONFIGURATION FILE
+Many of the options that can be set on the command line can also be
+controlled through values set in the
+.B [exportd]
+or, in some cases, the
+.B [nfsd]
+sections of the
+.I /etc/nfs.conf
+configuration file.
+Values recognized in the
+.B [exportd]
+section include 
+.B debug 
+which each have the same effect as the option with the same name.
+.SH FILES
+.TP 2.5i
+.I /etc/exports
+input file for
+.BR exportfs ,
+listing exports, export options, and access control lists
+.SH SEE ALSO
+.BR exportfs (8),
+.BR exports (5),
+.BR showmount (8),
+.BR nfs.conf (5),
+.BR firwall-cmd (1),
+.sp
+RFC 3530 - "Network File System (NFS) version 4 Protocol"
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/5] exportd: Moved cache upcalls routines into libexport.a
  2021-02-09 21:23 [PATCH 0/5 V1] exportd: The NFSv4 only mounting daemon Steve Dickson
  2021-02-09 21:23 ` [PATCH 1/5] exportd: the initial shell of the v4 export support Steve Dickson
@ 2021-02-09 21:23 ` Steve Dickson
  2021-02-09 21:23 ` [PATCH 3/5] exportd: multiple threads Steve Dickson
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Steve Dickson @ 2021-02-09 21:23 UTC (permalink / raw
  To: Linux NFS Mailing list

Move the cache management code into libexport.a
so both mountd and exportd can use it.

Introduce cache_proccess_loop() which will
be used by exportd, instead of my_svc_run().

Signed-off-by: Steve Dickson <steved@redhat.com>
---
 support/export/Makefile.am                |  3 +-
 {utils/mountd => support/export}/auth.c   |  4 +-
 {utils/mountd => support/export}/cache.c  | 46 +++++++++++++++++++++--
 support/export/export.h                   | 34 +++++++++++++++++
 {utils/mountd => support/export}/v4root.c |  0
 utils/exportd/Makefile.am                 | 12 ++++--
 utils/exportd/exportd.c                   | 30 ++++++++++++++-
 utils/mountd/Makefile.am                  |  4 +-
 8 files changed, 120 insertions(+), 13 deletions(-)
 rename {utils/mountd => support/export}/auth.c (99%)
 rename {utils/mountd => support/export}/cache.c (98%)
 create mode 100644 support/export/export.h
 rename {utils/mountd => support/export}/v4root.c (100%)

diff --git a/support/export/Makefile.am b/support/export/Makefile.am
index 13f7a49..7de82a8 100644
--- a/support/export/Makefile.am
+++ b/support/export/Makefile.am
@@ -11,7 +11,8 @@ EXTRA_DIST	= mount.x
 
 noinst_LIBRARIES = libexport.a
 libexport_a_SOURCES = client.c export.c hostname.c \
-		      xtab.c mount_clnt.c mount_xdr.c
+		      xtab.c mount_clnt.c mount_xdr.c \
+			  cache.c auth.c v4root.c
 BUILT_SOURCES 	= $(GENFILES)
 
 noinst_HEADERS = mount.h
diff --git a/utils/mountd/auth.c b/support/export/auth.c
similarity index 99%
rename from utils/mountd/auth.c
rename to support/export/auth.c
index 67627f7..0bfa77d 100644
--- a/utils/mountd/auth.c
+++ b/support/export/auth.c
@@ -22,7 +22,7 @@
 #include "misc.h"
 #include "nfslib.h"
 #include "exportfs.h"
-#include "mountd.h"
+#include "export.h"
 #include "v4root.h"
 
 enum auth_error
@@ -43,11 +43,13 @@ extern int use_ipaddr;
 
 extern struct state_paths etab;
 
+/*
 void
 auth_init(void)
 {
 	auth_reload();
 }
+*/
 
 /*
  * A client can match many different netgroups and it's tough to know
diff --git a/utils/mountd/cache.c b/support/export/cache.c
similarity index 98%
rename from utils/mountd/cache.c
rename to support/export/cache.c
index a81e820..f1569af 100644
--- a/utils/mountd/cache.c
+++ b/support/export/cache.c
@@ -30,11 +30,14 @@
 #include "nfsd_path.h"
 #include "nfslib.h"
 #include "exportfs.h"
-#include "mountd.h"
-#include "fsloc.h"
+#include "export.h"
 #include "pseudoflavors.h"
 #include "xcommon.h"
 
+#ifdef HAVE_JUNCTION_SUPPORT
+#include "fsloc.h"
+#endif
+
 #ifdef USE_BLKID
 #include "blkid/blkid.h"
 #endif
@@ -44,6 +47,7 @@
  */
 void	cache_set_fds(fd_set *fdset);
 int	cache_process_req(fd_set *readfds);
+void cache_process_loop(void);
 
 enum nfsd_fsid {
 	FSID_DEV = 0,
@@ -909,6 +913,7 @@ out:
 	xlog(D_CALL, "nfsd_fh: found %p path %s", found, found ? found->e_path : NULL);
 }
 
+#ifdef HAVE_JUNCTION_SUPPORT
 static void write_fsloc(char **bp, int *blen, struct exportent *ep)
 {
 	struct servers *servers;
@@ -931,7 +936,7 @@ static void write_fsloc(char **bp, int *blen, struct exportent *ep)
 	qword_addint(bp, blen, servers->h_referral);
 	release_replicas(servers);
 }
-
+#endif
 static void write_secinfo(char **bp, int *blen, struct exportent *ep, int flag_mask)
 {
 	struct sec_entry *p;
@@ -974,7 +979,10 @@ static int dump_to_cache(int f, char *buf, int blen, char *domain,
 		qword_addint(&bp, &blen, exp->e_anonuid);
 		qword_addint(&bp, &blen, exp->e_anongid);
 		qword_addint(&bp, &blen, exp->e_fsid);
+
+#ifdef HAVE_JUNCTION_SUPPORT
 		write_fsloc(&bp, &blen, exp);
+#endif
 		write_secinfo(&bp, &blen, exp, flag_mask);
 		if (exp->e_uuid == NULL || different_fs) {
 			char u[16];
@@ -1509,6 +1517,38 @@ int cache_process_req(fd_set *readfds)
 	return cnt;
 }
 
+/**
+ * cache_process_loop - process incoming upcalls
+ */
+void cache_process_loop(void)
+{
+	fd_set	readfds;
+	int	selret;
+
+	FD_ZERO(&readfds);
+
+	for (;;) {
+
+		cache_set_fds(&readfds);
+
+		selret = select(FD_SETSIZE, &readfds,
+				(void *) 0, (void *) 0, (struct timeval *) 0);
+
+
+		switch (selret) {
+		case -1:
+			if (errno == EINTR || errno == ECONNREFUSED
+			 || errno == ENETUNREACH || errno == EHOSTUNREACH)
+				continue;
+			xlog(L_ERROR, "my_svc_run() - select: %m");
+			return;
+
+		default:
+			cache_process_req(&readfds);
+		}
+	}
+}
+
 
 /*
  * Give IP->domain and domain+path->options to kernel
diff --git a/support/export/export.h b/support/export/export.h
new file mode 100644
index 0000000..4296db1
--- /dev/null
+++ b/support/export/export.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2021 Red Hat <nfs@redhat.com>
+ *
+ * support/export/export.h
+ *
+ * Declarations for export support 
+ */
+
+#ifndef EXPORT_H
+#define EXPORT_H
+
+#include "nfslib.h"
+
+unsigned int	auth_reload(void);
+nfs_export *	auth_authenticate(const char *what,
+					const struct sockaddr *caller,
+					const char *path);
+
+void		cache_open(void);
+void		cache_process_loop(void);
+
+struct nfs_fh_len *
+		cache_get_filehandle(nfs_export *exp, int len, char *p);
+int		cache_export(nfs_export *exp, char *path);
+
+bool ipaddr_client_matches(nfs_export *exp, struct addrinfo *ai);
+bool namelist_client_matches(nfs_export *exp, char *dom);
+bool client_matches(nfs_export *exp, char *dom, struct addrinfo *ai);
+
+static inline bool is_ipaddr_client(char *dom)
+{
+	return dom[0] == '$';
+}
+#endif /* EXPORT__H */
diff --git a/utils/mountd/v4root.c b/support/export/v4root.c
similarity index 100%
rename from utils/mountd/v4root.c
rename to support/export/v4root.c
diff --git a/utils/exportd/Makefile.am b/utils/exportd/Makefile.am
index 2314d32..0fcd92f 100644
--- a/utils/exportd/Makefile.am
+++ b/utils/exportd/Makefile.am
@@ -7,10 +7,14 @@ EXTRA_DIST  = $(man8_MANS)
 
 sbin_PROGRAMS	=	exportd
 
-exportd_SOURCES = exportd.c 
-exportd_LDADD = ../../support/nfs/libnfs.la
-
-exportd_CPPFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS)
+exportd_SOURCES = exportd.c
+exportd_LDADD = ../../support/export/libexport.a \
+			../../support/nfs/libnfs.la \
+			../../support/misc/libmisc.a \
+			$(OPTLIBS) $(LIBBLKID) $(LIBPTHREAD) 
+
+exportd_CPPFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS) \
+		-I$(top_srcdir)/support/export
 
 MAINTAINERCLEANFILES = Makefile.in
 
diff --git a/utils/exportd/exportd.c b/utils/exportd/exportd.c
index 53712fa..150938c 100644
--- a/utils/exportd/exportd.c
+++ b/utils/exportd/exportd.c
@@ -18,7 +18,16 @@
 
 #include "nfslib.h"
 #include "conffile.h"
+#include "exportfs.h"
+#include "export.h"
 
+extern void my_svc_run(void);
+
+struct state_paths etab;
+struct state_paths rmtab;
+
+int manage_gids;
+int use_ipaddr = -1;
 
 static struct option longopts[] =
 {
@@ -36,7 +45,7 @@ inline static void set_signals(void);
 static void 
 killer (int sig)
 {
-	xlog (L_NOTICE, "Caught signal %d, un-registering and exiting.", sig);
+	xlog (L_NOTICE, "Caught signal %d, exiting.", sig);
 	exit(0);
 }
 static void
@@ -110,12 +119,29 @@ main(int argc, char **argv)
 
 	}
 
+	if (!setup_state_path_names(progname, ETAB, ETABTMP, ETABLCK, &etab))
+		return 1;
+	if (!setup_state_path_names(progname, RMTAB, RMTABTMP, RMTABLCK, &rmtab))
+		return 1;
+
 	if (!foreground) 
 		xlog_stderr(0);
 
 	daemon_init(foreground);
 
 	set_signals();
-	
 	daemon_ready();
+
+	/* Open files now to avoid sharing descriptors among forked processes */
+	cache_open();
+
+	/* Process incoming upcalls */
+	cache_process_loop();
+
+	xlog(L_ERROR, "%s: process loop terminated unexpectedly. Exiting...\n",
+		progname);
+
+	free_state_path_names(&etab);
+	free_state_path_names(&rmtab);
+	exit(1);
 }
diff --git a/utils/mountd/Makefile.am b/utils/mountd/Makefile.am
index 18610f1..cac3275 100644
--- a/utils/mountd/Makefile.am
+++ b/utils/mountd/Makefile.am
@@ -13,8 +13,8 @@ KPREFIX		= @kprefix@
 sbin_PROGRAMS	= mountd
 
 noinst_HEADERS = fsloc.h
-mountd_SOURCES = mountd.c mount_dispatch.c auth.c rmtab.c cache.c \
-		 svc_run.c fsloc.c v4root.c mountd.h
+mountd_SOURCES = mountd.c mount_dispatch.c rmtab.c \
+		 svc_run.c fsloc.c mountd.h
 mountd_LDADD = ../../support/export/libexport.a \
 	       ../../support/nfs/libnfs.la \
 	       ../../support/misc/libmisc.a \
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/5] exportd: multiple threads
  2021-02-09 21:23 [PATCH 0/5 V1] exportd: The NFSv4 only mounting daemon Steve Dickson
  2021-02-09 21:23 ` [PATCH 1/5] exportd: the initial shell of the v4 export support Steve Dickson
  2021-02-09 21:23 ` [PATCH 2/5] exportd: Moved cache upcalls routines into libexport.a Steve Dickson
@ 2021-02-09 21:23 ` Steve Dickson
  2021-02-09 21:23 ` [PATCH 4/5] exportd/exportfs: Add the state-directory-path option Steve Dickson
  2021-02-09 21:23 ` [PATCH 5/5] exportd: Enabled junction support Steve Dickson
  4 siblings, 0 replies; 6+ messages in thread
From: Steve Dickson @ 2021-02-09 21:23 UTC (permalink / raw
  To: Linux NFS Mailing list

Ported the multiple thread code from mountd (commit 11d34d11)

Signed-off-by: Steve Dickson <steved@redhat.com>
---
 nfs.conf                  |   3 +
 systemd/nfs.conf.man      |   9 +++
 utils/exportd/exportd.c   | 118 ++++++++++++++++++++++++++++++++++++--
 utils/exportd/exportd.man |   7 +++
 4 files changed, 133 insertions(+), 4 deletions(-)

diff --git a/nfs.conf b/nfs.conf
index 9fcf1bf..4b344fa 100644
--- a/nfs.conf
+++ b/nfs.conf
@@ -29,6 +29,9 @@
 # port=0
 # udp-port=0
 #
+[exportd]
+# debug="all|auth|call|general|parse"
+# threads=1
 [mountd]
 # debug="all|auth|call|general|parse"
 # manage-gids=n
diff --git a/systemd/nfs.conf.man b/systemd/nfs.conf.man
index 16e0ec4..a4379fd 100644
--- a/systemd/nfs.conf.man
+++ b/systemd/nfs.conf.man
@@ -128,6 +128,15 @@ then the client will be able to mount the path as
 but on the server, this will resolve to the path
 .BR /my/root/filesystem .
 
+.TP
+.B exportd
+Recognized values:
+.B threads
+
+See
+.BR exportd (8)
+for details.
+
 .TP
 .B nfsdcltrack
 Recognized values:
diff --git a/utils/exportd/exportd.c b/utils/exportd/exportd.c
index 150938c..bf5f431 100644
--- a/utils/exportd/exportd.c
+++ b/utils/exportd/exportd.c
@@ -15,6 +15,8 @@
 #include <signal.h>
 #include <string.h>
 #include <getopt.h>
+#include <errno.h>
+#include <wait.h>
 
 #include "nfslib.h"
 #include "conffile.h"
@@ -26,6 +28,13 @@ extern void my_svc_run(void);
 struct state_paths etab;
 struct state_paths rmtab;
 
+/* Number of mountd threads to start.   Default is 1 and
+ * that's probably enough unless you need hundreds of
+ * clients to be able to mount at once.  */
+static int num_threads = 1;
+/* Arbitrary limit on number of threads */
+#define MAX_THREADS 64
+
 int manage_gids;
 int use_ipaddr = -1;
 
@@ -34,6 +43,7 @@ static struct option longopts[] =
 	{ "foreground", 0, 0, 'F' },
 	{ "debug", 1, 0, 'd' },
 	{ "help", 0, 0, 'h' },
+	{ "num-threads", 1, 0, 't' },
 	{ NULL, 0, 0, 0 }
 };
 
@@ -42,10 +52,85 @@ static struct option longopts[] =
  */
 inline static void set_signals(void);
 
+/* Wait for all worker child processes to exit and reap them */
+static void
+wait_for_workers (void)
+{
+	int status;
+	pid_t pid;
+
+	for (;;) {
+
+		pid = waitpid(0, &status, 0);
+
+		if (pid < 0) {
+			if (errno == ECHILD)
+				return; /* no more children */
+			xlog(L_FATAL, "mountd: can't wait: %s\n",
+					strerror(errno));
+		}
+
+		/* Note: because we SIG_IGN'd SIGCHLD earlier, this
+		 * does not happen on 2.6 kernels, and waitpid() blocks
+		 * until all the children are dead then returns with
+		 * -ECHILD.  But, we don't need to do anything on the
+		 * death of individual workers, so we don't care. */
+		xlog(L_NOTICE, "mountd: reaped child %d, status %d\n",
+				(int)pid, status);
+	}
+}
+
+/* Fork num_threads worker children and wait for them */
+static void
+fork_workers(void)
+{
+	int i;
+	pid_t pid;
+
+	xlog(L_NOTICE, "mountd: starting %d threads\n", num_threads);
+
+	for (i = 0 ; i < num_threads ; i++) {
+		pid = fork();
+		if (pid < 0) {
+			xlog(L_FATAL, "mountd: cannot fork: %s\n",
+					strerror(errno));
+		}
+		if (pid == 0) {
+			/* worker child */
+
+			/* Re-enable the default action on SIGTERM et al
+			 * so that workers die naturally when sent them.
+			 * Only the parent unregisters with pmap and
+			 * hence needs to do special SIGTERM handling. */
+			struct sigaction sa;
+			sa.sa_handler = SIG_DFL;
+			sa.sa_flags = 0;
+			sigemptyset(&sa.sa_mask);
+			sigaction(SIGHUP, &sa, NULL);
+			sigaction(SIGINT, &sa, NULL);
+			sigaction(SIGTERM, &sa, NULL);
+
+			/* fall into my_svc_run in caller */
+			return;
+		}
+	}
+
+	/* in parent */
+	wait_for_workers();
+	xlog(L_NOTICE, "exportd: no more workers, exiting\n");
+	exit(0);
+}
+
 static void 
 killer (int sig)
 {
+	if (num_threads > 1) {
+		/* play Kronos and eat our children */
+		kill(0, SIGTERM);
+		wait_for_workers();
+	}
 	xlog (L_NOTICE, "Caught signal %d, exiting.", sig);
+
 	exit(0);
 }
 static void
@@ -78,10 +163,20 @@ static void
 usage(const char *prog, int n)
 {
 	fprintf(stderr,
-		"Usage: %s [-f|--foreground] [-h|--help] [-d kind|--debug kind]\n", prog);
+		"Usage: %s [-f|--foreground] [-h|--help] [-d kind|--debug kind]\n"
+"	[-t num|--num-threads=num]\n", prog);
 	exit(n);
 }
 
+inline static void 
+read_exportd_conf(char *progname)
+{
+	conf_init_file(NFS_CONFFILE);
+
+	xlog_from_conffile(progname);
+
+	num_threads = conf_get_num("exportd", "threads", num_threads);
+}
 int
 main(int argc, char **argv)
 {
@@ -98,10 +193,10 @@ main(int argc, char **argv)
 	/* Initialize logging. */
 	xlog_open(progname);
 
-	conf_init_file(NFS_CONFFILE);
-	xlog_from_conffile(progname);
+	/* Read in config setting */
+	read_exportd_conf(progname);
 
-	while ((c = getopt_long(argc, argv, "d:fh", longopts, NULL)) != EOF) {
+	while ((c = getopt_long(argc, argv, "d:fht:", longopts, NULL)) != EOF) {
 		switch (c) {
 		case 'd':
 			xlog_sconfig(optarg, 1);
@@ -112,6 +207,9 @@ main(int argc, char **argv)
 		case 'h':
 			usage(progname, 0);
 			break;
+		case 't':
+			num_threads = atoi (optarg);
+			break;
 		case '?':
 		default:
 			usage(progname, 1);
@@ -132,6 +230,18 @@ main(int argc, char **argv)
 	set_signals();
 	daemon_ready();
 
+	/* silently bounds check num_threads */
+	if (foreground)
+		num_threads = 1;
+	else if (num_threads < 1)
+		num_threads = 1;
+	else if (num_threads > MAX_THREADS)
+		num_threads = MAX_THREADS;
+
+	if (num_threads > 1)
+		fork_workers();
+
+
 	/* Open files now to avoid sharing descriptors among forked processes */
 	cache_open();
 
diff --git a/utils/exportd/exportd.man b/utils/exportd/exportd.man
index 96e133c..fae47d0 100644
--- a/utils/exportd/exportd.man
+++ b/utils/exportd/exportd.man
@@ -44,6 +44,13 @@ Run in foreground (do not daemonize)
 .TP
 .B \-h " or " \-\-help
 Display usage message.
+.TP
+.BR "\-t N" " or " "\-\-num\-threads=N " or  " \-\-num\-threads N "
+This option specifies the number of worker threads that rpc.mountd
+spawns.  The default is 1 thread, which is probably enough.  More
+threads are usually only needed for NFS servers which need to handle
+mount storms of hundreds of NFS mounts in a few seconds, or when
+your DNS server is slow or unreliable.
 .SH CONFIGURATION FILE
 Many of the options that can be set on the command line can also be
 controlled through values set in the
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/5] exportd/exportfs: Add the state-directory-path option
  2021-02-09 21:23 [PATCH 0/5 V1] exportd: The NFSv4 only mounting daemon Steve Dickson
                   ` (2 preceding siblings ...)
  2021-02-09 21:23 ` [PATCH 3/5] exportd: multiple threads Steve Dickson
@ 2021-02-09 21:23 ` Steve Dickson
  2021-02-09 21:23 ` [PATCH 5/5] exportd: Enabled junction support Steve Dickson
  4 siblings, 0 replies; 6+ messages in thread
From: Steve Dickson @ 2021-02-09 21:23 UTC (permalink / raw
  To: Linux NFS Mailing list

Ported state-directory-path option from mountd (commit a15bd948)
Signed-off-by: Steve Dickson <steved@redhat.com>
---
 nfs.conf                    |  1 +
 systemd/nfs.conf.man        |  3 ++-
 utils/exportd/exportd.c     | 35 +++++++++++++++++++++++++++--------
 utils/exportfs/exportfs.c   | 25 +++++++++++++++++--------
 utils/exportfs/exportfs.man |  7 +++++--
 5 files changed, 52 insertions(+), 19 deletions(-)

diff --git a/nfs.conf b/nfs.conf
index 4b344fa..bebb2e3 100644
--- a/nfs.conf
+++ b/nfs.conf
@@ -31,6 +31,7 @@
 #
 [exportd]
 # debug="all|auth|call|general|parse"
+# state-directory-path=/var/lib/nfs
 # threads=1
 [mountd]
 # debug="all|auth|call|general|parse"
diff --git a/systemd/nfs.conf.man b/systemd/nfs.conf.man
index a4379fd..d2187f8 100644
--- a/systemd/nfs.conf.man
+++ b/systemd/nfs.conf.man
@@ -131,7 +131,8 @@ but on the server, this will resolve to the path
 .TP
 .B exportd
 Recognized values:
-.B threads
+.BR threads ,
+.BR state-directory-path
 
 See
 .BR exportd (8)
diff --git a/utils/exportd/exportd.c b/utils/exportd/exportd.c
index bf5f431..be6a2a5 100644
--- a/utils/exportd/exportd.c
+++ b/utils/exportd/exportd.c
@@ -26,7 +26,6 @@
 extern void my_svc_run(void);
 
 struct state_paths etab;
-struct state_paths rmtab;
 
 /* Number of mountd threads to start.   Default is 1 and
  * that's probably enough unless you need hundreds of
@@ -80,6 +79,12 @@ wait_for_workers (void)
 	}
 }
 
+inline void
+cleanup_lockfiles (void)
+{
+	unlink(etab.lockfn);
+}
+
 /* Fork num_threads worker children and wait for them */
 static void
 fork_workers(void)
@@ -117,6 +122,8 @@ fork_workers(void)
 
 	/* in parent */
 	wait_for_workers();
+	cleanup_lockfiles();
+	free_state_path_names(&etab);
 	xlog(L_NOTICE, "exportd: no more workers, exiting\n");
 	exit(0);
 }
@@ -129,6 +136,8 @@ killer (int sig)
 		kill(0, SIGTERM);
 		wait_for_workers();
 	}
+	cleanup_lockfiles();
+	free_state_path_names(&etab);
 	xlog (L_NOTICE, "Caught signal %d, exiting.", sig);
 
 	exit(0);
@@ -159,24 +168,33 @@ set_signals(void)
 	sa.sa_handler = sig_hup;
 	sigaction(SIGHUP, &sa, NULL);
 }
+
 static void
 usage(const char *prog, int n)
 {
 	fprintf(stderr,
 		"Usage: %s [-f|--foreground] [-h|--help] [-d kind|--debug kind]\n"
+"	[-s|--state-directory-path path]\n"
 "	[-t num|--num-threads=num]\n", prog);
 	exit(n);
 }
 
 inline static void 
-read_exportd_conf(char *progname)
+read_exportd_conf(char *progname, char **argv)
 {
+	char *s;
+
 	conf_init_file(NFS_CONFFILE);
 
 	xlog_from_conffile(progname);
 
 	num_threads = conf_get_num("exportd", "threads", num_threads);
+
+	s = conf_get_str("exportd", "state-directory-path");
+	if (s && !state_setup_basedir(argv[0], s))
+		exit(1);
 }
+
 int
 main(int argc, char **argv)
 {
@@ -194,9 +212,9 @@ main(int argc, char **argv)
 	xlog_open(progname);
 
 	/* Read in config setting */
-	read_exportd_conf(progname);
+	read_exportd_conf(progname, argv);
 
-	while ((c = getopt_long(argc, argv, "d:fht:", longopts, NULL)) != EOF) {
+	while ((c = getopt_long(argc, argv, "d:fhs:t:", longopts, NULL)) != EOF) {
 		switch (c) {
 		case 'd':
 			xlog_sconfig(optarg, 1);
@@ -207,6 +225,10 @@ main(int argc, char **argv)
 		case 'h':
 			usage(progname, 0);
 			break;
+		case 's':
+			if (!state_setup_basedir(argv[0], optarg))
+				exit(1);
+			break;
 		case 't':
 			num_threads = atoi (optarg);
 			break;
@@ -219,9 +241,7 @@ main(int argc, char **argv)
 
 	if (!setup_state_path_names(progname, ETAB, ETABTMP, ETABLCK, &etab))
 		return 1;
-	if (!setup_state_path_names(progname, RMTAB, RMTABTMP, RMTABLCK, &rmtab))
-		return 1;
-
+	
 	if (!foreground) 
 		xlog_stderr(0);
 
@@ -252,6 +272,5 @@ main(int argc, char **argv)
 		progname);
 
 	free_state_path_names(&etab);
-	free_state_path_names(&rmtab);
 	exit(1);
 }
diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c
index 9fcae0b..fcab3b1 100644
--- a/utils/exportfs/exportfs.c
+++ b/utils/exportfs/exportfs.c
@@ -91,7 +91,23 @@ release_lockfile()
 		_lockfd = -1;
 	}
 }
+inline static void 
+read_exportfs_conf(char **argv)
+{
+	char *s;
+
+	conf_init_file(NFS_CONFFILE);
+	xlog_from_conffile("exportfs");
+
+	/* NOTE: following uses "mountd" section of nfs.conf !!!! */
+	s = conf_get_str("mountd", "state-directory-path");
+	/* Also look in the exportd section */
+	if (s == NULL)
+		s = conf_get_str("exportd", "state-directory-path");
+	if (s && !state_setup_basedir(argv[0], s))
+		exit(1);
 
+}
 int
 main(int argc, char **argv)
 {
@@ -105,7 +121,6 @@ main(int argc, char **argv)
 	int	f_ignore = 0;
 	int	i, c;
 	int	force_flush = 0;
-	char	*s;
 
 	if ((progname = strrchr(argv[0], '/')) != NULL)
 		progname++;
@@ -116,15 +131,9 @@ main(int argc, char **argv)
 	xlog_stderr(1);
 	xlog_syslog(0);
 
-	conf_init_file(NFS_CONFFILE);
-	xlog_from_conffile("exportfs");
+	read_exportfs_conf(argv);
 	nfsd_path_init();
 
-	/* NOTE: following uses "mountd" section of nfs.conf !!!! */
-	s = conf_get_str("mountd", "state-directory-path");
-	if (s && !state_setup_basedir(argv[0], s))
-		exit(1);
-
 	while ((c = getopt(argc, argv, "ad:fhio:ruvs")) != EOF) {
 		switch(c) {
 		case 'a':
diff --git a/utils/exportfs/exportfs.man b/utils/exportfs/exportfs.man
index 91d3589..6d417a7 100644
--- a/utils/exportfs/exportfs.man
+++ b/utils/exportfs/exportfs.man
@@ -167,9 +167,11 @@ When a list is given, the members should be comma-separated.
 .B exportfs
 will also recognize the
 .B state-directory-path
-value from the
+value from both the 
 .B [mountd]
-section.
+section and the
+.B [exportd]
+section
 
 .SH DISCUSSION
 .SS Exporting Directories
@@ -327,6 +329,7 @@ table of clients accessing server's exports
 .BR exports (5),
 .BR nfs.conf (5),
 .BR rpc.mountd (8),
+.BR exportd (8),
 .BR netgroup (5)
 .SH AUTHORS
 Olaf Kirch <okir@monad.swb.de>
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 5/5] exportd: Enabled junction support
  2021-02-09 21:23 [PATCH 0/5 V1] exportd: The NFSv4 only mounting daemon Steve Dickson
                   ` (3 preceding siblings ...)
  2021-02-09 21:23 ` [PATCH 4/5] exportd/exportfs: Add the state-directory-path option Steve Dickson
@ 2021-02-09 21:23 ` Steve Dickson
  4 siblings, 0 replies; 6+ messages in thread
From: Steve Dickson @ 2021-02-09 21:23 UTC (permalink / raw
  To: Linux NFS Mailing list

Moved the junction support from mountd to libexport.a
so both exportd and mountd can use the code.

Signed-off-by: Steve Dickson <steved@redhat.com>
---
 support/export/Makefile.am                | 2 +-
 {utils/mountd => support/export}/fsloc.c  | 0
 {utils/mountd => support/include}/fsloc.h | 0
 utils/exportd/Makefile.am                 | 5 ++++-
 utils/mountd/Makefile.am                  | 3 +--
 5 files changed, 6 insertions(+), 4 deletions(-)
 rename {utils/mountd => support/export}/fsloc.c (100%)
 rename {utils/mountd => support/include}/fsloc.h (100%)

diff --git a/support/export/Makefile.am b/support/export/Makefile.am
index 7de82a8..a9e710c 100644
--- a/support/export/Makefile.am
+++ b/support/export/Makefile.am
@@ -12,7 +12,7 @@ EXTRA_DIST	= mount.x
 noinst_LIBRARIES = libexport.a
 libexport_a_SOURCES = client.c export.c hostname.c \
 		      xtab.c mount_clnt.c mount_xdr.c \
-			  cache.c auth.c v4root.c
+			  cache.c auth.c v4root.c fsloc.c
 BUILT_SOURCES 	= $(GENFILES)
 
 noinst_HEADERS = mount.h
diff --git a/utils/mountd/fsloc.c b/support/export/fsloc.c
similarity index 100%
rename from utils/mountd/fsloc.c
rename to support/export/fsloc.c
diff --git a/utils/mountd/fsloc.h b/support/include/fsloc.h
similarity index 100%
rename from utils/mountd/fsloc.h
rename to support/include/fsloc.h
diff --git a/utils/exportd/Makefile.am b/utils/exportd/Makefile.am
index 0fcd92f..2fd3ba1 100644
--- a/utils/exportd/Makefile.am
+++ b/utils/exportd/Makefile.am
@@ -1,6 +1,9 @@
 ## Process this file with automake to produce Makefile.in
 
-OPTLIBS     =
+OPTLIBS		=
+if CONFIG_JUNCTION
+OPTLIBS		+= ../../support/junction/libjunction.la $(LIBXML2)
+endif
 
 man8_MANS   = exportd.man
 EXTRA_DIST  = $(man8_MANS)
diff --git a/utils/mountd/Makefile.am b/utils/mountd/Makefile.am
index cac3275..859f28e 100644
--- a/utils/mountd/Makefile.am
+++ b/utils/mountd/Makefile.am
@@ -12,9 +12,8 @@ RPCPREFIX	= rpc.
 KPREFIX		= @kprefix@
 sbin_PROGRAMS	= mountd
 
-noinst_HEADERS = fsloc.h
 mountd_SOURCES = mountd.c mount_dispatch.c rmtab.c \
-		 svc_run.c fsloc.c mountd.h
+		 svc_run.c mountd.h
 mountd_LDADD = ../../support/export/libexport.a \
 	       ../../support/nfs/libnfs.la \
 	       ../../support/misc/libmisc.a \
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-02-09 22:27 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-02-09 21:23 [PATCH 0/5 V1] exportd: The NFSv4 only mounting daemon Steve Dickson
2021-02-09 21:23 ` [PATCH 1/5] exportd: the initial shell of the v4 export support Steve Dickson
2021-02-09 21:23 ` [PATCH 2/5] exportd: Moved cache upcalls routines into libexport.a Steve Dickson
2021-02-09 21:23 ` [PATCH 3/5] exportd: multiple threads Steve Dickson
2021-02-09 21:23 ` [PATCH 4/5] exportd/exportfs: Add the state-directory-path option Steve Dickson
2021-02-09 21:23 ` [PATCH 5/5] exportd: Enabled junction support Steve Dickson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.