X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=utils%2Fnfsd%2Fnfsd.c;h=e87c0a95952d17e584476312ef250ba1519d3bca;hp=c82249b7f6e0b72ab48c70f8a14c25614beeeb06;hb=e79baddaa1d8cf24cce929e14f6f91ac0d5e15d0;hpb=094b26031a376050d8610d055eb01c7949ad6547 diff --git a/utils/nfsd/nfsd.c b/utils/nfsd/nfsd.c index c82249b..e87c0a9 100644 --- a/utils/nfsd/nfsd.c +++ b/utils/nfsd/nfsd.c @@ -27,6 +27,10 @@ #include "nfssvc.h" #include "xlog.h" +#ifndef NFSD_NPROC +#define NFSD_NPROC 8 +#endif + static void usage(const char *); static struct option longopts[] = @@ -34,6 +38,7 @@ static struct option longopts[] = { "host", 1, 0, 'H' }, { "help", 0, 0, 'h' }, { "no-nfs-version", 1, 0, 'N' }, + { "nfs-version", 1, 0, 'V' }, { "no-tcp", 0, 0, 'T' }, { "no-udp", 0, 0, 'U' }, { "port", 1, 0, 'P' }, @@ -42,17 +47,63 @@ static struct option longopts[] = { "syslog", 0, 0, 's' }, { NULL, 0, 0, 0 } }; -unsigned int protobits = NFSCTL_ALLBITS; -unsigned int versbits = NFSCTL_ALLBITS; -int minorvers4 = NFSD_MAXMINORVERS4; /* nfsv4 minor version */ + +/* given a family and ctlbits, disable any that aren't listed in netconfig */ +#ifdef HAVE_LIBTIRPC +static void +nfsd_enable_protos(unsigned int *proto4, unsigned int *proto6) +{ + struct netconfig *nconf; + unsigned int *famproto; + void *handle; + + xlog(D_GENERAL, "Checking netconfig for visible protocols."); + + handle = setnetconfig(); + while((nconf = getnetconfig(handle))) { + if (!(nconf->nc_flag & NC_VISIBLE)) + continue; + + if (!strcmp(nconf->nc_protofmly, NC_INET)) + famproto = proto4; + else if (!strcmp(nconf->nc_protofmly, NC_INET6)) + famproto = proto6; + else + continue; + + if (!strcmp(nconf->nc_proto, NC_TCP)) + NFSCTL_TCPSET(*famproto); + else if (!strcmp(nconf->nc_proto, NC_UDP)) + NFSCTL_UDPSET(*famproto); + + xlog(D_GENERAL, "Enabling %s %s.", nconf->nc_protofmly, + nconf->nc_proto); + } + endnetconfig(handle); + return; +} +#else /* HAVE_LIBTIRPC */ +static void +nfsd_enable_protos(unsigned int *proto4, unsigned int *proto6) +{ + /* Enable all IPv4 protocols if no TIRPC support */ + *proto4 = NFSCTL_ALLBITS; + *proto6 = 0; +} +#endif /* HAVE_LIBTIRPC */ int main(int argc, char **argv) { - int count = 1, c, error, portnum = 0, fd, found_one; + int count = NFSD_NPROC, c, error = 0, portnum = 0, fd, found_one; char *p, *progname, *port; char *haddr = NULL; int socket_up = 0; + int minorvers41 = 0; /* nfsv4 minor version */ + unsigned int versbits = NFSCTL_ALLBITS; + unsigned int protobits = NFSCTL_ALLBITS; + unsigned int proto4 = 0; + unsigned int proto6 = 0; progname = strdup(basename(argv[0])); if (!progname) { @@ -69,7 +120,7 @@ main(int argc, char **argv) xlog_syslog(0); xlog_stderr(1); - while ((c = getopt_long(argc, argv, "dH:hN:p:P:sTU", longopts, NULL)) != EOF) { + while ((c = getopt_long(argc, argv, "dH:hN:V:p:P:sTU", longopts, NULL)) != EOF) { switch(c) { case 'd': xlog_config(D_ALL, 1); @@ -108,7 +159,12 @@ main(int argc, char **argv) switch((c = strtol(optarg, &p, 0))) { case 4: if (*p == '.') { - minorvers4 = -atoi(p + 1); + int i = atoi(p+1); + if (i != 1) { + fprintf(stderr, "%s: unsupported minor version\n", optarg); + exit(1); + } + minorvers41 = -1; break; } case 3: @@ -120,6 +176,27 @@ main(int argc, char **argv) exit(1); } break; + case 'V': + switch((c = strtol(optarg, &p, 0))) { + case 4: + if (*p == '.') { + int i = atoi(p+1); + if (i != 1) { + fprintf(stderr, "%s: unsupported minor version\n", optarg); + exit(1); + } + minorvers41 = 1; + break; + } + case 3: + case 2: + NFSCTL_VERSET(versbits, c); + break; + default: + fprintf(stderr, "%s: Unsupported version\n", optarg); + exit(1); + } + break; case 's': xlog_syslog(1); xlog_stderr(0); @@ -137,15 +214,38 @@ main(int argc, char **argv) } } + if (optind < argc) { + if ((count = atoi(argv[optind])) < 0) { + /* insane # of servers */ + fprintf(stderr, + "%s: invalid server count (%d), using 1\n", + argv[0], count); + count = 1; + } else if (count == 0) { + /* + * don't bother setting anything else if the threads + * are coming down anyway. + */ + socket_up = 1; + goto set_threads; + } + } + xlog_open(progname); - /* - * Do some sanity checking, if the ctlbits are set - */ - if (!NFSCTL_UDPISSET(protobits) && !NFSCTL_TCPISSET(protobits)) { - xlog(L_ERROR, "invalid protocol specified"); - exit(1); + nfsd_enable_protos(&proto4, &proto6); + + if (!NFSCTL_TCPISSET(protobits)) { + NFSCTL_TCPUNSET(proto4); + NFSCTL_TCPUNSET(proto6); + } + + if (!NFSCTL_UDPISSET(protobits)) { + NFSCTL_UDPUNSET(proto4); + NFSCTL_UDPUNSET(proto6); } + + /* make sure that at least one version is enabled */ found_one = 0; for (c = NFSD_MINVERS; c <= NFSD_MAXVERS; c++) { if (NFSCTL_VERISSET(versbits, c)) @@ -156,28 +256,20 @@ main(int argc, char **argv) exit(1); } - if (NFSCTL_VERISSET(versbits, 4) && !NFSCTL_TCPISSET(protobits)) { + if (NFSCTL_VERISSET(versbits, 4) && + !NFSCTL_TCPISSET(proto4) && + !NFSCTL_TCPISSET(proto6)) { xlog(L_ERROR, "version 4 requires the TCP protocol"); exit(1); } - if (haddr == NULL) { - struct in_addr in = {INADDR_ANY}; - haddr = strdup(inet_ntoa(in)); - } if (chdir(NFS_STATEDIR)) { xlog(L_ERROR, "chdir(%s) failed: %m", NFS_STATEDIR); exit(1); } - if (optind < argc) { - if ((count = atoi(argv[optind])) < 0) { - /* insane # of servers */ - xlog(L_ERROR, "invalid server count (%d), using 1", - count); - count = 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()) { @@ -190,11 +282,17 @@ main(int argc, char **argv) * registered with rpcbind. Note that on older kernels w/o the right * interfaces, these are a no-op. */ - nfssvc_setvers(versbits, minorvers4); + nfssvc_setvers(versbits, minorvers41); + + error = nfssvc_set_sockets(AF_INET, proto4, haddr, port); + if (!error) + socket_up = 1; - error = nfssvc_set_sockets(AF_INET, protobits, haddr, port); +#ifdef IPV6_SUPPORTED + error = nfssvc_set_sockets(AF_INET6, proto6, haddr, port); if (!error) socket_up = 1; +#endif /* IPV6_SUPPORTED */ set_threads: /* don't start any threads if unable to hand off any sockets */ @@ -236,7 +334,7 @@ static void usage(const char *prog) { fprintf(stderr, "Usage:\n" - "%s [-d|--debug] [-H hostname] [-p|-P|--port port] [-N|--no-nfs-version version ] [-s|--syslog] [-T|--no-tcp] [-U|--no-udp] nrservs\n", + "%s [-d|--debug] [-H hostname] [-p|-P|--port port] [-N|--no-nfs-version version] [-V|--nfs-version version] [-s|--syslog] [-T|--no-tcp] [-U|--no-udp] nrservs\n", prog); exit(2); }