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
This commit is contained in:
Alfred Perlstein 2004-07-12 06:22:42 +00:00
parent 67aff1896c
commit d58d3648dd
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=132018
3 changed files with 31 additions and 2 deletions

View File

@ -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;

View File

@ -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)

View File

@ -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);