]> git.decadent.org.uk Git - nfs-utils.git/blobdiff - utils/mountd/mountd.c
See Changelog
[nfs-utils.git] / utils / mountd / mountd.c
index 1eeefdcf0ffa872211d177366717dd7f6f7bc00d..971e4f4e2be8ca774328aed24c921bdea4f7edcc 100644 (file)
 #include <arpa/inet.h>
 #include <unistd.h>
 #include <stdlib.h>
+#include <string.h>
 #include <getopt.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <sys/resource.h>
 #include "xmalloc.h"
 #include "misc.h"
 #include "mountd.h"
@@ -29,6 +31,7 @@ static struct nfs_fh_len *get_rootfh(struct svc_req *, dirpath *, int *, int v3)
 static struct option longopts[] =
 {
        { "foreground", 0, 0, 'F' },
+       { "descriptors", 1, 0, 'o' },
        { "debug", 1, 0, 'd' },
        { "help", 0, 0, 'h' },
        { "exports-file", 1, 0, 'f' },
@@ -36,6 +39,7 @@ static struct option longopts[] =
        { "no-nfs-version", 1, 0, 'N' },
        { "version", 0, 0, 'v' },
        { "port", 1, 0, 'p' },
+       { "no-tcp", 0, 0, 'n' },
        { NULL, 0, 0, 0 }
 };
 
@@ -388,13 +392,23 @@ main(int argc, char **argv)
        char    *export_file = _PATH_EXPORTS;
        int     foreground = 0;
        int     port = 0;
+       int     descriptors = 256;
        int     c;
        struct sigaction sa;
+       struct rlimit rlim;
 
        /* Parse the command line options and arguments. */
        opterr = 0;
-       while ((c = getopt_long(argc, argv, "Fd:f:p:P:hN:V:v", longopts, NULL)) != EOF)
+       while ((c = getopt_long(argc, argv, "on:Fd:f:p:P:hN:V:v", longopts, NULL)) != EOF)
                switch (c) {
+               case 'o':
+                       descriptors = atoi(optarg);
+                       if (descriptors <= 0) {
+                               fprintf(stderr, "%s: bad descriptors: %s\n",
+                                       argv [0], optarg);
+                               usage(argv [0], 1);
+                       }
+                       break;
                case 'F':
                        foreground = 1;
                        break;
@@ -419,6 +433,9 @@ main(int argc, char **argv)
                case 'N':
                        nfs_version &= ~(1 << (atoi (optarg) - 1));
                        break;
+               case 'n':
+                       _rpcfdtype = SOCK_DGRAM;
+                       break;
                case 'V':
                        nfs_version |= 1 << (atoi (optarg) - 1);
                        break;
@@ -436,6 +453,25 @@ main(int argc, char **argv)
        if (optind != argc || !(nfs_version & 0x7))
                usage(argv [0], 1);
 
+       if (chdir(NFS_STATEDIR)) {
+               fprintf(stderr, "%s: chdir(%s) failed: %s\n",
+                       argv [0], NFS_STATEDIR, strerror(errno));
+               exit(1);
+       }
+
+       if (getrlimit (RLIMIT_NOFILE, &rlim) != 0) {
+               fprintf(stderr, "%s: getrlimit (RLIMIT_NOFILE) failed: %s\n",
+                       argv [0], strerror(errno));
+               exit(1);
+       }
+
+       rlim.rlim_cur = descriptors;
+       if (setrlimit (RLIMIT_NOFILE, &rlim) != 0) {
+               fprintf(stderr, "%s: setrlimit (RLIMIT_NOFILE) failed: %s\n",
+                       argv [0], strerror(errno));
+               exit(1);
+       }
+
        /* Initialize logging. */
 /*     xlog_open("mountd"); */
 
@@ -445,16 +481,25 @@ main(int argc, char **argv)
        sigaction(SIGHUP, &sa, NULL);
        sigaction(SIGINT, &sa, NULL);
        sigaction(SIGTERM, &sa, NULL);
+       /* WARNING: the following works on Linux and SysV, but not BSD! */
+       sigaction(SIGCHLD, &sa, NULL);
+
+       /* Daemons should close all extra filehandles ... *before* RPC init. */
+       if (!foreground) {
+               int fd = sysconf (_SC_OPEN_MAX);
+               while (--fd > 2)
+                       (void) close(fd);
+       }
 
        if (nfs_version & 0x1)
                rpc_init("mountd", MOUNTPROG, MOUNTVERS,
-                        mount_dispatch, port, 0);
+                        mount_dispatch, port);
        if (nfs_version & (0x1 << 1))
                rpc_init("mountd", MOUNTPROG, MOUNTVERS_POSIX,
-                        mount_dispatch, port, 0);
+                        mount_dispatch, port);
        if (nfs_version & (0x1 << 2))
                rpc_init("mountd", MOUNTPROG, MOUNTVERS_NFSV3,
-                        mount_dispatch, port, 0);
+                        mount_dispatch, port);
 
        sa.sa_handler = killer;
        sigaction(SIGHUP, &sa, NULL);
@@ -494,9 +539,9 @@ static void
 usage(const char *prog, int n)
 {
        fprintf(stderr,
-"Usage: %s [-Fhnv] [-d kind] [-f exports-file] [-V version]\n"
-"      [-N version] [--debug kind] [-p|--port port] [--help] [--version]\n"
-"      [--exports-file=file] [--nfs-version version]\n"
-"      [--no-nfs-version version]\n", prog);
+"Usage: %s [-F|--foreground] [-h|--help] [-v|--version] [-d kind|--debug kind]\n"
+"      [-o num|--descriptors num] [-f exports-file|--exports-file=file]\n"
+"      [-p|--port port] [-V version|--nfs-version version]\n"
+"      [-N version|--no-nfs-version version] [-n|--no-tcp]\n", prog);
        exit(n);
 }