summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--utils/nfsd/nfsd.c3
-rw-r--r--utils/nfsd/nfssvc.c52
-rw-r--r--utils/nfsd/nfssvc.h1
3 files changed, 53 insertions, 3 deletions
diff --git a/utils/nfsd/nfsd.c b/utils/nfsd/nfsd.c
index 1cda1e5..658b8fa 100644
--- a/utils/nfsd/nfsd.c
+++ b/utils/nfsd/nfsd.c
@@ -246,6 +246,9 @@ main(int argc, char **argv)
exit(1);
}
+ /* make sure nfsdfs is mounted if it's available */
+ nfssvc_mount_nfsdfs(progname);
+
/* can only change number of threads if nfsd is already up */
if (nfssvc_inuse()) {
socket_up = 1;
diff --git a/utils/nfsd/nfssvc.c b/utils/nfsd/nfssvc.c
index 34c67ca..7693626 100644
--- a/utils/nfsd/nfssvc.c
+++ b/utils/nfsd/nfssvc.c
@@ -15,9 +15,11 @@
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
+#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
+#include <stdlib.h>
#include "nfslib.h"
#include "xlog.h"
@@ -31,9 +33,13 @@
*/
#undef IPV6_SUPPORTED
-#define NFSD_PORTS_FILE "/proc/fs/nfsd/portlist"
-#define NFSD_VERS_FILE "/proc/fs/nfsd/versions"
-#define NFSD_THREAD_FILE "/proc/fs/nfsd/threads"
+#ifndef NFSD_FS_DIR
+#define NFSD_FS_DIR "/proc/fs/nfsd"
+#endif
+
+#define NFSD_PORTS_FILE NFSD_FS_DIR "/portlist"
+#define NFSD_VERS_FILE NFSD_FS_DIR "/versions"
+#define NFSD_THREAD_FILE NFSD_FS_DIR "/threads"
/*
* declaring a common static scratch buffer here keeps us from having to
@@ -44,6 +50,46 @@
char buf[128];
/*
+ * Using the "new" interfaces for nfsd requires that /proc/fs/nfsd is
+ * actually mounted. Make an attempt to mount it here if it doesn't appear
+ * to be. If the mount attempt fails, no big deal -- fall back to using nfsctl
+ * instead.
+ */
+void
+nfssvc_mount_nfsdfs(char *progname)
+{
+ int err;
+ struct stat statbuf;
+
+ err = stat(NFSD_THREAD_FILE, &statbuf);
+ if (err == 0)
+ return;
+
+ if (errno != ENOENT) {
+ xlog(L_ERROR, "Unable to stat %s: errno %d (%m)",
+ NFSD_THREAD_FILE, errno);
+ return;
+ }
+
+ /*
+ * this call can return an error if modprobe is set up to automatically
+ * mount nfsdfs when nfsd.ko is plugged in. So, ignore the return
+ * code from it and just check for the "threads" file afterward.
+ */
+ system("/bin/mount -t nfsd nfsd " NFSD_FS_DIR " >/dev/null 2>&1");
+
+ err = stat(NFSD_THREAD_FILE, &statbuf);
+ if (err == 0)
+ return;
+
+ xlog(L_WARNING, "Unable to access " NFSD_FS_DIR " errno %d (%m)."
+ "\nPlease try, as root, 'mount -t nfsd nfsd " NFSD_FS_DIR
+ "' and then restart %s to correct the problem", errno, progname);
+
+ return;
+}
+
+/*
* Are there already sockets configured? If not, then it is safe to try to
* open some and pass them through.
*
diff --git a/utils/nfsd/nfssvc.h b/utils/nfsd/nfssvc.h
index 0c69bd6..1a01cec 100644
--- a/utils/nfsd/nfssvc.h
+++ b/utils/nfsd/nfssvc.h
@@ -20,6 +20,7 @@
*
*/
+void nfssvc_mount_nfsdfs(char *progname);
int nfssvc_inuse(void);
int nfssvc_set_sockets(const int family, const unsigned int protobits,
const char *host, const char *port);