[Cluster-devel] cluster/magma/lib global.c magma.h

lhh at sourceware.org lhh at sourceware.org
Fri Jun 16 20:02:25 UTC 2006


CVSROOT:	/cvs/cluster
Module name:	cluster
Branch: 	STABLE
Changes by:	lhh at sourceware.org	2006-06-16 20:02:25

Modified files:
	magma/lib      : global.c magma.h 

Log message:
	Merge from RHEL4 branch - fix #193128, part 1

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/magma/lib/global.c.diff?cvsroot=cluster&only_with_tag=STABLE&r1=1.9.2.1&r2=1.9.2.1.6.1
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/magma/lib/magma.h.diff?cvsroot=cluster&only_with_tag=STABLE&r1=1.9.2.2.6.1&r2=1.9.2.2.6.2

--- cluster/magma/lib/Attic/global.c	2005/01/17 18:40:05	1.9.2.1
+++ cluster/magma/lib/Attic/global.c	2006/06/16 20:02:25	1.9.2.1.6.1
@@ -390,13 +390,66 @@
 int
 clu_lock(char *resource, int flags, void **lockpp)
 {
-	int ret, block = 0, err;
+	int ret = 0, block = 0, conv = 0, err;
 
 	block = !(flags & CLK_NOWAIT);
 
+	/*
+	   Bug 193128
+
+	   Try to use a conversion lock mechanism when possible
+	   If the caller calls explicitly with a NULL lock, then
+	   assume the caller knows what it is doing.
+
+	   Only take the NULL lock if:
+	   (a) the user isn't specifying CONVERT; if they are, they
+	       know what they are doing.
+
+	   ...and one of...
+
+	   (b) This is a blocking call, or
+	   (c) The user requested a NULL lock explicitly.  In this case,
+	       short-out early; there's no reason to convert a NULL lock
+	       to a NULL lock.
+	 */
+	if (!(flags & CLK_CONVERT) &&
+	    (block || ((flags & CLK_EX) == 0))) {
+		/* Acquire NULL lock */
+		pthread_rwlock_wrlock(&dflt_lock);
+		ret = cp_lock(_cpp, resource, CLK_NULL, lockpp);
+		err = errno;
+		pthread_rwlock_unlock(&dflt_lock);
+		if (ret == 0) {
+			if ((flags & CLK_EX) == 0) {
+				/* User only wanted a NULL lock... */
+				return 0;
+			}
+			/*
+			   Ok, NULL lock was taken, rest of blocking
+			   call should be done using lock conversions.
+			 */
+			flags |= CLK_CONVERT;
+			conv = 1;
+		} else {
+			switch(err) {
+			case EINVAL:
+				/* Oops, null locks don't work on this
+				   plugin; use normal spam mode */
+				break;
+			default:
+				errno = err;
+				return -1;
+			}
+		}
+	}
+
 	while (1) {
+		/*
+		printf("upgrading to requested lock %04x...\n", flags);
+		*/
 		pthread_rwlock_wrlock(&dflt_lock);
-		ret = cp_lock(_cpp, resource, flags | CLK_NOWAIT, lockpp);
+		ret = cp_lock(_cpp, resource,
+			      flags | CLK_NOWAIT, lockpp);
 		err = errno;
 		pthread_rwlock_unlock(&dflt_lock);
 
@@ -407,7 +460,16 @@
 
 		break;
 	}
-			
+
+	if (ret != 0 && conv) {
+		/* If we get some other error, release the NL lock we
+		 took so we don't leak locks*/
+		pthread_rwlock_wrlock(&dflt_lock);
+		cp_unlock(_cpp, resource, lockpp);
+		pthread_rwlock_unlock(&dflt_lock);
+		errno = err;
+	}
+
 	return ret;
 }
 
--- cluster/magma/lib/Attic/magma.h	2006/01/20 16:10:12	1.9.2.2.6.1
+++ cluster/magma/lib/Attic/magma.h	2006/06/16 20:02:25	1.9.2.2.6.2
@@ -110,7 +110,11 @@
 #define CLK_WRITE	(1<<1)	/** Write lock */
 #define CLK_READ	(1<<2)	/** Read lock */
 #define CLK_HOLDER	(1<<3)  /** Return the holder node ID if lock is held*/
-#define CLK_EX		(CLK_READ|CLK_WRITE)
+#define CLK_CONVERT	(1<<4)	/** Convert this lock to a new type (may not
+				    be supported on all plugins; caller
+				    must be aware of this fact */
+#define CLK_EX		(CLK_READ|CLK_WRITE) /** Exclusive lock */
+#define CLK_NULL	(0)	/** No bits set */
 
 
 #define NODE_ID_NONE	((uint64_t)-1) /** The nonexistent cluster member */




More information about the Cluster-devel mailing list