]> sourceware.org Git - lvm2.git/commitdiff
Attempt to improve clustered 'lvchange -aey' behaviour to try local node before
authorAlasdair Kergon <agk@redhat.com>
Sat, 21 Jan 2012 05:29:51 +0000 (05:29 +0000)
committerAlasdair Kergon <agk@redhat.com>
Sat, 21 Jan 2012 05:29:51 +0000 (05:29 +0000)
remote nodes and address some existing anomalies.

WHATS_NEW
lib/activate/activate.c
lib/locking/cluster_locking.c
lib/locking/locking.c
lib/locking/locking.h

index e8444562d879e3a2b6878dd0100a5c8e6703faa7..3278baa5664bacab2516d5230a960103e716bb6c 100644 (file)
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,7 @@
 Version 2.02.89 - 
 ==================================
+  Change exclusive LV activation logic to try local node before remote nodes.
+  Add CLVMD_FLAG_REMOTE to skip processing on local node.
   Prompt if request is made to remove a snapshot whose "Merge failed".
   Allow removal of an invalid snapshot that was to be merged on next activation.
   Don't allow a user to merge an invalid snapshot.
index edb9fa9644006b740f7015d35d2c839a2e8a8ccd..b647407757715736277ecd480dcfc4193d873938 100644 (file)
@@ -930,7 +930,8 @@ static int _lv_is_active(struct logical_volume *lv,
                l = 1;
 
        if (!vg_is_clustered(lv->vg)) {
-               e = 1;  /* exclusive by definition */
+               if (l)
+                       e = 1;  /* exclusive by definition */
                goto out;
        }
 
@@ -950,21 +951,15 @@ static int _lv_is_active(struct logical_volume *lv,
         * New users of this function who specifically ask for 'exclusive'
         * will be given an error message.
         */
-       if (l) {
-               if (exclusive)
-                       log_error("Unable to determine exclusivity of %s",
-                                 lv->name);
-               goto out;
-       }
+       log_error("Unable to determine exclusivity of %s", lv->name);
+
+       e = 0;
+
+       /*
+        * We used to attempt activate_lv_excl_local(lv->vg->cmd, lv) here,
+        * but it's unreliable.
+        */
 
-       /* FIXME: Is this fallback alright? */
-       if (activate_lv_excl(lv->vg->cmd, lv)) {
-               if (!deactivate_lv(lv->vg->cmd, lv))
-                       stack;
-               /* FIXME: locally & exclusive are undefined. */
-               return 0;
-       }
-       /* FIXME: Check exclusive value here. */
 out:
        if (locally)
                *locally = l;
index 6ab9c0ef8647783e840e8fd88c07caf5c297047e..990e8b13aa743ef7fc0339567bcb3dffcd0fc5b0 100644 (file)
@@ -178,21 +178,19 @@ static void _build_header(struct clvm_header *head, int clvmd_cmd, const char *n
        head->clientid = 0;
        head->arglen = len;
 
-       if (node) {
-               /*
-                * Allow a couple of special node names:
-                * "*" for all nodes,
-                * "." for the local node only
-                */
-               if (strcmp(node, "*") == 0) {
-                       head->node[0] = '\0';
-               } else if (strcmp(node, ".") == 0) {
-                       head->node[0] = '\0';
-                       head->flags = CLVMD_FLAG_LOCAL;
-               } else
-                       strcpy(head->node, node);
-       } else
+       /*
+        * Handle special node names.
+        */
+       if (!node || !strcmp(node, NODE_ALL))
+               head->node[0] = '\0';
+       else if (!strcmp(node, NODE_LOCAL)) {
                head->node[0] = '\0';
+               head->flags = CLVMD_FLAG_LOCAL;
+       } else if (!strcmp(node, NODE_REMOTE)) {
+               head->node[0] = '\0';
+               head->flags = CLVMD_FLAG_REMOTE;
+       } else
+               strcpy(head->node, node);
 }
 
 /*
@@ -357,9 +355,6 @@ static int _lock_for_cluster(struct cmd_context *cmd, unsigned char clvmd_cmd,
         * so we only need to do them on the local node because all
         * locks are cluster-wide.
         *
-        * Also, if the lock is exclusive it makes no sense to try to
-        * acquire it on all nodes, so just do that on the local node too.
-        *
         * P_ locks /do/ get distributed across the cluster because they might
         * have side-effects.
         *
@@ -367,13 +362,15 @@ static int _lock_for_cluster(struct cmd_context *cmd, unsigned char clvmd_cmd,
         */
        if (clvmd_cmd == CLVMD_CMD_SYNC_NAMES) {
                if (flags & LCK_LOCAL)
-                       node = ".";
+                       node = NODE_LOCAL;
        } else if (clvmd_cmd != CLVMD_CMD_VG_BACKUP) {
                if (strncmp(name, "P_", 2) &&
                    (clvmd_cmd == CLVMD_CMD_LOCK_VG ||
                     (flags & LCK_LOCAL) ||
                     !(flags & LCK_CLUSTER_VG)))
-                       node = ".";
+                       node = NODE_LOCAL;
+               else if (flags & LCK_REMOTE)
+                       node = NODE_REMOTE;
        }
 
        status = _cluster_request(clvmd_cmd, node, args, len,
@@ -493,12 +490,13 @@ int lock_resource(struct cmd_context *cmd, const char *resource, uint32_t flags)
                return 0;
        }
 
-       log_very_verbose("Locking %s %s %s (%s%s%s%s%s%s%s%s) (0x%x)", lock_scope, lockname,
+       log_very_verbose("Locking %s %s %s (%s%s%s%s%s%s%s%s%s) (0x%x)", lock_scope, lockname,
                         lock_type, lock_scope,
                         flags & LCK_NONBLOCK ? "|NONBLOCK" : "",
                         flags & LCK_HOLD ? "|HOLD" : "",
-                        flags & LCK_LOCAL ? "|LOCAL" : "",
                         flags & LCK_CLUSTER_VG ? "|CLUSTER" : "",
+                        flags & LCK_LOCAL ? "|LOCAL" : "",
+                        flags & LCK_REMOTE ? "|REMOTE" : "",
                         flags & LCK_CACHE ? "|CACHE" : "",
                         flags & LCK_ORIGIN_ONLY ? "|ORIGIN_ONLY" : "",
                         flags & LCK_REVERT ? "|REVERT" : "",
index 4b8a957beaa85ea62553d1d4b5dec6ca63c2b8d1..6fc7bf6518a88fb15eedb914b6991620d1b5bbb5 100644 (file)
@@ -539,6 +539,33 @@ int suspend_lvs(struct cmd_context *cmd, struct dm_list *lvs,
        return 1;
 }
 
+/*
+ * First try to activate exclusively locally.
+ * Then if the VG is clustered and the LV is not yet active (e.g. due to 
+ * an activation filter) try activating on remote nodes.
+ */
+int activate_lv_excl(struct cmd_context *cmd, struct logical_volume *lv) 
+{
+       /* Non-clustered VGs are only activated locally. */
+       if (!vg_is_clustered(lv->vg))
+               return activate_lv_excl_local(cmd, lv);
+
+       if (lv_is_active_exclusive(lv))
+               return 1;
+
+       if (!activate_lv_excl_local(cmd, lv))
+               return_0;
+
+       if (lv_is_active_exclusive(lv))
+               return 1;
+
+       /* FIXME Deal with error return codes. */
+       if (activate_lv_excl_remote(cmd, lv))
+               stack;
+
+       return lv_is_active_exclusive(lv);
+}
+
 /* Lock a list of LVs */
 int activate_lvs(struct cmd_context *cmd, struct dm_list *lvs, unsigned exclusive)
 {
index f5e1e62a88c6ed55c1ff14a8495c2f25dea180b5..817897367fffa78fd988bfebadae4134de409556 100644 (file)
@@ -97,6 +97,7 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
 #define LCK_CLUSTER_VG 0x00000080U     /* VG is clustered */
 
 #define LCK_LOCAL      0x00000040U     /* Don't propagate to other nodes */
+#define LCK_REMOTE     0x00000800U     /* Propagate to remote nodes only */
 #define LCK_CACHE      0x00000100U     /* Operation on cache only using P_ lock */
 #define LCK_ORIGIN_ONLY        0x00000200U     /* Operation should bypass any snapshots */
 #define LCK_REVERT     0x00000400U     /* Revert any incomplete change */
@@ -176,9 +177,16 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
 #define suspend_lv(cmd, lv)    lock_lv_vol(cmd, lv, LCK_LV_SUSPEND | LCK_HOLD)
 #define suspend_lv_origin(cmd, lv)     lock_lv_vol(cmd, lv, LCK_LV_SUSPEND | LCK_HOLD | LCK_ORIGIN_ONLY)
 #define deactivate_lv(cmd, lv) lock_lv_vol(cmd, lv, LCK_LV_DEACTIVATE)
+
 #define activate_lv(cmd, lv)   lock_lv_vol(cmd, lv, LCK_LV_ACTIVATE | LCK_HOLD)
-#define activate_lv_excl(cmd, lv)      \
-                               lock_lv_vol(cmd, lv, LCK_LV_EXCLUSIVE | LCK_HOLD)
+#define activate_lv_excl_local(cmd, lv)        \
+                               lock_lv_vol(cmd, lv, LCK_LV_EXCLUSIVE | LCK_HOLD | LCK_LOCAL)
+#define activate_lv_excl_remote(cmd, lv)       \
+                               lock_lv_vol(cmd, lv, LCK_LV_EXCLUSIVE | LCK_HOLD | LCK_REMOTE)
+
+struct logical_volume;
+int activate_lv_excl(struct cmd_context *cmd, struct logical_volume *lv);
+
 #define activate_lv_local(cmd, lv)     \
        lock_lv_vol(cmd, lv, LCK_LV_ACTIVATE | LCK_HOLD | LCK_LOCAL)
 #define deactivate_lv_local(cmd, lv)   \
This page took 0.043113 seconds and 5 git commands to generate.