Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.sbin/nfsd Let nfsd behave like all other programs: tries...
details: https://anonhg.NetBSD.org/src/rev/7047ecb1df70
branches: trunk
changeset: 780957:7047ecb1df70
user: christos <christos%NetBSD.org@localhost>
date: Mon Aug 13 08:19:11 2012 +0000
description:
Let nfsd behave like all other programs: tries to use both inet4 and inet6
by default and both udp and tcp: -4 uses only inet4, -6 uses only inet6,
-t uses only tcp, -u uses only udp. For compatibility, we detect old option
usage, we warn, and DTRT.
diffstat:
usr.sbin/nfsd/nfsd.8 | 27 +-
usr.sbin/nfsd/nfsd.c | 561 +++++++++++++++++++-------------------------------
2 files changed, 234 insertions(+), 354 deletions(-)
diffs (truncated from 747 to 300 lines):
diff -r 0feadb305de6 -r 7047ecb1df70 usr.sbin/nfsd/nfsd.8
--- a/usr.sbin/nfsd/nfsd.8 Mon Aug 13 08:07:03 2012 +0000
+++ b/usr.sbin/nfsd/nfsd.8 Mon Aug 13 08:19:11 2012 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: nfsd.8,v 1.21 2008/03/17 09:57:11 yamt Exp $
+.\" $NetBSD: nfsd.8,v 1.22 2012/08/13 08:19:11 christos Exp $
.\"
.\" Copyright (c) 1989, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -29,7 +29,7 @@
.\"
.\" @(#)nfsd.8 8.4 (Berkeley) 3/29/95
.\"
-.Dd March 17, 2008
+.Dd August 12, 2012
.Dt NFSD 8
.Os
.Sh NAME
@@ -39,7 +39,7 @@
server
.Sh SYNOPSIS
.Nm
-.Op Fl 6rut
+.Op Fl 46rut
.Op Fl n Ar num_threads
.Sh DESCRIPTION
.Nm
@@ -73,20 +73,31 @@
A server should run enough threads to handle
the maximum level of concurrency from its clients.
.It Fl 6
-Listen to IPv6 requests as well as IPv4 requests. If IPv6 support is not
-available, nfsd will silently continue and just use IPv4.
+Listen to only IPv6 requests.
+By default
+.Nm
+listens to both IPv6 and IPv4 and tries to register for both.
+.It Fl 4
+Listen to only IPv4 requests.
.It Fl t
-Serve
+Serve only
.Tn TCP NFS
clients.
+By default
+.Nm
+serves both
+.Tn TCP NFS
+and
+.TN UDP NFS
+clients
.It Fl u
-Serve
+Serve only
.Tn UDP NFS
clients.
.El
.Pp
For example,
-.Dq Li "nfsd -t -u -n 6"
+.Dq Li "nfsd -n 6"
serves
.Tn UDP
and
diff -r 0feadb305de6 -r 7047ecb1df70 usr.sbin/nfsd/nfsd.c
--- a/usr.sbin/nfsd/nfsd.c Mon Aug 13 08:07:03 2012 +0000
+++ b/usr.sbin/nfsd/nfsd.c Mon Aug 13 08:19:11 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: nfsd.c,v 1.58 2011/08/30 20:07:31 joerg Exp $ */
+/* $NetBSD: nfsd.c,v 1.59 2012/08/13 08:19:11 christos Exp $ */
/*
* Copyright (c) 1989, 1993, 1994
@@ -42,7 +42,7 @@
#if 0
static char sccsid[] = "@(#)nfsd.c 8.9 (Berkeley) 3/29/95";
#else
-__RCSID("$NetBSD: nfsd.c,v 1.58 2011/08/30 20:07:31 joerg Exp $");
+__RCSID("$NetBSD: nfsd.c,v 1.59 2012/08/13 08:19:11 christos Exp $");
#endif
#endif /* not lint */
@@ -114,6 +114,135 @@
return NULL;
}
+struct conf {
+ struct addrinfo *ai;
+ struct netconfig *nc;
+ struct netbuf nb;
+ struct pollfd pfd;
+};
+
+#define NFS_UDP4 0
+#define NFS_TCP4 1
+#define NFS_UDP6 2
+#define NFS_TCP6 3
+
+static int cfg_family[] = { PF_INET, PF_INET, PF_INET6, PF_INET6 };
+static const char *cfg_netconf[] = { "udp", "tcp", "udp6", "tcp6" };
+static int cfg_socktype[] = {
+ SOCK_DGRAM, SOCK_STREAM, SOCK_DGRAM, SOCK_STREAM };
+static int cfg_protocol[] = {
+ IPPROTO_UDP, IPPROTO_TCP, IPPROTO_UDP, IPPROTO_TCP };
+
+static int
+tryconf(struct conf *cfg, int t, int reregister)
+{
+ struct addrinfo hints;
+ int ecode;
+
+ memset(cfg, 0, sizeof(cfg));
+ memset(&hints, 0, sizeof hints);
+ hints.ai_flags = AI_PASSIVE;
+ hints.ai_family = cfg_family[t];
+ hints.ai_socktype = cfg_socktype[t];
+ hints.ai_protocol = cfg_protocol[t];
+
+ ecode = getaddrinfo(NULL, "nfs", &hints, &cfg->ai);
+ if (ecode != 0) {
+ syslog(LOG_ERR, "getaddrinfo %s: %s", cfg_netconf[t],
+ gai_strerror(ecode));
+ return -1;
+ }
+
+ cfg->nc = getnetconfigent(cfg_netconf[t]);
+
+ if (cfg->nc == NULL) {
+ syslog(LOG_ERR, "getnetconfigent %s failed: %m",
+ cfg_netconf[t]);
+ return -1;
+ }
+
+ cfg->nb.buf = cfg->ai->ai_addr;
+ cfg->nb.len = cfg->nb.maxlen = cfg->ai->ai_addrlen;
+ if (reregister)
+ if (!rpcb_set(RPCPROG_NFS, 2, cfg->nc, &cfg->nb)) {
+ syslog(LOG_ERR, "rpcb_set %s failed", cfg_netconf[t]);
+ freenetconfigent(cfg->nc);
+ cfg->nc = NULL;
+ return -1;
+ }
+ return 0;
+}
+
+static int
+setupsock(struct conf *cfg, struct pollfd *set, int p)
+{
+ int sock;
+ struct nfsd_args nfsdargs;
+ struct addrinfo *ai = cfg->ai;
+ int on = 1;
+
+ sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+
+ if (sock == -1) {
+ syslog(LOG_ERR, "can't create %s socket: %m", cfg_netconf[p]);
+ return -1;
+ }
+ if (cfg_family[p] == PF_INET6) {
+ if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on,
+ sizeof(on)) == -1) {
+ syslog(LOG_ERR, "can't set v6-only binding for %s "
+ "socket: %m", cfg_netconf[p]);
+ goto out;
+ }
+ }
+
+ if (cfg_protocol[p] == IPPROTO_TCP) {
+ if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on,
+ sizeof(on)) == -1) {
+ syslog(LOG_ERR, "setsockopt SO_REUSEADDR for %s: %m",
+ cfg_netconf[p]);
+ goto out;
+ }
+ }
+
+ if (bind(sock, ai->ai_addr, ai->ai_addrlen) == -1) {
+ syslog(LOG_ERR, "can't bind %s addr: %m", cfg_netconf[p]);
+ goto out;
+ }
+
+ if (cfg_protocol[p] == IPPROTO_TCP) {
+ if (listen(sock, 5) == -1) {
+ syslog(LOG_ERR, "listen failed");
+ goto out;
+ }
+ }
+
+ if (!rpcb_set(RPCPROG_NFS, 2, cfg->nc, &cfg->nb) ||
+ !rpcb_set(RPCPROG_NFS, 3, cfg->nc, &cfg->nb)) {
+ syslog(LOG_ERR, "can't register with %s portmap",
+ cfg_netconf[p]);
+ goto out;
+ }
+
+
+ if (cfg_protocol[p] == IPPROTO_TCP)
+ set->fd = sock;
+ else {
+ nfsdargs.sock = sock;
+ nfsdargs.name = NULL;
+ nfsdargs.namelen = 0;
+ if (nfssvc(NFSSVC_ADDSOCK, &nfsdargs) < 0) {
+ syslog(LOG_ERR, "can't add %s socket", cfg_netconf[p]);
+ goto out;
+ }
+ (void)close(sock);
+ }
+ return 0;
+out:
+ (void)close(sock);
+ return -1;
+}
+
/*
* Nfs server daemon mostly just a user context for nfssvc()
*
@@ -127,41 +256,37 @@
* For connection based sockets, loop doing accepts. When you get a new
* socket from accept, pass the msgsock into the kernel via nfssvc().
* The arguments are:
- * -c - support iso cltp clients
* -r - reregister with portmapper
- * -t - support tcp nfs clients
- * -u - support udp nfs clients
- * followed by "n" which is the number of nfsd threads to create
+ * -t - support only tcp nfs clients
+ * -u - support only udp nfs clients
+ * -n num how many threads to create.
+ * -4 - use only ipv4
+ * -6 - use only ipv6
*/
int
main(int argc, char *argv[])
{
- struct nfsd_args nfsdargs;
- struct addrinfo *ai_udp, *ai_tcp, *ai_udp6, *ai_tcp6, hints;
- struct netconfig *nconf_udp, *nconf_tcp, *nconf_udp6, *nconf_tcp6;
- struct netbuf nb_udp, nb_tcp, nb_udp6, nb_tcp6;
- struct sockaddr_in inetpeer;
- struct sockaddr_in6 inet6peer;
- struct pollfd set[4];
- socklen_t len;
- int ch, cltpflag, connect_type_cnt, i, maxsock, msgsock, serrno;
- int nfsdcnt, on = 1, reregister, sock, tcpflag, tcpsock;
- int tcp6sock, ip6flag;
- int tp4cnt, tp4flag, tpipcnt, tpipflag, udpflag, ecode, s;
+ struct conf cfg[4];
+ struct pollfd set[__arraycount(cfg)];
+ int ch, connect_type_cnt;
+ size_t i, nfsdcnt;
+ int reregister;
+ int tcpflag, udpflag;
+ int ip6flag, ip4flag;
+ int s, compat;
#define DEFNFSDCNT 4
nfsdcnt = DEFNFSDCNT;
- cltpflag = reregister = tcpflag = tp4cnt = tp4flag = tpipcnt = 0;
- tpipflag = udpflag = ip6flag = 0;
- nconf_udp = nconf_tcp = nconf_udp6 = nconf_tcp6 = NULL;
- maxsock = 0;
- tcpsock = tcp6sock = -1;
-#define GETOPT "6n:rtu"
-#define USAGE "[-rtu] [-n num_servers]"
+ compat = reregister = 0;
+ tcpflag = udpflag = 1;
+ ip6flag = ip4flag = 1;
+#define GETOPT "46n:rtu"
+#define USAGE "[-46rtu] [-n num_servers]"
while ((ch = getopt(argc, argv, GETOPT)) != -1) {
switch (ch) {
case '6':
ip6flag = 1;
+ ip4flag = 0;
s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
if (s < 0 && (errno == EPROTONOSUPPORT ||
errno == EPFNOSUPPORT || errno == EAFNOSUPPORT))
@@ -169,10 +294,21 @@
else
close(s);
break;
+ case '4':
+ ip6flag = 0;
+ ip4flag = 1;
+ s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (s < 0 && (errno == EPROTONOSUPPORT ||
+ errno == EPFNOSUPPORT || errno == EAFNOSUPPORT))
+ ip4flag = 0;
+ else
+ close(s);
+ break;
case 'n':
nfsdcnt = atoi(optarg);
if (nfsdcnt < 1) {
- warnx("nfsd count %d; reset to %d", nfsdcnt, DEFNFSDCNT);
+ warnx("nfsd count %zu; reset to %d", nfsdcnt,
+ DEFNFSDCNT);
nfsdcnt = DEFNFSDCNT;
Home |
Main Index |
Thread Index |
Old Index