X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=utils%2Fmountd%2Fmountd.c;h=971e4f4e2be8ca774328aed24c921bdea4f7edcc;hp=164983a7938f1efbb37f35c3a811fa4c9393f061;hb=8b064fcf464aaf3717d8940f97a7d3f8bf21de1a;hpb=08f6b0ea56f96eac00b092c7d5e1f6486eb6f457 diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c index 164983a..971e4f4 100644 --- a/utils/mountd/mountd.c +++ b/utils/mountd/mountd.c @@ -14,9 +14,11 @@ #include #include #include +#include #include #include #include +#include #include "xmalloc.h" #include "misc.h" #include "mountd.h" @@ -24,11 +26,12 @@ static void usage(const char *, int exitcode); static exports get_exportlist(void); -static struct knfs_fh * get_rootfh(struct svc_req *, dirpath *, int *); +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 } }; @@ -65,19 +69,21 @@ mount_null_1_svc(struct svc_req *rqstp, void *argp, void *resp) bool_t mount_mnt_1_svc(struct svc_req *rqstp, dirpath *path, fhstatus *res) { - struct knfs_fh *fh; + struct nfs_fh_len *fh; xlog(D_CALL, "MNT1(%s) called", *path); - if ((fh = get_rootfh(rqstp, path, &res->fhs_status)) != NULL) - memcpy(&res->fhstatus_u.fhs_fhandle, fh, 32); + if ((fh = get_rootfh(rqstp, path, &res->fhs_status, 0)) != NULL) + memcpy(&res->fhstatus_u.fhs_fhandle, fh->fh_handle, 32); return 1; } bool_t mount_dump_1_svc(struct svc_req *rqstp, void *argp, mountlist *res) { + struct sockaddr_in *addr = + (struct sockaddr_in *) svc_getcaller(rqstp->rq_xprt); xlog(L_NOTICE, "dump request from %s", - inet_ntoa(svc_getcaller(rqstp->rq_xprt)->sin_addr)); + inet_ntoa(addr->sin_addr)); *res = mountlist_list(); return 1; @@ -86,7 +92,8 @@ mount_dump_1_svc(struct svc_req *rqstp, void *argp, mountlist *res) bool_t mount_umnt_1_svc(struct svc_req *rqstp, dirpath *argp, void *resp) { - struct sockaddr_in *sin = svc_getcaller(rqstp->rq_xprt); + struct sockaddr_in *sin + = (struct sockaddr_in *) svc_getcaller(rqstp->rq_xprt); nfs_export *exp; char *p = *argp; char rpath[MAXPATHLEN+1]; @@ -113,15 +120,17 @@ mount_umntall_1_svc(struct svc_req *rqstp, void *argp, void *resp) /* Reload /etc/xtab if necessary */ auth_reload(); - mountlist_del_all(svc_getcaller(rqstp->rq_xprt)); + mountlist_del_all((struct sockaddr_in *) svc_getcaller(rqstp->rq_xprt)); return 1; } bool_t mount_export_1_svc(struct svc_req *rqstp, void *argp, exports *resp) { + struct sockaddr_in *addr = + (struct sockaddr_in *) svc_getcaller(rqstp->rq_xprt); xlog(L_NOTICE, "export request from %s", - inet_ntoa(svc_getcaller(rqstp->rq_xprt)->sin_addr)); + inet_ntoa(addr->sin_addr)); *resp = get_exportlist(); return 1; } @@ -129,8 +138,10 @@ mount_export_1_svc(struct svc_req *rqstp, void *argp, exports *resp) bool_t mount_exportall_1_svc(struct svc_req *rqstp, void *argp, exports *resp) { + struct sockaddr_in *addr = + (struct sockaddr_in *) svc_getcaller(rqstp->rq_xprt); xlog(L_NOTICE, "exportall request from %s", - inet_ntoa(svc_getcaller(rqstp->rq_xprt)->sin_addr)); + inet_ntoa(addr->sin_addr)); *resp = get_exportlist(); return 1; } @@ -149,7 +160,8 @@ mount_exportall_1_svc(struct svc_req *rqstp, void *argp, exports *resp) bool_t mount_pathconf_2_svc(struct svc_req *rqstp, dirpath *path, ppathcnf *res) { - struct sockaddr_in *sin = svc_getcaller(rqstp->rq_xprt); + struct sockaddr_in *sin + = (struct sockaddr_in *) svc_getcaller(rqstp->rq_xprt); struct stat stb; nfs_export *exp; char rpath[MAXPATHLEN+1]; @@ -203,24 +215,25 @@ bool_t mount_mnt_3_svc(struct svc_req *rqstp, dirpath *path, mountres3 *res) { static int flavors[] = { AUTH_NULL, AUTH_UNIX }; - struct knfs_fh *fh; + struct nfs_fh_len *fh; xlog(D_CALL, "MNT3(%s) called", *path); - if ((fh = get_rootfh(rqstp, path, (int *) &res->fhs_status)) != NULL) { + if ((fh = get_rootfh(rqstp, path, (int *) &res->fhs_status, 1)) != NULL) { struct mountres3_ok *ok = &res->mountres3_u.mountinfo; - ok->fhandle.fhandle3_len = 32; - ok->fhandle.fhandle3_val = (char *) fh; + ok->fhandle.fhandle3_len = fh->fh_size; + ok->fhandle.fhandle3_val = fh->fh_handle; ok->auth_flavors.auth_flavors_len = 2; ok->auth_flavors.auth_flavors_val = flavors; } return 1; } -static struct knfs_fh * -get_rootfh(struct svc_req *rqstp, dirpath *path, int *error) +static struct nfs_fh_len * +get_rootfh(struct svc_req *rqstp, dirpath *path, int *error, int v3) { - struct sockaddr_in *sin = svc_getcaller(rqstp->rq_xprt); + struct sockaddr_in *sin = + (struct sockaddr_in *) svc_getcaller(rqstp->rq_xprt); struct stat stb; nfs_export *exp; char rpath[MAXPATHLEN+1]; @@ -252,19 +265,23 @@ get_rootfh(struct svc_req *rqstp, dirpath *path, int *error) xlog(L_WARNING, "%s is not a directory or regular file", p); *error = NFSERR_NOTDIR; } else { - struct knfs_fh *fh; + struct nfs_fh_len *fh; - if (!exp->m_exported) + if (exp->m_exported<1) export_export(exp); if (!exp->m_xtabent) xtab_append(exp); - /* We first try the new nfs syscall. */ - fh = getfh ((struct sockaddr *) sin, p); - if (fh == NULL && errno == EINVAL) - /* Let's try the old one. */ - fh = getfh_old ((struct sockaddr *) sin, - stb.st_dev, stb.st_ino); + if (v3) + fh = getfh_size ((struct sockaddr *) sin, p, 64); + if (!v3 || (fh == NULL && errno == EINVAL)) { + /* We first try the new nfs syscall. */ + fh = getfh ((struct sockaddr *) sin, p); + if (fh == NULL && errno == EINVAL) + /* Let's try the old one. */ + fh = getfh_old ((struct sockaddr *) sin, + stb.st_dev, stb.st_ino); + } if (fh != NULL) { mountlist_add(exp, p); *error = NFS_OK; @@ -375,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; @@ -406,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; @@ -423,8 +453,27 @@ 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"); +/* xlog_open("mountd"); */ sa.sa_handler = SIG_IGN; sa.sa_flags = 0; @@ -432,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); @@ -481,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); }