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
next prev parent 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox