Skip to contentSkip to conversation

NLM failover - nlm_unlock

PATCH In review Wendy Cheng 3 participants 16 messages Sep 14, 2006 – Mar 30, 2007 1 message not in the archive

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/4 NLM failover - nlm_unlock

By writing exported filesytem id into /proc/fs/nfsd/nlm_unlock, this patch walks thru lockd's global nlm_files list to release all the locks associated with the particular id. It is used to enable NFS lock failover with active-active clustered servers.

Relevant steps:
1) Exports filesystem with "fsid" option as:
/etc/exports entry> /mnt/ext3/exports *(fsid=1234,sync,rw)
2) Drops locks based on fsid by:
shell> echo 1234 > /proc/fs/nfsd/nlm_unlock

fs/lockd/svcsubs.c          |   79 +++++++++++++++++++++++++++++++++++++++++---
fs/nfsd/nfsctl.c            |   42 +++++++++++++++++++++++
include/linux/lockd/bind.h  |    5 ++
include/linux/lockd/lockd.h |    2 +
include/linux/nfsd/debug.h  |    1
5 files changed, 124 insertions(+), 5 deletions(-)
include/linux/lockd/lockd.h +2 -0
@@ -132,6 +132,7 @@ struct nlm_block {
 #define NLM_ACT_CHECK		0		/* check for locks */
 #define NLM_ACT_MARK		1		/* mark & sweep */
 #define NLM_ACT_UNLOCK		2		/* release all locks */
+#define NLM_ACT_FO_UNLOCK	3		/* failover release locks */
 
 /*
  * Global variables
@@ -195,6 +196,7 @@ void		  nlm_release_file(struct nlm_file
 void		  nlmsvc_mark_resources(void);
 void		  nlmsvc_free_host_resources(struct nlm_host *);
 void		  nlmsvc_invalidate_all(void);
+int 		  nlmsvc_fo_unlock(int *fsid);
 
 static __inline__ struct inode *
 nlmsvc_file_inode(struct nlm_file *file)
fs/lockd/svcsubs.c +74 -5

130 lines not on this page · raw message

include/linux/lockd/bind.h +5 -0
@@ -33,4 +33,9 @@ extern int	nlmclnt_proc(struct inode *, 
 extern int	lockd_up(void);
 extern void	lockd_down(void);
 
+/*
+ * NLM failover
+ */
+extern int     nlmsvc_fo_unlock(int *fsid);
+
 #endif /* LINUX_LOCKD_BIND_H */
fs/nfsd/nfsctl.c +42 -0

78 lines not on this page · raw message

include/linux/nfsd/debug.h +1 -0
@@ -32,6 +32,7 @@
 #define NFSDDBG_REPCACHE	0x0080
 #define NFSDDBG_XDR		0x0100
 #define NFSDDBG_LOCKD		0x0200
+#define NFSDDBG_CLUSTER 	0x0400
 #define NFSDDBG_ALL		0x7FFF
 #define NFSDDBG_NOCHANGE	0xFFFF
 

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

A message that is not in the archive (sent off-list or not yet received): message from Wendy Cheng on Thursday September 14

#2 lore raw

Firstly, sorry for the delay in responding to these.

Quoted 10 lines · wcheng at redhat.com

By writing exported filesytem id into /proc/fs/nfsd/nlm_unlock, this patch walks thru lockd's global nlm_files list to release all the locks associated with the particular id. It is used to enable NFS lock failover with active-active clustered servers.

Relevant steps:
1) Exports filesystem with "fsid" option as:

   /etc/exports entry> /mnt/ext3/exports *(fsid=1234,sync,rw)
2) Drops locks based on fsid by:
   shell> echo 1234 > /proc/fs/nfsd/nlm_unlock

I actually felt a bit more comfortable with the server-ip based approach, how I cannot really fault the fsid based approach, and it does seem to have some advantages, so I guess we go with it.

Quoted 20 lines

/*
+ * Get fsid from nfs_fh:
+ * return 1 if *fsid contains a valid value.
+ */

fs/lockd/svcsubs.c +16 -0
+static inline int
+nlm_fo_get_fsid(struct nfs_fh *fh, int *fsid)
+{
+	struct nfs_fhbase_new *fh_base = (struct nfs_fhbase_new *) fh->data;
+ 	int data_left = fh->size/4;
+ 
+ 	nlm_debug_print_fh("nlm_fo_find_fsid", fh);
+ 
+ 	/* From fb_version to fb_auth - at least two u32 */
+ 	if (data_left < 2)		
+ 		return 0;
+  
+ 	/* For various types, check out 
+ 	 * inlcude/linux/nfsd/nfsfsh.h
+ 	 */
+ 	if ((fh_base->fb_version != 1) ||  

fs/lockd/svcsubs.c again: · line 247

Quoted 10 lines
fs/lockd/svcsubs.c +10 -0
+ 		(fh_base->fb_auth_type != 0) ||
+ 		(fh_base->fb_fsid_type != 1))
+ 		return 0;
+ 
+ 	/* The fb_auth is 0 bytes long - imply fb_auth[0] has
+ 	 * fsid value.
+ 	 */
+ 	*fsid = (int) fh_base->fb_auth[0];
+ 	return 1;
+}

It would be really nice if this could be in the nfsd code rather than in the lockd code. Maybe if the nlm_fopen call passed back the fsid?

Quoted 6 lines
fs/lockd/svcsubs.c +2 -0
+
+/*
  * Operate on a single file
  */
 static inline int

fs/lockd/svcsubs.c nlm_inspect_file(struct nlm_host *host, · line 273

Quoted 9 lines
fs/lockd/svcsubs.c +2 -2
@@ -234,21 +267,42 @@ nlm_inspect_file(struct nlm_host *host, 
  * Loop over all files in the file table.
  */
 static int
-nlm_traverse_files(struct nlm_host *host, int action)
+nlm_traverse_files(struct nlm_host *host, int *fsidp, int action)
 {
 	struct nlm_file	*file, **fp;
-	int i, ret = 0;
+	int i, ret = 0, found, fsid_in=0, fsid, act=action;

Unfortunately all of this will have to change due to Olaf's recent changes in lockd. Should be quite do-able, just needs to be different.

fs/lockd/svcsubs.c nlmsvc_invalidate_all(void) · line 405

Quoted 10 lines
fs/lockd/svcsubs.c +10 -0
+/*
+ * release locks associated with an export fsid upon failover
+ */
+int
+nlmsvc_fo_unlock(int *fsid)
+{
+	/* drop the locks */
+	return (nlm_traverse_files(NULL, fsid, NLM_ACT_FO_UNLOCK)); 
+}
+

I really don't think fsid should be an 'int *', just an int. Other callers of nlm_traverse_files can just pass an fsid of 0 - they don't need to be able to pass NULL.

NeilBrown

#3 lore raw
Quoted 14 lines · Neil Brown
Quoted 11 lines · wcheng at redhat.com

By writing exported filesytem id into /proc/fs/nfsd/nlm_unlock, this patch walks thru lockd's global nlm_files list to release all the locks associated with the particular id. It is used to enable NFS lock failover with active-active clustered servers.

Relevant steps:
1) Exports filesystem with "fsid" option as:

   /etc/exports entry> /mnt/ext3/exports *(fsid=1234,sync,rw)
2) Drops locks based on fsid by:
   shell> echo 1234 > /proc/fs/nfsd/nlm_unlock
Quoted 4 lines

I actually felt a bit more comfortable with the server-ip based approach, how I cannot really fault the fsid based approach, and it does seem to have some advantages, so I guess we go with it.

Neil,

I replaced the checking inside nlm_traverse_files with nlm_file_inuse() as we discussed in:
http://sourceforge.net/mailarchive/forum.php?thread_id=31885384&forum_id=4930

If a separate patch is a better idea, feel free to yank it out. The code is based on 2.6.21.rc4 kernel and can be used independently (without other NLM failover patches). We submit it earlier (others still being worked on) to avoid the tedious rebase efforts. There are also customer requests from our distribution to ask for this function in a single server (no cluster) environment.

-- Wendy

-------------- next part --------------
A non-text attachment was scrubbed...
Name: nlm_unlock.patch
Type: text/x-patch
Size: 8956 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/cluster-devel/attachments/20070323/c90f29b2/attachment.bin>

#4 lore raw

[Cluster-devel] Re: [NFS] [PATCH 2/4 Revised] NLM failover - nlm_set_igrace

In reply to a message not in the archive
Quoted 9 lines · wcheng at redhat.com

This change enables per NFS-export entry lockd grace period. The implementation is based on a double linked list fo_fsid_list that contains entries of fsid info. It is expected this would not be a frequent event. The fo_fsid_list is short and the entries expire within a maximum of 50 seconds. The grace period setting follows the existing NLM grace period handling logic and is triggered via echoing the NFS export filesystem id into nfsd procfs entry as:

shell> echo 1234 > /proc/fs/nfsd/nlm_set_igrace

What is the 'i' for?
How about /proc/fs/nfsd/nlm_set_grace_for_fsid ??

include/linux/lockd/lockd.h struct nlm_file { · line 110

Quoted 7 lines
include/linux/lockd/lockd.h +1 -0
@@ -107,6 +107,17 @@ struct nlm_file {
 	int		       	f_hash;		/* hash of f_handle */
 };
 
+#define NLM_FO_MAX_FSID_GP	127

Why do you need this limit?

include/linux/lockd/lockd.h struct nlm_file { · line 115

Quoted 5 lines
include/linux/lockd/lockd.h +5 -0
+ *
+ * Also, please don't ask why using opencoded list manipulation, 
+ * instead of <linux/list.h>, unless you can point to me where
+ * in that file have existing macro and/or functions that can do
+ * single linked list. 

I don't think this comment is appropriate any more. You are using list.h lists, not open coding them.

Quoted 6 lines
include/linux/lockd/lockd.h +6 -0
+	/* check to see whether this_fsid is in fo_fsid_list list */
+	list_for_each_safe(p, tlist, &fo_fsid_list) {
+		e_this = list_entry(p, struct fo_fsid, g_list);
+		if (time_before(e_this->g_expire, jiffies)) {
+			printk("lockd: fsid=%d grace period expires\n",
+				e_this->g_fsid);

include/linux/lockd/lockd.h struct nlm_file {

Quoted 10 lines
include/linux/lockd/lockd.h +10 -0
+			list_del(p);
+			fo_fsid_cnt--;
+			kfree(e_this);
+		} else if (e_this->g_fsid == this_fsid) {
+			if (!e_this->g_flag) {
+				e_this->g_flag = 1;
+				printk("lockd: fsid=%d in grace period\n",
+					e_this->g_fsid);
+			}
+			rc = 1;

I assume this 'g_flag' was just for debugging. Can it be take out now?
Also, I though you should break out of the loop once you set rc = 1.

include/linux/lockd/lockd.h nlm4svc_proc_test(struct svc_rqst *rqstp · line 108

Quoted 11 lines

* Obtain client and file from arguments
*/

include/linux/lockd/lockd.h +1 -1
@@ -89,7 +102,7 @@ nlm4svc_proc_test(struct svc_rqst *rqstp
 	resp->cookie = argp->cookie;
 
 	/* Don't accept test requests during grace period */
-	if (nlmsvc_grace_period) {
+	if ((nlmsvc_grace_period) || (nlm4svc_fo_grace_period(argp))) {
 		resp->status = nlm_lck_denied_grace_period;
 		return rpc_success;
 	}

I think this (and the rest) would look cleaner if you put the 'nlmsvc_grace_period' test into the nlm4svc_fo_grace_period function.

NeilBrown

#5 lore raw

[Cluster-devel] Re: [NFS] [PATCH 2/4 Revised] NLM failover - nlm_set_igrace

Revised patch based on 2.6.21-rc4.

The change enables per NFS-export entry lockd grace period. A linked list, fo_fsid_list, contains entries of fsid info. This list is expected to be short and entries expire within a maximum of 50 seconds. It follows the existing NLM grace period handling logic and is triggered via echoing the NFS export filesystem id (fsid) into nfsd procfs entry as:

shell> echo 1234 > /proc/fs/nfsd/nlm_set_grace_for_fsid

-- Wendy

-------------- next part --------------
A non-text attachment was scrubbed...
Name: nlm_grace.patch
Type: text/x-patch
Size: 15229 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/cluster-devel/attachments/20070326/8b4c1701/attachment.bin>

#6 lore raw

[Cluster-devel] Re: [NFS] [PATCH 2/4 Revised] NLM failover - nlm_set_igrace

Quoted 1 line · Wendy Cheng

Revised patch based on 2.6.21-rc4.

Were there supposed to be 4 patches? If so, where can I find the full series?

--b.

-------------------------------------------------------------------------
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 - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

#7 lore raw

[Cluster-devel] Re: [NFS] [PATCH 2/4 Revised] NLM failover - nlm_set_igrace

Quoted 13 lines · J. Bruce Fields
Quoted 3 lines · Wendy Cheng

Revised patch based on 2.6.21-rc4.

Were there supposed to be 4 patches? If so, where can I find the full series?

--b.

These are revised patches based on the discussion we had last September (shame on me to put this off for so long).

General description:
https://www.redhat.com/archives/cluster-devel/2006-September/msg00034.html
Patch 4-1 is based on:
https://www.redhat.com/archives/cluster-devel/2006-September/msg00035.html
new patch at:
https://www.redhat.com/archives/cluster-devel/2007-March/msg00218.html
Patch 4-2 is based on:
https://www.redhat.com/archives/cluster-devel/2006-September/msg00036.html
new patch at:
https://www.redhat.com/archives/cluster-devel/2007-March/msg00231.html
patch 4-3 original patch on:
https://www.redhat.com/archives/cluster-devel/2006-September/msg00037.html
For 2.6.21 kernel, this patch is no longer needed. Patch 4.4 is nfs-utils (user mode) original patch on:
https://www.redhat.com/archives/cluster-devel/2006-September/msg00038.html
New patch: to be followed.

-- Wendy

-------------------------------------------------------------------------
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 - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

#8 lore raw

[Cluster-devel] Re: [NFS] [PATCH 2/4 Revised] NLM failover - nlm_set_igrace

Quoted 1 line · Wendy Cheng

These are revised patches based on the discussion we had last September

OK. Would you remind just resending the revised versions of all of them whenever they're ready?

It's just that applying patches off a web email archive is a bit of a pain (there's all this &amp; stuff to deal with, and who knows what it does to the whitespace), while we all have piles of scripts to deal with plain emailed patches....

Looks like interesting stuff.

--b.

-------------------------------------------------------------------------
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 - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

#9 lore raw

[Cluster-devel] Re: [NFS] [PATCH 2/4 Revised] NLM failover - nlm_set_igrace

Quoted 10 lines · J. Bruce Fields
Quoted 3 lines · Wendy Cheng

These are revised patches based on the discussion we had last September

OK. Would you remind just resending the revised versions of all of them whenever they're ready?

Quoted 10 lines

It's just that applying patches off a web email archive is a bit of a pain (there's all this &amp; stuff to deal with, and who knows what it does to the whitespace), while we all have piles of scripts to deal with plain emailed patches....

Looks like interesting stuff.

--b.

Will do. We have one more patch (user space statd) to finish up - need to look into what has been changed in Neil's new nfs-util release. I could be his first tester (a scary thought :))..

-- Wendy

-------------------------------------------------------------------------
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 - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

#10 lore raw

[Cluster-devel] Re: [NFS] [PATCH 3/4 Revised] NLM failover - statd changes

In reply to a message not in the archive
Quoted 51 lines · wcheng at redhat.com

This kernel patch should be paired with nfs-utils user mode changes (in patch 4-4 based on nfs-utils-1.0.8-rc4) that is optional. If changes made in patch 4-4 is not presented in nfs-utils, the rpc.statd will ignore whatever this kernel patch does.

The changes record the ip interface that accepts the lock requests and passes the correct "my_name" (in standard IPV4 dot notation) to user mode statd (instead of system_utsname.nodename). This enables rpc.statd to add the correct taken-over IPv4 address into the 3rd parameter of ha_callout program. Current nfs-utils always resets "my_name" into loopback address (127.0.0.1), regardless the statement made in rpc.statd man page. Check out "man rpc.statd" for details.

 fs/lockd/host.c                |    4 ++--
 fs/lockd/mon.c                 |   21 +++++++++++++++++----
 fs/lockd/svc4proc.c            |    8 +++++++-
 fs/lockd/svcproc.c             |    2 +-
 include/linux/lockd/lockd.h    |    5 +++--
 include/linux/lockd/sm_inter.h |    1 +
 include/linux/sunrpc/svc.h     |    5 +++--
 net/sunrpc/svcsock.c           |    5 +++++
 8 files changed, 39 insertions(+), 12 deletions(-)
include/linux/sunrpc/svc.h +3 -2
@@ -102,6 +102,7 @@ static inline void svc_putu32(struct kve
 	iov->iov_len += sizeof(u32);
 }
 
+typedef __u32  svc_addr_t;
 
 /*
  * The context of a single thread, including the request currently being
@@ -138,8 +139,8 @@ struct svc_rqst {
 	unsigned short
 				rq_secure  : 1;	/* secure port */
 
-
-	__u32			rq_daddr;	/* dest addr of request - reply from here */
+	svc_addr_t		rq_daddr;	/* dest addr of request 
+						   - reply from here */
 
 	void *			rq_argp;	/* decoded arguments */
 	void *			rq_resp;	/* xdr'd results */

include/linux/lockd/lockd.h line 42

Quoted 4 lines
include/linux/lockd/lockd.h +1 -0
@@ -39,12 +39,13 @@
 struct nlm_host {
 	struct nlm_host *	h_next;		/* linked list (hash table) */
 	struct sockaddr_in	h_addr;		/* peer address */
+	svc_addr_t		h_server;	/* server ip for NLM failover */

Comment should say 'or 0 for client'.

include/linux/lockd/lockd.h line 48

Quoted 7 lines
include/linux/lockd/lockd.h +1 -1
 	struct rpc_clnt	*	h_rpcclnt;	/* RPC client to talk to peer */
 	char			h_name[20];	/* remote hostname */
 	u32			h_version;	/* interface version */
 	unsigned short		h_proto;	/* transport proto */
 	unsigned short		h_reclaiming : 1,
-				h_server     : 1, /* server side, not client side */
+				h_notused    : 1, 

Just discard this, no need to rename it to 'h_notused'.

include/linux/lockd/lockd.h

Quoted 6 lines
include/linux/lockd/lockd.h +5 -0
+#if 0
+	if (argp->reclaim) {
+		printk("nlm4svc_proc_lock lock reclaim received\n");
+	}
+#endif

Can this be removed?

So: mostly looks OK, but will need quite a bit of reworking do to recent changes in lockd code. So if you can get me a version that applies to latest -mm, I'll take it from there.

Thanks,
NeilBrown

#11 lore raw

[Cluster-devel] Re: [NFS] [PATCH 3/4 Revised] NLM failover - statd changes

Quoted 6 lines · Neil Brown

So: mostly looks OK, but will need quite a bit of reworking do to recent changes in lockd code. So if you can get me a version that applies to latest -mm, I'll take it from there.

Thanks ! I'm tied with another issue at this moment but will get this done (and tested) sometime next week.

-- Wendy

#12 lore raw

PATCH 2/4 NLM failover - nlm_set_igrace

This change enables per NFS-export entry lockd grace period. The implementation is based on a double linked list fo_fsid_list that contains entries of fsid info. It is expected this would not be a frequent event. The fo_fsid_list is short and the entries expire within a maximum of 50 seconds. The grace period setting follows the existing NLM grace period handling logic and is triggered via echoing the NFS export filesystem id into nfsd procfs entry as:

shell> echo 1234 > /proc/fs/nfsd/nlm_set_igrace

fs/lockd/svc.c              |    8 +
fs/lockd/svc4proc.c         |   28 +++++-
fs/lockd/svcproc.c          |   29 +++++--
fs/lockd/svcsubs.c          |  180 ++++++++++++++++++++++++++++++++++++++++++++
fs/nfsd/nfsctl.c            |   32 +++++++
include/linux/lockd/bind.h  |    3
include/linux/lockd/lockd.h |   14 +++
7 files changed, 279 insertions(+), 15 deletions(-)
include/linux/lockd/lockd.h +14 -0
@@ -107,6 +107,17 @@ struct nlm_file {
 	int		       	f_hash;		/* hash of f_handle */
 };
 
+#define NLM_FO_MAX_FSID_GP	127
+
+/* Server fsid linked list for NLM lock failover */
+struct fo_fsid {
+	struct list_head	g_list;		/* linked list */
+	unsigned long		g_expire;	/* when this grace period
+						 * will expire */
+	int			g_fsid;		/* exported fsid */
+	int			g_flag;		/* printk flag */
+};
+
 /*
  * This is a server block (i.e. a lock requested by some client which
  * couldn't be granted because of a conflicting lock).
@@ -187,6 +198,8 @@ void		  nlmsvc_traverse_blocks(struct nl
 					int action);
 void	  nlmsvc_grant_reply(struct svc_rqst *, struct nlm_cookie *, u32);
 
+unsigned long set_grace_period(void); /*required by svcsubs.c and svc.c 
+					to support nlm failover */
 /*
  * File handling for the server personality
  */
@@ -197,6 +210,7 @@ void		  nlmsvc_mark_resources(void);
 void		  nlmsvc_free_host_resources(struct nlm_host *);
 void		  nlmsvc_invalidate_all(void);
 int 		  nlmsvc_fo_unlock(int *fsid);
+int 		  nlmsvc_fo_check(struct nfs_fh *fh);
 
 static __inline__ struct inode *
 nlmsvc_file_inode(struct nlm_file *file)
fs/lockd/svcsubs.c +180 -0

189 lines not on this page · raw message

include/linux/lockd/bind.h +3 -0
@@ -37,5 +37,8 @@ extern void	lockd_down(void);
  * NLM failover
  */
 extern int     nlmsvc_fo_unlock(int *fsid);
+extern int     nlmsvc_fo_setgrace(int fsid);
+extern void    nlmsvc_fo_reset_servs(void);
+
 
 #endif /* LINUX_LOCKD_BIND_H */
fs/nfsd/nfsctl.c +32 -0
@@ -56,6 +56,7 @@ enum {
 	NFSD_List,
 	NFSD_Fh,
 	NFSD_NlmUnlock,
+	NFSD_NlmIgrace,
 	NFSD_Threads,
 	NFSD_Versions,
 	/*
@@ -93,6 +94,7 @@ static ssize_t write_recoverydir(struct 
 #define NFSDDBG_FACILITY	NFSDDBG_CLUSTER
 
 static ssize_t write_fo_unlock(struct file *file, char *buf, size_t size);
+static ssize_t write_fo_grace(struct file *file, char *buf, size_t size);
 
 static ssize_t (*write_op[])(struct file *, char *, size_t) = {
 	[NFSD_Svc] = write_svc,
@@ -104,6 +106,7 @@ static ssize_t (*write_op[])(struct file
 	[NFSD_Getfs] = write_getfs,
 	[NFSD_Fh] = write_filehandle,
 	[NFSD_NlmUnlock] = write_fo_unlock,
+	[NFSD_NlmIgrace] = write_fo_grace,
 	[NFSD_Threads] = write_threads,
 	[NFSD_Versions] = write_versions,
 #ifdef CONFIG_NFSD_V4
@@ -375,6 +378,34 @@ static ssize_t write_fo_unlock(struct fi
 	return strlen(buf);
 }
 
+static ssize_t write_fo_grace(struct file *file, char *buf, size_t size)
+{
+	char *mesg = buf;
+	int fsid, rc;
+ 
+	if (size <= 0) return -EINVAL;
+ 
+	/* convert string into a valid fsid */
+	rc = get_int(&mesg, &fsid);
+	if (rc) {
+		dprintk("do_nlm_fsid_grace: invalid fsid (%s)\n", buf);
+		return rc;
+	}
+ 
+	/* call nlm to set the grace period */
+	rc = nlmsvc_fo_setgrace(fsid);
+	if (rc) {
+		dprintk("nlmsvc_fo_setgrace return rc=%d\n", rc);
+		return rc;
+	}
+ 
+	dprintk("nlm set fsid=%d grace period\n", fsid);
+ 
+	/* done */
+	sprintf(buf, "nlm set per fsid=%d grace period\n", fsid);
+	return strlen(buf);
+}
+
 extern int nfsd_nrthreads(void);
 
 static ssize_t write_threads(struct file *file, char *buf, size_t size)
@@ -524,6 +555,7 @@ static int nfsd_fill_super(struct super_
 		[NFSD_List] = {"exports", &exports_operations, S_IRUGO},
 		[NFSD_Fh] = {"filehandle", &transaction_ops, S_IWUSR|S_IRUSR},
 		[NFSD_NlmUnlock] = {"nlm_unlock", &transaction_ops, S_IWUSR|S_IRUSR},
+		[NFSD_NlmIgrace] = {"nlm_set_igrace", &transaction_ops, S_IWUSR|S_IRUSR},
 		[NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR},
 		[NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR},
 #ifdef CONFIG_NFSD_V4
fs/lockd/svc4proc.c +21 -7
@@ -18,9 +18,22 @@
 #include <linux/lockd/share.h>
 #include <linux/lockd/sm_inter.h>
 
-
 #define NLMDBG_FACILITY		NLMDBG_CLIENT
 
+extern struct list_head fo_fsid_list;
+
+/* 
+ * Check for per filesystem failover grace period 
+ */
+static inline int
+nlm4svc_fo_grace_period(struct nlm_args *argp) 
+{
+	if (unlikely(!list_empty(&fo_fsid_list)))
+		return(nlmsvc_fo_check(&argp->lock.fh));
+
+	return 0;
+}
+
 /*
  * Obtain client and file from arguments
  */
@@ -89,7 +102,7 @@ nlm4svc_proc_test(struct svc_rqst *rqstp
 	resp->cookie = argp->cookie;
 
 	/* Don't accept test requests during grace period */
-	if (nlmsvc_grace_period) {
+	if ((nlmsvc_grace_period) || (nlm4svc_fo_grace_period(argp))) {
 		resp->status = nlm_lck_denied_grace_period;
 		return rpc_success;
 	}
@@ -119,7 +132,8 @@ nlm4svc_proc_lock(struct svc_rqst *rqstp
 	resp->cookie = argp->cookie;
 
 	/* Don't accept new lock requests during grace period */
-	if (nlmsvc_grace_period && !argp->reclaim) {
+	if ((nlmsvc_grace_period || (nlm4svc_fo_grace_period(argp))) 
+			&& !argp->reclaim) {
 		resp->status = nlm_lck_denied_grace_period;
 		return rpc_success;
 	}
@@ -162,7 +176,7 @@ nlm4svc_proc_cancel(struct svc_rqst *rqs
 	resp->cookie = argp->cookie;
 
 	/* Don't accept requests during grace period */
-	if (nlmsvc_grace_period) {
+	if ((nlmsvc_grace_period || (nlm4svc_fo_grace_period(argp)))) {
 		resp->status = nlm_lck_denied_grace_period;
 		return rpc_success;
 	}
@@ -195,7 +209,7 @@ nlm4svc_proc_unlock(struct svc_rqst *rqs
 	resp->cookie = argp->cookie;
 
 	/* Don't accept new lock requests during grace period */
-	if (nlmsvc_grace_period) {
+	if (nlmsvc_grace_period || (nlm4svc_fo_grace_period(argp))) {
 		resp->status = nlm_lck_denied_grace_period;
 		return rpc_success;
 	}
@@ -330,7 +344,7 @@ nlm4svc_proc_share(struct svc_rqst *rqst
 	resp->cookie = argp->cookie;
 
 	/* Don't accept new lock requests during grace period */
-	if (nlmsvc_grace_period && !argp->reclaim) {
+	if ((nlmsvc_grace_period ||(nlm4svc_fo_grace_period(argp))) && !argp->reclaim) {
 		resp->status = nlm_lck_denied_grace_period;
 		return rpc_success;
 	}
@@ -363,7 +377,7 @@ nlm4svc_proc_unshare(struct svc_rqst *rq
 	resp->cookie = argp->cookie;
 
 	/* Don't accept requests during grace period */
-	if (nlmsvc_grace_period) {
+	if (nlmsvc_grace_period || (nlm4svc_fo_grace_period(argp))) {
 		resp->status = nlm_lck_denied_grace_period;
 		return rpc_success;
 	}
fs/lockd/svcproc.c +23 -6
@@ -50,6 +50,21 @@ cast_to_nlm(u32 status, u32 vers)
 #endif
 
 /*
+ * Check for per filesystem failover grace period 
+ */
+
+extern struct list_head fo_fsid_list;
+
+int inline
+nlmsvc_fo_grace_period(struct nlm_args *argp)
+{
+	if (unlikely(!list_empty(&fo_fsid_list)))
+		return(nlmsvc_fo_check(&argp->lock.fh));
+
+	return 0;
+}
+
+/*
  * Obtain client and file from arguments
  */
 static u32
@@ -115,7 +130,7 @@ nlmsvc_proc_test(struct svc_rqst *rqstp,
 	resp->cookie = argp->cookie;
 
 	/* Don't accept test requests during grace period */
-	if (nlmsvc_grace_period) {
+	if (nlmsvc_grace_period || (nlmsvc_fo_grace_period(argp))) {
 		resp->status = nlm_lck_denied_grace_period;
 		return rpc_success;
 	}
@@ -146,7 +161,8 @@ nlmsvc_proc_lock(struct svc_rqst *rqstp,
 	resp->cookie = argp->cookie;
 
 	/* Don't accept new lock requests during grace period */
-	if (nlmsvc_grace_period && !argp->reclaim) {
+	if ((nlmsvc_grace_period || (nlmsvc_fo_grace_period(argp))) 
+			&& !argp->reclaim) {
 		resp->status = nlm_lck_denied_grace_period;
 		return rpc_success;
 	}
@@ -189,7 +205,7 @@ nlmsvc_proc_cancel(struct svc_rqst *rqst
 	resp->cookie = argp->cookie;
 
 	/* Don't accept requests during grace period */
-	if (nlmsvc_grace_period) {
+	if (nlmsvc_grace_period || nlmsvc_fo_grace_period(argp)) {
 		resp->status = nlm_lck_denied_grace_period;
 		return rpc_success;
 	}
@@ -222,7 +238,7 @@ nlmsvc_proc_unlock(struct svc_rqst *rqst
 	resp->cookie = argp->cookie;
 
 	/* Don't accept new lock requests during grace period */
-	if (nlmsvc_grace_period) {
+	if (nlmsvc_grace_period || nlmsvc_fo_grace_period(argp)) {
 		resp->status = nlm_lck_denied_grace_period;
 		return rpc_success;
 	}
@@ -359,7 +375,8 @@ nlmsvc_proc_share(struct svc_rqst *rqstp
 	resp->cookie = argp->cookie;
 
 	/* Don't accept new lock requests during grace period */
-	if (nlmsvc_grace_period && !argp->reclaim) {
+	if ((nlmsvc_grace_period || (nlmsvc_fo_grace_period(argp))) 
+			&& !argp->reclaim) {
 		resp->status = nlm_lck_denied_grace_period;
 		return rpc_success;
 	}
@@ -392,7 +409,7 @@ nlmsvc_proc_unshare(struct svc_rqst *rqs
 	resp->cookie = argp->cookie;
 
 	/* Don't accept requests during grace period */
-	if (nlmsvc_grace_period) {
+	if (nlmsvc_grace_period || nlmsvc_fo_grace_period(argp)) {
 		resp->status = nlm_lck_denied_grace_period;
 		return rpc_success;
 	}
fs/lockd/svc.c +6 -2
@@ -71,7 +71,7 @@ static const int		nlm_port_min = 0, nlm_
 
 static struct ctl_table_header * nlm_sysctl_table;
 
-static unsigned long set_grace_period(void)
+unsigned long set_grace_period(void)
 {
 	unsigned long grace_period;
 
@@ -81,7 +81,6 @@ static unsigned long set_grace_period(vo
 				/ nlm_timeout) * nlm_timeout * HZ;
 	else
 		grace_period = nlm_timeout * 5 * HZ;
-	nlmsvc_grace_period = 1;
 	return grace_period + jiffies;
 }
 
@@ -129,6 +128,8 @@ lockd(struct svc_rqst *rqstp)
 	nlmsvc_timeout = nlm_timeout * HZ;
 
 	grace_period_expire = set_grace_period();
+	nlmsvc_grace_period = 1;
+	(void) nlmsvc_fo_reset_servs();
 
 	/*
 	 * The main request loop. We don't terminate until the last
@@ -143,6 +144,8 @@ lockd(struct svc_rqst *rqstp)
 			if (nlmsvc_ops) {
 				nlmsvc_invalidate_all();
 				grace_period_expire = set_grace_period();
+				nlmsvc_grace_period = 1;
+				(void) nlmsvc_fo_reset_servs();
 			}
 		}
 
@@ -189,6 +192,7 @@ lockd(struct svc_rqst *rqstp)
 			nlmsvc_invalidate_all();
 		nlm_shutdown_hosts();
 		nlmsvc_pid = 0;
+		(void) nlmsvc_fo_reset_servs();
 	} else
 		printk(KERN_DEBUG
 			"lockd: new process, skipping host shutdown\n");

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

#13 lore raw

PATCH 3/4 NLM failover - statd changes

This kernel patch should be paired with nfs-utils user mode changes (in patch 4-4 based on nfs-utils-1.0.8-rc4) that is optional. If changes made in patch 4-4 is not presented in nfs-utils, the rpc.statd will ignore whatever this kernel patch does.

The changes record the ip interface that accepts the lock requests and passes the correct "my_name" (in standard IPV4 dot notation) to user mode statd (instead of system_utsname.nodename). This enables rpc.statd to add the correct taken-over IPv4 address into the 3rd parameter of ha_callout program. Current nfs-utils always resets "my_name" into loopback address (127.0.0.1), regardless the statement made in rpc.statd man page. Check out "man rpc.statd" for details.

fs/lockd/host.c                |    4 ++--
fs/lockd/mon.c                 |   21 +++++++++++++++++----
fs/lockd/svc4proc.c            |    8 +++++++-
fs/lockd/svcproc.c             |    2 +-
include/linux/lockd/lockd.h    |    5 +++--
include/linux/lockd/sm_inter.h |    1 +
include/linux/sunrpc/svc.h     |    5 +++--
net/sunrpc/svcsock.c           |    5 +++++
8 files changed, 39 insertions(+), 12 deletions(-)
include/linux/sunrpc/svc.h +3 -2
@@ -102,6 +102,7 @@ static inline void svc_putu32(struct kve
 	iov->iov_len += sizeof(u32);
 }
 
+typedef __u32  svc_addr_t;
 	
 /*
  * The context of a single thread, including the request currently being
@@ -138,8 +139,8 @@ struct svc_rqst {
 	unsigned short
 				rq_secure  : 1;	/* secure port */
 
-
-	__u32			rq_daddr;	/* dest addr of request - reply from here */
+	svc_addr_t		rq_daddr;	/* dest addr of request 
+						   - reply from here */
 
 	void *			rq_argp;	/* decoded arguments */
 	void *			rq_resp;	/* xdr'd results */
include/linux/lockd/lockd.h +3 -2
@@ -39,12 +39,13 @@
 struct nlm_host {
 	struct nlm_host *	h_next;		/* linked list (hash table) */
 	struct sockaddr_in	h_addr;		/* peer address */
+	svc_addr_t		h_server;	/* server ip for NLM failover */
 	struct rpc_clnt	*	h_rpcclnt;	/* RPC client to talk to peer */
 	char			h_name[20];	/* remote hostname */
 	u32			h_version;	/* interface version */
 	unsigned short		h_proto;	/* transport proto */
 	unsigned short		h_reclaiming : 1,
-				h_server     : 1, /* server side, not client side */
+				h_notused    : 1, 
 				h_inuse      : 1,
 				h_killed     : 1,
 				h_monitored  : 1;
@@ -175,7 +176,7 @@ int		  nlmclnt_reclaim(struct nlm_host *
  */
 struct nlm_host * nlmclnt_lookup_host(struct sockaddr_in *, int, int);
 struct nlm_host * nlmsvc_lookup_host(struct svc_rqst *);
-struct nlm_host * nlm_lookup_host(int server, struct sockaddr_in *, int, int);
+struct nlm_host * nlm_lookup_host(svc_addr_t server, struct sockaddr_in *, int, int);
 struct rpc_clnt * nlm_bind_host(struct nlm_host *);
 void		  nlm_rebind_host(struct nlm_host *);
 struct nlm_host * nlm_get_host(struct nlm_host *);
include/linux/lockd/sm_inter.h +1 -0
@@ -25,6 +25,7 @@
  */
 struct nsm_args {
 	u32		addr;		/* remote address */
+	u32		serv;		/* server ip address */
 	u32		prog;		/* RPC callback info */
 	u32		vers;
 	u32		proc;
net/sunrpc/svcsock.c +5 -0
@@ -454,6 +454,7 @@ svc_recvfrom(struct svc_rqst *rqstp, str
 	struct msghdr	msg;
 	struct socket	*sock;
 	int		len, alen;
+	struct sockaddr_in   daddr;
 
 	rqstp->rq_addrlen = sizeof(rqstp->rq_addr);
 	sock = rqstp->rq_sock->sk_sock;
@@ -474,6 +475,10 @@ svc_recvfrom(struct svc_rqst *rqstp, str
 	alen = sizeof(rqstp->rq_addr);
 	sock->ops->getname(sock, (struct sockaddr *)&rqstp->rq_addr, &alen, 1);
 
+	/* add server ip for nlm lock failover */
+	sock->ops->getname(sock, (struct sockaddr *)&daddr, &alen, 0);
+	rqstp->rq_daddr = daddr.sin_addr.s_addr;
+
 	dprintk("svc: socket %p recvfrom(%p, %Zu) = %d\n",
 		rqstp->rq_sock, iov[0].iov_base, iov[0].iov_len, len);
 
fs/lockd/svc4proc.c +7 -1
@@ -138,6 +138,12 @@ nlm4svc_proc_lock(struct svc_rqst *rqstp
 		return rpc_success;
 	}
 
+#if 0
+	if (argp->reclaim) {
+		printk("nlm4svc_proc_lock lock reclaim received\n");
+	}
+#endif
+
 	/* Obtain client and file */
 	if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file)))
 		return rpc_success;
@@ -462,7 +468,7 @@ nlm4svc_proc_sm_notify(struct svc_rqst *
 	} else {
 		/* If we run on an NFS server, delete all locks held by the client */
 
-		if ((host = nlm_lookup_host(1, &saddr, prot, vers)) != NULL) {
+		if ((host = nlm_lookup_host(rqstp->rq_daddr, &saddr, prot, vers)) != NULL) {
 			nlmsvc_free_host_resources(host);
 			nlm_release_host(host);
 		}
fs/lockd/svcproc.c +1 -1
@@ -491,7 +491,7 @@ nlmsvc_proc_sm_notify(struct svc_rqst *r
 		}
 	} else {
 		/* If we run on an NFS server, delete all locks held by the client */
-		if ((host = nlm_lookup_host(1, &saddr, prot, vers)) != NULL) {
+		if ((host = nlm_lookup_host(rqstp->rq_daddr, &saddr, prot, vers)) != NULL) {
 			nlmsvc_free_host_resources(host);
 			nlm_release_host(host);
 		}
fs/lockd/mon.c +17 -4
@@ -47,7 +47,8 @@ nsm_mon_unmon(struct nlm_host *host, u32
 	}
 
 	args.addr = host->h_addr.sin_addr.s_addr;
-	args.proto= (host->h_proto<<1) | host->h_server;
+	args.serv = host->h_server;
+	args.proto= (host->h_proto<<1) | (host->h_server ? 1:0);
 	args.prog = NLM_PROGRAM;
 	args.vers = host->h_version;
 	args.proc = NLMPROC_NSM_NOTIFY;
@@ -135,6 +136,13 @@ out_err:
 	return clnt;
 }
 
+/* We want "buffer" in xdr_encode_common() to hold
+ * either the system_utsname.nodename string (__NEW_UTS_LEN+1)
+ * or IPv4 dot notation (16 bytes+1) for now.
+ */ 
+
+#define	XDR_ENCODE_BUF_LEN __NEW_UTS_LEN+1	
+
 /*
  * XDR functions for NSM.
  */
@@ -142,7 +150,7 @@ out_err:
 static u32 *
 xdr_encode_common(struct rpc_rqst *rqstp, u32 *p, struct nsm_args *argp)
 {
-	char	buffer[20];
+	char	buffer[XDR_ENCODE_BUF_LEN];
 
 	/*
 	 * Use the dotted-quad IP address of the remote host as
@@ -151,8 +159,13 @@ xdr_encode_common(struct rpc_rqst *rqstp
 	 * so this works alright.
 	 */
 	sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(argp->addr));
-	if (!(p = xdr_encode_string(p, buffer))
-	 || !(p = xdr_encode_string(p, system_utsname.nodename)))
+	if (!(p = xdr_encode_string(p, buffer)))
+		return ERR_PTR(-EIO);
+	if (argp->serv)
+		sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(argp->serv));
+	else
+		sprintf(buffer, "%s", system_utsname.nodename);
+	if (!(p = xdr_encode_string(p, buffer)))
 		return ERR_PTR(-EIO);
 	*p++ = htonl(argp->prog);
 	*p++ = htonl(argp->vers);
fs/lockd/host.c +2 -2
@@ -51,7 +51,7 @@ nlmclnt_lookup_host(struct sockaddr_in *
 struct nlm_host *
 nlmsvc_lookup_host(struct svc_rqst *rqstp)
 {
-	return nlm_lookup_host(1, &rqstp->rq_addr,
+	return nlm_lookup_host(rqstp->rq_daddr, &rqstp->rq_addr,
 			       rqstp->rq_prot, rqstp->rq_vers);
 }
 
@@ -59,7 +59,7 @@ nlmsvc_lookup_host(struct svc_rqst *rqst
  * Common host lookup routine for server & client
  */
 struct nlm_host *
-nlm_lookup_host(int server, struct sockaddr_in *sin,
+nlm_lookup_host(svc_addr_t server, struct sockaddr_in *sin,
 					int proto, int version)
 {
 	struct nlm_host	*host, **hp;

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

#14 lore raw

PATCH 3/4 NLM failover - statd changes

Just did a browsing on 2.6.21.rc4 statd code (also with few quick test runs to confirm). Look like this patch is no longer needed. I tentatively withdraw this patch. Will continue the test this week. A summary will be sent after all the testings are completed.

-- Wendy

#15 lore raw

PATCH 3/4 NLM failover - statd changes

Quoted 5 lines · Wendy Cheng

Just did a browsing on 2.6.21.rc4 statd code (also with few quick test runs to confirm). Look like this patch is no longer needed. I tentatively withdraw this patch. Will continue the test this week. A summary will be sent after all the testings are completed.

Neil,

I was wrong. Unlike other patches that can be individually tested, this patch has to combine with all other changes (including user mode statd patch) so my code reading deceived me. I'm mostly done but just found a new bug few minutes ago (that I never notice before). It is pretty late for me now so I'll continue tomorrow. G'night !

-- Wendy

#16 lore raw

PATCH 3/4 NLM failover - statd changes

Quoted 8 lines · Wendy Cheng
Quoted 5 lines · Wendy Cheng

Just did a browsing on 2.6.21.rc4 statd code (also with few quick test runs to confirm). Look like this patch is no longer needed. I tentatively withdraw this patch. Will continue the test this week. A summary will be sent after all the testings are completed.

Quoted 8 lines

Neil,

I was wrong. Unlike other patches that can be individually tested, this patch has to combine with all other changes (including user mode statd patch) so my code reading deceived me. I'm mostly done but just found a new bug few minutes ago (that I never notice before). It is pretty late for me now so I'll continue tomorrow.

Sorry to bug the list for this - it was intended to be a private mail but somehow cluster-devel got included... Wendy