linux-nfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Chuck Lever <chuck.lever@oracle.com>
To: Chuck Lever <chuck.lever@oracle.com>
Cc: trond.myklebust@netapp.com, linux-nfs@vger.kernel.org
Subject: Re: [PATCH 11/16] NFS: Add an API for cloning an nfs_client
Date: Thu, 12 May 2011 13:30:08 -0400	[thread overview]
Message-ID: <4FFB50FE-FCD9-48C4-837B-61AAC94F9903@oracle.com> (raw)
In-Reply-To: <20110509193803.16568.61644.stgit@matisse.1015granger.net>


On May 9, 2011, at 3:38 PM, Chuck Lever wrote:

> After a migration event, we have to preserve the client ID the client
> used with the source server, and introduce it to the destination
> server, in case the migration transparently migrated state for the
> migrating FSID.
> 
> Note that our RENEW and SETCLIENTID procs both take an nfs_client as
> an argument.  Thus, after a successful migration recovery, we want to
> have a nfs_client with the correct long-form and short-form client ID
> for the destination server to pass these procs.
> 
> To preserve the client IDs, we clone the source server's nfs_client.
> The migrated FSID is moved from the original nfs_client to the cloned
> one.
> 
> This patch introduces an API for cloning an nfs_client and moving an
> FSID to it.
> 
> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
> ---
> 
> fs/nfs/client.c   |   69 +++++++++++++++++++++++++++++++++++++++++++++++++++--
> fs/nfs/internal.h |    4 +++
> 2 files changed, 71 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/nfs/client.c b/fs/nfs/client.c
> index 536b0ba..2f5e29f 100644
> --- a/fs/nfs/client.c
> +++ b/fs/nfs/client.c
> @@ -135,6 +135,7 @@ struct nfs_client_initdata {
> 	const struct nfs_rpc_ops *rpc_ops;
> 	int proto;
> 	u32 minorversion;
> +	const char *long_clientid;
> };
> 
> /*
> @@ -184,6 +185,9 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_
> 	clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED;
> 	clp->cl_minorversion = cl_init->minorversion;
> 	clp->cl_mvops = nfs_v4_minor_ops[cl_init->minorversion];
> +	if (cl_init->long_clientid != NULL)
> +		clp->cl_cached_clientid = kstrdup(cl_init->long_clientid,
> +							GFP_KERNEL);
> #endif
> 	cred = rpc_lookup_machine_cred();
> 	if (!IS_ERR(cred))
> @@ -476,6 +480,10 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat
> 		/* Match the full socket address */
> 		if (!nfs_sockaddr_cmp(sap, clap))
> 			continue;
> +		/* Match on long-form client ID */
> +		if (data->long_clientid && clp->cl_cached_clientid &&
> +		    strcmp(data->long_clientid, clp->cl_cached_clientid))
> +			continue;
> 
> 		atomic_inc(&clp->cl_count);
> 		return clp;
> @@ -1426,8 +1434,65 @@ error:
> 	return error;
> }
> 
> -/*
> - * Set up a pNFS Data Server client.
> +/**
> + * nfs4_clone_client - Clone a client after a migration event
> + * clp: nfs_client to clone
> + * sap: address of destination server
> + * salen: size of "sap" in bytes
> + * ip_addr: NUL-terminated string containing local presentation address
> + * server: nfs_server to move from "clp" to the new one
> + *
> + * Returns negative errno or zero.  nfs_client field of "server" is
> + * updated to refer to a new or existing nfs_client that matches
> + * [server address, port, version, minorversion, client ID].  The
> + * nfs_server is moved from the old nfs_client's cl_superblocks list
> + * to the new nfs_client's list.
> + */
> +int nfs4_clone_client(struct nfs_client *clp, const struct sockaddr *sap,
> +		      size_t salen, const char *ip_addr,
> +		      struct nfs_server *server)
> +{
> +	struct rpc_clnt *rpcclnt = clp->cl_rpcclient;
> +	struct nfs_client_initdata cl_init = {
> +		.addr		= sap,
> +		.addrlen	= salen,
> +		.rpc_ops	= &nfs_v4_clientops,
> +		.proto		= rpc_protocol(rpcclnt),
> +		.minorversion	= clp->cl_minorversion,
> +		.long_clientid	= clp->cl_cached_clientid,
> +	};
> +	struct nfs_client *new;
> +	int status = 0;
> +
> +	dprintk("--> %s cloning \"%s\" (client ID %llx)\n",
> +		__func__, clp->cl_hostname, clp->cl_clientid);
> +
> +	new = nfs_get_client(&cl_init, rpcclnt->cl_timeout, ip_addr,
> +				rpcclnt->cl_auth->au_flavor, 0);
> +	if (IS_ERR(new)) {
> +		dprintk("<-- %s nfs_get_client failed\n", __func__);
> +		status = PTR_ERR(new);
> +		goto out;
> +	}
> +
> +	nfs_server_remove_lists(server);
> +	server->nfs_client = new;
> +	nfs_server_insert_lists(server);
> +
> +	dprintk("<-- %s moved (%llx:%llx) to nfs_client %p\n", __func__,
> +			(unsigned long long)server->fsid.major,
> +			(unsigned long long)server->fsid.minor, new);

We may be in trouble here.

Solaris servers use the cb_ident field to recognize a callback update rather than a full SETCLIENTID.  This is because a migrate-reboot-migrate sequence can leave a destination server with a group of short form client IDs associated with the same long-form client ID.

Cloning an nfs_client creates a new nfs_client in many cases, which bumps cb_ident.  On Linux, a callback with the original cb_ident would get us the old nfs_client anyway (via idr_find()).

They are proposing that we use the callback RPC program number instead to find the right state information.

> +
> +out:
> +	return status;
> +}
> +
> +/**
> + * nfs4_set_ds_client - Set up a pNFS Data Server client
> + * mds_clp: nfs_client representing the MDS
> + * ds_addr: IP address of DS
> + * ds_addrlen: size of "ds_addr" in bytes
> + * ds_proto: transport protocol to use to contact DS
>  *
>  * Return any existing nfs_client that matches server address,port,version
>  * and minorversion.
> diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
> index f6baf5b..0bf4e67 100644
> --- a/fs/nfs/internal.h
> +++ b/fs/nfs/internal.h
> @@ -154,6 +154,10 @@ extern struct nfs_server *nfs_clone_server(struct nfs_server *,
> 					   struct nfs_fattr *);
> extern void nfs_mark_client_ready(struct nfs_client *clp, int state);
> extern int nfs4_check_client_ready(struct nfs_client *clp);
> +extern int nfs4_clone_client(struct nfs_client *clp,
> +				const struct sockaddr *sap, size_t salen,
> +				const char *ip_addr,
> +				struct nfs_server *server);
> extern struct nfs_client *nfs4_set_ds_client(struct nfs_client* mds_clp,
> 					     const struct sockaddr *ds_addr,
> 					     int ds_addrlen, int ds_proto);
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
Chuck Lever
chuck[dot]lever[at]oracle[dot]com





  reply	other threads:[~2011-05-12 17:30 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-05-09 19:36 [PATCH 00/16] Client-side migration support for 2.6.40 [take 3] Chuck Lever
2011-05-09 19:36 ` [PATCH 01/16] SUNRPC: Allow temporary blocking of an rpc client Chuck Lever
2011-05-09 19:36 ` [PATCH 02/16] SUNRPC: Use RCU to dereference the rpc_clnt.cl_xprt field Chuck Lever
2011-05-09 19:36 ` [PATCH 03/16] SUNRPC: Move clnt->cl_server into struct rpc_xprt Chuck Lever
2011-05-09 19:36 ` [PATCH 04/16] SUNRPC: Add a helper to switch the transport of the rpc_client Chuck Lever
2011-05-09 19:37 ` [PATCH 05/16] SUNRPC: Add API to acquire source address Chuck Lever
2011-05-09 19:37 ` [PATCH 06/16] NFS: Add a client-side function to display file handles Chuck Lever
2011-05-09 19:37 ` [PATCH 07/16] NFS: Save root file handle in nfs_server Chuck Lever
2011-05-09 19:37 ` [PATCH 08/16] NFS: Introduce NFS_ATTR_FATTR_V4_LOCATIONS Chuck Lever
2011-05-09 19:37 ` [PATCH 09/16] NFS: Introduce nfs4_proc_get_mig_status() Chuck Lever
2011-05-09 19:37 ` [PATCH 10/16] NFS: Add infrastructure for updating callback data Chuck Lever
2011-05-09 19:38 ` [PATCH 11/16] NFS: Add an API for cloning an nfs_client Chuck Lever
2011-05-12 17:30   ` Chuck Lever [this message]
2011-05-12 19:30     ` Trond Myklebust
2011-05-09 19:38 ` [PATCH 12/16] NFS: Add functions to swap transports during migration recovery Chuck Lever
2011-05-09 19:38 ` [PATCH 13/16] NFS: Add basic migration support to state manager thread Chuck Lever
2011-05-09 19:38 ` [PATCH 14/16] NFS: Remove "const" from "struct nfs_server *" fields Chuck Lever
2011-05-09 19:38 ` [PATCH 15/16] NFS: Add migration recovery callouts in nfs4proc.c Chuck Lever
2011-05-09 19:38 ` [PATCH 16/16] NFS: Implement support for NFS4ERR_LEASE_MOVED Chuck Lever
2011-05-09 22:48   ` Chuck Lever
2011-05-11  0:20     ` Tom Haynes
     [not found]       ` <4DC9D636.3050307-8AdZ+HgO7noAvxtiuMwx3w@public.gmane.org>
2011-05-11 14:04         ` Chuck Lever
2011-05-12 15:37       ` Chuck Lever

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=4FFB50FE-FCD9-48C4-837B-61AAC94F9903@oracle.com \
    --to=chuck.lever@oracle.com \
    --cc=linux-nfs@vger.kernel.org \
    --cc=trond.myklebust@netapp.com \
    /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;
as well as URLs for NNTP newsgroup(s).