Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit abd1f500 authored by Olaf Kirch's avatar Olaf Kirch Committed by Linus Torvalds
Browse files

[PATCH] knfsd: lockd: optionally use hostnames for identifying peers



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: default avatarOlaf Kirch <okir@suse.de>
Signed-off-by: default avatarNeil Brown <neilb@suse.de>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 350fce8d
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -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;
+9 −3
Original line number Diff line number Diff line
@@ -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.
	 */
	if (nsm_use_hostnames) {
		name = argp->mon_name;
	} else {
		sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(argp->addr));
	if (!(p = xdr_encode_string(p, buffer))
		name = buffer;
	}
	if (!(p = xdr_encode_string(p, name))
	 || !(p = xdr_encode_string(p, utsname()->nodename)))
		return ERR_PTR(-EIO);
	*p++ = htonl(argp->prog);
+10 −0
Original line number Diff line number Diff line
@@ -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.
+1 −0
Original line number Diff line number Diff line
@@ -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
+2 −0
Original line number Diff line number Diff line
@@ -28,6 +28,8 @@ struct nsm_args {
	u32		prog;		/* RPC callback info */
	u32		vers;
	u32		proc;

	char *		mon_name;
};

/*