diff options
author | alfred <alfred@FreeBSD.org> | 2004-07-12 06:22:42 +0000 |
---|---|---|
committer | alfred <alfred@FreeBSD.org> | 2004-07-12 06:22:42 +0000 |
commit | 031e087d2c3a8f23b40ec3cd62b741f935e1e2e6 (patch) | |
tree | bf496bf6af68cb9b9d21598b856b458f96bb8fab | |
parent | df5304b63cb13fff0de92961ba80dea84c5c552c (diff) | |
download | FreeBSD-src-031e087d2c3a8f23b40ec3cd62b741f935e1e2e6.zip FreeBSD-src-031e087d2c3a8f23b40ec3cd62b741f935e1e2e6.tar.gz |
Use SO_REUSEADDR and SO_REUSEPORT when reconnecting NFS mounts.
Tune the timeout from 5 seconds to 12 seconds.
Provide a sysctl to show how many reconnects the NFS client has done.
Seems to fix IPv6 from: kuriyama
-rw-r--r-- | sys/kern/uipc_socket.c | 19 | ||||
-rw-r--r-- | sys/nfsclient/nfs_socket.c | 12 | ||||
-rw-r--r-- | sys/sys/socketvar.h | 2 |
3 files changed, 31 insertions, 2 deletions
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index f3a0108..6787573 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -1541,6 +1541,25 @@ sooptcopyin(sopt, buf, len, minlen) return 0; } +/* + * Kernel version of setsockopt(2)/ + * XXX: optlen is size_t, not socklen_t + */ +int +kern_setsockopt(struct socket *so, int level, int optname, void *optval, + size_t optlen) +{ + struct sockopt sopt; + + sopt.sopt_level = level; + sopt.sopt_name = optname; + sopt.sopt_dir = SOPT_SET; + sopt.sopt_val = optval; + sopt.sopt_valsize = optlen; + sopt.sopt_td = NULL; + return (sosetopt(so, &sopt)); +} + int sosetopt(so, sopt) struct socket *so; diff --git a/sys/nfsclient/nfs_socket.c b/sys/nfsclient/nfs_socket.c index f602e42..191d5d2 100644 --- a/sys/nfsclient/nfs_socket.c +++ b/sys/nfsclient/nfs_socket.c @@ -111,12 +111,15 @@ static int proct[NFS_NPROCS] = { static int nfs_realign_test; static int nfs_realign_count; static int nfs_bufpackets = 4; +static int nfs_reconnects; SYSCTL_DECL(_vfs_nfs); SYSCTL_INT(_vfs_nfs, OID_AUTO, realign_test, CTLFLAG_RW, &nfs_realign_test, 0, ""); SYSCTL_INT(_vfs_nfs, OID_AUTO, realign_count, CTLFLAG_RW, &nfs_realign_count, 0, ""); SYSCTL_INT(_vfs_nfs, OID_AUTO, bufpackets, CTLFLAG_RW, &nfs_bufpackets, 0, ""); +SYSCTL_INT(_vfs_nfs, OID_AUTO, reconnects, CTLFLAG_RD, &nfs_reconnects, 0, + "number of times the nfs client has had to reconnect"); /* @@ -157,7 +160,7 @@ nfs_connect(struct nfsmount *nmp, struct nfsreq *rep) { struct socket *so; int error, rcvreserve, sndreserve; - int pktscale; + int opt, pktscale; struct sockaddr *saddr; struct thread *td = &thread0; /* only used for socreate and sobind */ @@ -172,6 +175,10 @@ nfs_connect(struct nfsmount *nmp, struct nfsreq *rep) so = nmp->nm_so; nmp->nm_soflags = so->so_proto->pr_flags; + opt = 1; + (void)kern_setsockopt(so, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); + (void)kern_setsockopt(so, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)); + /* * Some servers require that the client port be a reserved port number. */ @@ -261,7 +268,7 @@ nfs_connect(struct nfsmount *nmp, struct nfsreq *rep) } SOCK_UNLOCK(so); } - so->so_rcv.sb_timeo = 5 * hz; + so->so_rcv.sb_timeo = 12 * hz; so->so_snd.sb_timeo = 5 * hz; /* @@ -357,6 +364,7 @@ nfs_reconnect(struct nfsreq *rep) struct nfsmount *nmp = rep->r_nmp; int error; + nfs_reconnects++; nfs_disconnect(nmp); while ((error = nfs_connect(nmp, rep)) != 0) { if (error == ERESTART) diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h index fb81792..cfe061b 100644 --- a/sys/sys/socketvar.h +++ b/sys/sys/socketvar.h @@ -438,6 +438,8 @@ struct uio; /* * From uipc_socket and friends */ +int kern_setsockopt(struct socket *so, int level, int optname, + void *optval, size_t optlen); int sockargs(struct mbuf **mp, caddr_t buf, int buflen, int type); int getsockaddr(struct sockaddr **namp, caddr_t uaddr, size_t len); void sbappend(struct sockbuf *sb, struct mbuf *m); |