]> sourceware.org Git - lvm2.git/commitdiff
Fix for bug 677739: removing final exclusive cmirror snapshot,
authorJonathan Earl Brassow <jbrassow@redhat.com>
Fri, 18 Feb 2011 00:36:04 +0000 (00:36 +0000)
committerJonathan Earl Brassow <jbrassow@redhat.com>
Fri, 18 Feb 2011 00:36:04 +0000 (00:36 +0000)
                    results in clvmd deadlock

When a logical volume is activated exclusively in a cluster, the
local (non-cluster-aware) target is used.  However, when creating
a snapshot on the exclusive LV, the resulting suspend/resume fails
to load the appropriate device-mapper table - instead loading the
cluster-aware target.

This patch adds an 'exclusive' parameter to the pertinent resume
functions to allow for the right target type to be loaded.

WHATS_NEW
daemons/clvmd/lvm-functions.c
lib/activate/activate.c
lib/activate/activate.h
lib/locking/file_locking.c
lib/locking/no_locking.c

index aff09b6660f28230098d62eac00354408367678f..ba89ece206af4aa68bf598da65860b3a60051fa2 100644 (file)
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
 Version 2.02.85 - 
 ===================================
+  Fix to make resuming exclusive cluster mirror use local target type.
 
 Version 2.02.84 - 9th February 2011
 ===================================
index 81e8b884f39e0c72b99ea873b4d60ad305154432..b5a0e4ec6ed1bf987a4efa83bc1975130d7186c8 100644 (file)
@@ -399,7 +399,7 @@ error:
 /* Resume the LV if it was active */
 static int do_resume_lv(char *resource, unsigned char lock_flags)
 {
-       int oldmode;
+       int oldmode, origin_only, exclusive;
 
        /* Is it open ? */
        oldmode = get_current_lock(resource);
@@ -407,8 +407,10 @@ static int do_resume_lv(char *resource, unsigned char lock_flags)
                DEBUGLOG("do_resume_lv, lock not already held\n");
                return 0;       /* We don't need to do anything */
        }
+       origin_only = (lock_flags & LCK_ORIGIN_ONLY_MODE) ? 1 : 0;
+       exclusive = (oldmode == LCK_EXCL) ? 1 : 0;
 
-       if (!lv_resume_if_active(cmd, resource, (lock_flags & LCK_ORIGIN_ONLY_MODE) ? 1 : 0))
+       if (!lv_resume_if_active(cmd, resource, origin_only, exclusive))
                return EIO;
 
        return 0;
index 9edb0114ff2bda8a6fb389ddec69bffbb4d440a7..cdd499d07522e9cf0eb7b562d7e5932876c17976 100644 (file)
@@ -1156,8 +1156,18 @@ int lv_suspend(struct cmd_context *cmd, const char *lvid_s)
 }
 ***********/
 
+ /*
+  * _lv_resume
+  * @cmd
+  * @lvid_s
+  * @origin_only
+  * @exclusive:  This parameter only has an affect in cluster-context.
+  *             It forces local target type to be used (instead of
+  *             cluster-aware type).
+  * @error_if_not_active
+  */
 static int _lv_resume(struct cmd_context *cmd, const char *lvid_s,
-                     unsigned origin_only,
+                     unsigned origin_only, unsigned exclusive,
                      int error_if_not_active)
 {
        struct logical_volume *lv;
@@ -1189,6 +1199,14 @@ static int _lv_resume(struct cmd_context *cmd, const char *lvid_s,
                goto out;
        }
 
+       /*
+        * When targets are activated exclusively in a cluster, the
+        * non-clustered target should be used.  This only happens
+        * if ACTIVATE_EXCL is set in lv->status.
+        */
+       if (exclusive)
+               lv->status |= ACTIVATE_EXCL;
+
        if (!_lv_activate_lv(lv, origin_only))
                goto_out;
 
@@ -1206,14 +1224,15 @@ out:
 }
 
 /* Returns success if the device is not active */
-int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only)
+int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s,
+                       unsigned origin_only, unsigned exclusive)
 {
-       return _lv_resume(cmd, lvid_s, origin_only, 0);
+       return _lv_resume(cmd, lvid_s, origin_only, exclusive, 0);
 }
 
 int lv_resume(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only)
 {
-       return _lv_resume(cmd, lvid_s, origin_only, 1);
+       return _lv_resume(cmd, lvid_s, origin_only, 0, 1);
 }
 
 static int _lv_has_open_snapshots(struct logical_volume *lv)
index c054c6db736ed7118e30235cc20667237d03b405..53ab19262774e7b53532e8d137380e4bd21d904e 100644 (file)
@@ -56,7 +56,8 @@ void activation_exit(void);
 /* int lv_suspend(struct cmd_context *cmd, const char *lvid_s); */
 int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only);
 int lv_resume(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only);
-int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only);
+int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s,
+                       unsigned origin_only, unsigned exclusive);
 int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive);
 int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s,
                            int exclusive);
index 68b0420b869db2765814625eeb8a06608ae1fcc5..95883b9194b64fc8d89ca8ed71758f6ad9daaeae 100644 (file)
@@ -293,7 +293,7 @@ static int _file_lock_resource(struct cmd_context *cmd, const char *resource,
                switch (flags & LCK_TYPE_MASK) {
                case LCK_UNLOCK:
                        log_very_verbose("Unlocking LV %s%s", resource, origin_only ? " without snapshots" : "");
-                       if (!lv_resume_if_active(cmd, resource, origin_only))
+                       if (!lv_resume_if_active(cmd, resource, origin_only, 0))
                                return 0;
                        break;
                case LCK_NULL:
index 3ad0d38b27e72bcb96d7c4f2de69e4642ec071a2..65ac29fb094a04af80c1710f670db4f757776f89 100644 (file)
@@ -46,7 +46,7 @@ static int _no_lock_resource(struct cmd_context *cmd, const char *resource,
                case LCK_NULL:
                        return lv_deactivate(cmd, resource);
                case LCK_UNLOCK:
-                       return lv_resume_if_active(cmd, resource, (flags & LCK_ORIGIN_ONLY) ? 1: 0);
+                       return lv_resume_if_active(cmd, resource, (flags & LCK_ORIGIN_ONLY) ? 1: 0, 0);
                case LCK_READ:
                        return lv_activate_with_filter(cmd, resource, 0);
                case LCK_WRITE:
This page took 0.044757 seconds and 5 git commands to generate.