All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeff Layton <jlayton@poochiereds.net>
To: Neil Brown <neilb@suse.de>
Cc: nfs@lists.sourceforge.net, Steve Dickson <SteveD@redhat.com>
Subject: Re: [PATCH 09/11] nfs-utils: mount: Fixed mounts to	multi-home servers
Date: Sun, 11 Mar 2007 15:58:03 -0400	[thread overview]
Message-ID: <45F45F4B.3030407@poochiereds.net> (raw)
In-Reply-To: <17894.12530.165078.511522@notabene.brown>

Neil Brown wrote:
> On Tuesday February 27, jlayton@poochiereds.net 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
> 
> 
> diff --git a/support/include/conn.h b/support/include/conn.h
> index 1761dc4..11f16ab 100644
> --- a/support/include/conn.h
> +++ b/support/include/conn.h
> @@ -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);
>  
> diff --git a/support/nfs/conn.c b/support/nfs/conn.c
> index 89f7676..1020b47 100644
> --- a/support/nfs/conn.c
> +++ b/support/nfs/conn.c
> @@ -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:
> diff --git a/utils/mount/nfsmount.c b/utils/mount/nfsmount.c
> index 507ccdb..0f66bdf 100644
> --- a/utils/mount/nfsmount.c
> +++ b/utils/mount/nfsmount.c
> @@ -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  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

  reply	other threads:[~2007-03-11 19:58 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-02-26 11:18 [PATCH 09/11] nfs-utils: mount: Fixed mounts to multi-home servers Steve Dickson
2007-02-27  6:32 ` Neil Brown
2007-02-27 18:12   ` Jeff Layton
2007-03-01  1:48     ` Neil Brown
2007-03-11 19:58       ` Jeff Layton [this message]
2007-03-11 22:38         ` Neil Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=45F45F4B.3030407@poochiereds.net \
    --to=jlayton@poochiereds.net \
    --cc=SteveD@redhat.com \
    --cc=neilb@suse.de \
    --cc=nfs@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.