The NFSv4 clientaddr= mount option communicates the client's local IP
address to the kernel.  This address is then provided to the server as
the client's callback address.  If the admin doesn't specify a clientaddr=
option, the mount command uses the get_client_address() function to
detect the client's local IP address.

Add support to the get_client_address() function for IPv6 addressing,
and rename the function to identify it as a local API.  Note there's
nothing specific to IPv6 here; we just make the API family-agnostic.

Signed-off-by: Chuck Lever <[EMAIL PROTECTED]>
---

 utils/mount/network.c |   17 ++++++++++-------
 utils/mount/network.h |    2 +-
 utils/mount/stropts.c |    4 +++-
 3 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/utils/mount/network.c b/utils/mount/network.c
index 5e6d17d..6c29e7c 100644
--- a/utils/mount/network.c
+++ b/utils/mount/network.c
@@ -860,29 +860,32 @@ int clnt_ping(struct sockaddr_in *saddr, const unsigned 
long prog,
 }
 
 /**
- * get_client_address - acquire our local network address
+ * nfs_client_address - acquire our local network address
  * @saddr: server's address
- * @caddr: filled in with our network address
+ * @laddr: filled in with our local network address
+ * @laddr_len: IN: length of buffer to fill in; OUT: length of filled-in 
address
  *
  * Discover a network address that the server will use to call us back.
  * On multi-homed clients, this address depends on which NIC we use to
  * route requests to the server.
  *
- * Use a connected datagram socket so as not to leave a socket in TIME_WAIT.
+ * A connected datagram socket is used to prevent leaving the socket
+ * in TIME_WAIT, to conserve the ephemeral port number space.  This helps
+ * reduce failed socket binds during mount storms.
  *
  * Returns one if successful, otherwise zero.
  */
-int get_client_address(struct sockaddr_in *saddr, struct sockaddr_in *caddr)
+int nfs_client_address(const struct sockaddr *saddr, struct sockaddr *laddr,
+                      socklen_t *laddr_len)
 {
-       socklen_t len = sizeof(*caddr);
        int sock, err;
 
-       sock = nfs_getsocket((struct sockaddr *)saddr, IPPROTO_UDP,
+       sock = nfs_getsocket(saddr, IPPROTO_UDP,
                                CONNECT_TIMEOUT, FALSE, TRUE);
        if (sock == RPC_ANYSOCK)
                return 0;
 
-       err = getsockname(sock, caddr, &len);
+       err = getsockname(sock, laddr, laddr_len);
        if (err && verbose)
                nfs_error(_("%s: error acquiring client's local address: %s"),
                                progname, strerror(errno));
diff --git a/utils/mount/network.h b/utils/mount/network.h
index 99ecc1e..7cabb16 100644
--- a/utils/mount/network.h
+++ b/utils/mount/network.h
@@ -48,7 +48,7 @@ static const struct timeval RETRY_TIMEOUT = { 3, 0 };
 
 int probe_bothports(clnt_addr_t *, clnt_addr_t *);
 int nfs_gethostbyname(const char *, struct sockaddr_in *);
-int get_client_address(struct sockaddr_in *, struct sockaddr_in *);
+int nfs_client_address(const struct sockaddr *, struct sockaddr *, socklen_t 
*);
 int nfs_call_umount(clnt_addr_t *, dirpath *);
 int clnt_ping(struct sockaddr_in *, const unsigned long,
                const unsigned long, const unsigned int,
diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c
index cadb1f4..6293766 100644
--- a/utils/mount/stropts.c
+++ b/utils/mount/stropts.c
@@ -178,12 +178,14 @@ static int append_clientaddr_option(struct sockaddr_in 
*saddr,
                                    struct mount_options *options)
 {
        struct sockaddr_in my_addr;
+       socklen_t len = sizeof(my_addr);
        char new_option[32];
 
        if (po_contains(options, "clientaddr") == PO_SUCCEEDED)
                return 1;
 
-       if (!get_client_address(saddr, &my_addr))
+       if (!nfs_client_address((struct sockaddr *)saddr,
+                               (struct sockaddr *)&my_addr, &len))
                return 0;
 
        snprintf(new_option, sizeof(new_option) - 1,

-
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to