File bug-938545_pacemaker-pengine-concurrent-fencing.patch of Package pacemaker.3577

commit d9800577e91610ab372b3fa543a0a4431f56b02b
Author: Gao,Yan <ygao@suse.com>
Date:   Tue Sep 8 16:31:06 2015 +0200

    Feature: pengine: Support concurrent fencing
    
    A pengine property "concurrent-fencing" can be configured to allow
    performing fencing operations in parallel. It defaults to "false".

diff --git a/include/crm/pengine/status.h b/include/crm/pengine/status.h
index b95b1e5..ddcdd78 100644
--- a/include/crm/pengine/status.h
+++ b/include/crm/pengine/status.h
@@ -62,6 +62,7 @@ enum pe_find {
 #  define pe_flag_stonith_enabled	0x00000010ULL
 #  define pe_flag_have_stonith_resource	0x00000020ULL
 #  define pe_flag_enable_unfencing	0x00000040ULL
+#  define pe_flag_concurrent_fencing	0x00000080ULL
 
 #  define pe_flag_stop_rsc_orphans	0x00000100ULL
 #  define pe_flag_stop_action_orphans	0x00000200ULL
diff --git a/lib/pengine/common.c b/lib/pengine/common.c
index e612384..070adef 100644
--- a/lib/pengine/common.c
+++ b/lib/pengine/common.c
@@ -108,6 +108,8 @@ pe_cluster_option pe_opts[] = {
 	  "How long to wait for the STONITH action (reboot,on,off) to complete", NULL },
 	{ XML_ATTR_HAVE_WATCHDOG, NULL, "boolean", NULL, "false", &check_boolean,
 	  "Enable watchdog integration", "Set automatically by the cluster if SBD is detected.  User configured values are ignored." },
+	{ "concurrent-fencing", NULL, "boolean", NULL, "false", &check_boolean,
+	  "Allow performing fencing operations in parallel", NULL },
 	{ "startup-fencing", "startup_fencing", "boolean", NULL, "true", &check_boolean,
 	  "STONITH unseen nodes", "Advanced Use Only!  Not using the default is very unsafe!" },
 
diff --git a/lib/pengine/unpack.c b/lib/pengine/unpack.c
index 2b016bc..dc00641 100644
--- a/lib/pengine/unpack.c
+++ b/lib/pengine/unpack.c
@@ -166,6 +166,10 @@ unpack_config(xmlNode * config, pe_working_set_t * data_set)
     data_set->stonith_action = pe_pref(data_set->config_hash, "stonith-action");
     crm_trace("STONITH will %s nodes", data_set->stonith_action);
 
+    set_config_flag(data_set, "concurrent-fencing", pe_flag_concurrent_fencing);
+    crm_debug("Concurrent fencing is %s",
+              is_set(data_set->flags, pe_flag_concurrent_fencing) ? "enabled" : "disabled");
+
     set_config_flag(data_set, "stop-all-resources", pe_flag_stop_everything);
     crm_debug("Stop all active resources: %s",
               is_set(data_set->flags, pe_flag_stop_everything) ? "true" : "false");
diff --git a/pengine/allocate.c b/pengine/allocate.c
index c2e56f9..c0b319a 100644
--- a/pengine/allocate.c
+++ b/pengine/allocate.c
@@ -1393,6 +1393,7 @@ stage6(pe_working_set_t * data_set)
     action_t *done = get_pseudo_op(STONITH_DONE, data_set);
     gboolean need_stonith = TRUE;
     GListPtr gIter = data_set->nodes;
+    GListPtr stonith_ops = NULL;
 
     crm_trace("Processing fencing and shutdown cases");
 
@@ -1421,11 +1422,15 @@ stage6(pe_working_set_t * data_set)
                 dc_down = stonith_op;
                 dc_fence = stonith_op;
 
-            } else {
+            } else if (is_set(data_set->flags, pe_flag_concurrent_fencing) == FALSE) {
                 if (last_stonith) {
                     order_actions(last_stonith, stonith_op, pe_order_optional);
                 }
                 last_stonith = stonith_op;
+
+            } else {
+                order_actions(stonith_op, done, pe_order_implies_then);
+                stonith_ops = g_list_append(stonith_ops, stonith_op);
             }
 
         } else if (node->details->online && node->details->shutdown &&
@@ -1490,8 +1495,21 @@ stage6(pe_working_set_t * data_set)
             order_actions(node_stop, dc_down, pe_order_optional);
         }
 
-        if (last_stonith && dc_down != last_stonith) {
-            order_actions(last_stonith, dc_down, pe_order_optional);
+        if (last_stonith) {
+            if (dc_down != last_stonith) {
+                order_actions(last_stonith, dc_down, pe_order_optional);
+            }
+
+        } else {
+            GListPtr gIter2 = NULL;
+
+            for (gIter2 = stonith_ops; gIter2 != NULL; gIter2 = gIter2->next) {
+                action_t *stonith_op = (action_t *) gIter2->data;
+
+                if (dc_down != stonith_op) {
+                    order_actions(stonith_op, dc_down, pe_order_optional);
+                }
+            }
         }
     }
 
@@ -1504,6 +1522,8 @@ stage6(pe_working_set_t * data_set)
     }
 
     order_actions(done, all_stopped, pe_order_implies_then);
+
+    g_list_free(stonith_ops);
     return TRUE;
 }
 
openSUSE Build Service is sponsored by