Skip to contentSkip to conversation

NLM lock failover

PATCH In review Wendy Cheng 1 participant 1 message Aug 1, 2006

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

PATCH 2/3 NLM lock failover

This change enables per ip NLM lock grace period. The implementation is based on a global single linked list nlm_servs that contains entries of per server ip info. It is expected this would not be a frequent event. The nlm_servs list would be 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 ipv4 dot address into /proc/fs/nfsd/nlm_set_ip_grace file.

fs/lockd/svc.c              |    8 +-
fs/lockd/svc4proc.c         |   41 ++++++++++---
fs/lockd/svcproc.c          |   43 +++++++++++---
fs/lockd/svcsubs.c          |  133 +++++++++++++++++++++++++++++++++++++
++++++ 
fs/nfsd/nfsctl.c            |   36 +++++++++++
include/linux/lockd/bind.h  |    3
include/linux/lockd/lockd.h |   15 ++++
7 files changed, 261 insertions(+), 18 deletions(-)
include/linux/lockd/lockd.h +15 -0
@@ -108,6 +108,13 @@ struct nlm_file {
 	__u32			f_iaddr;	/* server ip for failover */
 };
 
+/* Server ip linked list for NLM lock failover */
+struct nlm_serv {
+	struct nlm_serv *	s_next;		/* linked list */
+	unsigned long		s_grace_period;	/* per ip grace period */
+	struct in_addr		s_ip;		/* server ip */
+};
+
 /*
  * This is a server block (i.e. a lock requested by some client which
  * couldn't be granted because of a conflicting lock).
@@ -137,6 +144,13 @@ struct nlm_block {
 #define NLM_ACT_FO_UNLOCK	3		/* failover release locks */
 
 /*
+ * Floating ip failover grace period check
+ */
+#define NLMSVC_FO_PASSTHRU	0
+#define NLMSVC_FO_RECLAIM	1
+#define NLMSVC_FO_BLOCK_ANY	2
+
+/*
  * Global variables
  */
 extern struct rpc_program	nlm_program;
@@ -199,6 +213,7 @@ void		  nlmsvc_mark_resources(void);
 void		  nlmsvc_free_host_resources(struct nlm_host *);
 void		  nlmsvc_invalidate_all(void);
 int 		  nlmsvc_fo_unlock(struct in_addr *);
+int 		  nlmsvc_fo_check(__u32);
 
 static __inline__ struct inode *
 nlmsvc_file_inode(struct nlm_file *file)
fs/lockd/svcsubs.c +133 -0

142 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(struct in_addr *);
+extern int     nlmsvc_fo_setgrace(struct in_addr *);
+extern void    nlmsvc_fo_reset_servs(void);
+
 
 #endif /* LINUX_LOCKD_BIND_H */
fs/nfsd/nfsctl.c +36 -0
@@ -56,6 +56,7 @@ enum {
 	NFSD_List,
 	NFSD_Fh,
 	NFSD_Nlm_unlock,
+	NFSD_Nlm_ipgrace,
 	NFSD_Threads,
 	NFSD_Versions,
 	/*
@@ -93,6 +94,7 @@ static ssize_t write_recoverydir(struct 
 #define NFSDDBG_FACILITY	NFSDDBG_CLUSTER
 
 static ssize_t do_nlm_fo_unlock(struct file *file, char *buf, size_t size);
+static ssize_t do_nlm_ip_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_Nlm_unlock] = do_nlm_fo_unlock,
+	[NFSD_Nlm_ipgrace] = do_nlm_ip_grace,
 	[NFSD_Threads] = write_threads,
 	[NFSD_Versions] = write_versions,
 #ifdef CONFIG_NFSD_V4
@@ -362,9 +365,38 @@ int __get_nlm_host(char *buf, size_t siz
 	host_addr->s_addr = in_aton(buf);
 	dprintk("nfsd: __get_nlm_host (%u.%u.%u.%u)\n",
 		NIPQUAD(host_addr->s_addr));
+
 	return 0;
 }
 
+static ssize_t do_nlm_ip_grace(struct file *file, char *buf, size_t size)
+{
+	struct in_addr serv_addr;
+	int rc;
+
+	/* convert string into valid ip address */
+	rc = __get_nlm_host(buf, size, &serv_addr);
+	if (rc) {
+		dprintk("do_nlm_ip_grace: invalid ip (%s)\n", buf);
+		return rc;
+	}
+
+	/* call nlm to set the grace period */
+	rc = nlmsvc_fo_setgrace(&serv_addr);
+	if (rc) {
+		dprintk("nlmsvc_fo_setgrace return rc=%d\n", rc);
+		return rc;
+	}
+
+	dprintk("nlm set per ip grace period for %u.%u.%u.%u\n",
+		NIPQUAD(serv_addr.s_addr));
+
+	/* done */
+	sprintf(buf, "nlm set per ip grace period for %u.%u.%u.%u\n",
+		NIPQUAD(serv_addr.s_addr));
+	return strlen(buf);
+}
+
 static ssize_t do_nlm_fo_unlock(struct file *file, char *buf, size_t size)
 {
 	struct in_addr serv_addr;
@@ -384,6 +416,9 @@ static ssize_t do_nlm_fo_unlock(struct f
 		return rc;
 	}
 
+	dprintk("nlm ip unlock released for %u.%u.%u.%u\n",
+		NIPQUAD(serv_addr.s_addr));
+
 	/* done */
 	sprintf(buf, "nlm ip unlock released for %u.%u.%u.%u\n",
 		NIPQUAD(serv_addr.s_addr));
@@ -539,6 +574,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_Nlm_unlock] = {"nlm_unlock", &transaction_ops, S_IWUSR|S_IRUSR},
+		[NFSD_Nlm_ipgrace] = {"nlm_set_ip_grace", &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 +33 -8

100 lines not on this page · raw message

fs/lockd/svcproc.c +35 -8

102 lines not on this page · raw message

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");

-------------------------------------------------------------------------
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