cluster: RHEL48 - magma-plugins: Handle other errors from dlm_lock

Lon Hohberger lon at fedoraproject.org
Mon Apr 5 14:23:25 UTC 2010


Gitweb:        http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=23ac11b4d1ee465ab8cf377008740156ca1ebc25
Commit:        23ac11b4d1ee465ab8cf377008740156ca1ebc25
Parent:        19bb0c8920a245c58f1a96d8e37387f7d83d1f17
Author:        Lon Hohberger <lhh at redhat.com>
AuthorDate:    Tue Feb 16 16:33:19 2010 -0500
Committer:     Lon Hohberger <lhh at redhat.com>
CommitterDate: Mon Apr 5 09:55:00 2010 -0400

magma-plugins: Handle other errors from dlm_lock

If writing to the dlm lockspace file descriptor failed
due to delivery of a signal, libdlm and magma-plugins were
passing EINTR back up back up to the caller instead of
retrying the lock or unlock request like they should have.

Additionally, when any error except EAGAIN occurred, we
were overwriting errno with the value of lksb->sb_status,
which was always EINPROG (65539), causing the caller to
have an incorrect errno value.

Resolves: rhbz#294491 rhbz#572792

Signed-off-by: Lon Hohberger <lhh at redhat.com>
---
 magma-plugins/sm/sm.c |   42 +++++++++++++++++++++++++++++++-----------
 1 files changed, 31 insertions(+), 11 deletions(-)

diff --git a/magma-plugins/sm/sm.c b/magma-plugins/sm/sm.c
index 666bb4f..3503d16 100644
--- a/magma-plugins/sm/sm.c
+++ b/magma-plugins/sm/sm.c
@@ -36,7 +36,7 @@
 #include <sys/select.h>
 #include <sys/stat.h>
 
-#define MODULE_DESCRIPTION "CMAN/SM Plugin v1.1.7.6"
+#define MODULE_DESCRIPTION "CMAN/SM Plugin v1.1.7.7"
 #define MODULE_AUTHOR      "Lon Hohberger"
 
 #define DLM_LS_NAME	   "Magma"
@@ -571,12 +571,18 @@ _dlm_lock(sm_priv_t *p, int mode, struct dlm_lksb *lksb, int options,
         int ret;
 
 	/* Ok, we have the NL lock.  Now convert it. */
-        ret = dlm_ls_lock(p->ls, mode, lksb, options,
+	/* Check for EINTR returned from write() in libdlm.c */
+	do {
+        	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 < 0) {
+			if (errno == EINTR)
+				continue;
+			return -1;
+		}
+	} while (0);
 
 	while (lksb->sb_status == EINPROG) {
 		if (wait_for_dlm_event(p->ls) < 0) {
@@ -645,13 +651,18 @@ _dlm_unlock(sm_priv_t *p, struct dlm_lksb *lksb)
 {
         int ret;
 
-        ret = dlm_ls_unlock(p->ls, lksb->sb_lkid, 0, lksb, NULL);
+	/* Check for EINTR returned from write() in libdlm.c */
+	do {
+        	ret = dlm_ls_unlock(p->ls, lksb->sb_lkid, 0, lksb, NULL);
 
-        if (ret != 0)
-                return ret;
+		if (ret < 0) {
+			if (errno == EINTR)
+				continue;
+			return -1;
+		}
+	} while (0);
 
         /* lksb->sb_status should be EINPROG at this point */
-
 	while (lksb->sb_status == EINPROG) {
 		if (wait_for_dlm_event(p->ls) < 0) {
 			if (lksb->sb_status == EINPROG)
@@ -799,7 +810,7 @@ sm_lock(cluster_plugin_t *self,
 	   the CLK_CONVERT flag, then assume it's a previous lksb with
 	   a held lock. */
 	if ((flags & CLK_CONVERT) && *lockpp) {
-		lksb = (struct lksb *)(*lockpp);
+		lksb = (struct dlm_lksb *)(*lockpp);
 		options |= LKF_CONVERT;
 	} else {
 		lksb = malloc(sz);
@@ -838,8 +849,17 @@ sm_lock(cluster_plugin_t *self,
 		errno = EAGAIN;
 		return -1;
 	default:
-		fprintf(stderr, "_dlm_lock: %d / %d\n", ret, errno);
-		ret = lksb->sb_status;
+		/* Other error conditions: Pass back to caller.
+		 * Note that 'ret' is still the indicator for a
+		 * successful call to dlm_ls_lock.  So, in the
+		 * successful case, we want to pass the 
+		 * lock state back, otherwise errno in the event
+		 * of a failed call. */
+		if (ret == 0) {
+			ret = lksb->sb_status;
+		} else {
+			ret = errno;
+		}
 		free(lksb);
 		errno = ret;
 		return -1;


More information about the cluster-commits mailing list