nfs-utils: mount: Fixed mounts to multi-home servers
Subsystems (2)
PATCH 9/11 nfs-utils: mount: Fixed mounts to multi-home servers
commit 253c6b866a1ed4678c30131a41ef96821bae9d5f
Author: Steve Dickson <[email protected]> Date: Sat Feb 24 16:08:22 2007 -0500
Doing a connect on UDP sockets causes the Linux network stack to reject UDP patches from multi-home server with nic on the same subnet which caused mounts to hang.
support/nfs/conn.c +1 -1
@@ -98,7 +98,7 @@ int get_socket(struct sockaddr_in *saddr, u_int p_prot, int resvp)return RPC_ANYSOCK ; } } -if (type ==SOCK_STREAM || type ==SOCK_DGRAM ) { +if (type ==SOCK_STREAM ) { cc =connect (so, (struct sockaddr *)saddr, namelen);if (cc <0 ) { rpc_createerr.cf_stat =RPC_SYSTEMERROR ;
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
Quoted 15 lines · On Monday February 26, [email protected] wrote:
commit
253c6b866a1ed4678c30131a41ef96821bae9d5fAuthor: Steve Dickson <[email protected]> Date: Sat Feb 24 16:08:22 2007 -0500Doing a connect on UDP sockets causes the Linux network stack to reject UDP patches from multi-home server with nic on the same subnet which caused mounts to hang.
Signed-off-by Steve Dickson <[email protected]>support/nfs/conn.c +0
-0
support/nfs/conn.c int get_socket(struct sockaddr_in *saddr, u_int p_prot, int resvp) · line 101
Quoted 5 lines
support/nfs/conn.c +1
-1@@ -98,7 +98,7 @@ int get_socket(struct sockaddr_in *saddr, u_int p_prot, int resvp)return RPC_ANYSOCK ; } } -if (type ==SOCK_STREAM || type ==SOCK_DGRAM ) { +if (type ==SOCK_STREAM ) {
You are reverting a change from commit
c2db41e8abb6ddc9d03a0c91c6db043fa0f85a8f
This was needed so we could find our local address to get the call-back address sent to the server right for NFSv4.
I think the correct thing to do here is to fix mountd so that it replies from the correct address. Careful use of IP_PKTINFO makes this fairly easy to manage.... except that the recvfrom and sendto code is buried inside libc.... but if memory serves, that was fixed to get this right some time ago.
What OS is running on this multi-homed server??
Maybe we have to do something ghastly like disconnect the socket after getting the local address... I hope not.
NeilBrown
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
Quoted 34 lines · Neil Brown
Quoted 15 lines · On Monday February 26, [email protected] wrote:
commit
253c6b866a1ed4678c30131a41ef96821bae9d5fAuthor: Steve Dickson <[email protected]> Date: Sat Feb 24 16:08:22 2007 -0500Doing a connect on UDP sockets causes the Linux network stack to reject UDP patches from multi-home server with nic on the same subnet which caused mounts to hang.
Signed-off-by Steve Dickson <[email protected]>support/nfs/conn.c +0
-0support/nfs/conn.c int get_socket(struct sockaddr_in *saddr, u_int p_prot, int resvp) · line 101
Quoted 5 lines
support/nfs/conn.c +1
-1@@ -98,7 +98,7 @@ int get_socket(struct sockaddr_in *saddr, u_int p_prot, int resvp)return RPC_ANYSOCK ; } } -if (type ==SOCK_STREAM || type ==SOCK_DGRAM ) { +if (type ==SOCK_STREAM ) {You are reverting a change from commit
c2db41e8abb6ddc9d03a0c91c6db043fa0f85a8fThis was needed so we could find our local address to get the call-back address sent to the server right for NFSv4.
I think the correct thing to do here is to fix mountd so that it replies from the correct address. Careful use of
IP_PKTINFOmakes this fairly easy to manage.... except that the recvfrom and sendto code is buried inside libc.... but if memory serves, that was fixed to get this right some time ago.
Quoted 7 lines
What OS is running on this multi-homed server??
Maybe we have to do something ghastly like disconnect the socket after getting the local address... I hope not.
NeilBrown
I know we saw this with Solaris servers in particular (it's been a while, but I think I was testing against Solaris 8). The fedora BZ is here if you want to see all the gory details:
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=212471
I'm thinking we will have to deal with this situation, unfortunately, so maybe disconnecting the socket after getting the address is the best thing?
-- Jeff
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
Quoted 11 lines · On Tuesday February 27, [email protected] wrote:
I know we saw this with Solaris servers in particular (it's been a while, but I think I was testing against Solaris 8). The fedora BZ is here if you want to see all the gory details:
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=212471
I'm thinking we will have to deal with this situation, unfortunately, so maybe disconnecting the socket after getting the address is the best thing?
-- Jeff
Thanks for the link... Looks like we do need to be very careful about connecting UDP sockets.
This patch maybe?
NeilBrown
support/include/conn.h +1 -1
@@ -35,7 +35,7 @@ int clnt_ping(struct sockaddr_in *, const u_long, const u_long, const u_int, struct sockaddr_in *);u_long nfsvers_to_mnt (const u_long );u_long mntvers_to_nfs (const u_long ); -int get_socket (struct sockaddr_in *,u_int ,int ); +int get_socket (struct sockaddr_in *,u_int ,int ,int );CLIENT *mnt_openclnt (clnt_addr_t *,int *);void mnt_closeclnt (CLIENT *,int );
support/nfs/conn.c +20 -13
@@ -49,7 +49,7 @@ u_long mntvers_to_nfs(const u_long vers)* RPC_ANYSOCK is returned which will cause * the RPC code to create the socket instead. */ -int get_socket (struct sockaddr_in *saddr,u_int p_prot,int resvp) +int get_socket (struct sockaddr_in *saddr,u_int p_prot,int resvp,int conn) {int so, cc, type;struct sockaddr_in laddr;
@@ -98,7 +98,7 @@ int get_socket(struct sockaddr_in *saddr, u_int p_prot, int resvp)return RPC_ANYSOCK ; } } -if (type ==SOCK_STREAM || type ==SOCK_DGRAM ) { +if (type ==SOCK_STREAM || (conn && type ==SOCK_DGRAM )) { cc =connect (so, (struct sockaddr *)saddr, namelen);if (cc <0 ) { rpc_createerr.cf_stat =RPC_SYSTEMERROR ;
@@ -129,9 +129,10 @@ clnt_ping(struct sockaddr_in *saddr, const u_long prog, const u_long vers,CLIENT *clnt=NULL ;int sock, stat;static char clnt_res; +struct sockaddr dissolve; rpc_createerr.cf_stat = stat = errno =0 ; - sock =get_socket (saddr, prot, FALSE); + sock =get_socket (saddr, prot, FALSE, TRUE);if (sock ==RPC_ANYSOCK && errno ==ETIMEDOUT ) {/* * TCP timeout. Bubble up the error to see
@@ -141,8 +142,22 @@ clnt_ping(struct sockaddr_in *saddr, const u_long prog, const u_long vers, goto out_bad; } +if (caddr) { +/* Get the address of our end of this connection */ +socklen_t len =sizeof (*caddr); +if (getsockname (sock, caddr, &len) !=0 ) + caddr->sin_family =0 ; + } +switch (prot) {case IPPROTO_UDP : +/* The socket is connected (so we could getsockname successfully), +* but some servers on multi-homed hosts reply from +* the wrong address, so if we stay connected, we lose the reply. +*/ + dissolve.sa_family =AF_UNSPEC ; +connect (sock, &dissolve,sizeof (dissolve)); + clnt =clntudp_bufcreate (saddr, prog, vers,RETRY_TIMEOUT , &sock,RPCSMALLMSGSIZE ,RPCSMALLMSGSIZE );
@@ -166,15 +181,7 @@ clnt_ping(struct sockaddr_in *saddr, const u_long prog, const u_long vers, rpc_createerr.cf_stat = stat; }clnt_destroy (clnt); -if (sock !=-1 ) { -if (caddr) { -/* Get the address of our end of this connection */ -socklen_t len =sizeof (*caddr); -if (getsockname (sock, caddr, &len) !=0 ) - caddr->sin_family =0 ; - } -close (sock); - } +close (sock);if (stat ==RPC_SUCCESS )return 1 ;
@@ -191,7 +198,7 @@ CLIENT *mnt_openclnt(clnt_addr_t *mnt_server, int *msock)/* contact the mount daemon via TCP */ mnt_saddr->sin_port =htons ((u_short )mnt_pmap->pm_port); - *msock =get_socket (mnt_saddr, mnt_pmap->pm_prot, TRUE); + *msock =get_socket (mnt_saddr, mnt_pmap->pm_prot, TRUE, FALSE);switch (mnt_pmap->pm_prot) {case IPPROTO_UDP :
utils/mount/nfsmount.c +1 -1
@@ -306,7 +306,7 @@ getport(enum clnt_stat stat; saddr->sin_port =htons (PMAPPORT ); - socket =get_socket (saddr, prot, FALSE); + socket =get_socket (saddr, prot, FALSE, FALSE);switch (prot) {case IPPROTO_UDP :
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
Quoted 122 lines · Neil Brown
Quoted 10 lines · On Tuesday February 27, [email protected] wrote:
I know we saw this with Solaris servers in particular (it's been a while, but I think I was testing against Solaris 8). The fedora BZ is here if you want to see all the gory details:
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=212471
I'm thinking we will have to deal with this situation, unfortunately, so maybe disconnecting the socket after getting the address is the best thing?
-- Jeff
Thanks for the link... Looks like we do need to be very careful about connecting UDP sockets.
This patch maybe?
NeilBrown
support/include/conn.h +1
-1@@ -35,7 +35,7 @@ int clnt_ping(struct sockaddr_in *, const u_long, const u_long, const u_int, struct sockaddr_in *);u_long nfsvers_to_mnt (const u_long );u_long mntvers_to_nfs (const u_long ); -int get_socket (struct sockaddr_in *,u_int ,int ); +int get_socket (struct sockaddr_in *,u_int ,int ,int );CLIENT *mnt_openclnt (clnt_addr_t *,int *);void mnt_closeclnt (CLIENT *,int );support/nfs/conn.c +20
-13@@ -49,7 +49,7 @@ u_long mntvers_to_nfs(const u_long vers)* RPC_ANYSOCK is returned which will cause * the RPC code to create the socket instead. */ -int get_socket (struct sockaddr_in *saddr,u_int p_prot,int resvp) +int get_socket (struct sockaddr_in *saddr,u_int p_prot,int resvp,int conn) {int so, cc, type;struct sockaddr_in laddr;@@ -98,7 +98,7 @@ int get_socket(struct sockaddr_in *saddr, u_int p_prot, int resvp)return RPC_ANYSOCK ; } } -if (type ==SOCK_STREAM || type ==SOCK_DGRAM ) { +if (type ==SOCK_STREAM || (conn && type ==SOCK_DGRAM )) { cc =connect (so, (struct sockaddr *)saddr, namelen);if (cc <0 ) { rpc_createerr.cf_stat =RPC_SYSTEMERROR ;@@ -129,9 +129,10 @@ clnt_ping(struct sockaddr_in *saddr, const u_long prog, const u_long vers,CLIENT *clnt=NULL ;int sock, stat;static char clnt_res; +struct sockaddr dissolve; rpc_createerr.cf_stat = stat = errno =0 ; - sock =get_socket (saddr, prot, FALSE); + sock =get_socket (saddr, prot, FALSE, TRUE);if (sock ==RPC_ANYSOCK && errno ==ETIMEDOUT ) {/* * TCP timeout. Bubble up the error to see @@ -141,8 +142,22 @@ clnt_ping(struct sockaddr_in *saddr, const u_long prog, const u_long vers, goto out_bad; } +if (caddr) { +/* Get the address of our end of this connection */ +socklen_t len =sizeof (*caddr); +if (getsockname (sock, caddr, &len) !=0 ) + caddr->sin_family =0 ; + } +switch (prot) {case IPPROTO_UDP : +/* The socket is connected (so we could getsockname successfully), +* but some servers on multi-homed hosts reply from +* the wrong address, so if we stay connected, we lose the reply. +*/ + dissolve.sa_family =AF_UNSPEC ; +connect (sock, &dissolve,sizeof (dissolve)); + clnt =clntudp_bufcreate (saddr, prog, vers,RETRY_TIMEOUT , &sock,RPCSMALLMSGSIZE ,RPCSMALLMSGSIZE );@@ -166,15 +181,7 @@ clnt_ping(struct sockaddr_in *saddr, const u_long prog, const u_long vers, rpc_createerr.cf_stat = stat; }clnt_destroy (clnt); -if (sock !=-1 ) { -if (caddr) { -/* Get the address of our end of this connection */ -socklen_t len =sizeof (*caddr); -if (getsockname (sock, caddr, &len) !=0 ) - caddr->sin_family =0 ; - } -close (sock); - } +close (sock);if (stat ==RPC_SUCCESS )return 1 ;@@ -191,7 +198,7 @@ CLIENT *mnt_openclnt(clnt_addr_t *mnt_server, int *msock)/* contact the mount daemon via TCP */ mnt_saddr->sin_port =htons ((u_short )mnt_pmap->pm_port); - *msock =get_socket (mnt_saddr, mnt_pmap->pm_prot, TRUE); + *msock =get_socket (mnt_saddr, mnt_pmap->pm_prot, TRUE, FALSE);switch (mnt_pmap->pm_prot) {case IPPROTO_UDP :utils/mount/nfsmount.c +0
-0
utils/mount/nfsmount.c getport( · line 312
Quoted 8 lines
utils/mount/nfsmount.c +1
-1@@ -306,7 +306,7 @@ getport(enum clnt_stat stat; saddr->sin_port =htons (PMAPPORT ); - socket =get_socket (saddr, prot, FALSE); + socket =get_socket (saddr, prot, FALSE, FALSE);switch (prot) {case IPPROTO_UDP :
Hi Neil,
Apologies for the long delay, took me a bit to get my test rig back
together. This patch does indeed seem to fix the problem.
Thanks,
Jeff
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
Quoted 6 lines · On Sunday March 11, [email protected] wrote:
Hi Neil,
Apologies for the long delay, took me a bit to get my test rig back
together. This patch does indeed seem to fix the problem.
Thanks for testing!
I'll push it into the nfs-utils .git shortly.
Thanks,
NeilBrown
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs