[PATCH] knfsd: lockd: optionally use hostnames for identifying peers
authorOlaf Kirch <okir@suse.de>
Wed, 4 Oct 2006 09:16:01 +0000 (02:16 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Wed, 4 Oct 2006 14:55:17 +0000 (07:55 -0700)
This patch adds the nsm_use_hostnames sysctl and module param.  If set, lockd
will use the client's name (as given in the NLM arguments) to find the NSM
handle.  This makes recovery work when the NFS peer is multi-homed, and the
reboot notification arrives from a different IP than the original lock calls.

Signed-off-by: Olaf Kirch <okir@suse.de>
Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
fs/lockd/host.c
fs/lockd/mon.c
fs/lockd/svc.c
include/linux/lockd/lockd.h
include/linux/lockd/sm_inter.h

index 1bf384307d15ee1833f0498b7f119271d23144fc..a1423c66df04b4eb33cbe97f1c0ed150af799cfa 100644 (file)
@@ -462,7 +462,11 @@ __nsm_find(const struct sockaddr_in *sin,
        list_for_each(pos, &nsm_handles) {
                nsm = list_entry(pos, struct nsm_handle, sm_link);
 
-               if (!nlm_cmp_addr(&nsm->sm_addr, sin))
+               if (hostname && nsm_use_hostnames) {
+                       if (strlen(nsm->sm_name) != hostname_len
+                        || memcmp(nsm->sm_name, hostname, hostname_len))
+                               continue;
+               } else if (!nlm_cmp_addr(&nsm->sm_addr, sin))
                        continue;
                atomic_inc(&nsm->sm_count);
                goto out;
index 626b6c116a6d8eb3ef063efdaca0991ae859367c..709cf7c80545a7eb022741be3c02b9eaa6ca0a71 100644 (file)
@@ -47,6 +47,7 @@ nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res)
        }
 
        memset(&args, 0, sizeof(args));
+       args.mon_name = nsm->sm_name;
        args.addr = nsm->sm_addr.sin_addr.s_addr;
        args.prog = NLM_PROGRAM;
        args.vers = 3;
@@ -150,7 +151,7 @@ nsm_create(void)
 static u32 *
 xdr_encode_common(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp)
 {
-       char    buffer[20];
+       char    buffer[20], *name;
 
        /*
         * Use the dotted-quad IP address of the remote host as
@@ -158,8 +159,13 @@ xdr_encode_common(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp)
         * hostname first for whatever remote hostname it receives,
         * so this works alright.
         */
-       sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(argp->addr));
-       if (!(p = xdr_encode_string(p, buffer))
+       if (nsm_use_hostnames) {
+               name = argp->mon_name;
+       } else {
+               sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(argp->addr));
+               name = buffer;
+       }
+       if (!(p = xdr_encode_string(p, name))
         || !(p = xdr_encode_string(p, utsname()->nodename)))
                return ERR_PTR(-EIO);
        *p++ = htonl(argp->prog);
index 3cc369e5693f2d9af1c34e605c1ba2c615a21eae..a3b7602cd3830f52675f66fc51da42ddfe3fd2e8 100644 (file)
@@ -61,6 +61,7 @@ static DECLARE_WAIT_QUEUE_HEAD(lockd_exit);
 static unsigned long           nlm_grace_period;
 static unsigned long           nlm_timeout = LOCKD_DFLT_TIMEO;
 static int                     nlm_udpport, nlm_tcpport;
+int                            nsm_use_hostnames = 0;
 
 /*
  * Constants needed for the sysctl interface.
@@ -395,6 +396,14 @@ static ctl_table nlm_sysctls[] = {
                .extra1         = (int *) &nlm_port_min,
                .extra2         = (int *) &nlm_port_max,
        },
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "nsm_use_hostnames",
+               .data           = &nsm_use_hostnames,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec,
+       },
        { .ctl_name = 0 }
 };
 
@@ -483,6 +492,7 @@ module_param_call(nlm_udpport, param_set_port, param_get_int,
                  &nlm_udpport, 0644);
 module_param_call(nlm_tcpport, param_set_port, param_get_int,
                  &nlm_tcpport, 0644);
+module_param(nsm_use_hostnames, bool, 0644);
 
 /*
  * Initialising and terminating the module.
index 1fcf936d75b98b57392f893651645b1f1e46cbe8..7be7aeaeee58de50d7f2f225cdb3135773b4336b 100644 (file)
@@ -142,6 +142,7 @@ extern struct svc_procedure nlmsvc_procedures4[];
 #endif
 extern int                     nlmsvc_grace_period;
 extern unsigned long           nlmsvc_timeout;
+extern int                     nsm_use_hostnames;
 
 /*
  * Lockd client functions
index d93b074668ce370cd7c184448895f895e44ae734..daef509bb9b3c8823e80d15dbac950768c0c2eba 100644 (file)
@@ -28,6 +28,8 @@ struct nsm_args {
        u32             prog;           /* RPC callback info */
        u32             vers;
        u32             proc;
+
+       char *          mon_name;
 };
 
 /*