[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [Cluster-devel] [PATCH] work around rgmanager-caused DLM race condition, BZ #193128, pass 2



On Thu, 2006-06-15 at 12:43 -0400, Lon Hohberger wrote:
> These patches allows users of magma to use NULL locks (where supported)
> and attempt to convert in a loop, rather than take/release locks in a
> tight loop as is currently done.
> 
> -- Lon

Add checking in case the lock is not mastered locally; it seems as
though a locally mastered lock returns -1 / errno=EAGAIN, while a
remotely mastered lock will return 0 / errno=0, with lksb->sb_status set
to EAGAIN.

Replaces magma-plugins-193128-1.patch

-- Lon
Index: dumb/dumb.c
===================================================================
RCS file: /cvs/cluster/cluster/magma-plugins/dumb/Attic/dumb.c,v
retrieving revision 1.2
diff -u -r1.2 dumb.c
--- dumb/dumb.c	29 Jun 2004 20:25:49 -0000	1.2
+++ dumb/dumb.c	15 Jun 2006 23:05:46 -0000
@@ -35,7 +35,7 @@
 #include <netinet/in.h>
 #include <assert.h>
 
-#define MODULE_DESCRIPTION "Dumb Plugin v1.1"
+#define MODULE_DESCRIPTION "Dumb Plugin v1.1.1"
 #define MODULE_AUTHOR      "Lon Hohberger"
 #define DUMB_LOCK_PATH	   "/tmp/magma-dumb"
 
@@ -158,6 +158,12 @@
 
 	//printf("DUMB: %s called\n", __FUNCTION__);
 
+	if ((flags & CLK_EX) == 0) {
+		/* NULL lock not supported */
+		errno = EINVAL;
+		return -1;
+	}
+
 	fdp = malloc(sizeof(int));
 	if (!fdp)
 		return -1;
Index: gulm/gulm-lock.c
===================================================================
RCS file: /cvs/cluster/cluster/magma-plugins/gulm/Attic/gulm-lock.c,v
retrieving revision 1.5.2.3
diff -u -r1.5.2.3 gulm-lock.c
--- gulm/gulm-lock.c	27 Jan 2006 20:55:06 -0000	1.5.2.3
+++ gulm/gulm-lock.c	15 Jun 2006 23:05:46 -0000
@@ -269,13 +269,14 @@
 
 	*lockpp = NULL;
 
-	if (flags & CLK_EX) {
+	if ((flags & CLK_EX) == CLK_EX) {
 		state = lg_lock_state_Exclusive;
 	} else if (flags & CLK_READ) {
 		state = lg_lock_state_Shared;
 	} else if (flags & CLK_WRITE) {
 		state = lg_lock_state_Exclusive;
 	} else {
+		/* NULL Locks not supported on GULM */
 		errno = EINVAL;
 		return -1;
 	}
Index: gulm/gulm.c
===================================================================
RCS file: /cvs/cluster/cluster/magma-plugins/gulm/Attic/gulm.c,v
retrieving revision 1.6.2.6
diff -u -r1.6.2.6 gulm.c
--- gulm/gulm.c	24 Jan 2006 19:30:44 -0000	1.6.2.6
+++ gulm/gulm.c	15 Jun 2006 23:05:47 -0000
@@ -34,7 +34,7 @@
 #include <sys/types.h>
 #include <linux/unistd.h>
 
-#define MODULE_DESCRIPTION "GuLM Plugin v1.0.4"
+#define MODULE_DESCRIPTION "GuLM Plugin v1.0.5"
 #define MODULE_AUTHOR      "Lon Hohberger"
 
 
Index: sm/sm.c
===================================================================
RCS file: /cvs/cluster/cluster/magma-plugins/sm/Attic/sm.c,v
retrieving revision 1.9.2.8
diff -u -r1.9.2.8 sm.c
--- sm/sm.c	15 May 2006 16:59:11 -0000	1.9.2.8
+++ sm/sm.c	15 Jun 2006 23:05:47 -0000
@@ -35,7 +35,7 @@
 #include <sys/types.h>
 #include <sys/select.h>
 
-#define MODULE_DESCRIPTION "CMAN/SM Plugin v1.1.6"
+#define MODULE_DESCRIPTION "CMAN/SM Plugin v1.1.7.1"
 #define MODULE_AUTHOR      "Lon Hohberger"
 
 #define DLM_LS_NAME	   "Magma"
@@ -47,6 +47,7 @@
 
 /* Internal */
 static inline int _dlm_release_lockspace(sm_priv_t *p);
+static inline int _dlm_unlock(sm_priv_t *p, struct dlm_lksb *lksb);
 
 
 /*
@@ -560,24 +561,13 @@
 {
         int ret;
 
-        /*
-         * per pjc: create/open lockspace when first lock is taken
-         */
-        ret = dlm_ls_lock(p->ls, mode, lksb, options, resource,
-                          strlen(resource), 0, ast_function, lksb,
-                          NULL, NULL);
-
-        if (ret < 0) {
-#if 0
-                if (errno == ENOENT) {
-                        /* This should not happen if we have a lock
-                           ref open in the LS ! */A
-                        assert(0);
-                }
-#endif
+	/* Ok, we have the NL lock.  Now convert it. */
+        ret = dlm_ls_lock(p->ls, mode, lksb, options,
+			  resource, strlen(resource), 0, ast_function,
+			  lksb, NULL, NULL);
 
+        if (ret < 0)
                 return -1;
-        }
 
         if ((ret = (wait_for_dlm_event(p->ls) < 0))) {
                 fprintf(stderr, "wait_for_dlm_event: %d / %d\n",
@@ -585,6 +575,7 @@
                 return -1;
         }
 
+	/* Got the lock ! */
         return 0;
 }
 
@@ -760,42 +751,64 @@
 
 	p = (sm_priv_t *)self->cp_private.p_data;
 	assert(p);
-	*lockpp = NULL;
-	if (flags & CLK_EX) {
+
+	if ((flags & CLK_EX) == CLK_EX) {
 		mode = LKM_EXMODE;
 	} else if (flags & CLK_READ) {
 		mode = LKM_PRMODE;
 	} else if (flags & CLK_WRITE) {
 		mode = LKM_PWMODE;
-	} else {
-		errno = EINVAL;
-		return -1;
+	} else if ((flags & CLK_EX) == 0){
+		mode = LKM_NLMODE;
 	}
 
 	if (flags & CLK_NOWAIT)
 		options = LKF_NOQUEUE;
+	if (flags & CLK_CONVERT)
+		flags &= ~CLK_HOLDER; /* CLK_HOLDER mutually exclusive with
+					 CLK_CONVERT */
 
 	/* Allocate our lock structure. */
 	sz = (sizeof(*lksb) > sizeof(uint64_t) ? sizeof(*lksb) :
 	      sizeof(uint64_t));
 
-	lksb = malloc(sz);
-	assert(lksb);
-	memset(lksb, 0, sz);
-
-	while(!p->ls) {
+	while(!p->ls)
 		_dlm_acquire_lockspace(p, DLM_LS_NAME);
-	}
 	assert(p->ls);
 
+	/* If we've got a non-zero pointer and we're being called with
+	   the CLK_CONVERT flag, then assume it's a previous lksb with
+	   a held lock. */
+	if ((flags & CLK_CONVERT) && *lockpp) {
+		lksb = (struct lksb *)*lockpp;
+		options |= LKF_CONVERT;
+	} else {
+		lksb = malloc(sz);
+		assert(lksb);
+		memset(lksb, 0, sz);
+	}
+
+	/* Take the real lock, or at least, try to. */
 	ret = _dlm_lock(p, mode, lksb, options, resource);
 
-	switch(lksb->sb_status) {
-	case 0:
-		*lockpp = (void *)lksb;
-		return 0;
+	/* Got the lock? */
+	if (ret == 0) {
+		if (lksb->sb_status == 0) {
+			*lockpp = (void *)lksb;
+			return 0;
+		}
+
+		/* Flip errno so we only have one switch statement */
+		errno = lksb->sb_status;
+	}
+
+	switch(errno) {
 	case EAGAIN:
-		if ((flags & CLK_HOLDER) &&
+		if (flags & CLK_CONVERT) {
+			*lockpp = (void *)lksb;
+			/* Nothing special here */
+			/* Lock is busy */
+		} else if ((flags & CLK_HOLDER) &&
 		    (_get_holder(resource, p, mode, &holder) == 0)) {
 			memset(lksb, 0, sz);
 			*((uint64_t *)lksb) = holder;
@@ -806,7 +819,7 @@
 		errno = EAGAIN;
 		return -1;
 	default:
-		fprintf(stderr, "_dlm_lock: %d / %d\n", ret, lksb->sb_status);
+		fprintf(stderr, "_dlm_lock: %d / %d\n", ret, errno);
 		ret = lksb->sb_status;
 		free(lksb);
 		errno = ret;

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]