Blame SOURCES/bz1078078-pcmk-pe_store_non_resource_actions_in_a_hashtable_where_we_can_easily_and_cheaply_find_them_again.patch

7ebc05
commit 3544fb711731cb6ebcd48c2af808e4ec25e5eaed
7ebc05
Author: Andrew Beekhof <andrew@beekhof.net>
7ebc05
Date:   Wed Apr 2 15:44:31 2014 +1100
7ebc05
7ebc05
    Refactor: PE: Store non-resource actions in a hashtable where we can easily (and cheaply) find them again
7ebc05
    
7ebc05
    (cherry picked from commit a65979cbbec616f978154e95b49e8f7bcd064a14)
7ebc05
7ebc05
diff --git a/include/crm/pengine/status.h b/include/crm/pengine/status.h
7ebc05
index c81566a..b74bf83 100644
7ebc05
--- a/include/crm/pengine/status.h
7ebc05
+++ b/include/crm/pengine/status.h
7ebc05
@@ -93,6 +93,7 @@ typedef struct pe_working_set_s {
7ebc05
     GHashTable *config_hash;
7ebc05
     GHashTable *domains;
7ebc05
     GHashTable *tickets;
7ebc05
+    GHashTable *singletons; /* Actions for which there can be only one - ie. fence nodeX */
7ebc05
 
7ebc05
     GListPtr nodes;
7ebc05
     GListPtr resources;
7ebc05
diff --git a/lib/pengine/status.c b/lib/pengine/status.c
7ebc05
index bb9dfcb..8695dae 100644
7ebc05
--- a/lib/pengine/status.c
7ebc05
+++ b/lib/pengine/status.c
7ebc05
@@ -191,6 +191,10 @@ cleanup_calculations(pe_working_set_t * data_set)
7ebc05
         g_hash_table_destroy(data_set->config_hash);
7ebc05
     }
7ebc05
 
7ebc05
+    if (data_set->singletons != NULL) {
7ebc05
+        g_hash_table_destroy(data_set->singletons);
7ebc05
+    }
7ebc05
+
7ebc05
     if (data_set->tickets) {
7ebc05
         g_hash_table_destroy(data_set->tickets);
7ebc05
     }
7ebc05
diff --git a/lib/pengine/utils.c b/lib/pengine/utils.c
7ebc05
index 410acfc..2520eeb 100644
7ebc05
--- a/lib/pengine/utils.c
7ebc05
+++ b/lib/pengine/utils.c
7ebc05
@@ -362,6 +362,17 @@ custom_action(resource_t * rsc, char *key, const char *task,
7ebc05
 
7ebc05
     if (save_action && rsc != NULL) {
7ebc05
         possible_matches = find_actions(rsc->actions, key, on_node);
7ebc05
+    } else if(save_action) {
7ebc05
+#if 0
7ebc05
+        action = g_hash_table_lookup(data_set->singletons, key);
7ebc05
+#else
7ebc05
+        /* More expensive but takes 'node' into account */
7ebc05
+        possible_matches = find_actions(data_set->actions, key, on_node);
7ebc05
+#endif
7ebc05
+    }
7ebc05
+
7ebc05
+    if(data_set->singletons == NULL) {
7ebc05
+        data_set->singletons = g_hash_table_new_full(crm_str_hash, g_str_equal, NULL, NULL);
7ebc05
     }
7ebc05
 
7ebc05
     if (possible_matches != NULL) {
7ebc05
@@ -424,6 +435,9 @@ custom_action(resource_t * rsc, char *key, const char *task,
7ebc05
 
7ebc05
         if (save_action) {
7ebc05
             data_set->actions = g_list_prepend(data_set->actions, action);
7ebc05
+            if(rsc == NULL) {
7ebc05
+                g_hash_table_insert(data_set->singletons, action->uuid, action);
7ebc05
+            }
7ebc05
         }
7ebc05
 
7ebc05
         if (rsc != NULL) {
7ebc05
@@ -1588,6 +1602,9 @@ order_actions(action_t * lh_action, action_t * rh_action, enum pe_ordering order
7ebc05
 
7ebc05
     crm_trace("Ordering Action %s before %s", lh_action->uuid, rh_action->uuid);
7ebc05
 
7ebc05
+    /* Ensure we never create a dependancy on ourselves... its happened */
7ebc05
+    CRM_ASSERT(lh_action != rh_action);
7ebc05
+
7ebc05
     /* Filter dups, otherwise update_action_states() has too much work to do */
7ebc05
     gIter = lh_action->actions_after;
7ebc05
     for (; gIter != NULL; gIter = gIter->next) {
7ebc05
@@ -1624,20 +1641,12 @@ action_t *
7ebc05
 get_pseudo_op(const char *name, pe_working_set_t * data_set)
7ebc05
 {
7ebc05
     action_t *op = NULL;
7ebc05
-    const char *op_s = name;
7ebc05
-    GListPtr possible_matches = NULL;
7ebc05
 
7ebc05
-    possible_matches = find_actions(data_set->actions, name, NULL);
7ebc05
-    if (possible_matches != NULL) {
7ebc05
-        if (g_list_length(possible_matches) > 1) {
7ebc05
-            pe_warn("Action %s exists %d times", name, g_list_length(possible_matches));
7ebc05
-        }
7ebc05
-
7ebc05
-        op = g_list_nth_data(possible_matches, 0);
7ebc05
-        g_list_free(possible_matches);
7ebc05
-
7ebc05
-    } else {
7ebc05
-        op = custom_action(NULL, strdup(op_s), op_s, NULL, TRUE, TRUE, data_set);
7ebc05
+    if(data_set->singletons) {
7ebc05
+        op = g_hash_table_lookup(data_set->singletons, name);
7ebc05
+    }
7ebc05
+    if (op == NULL) {
7ebc05
+        op = custom_action(NULL, strdup(name), name, NULL, TRUE, TRUE, data_set);
7ebc05
         set_bit(op->flags, pe_action_pseudo);
7ebc05
         set_bit(op->flags, pe_action_runnable);
7ebc05
     }
7ebc05
diff --git a/pengine/allocate.c b/pengine/allocate.c
7ebc05
index a07fdad..b9ce069 100644
7ebc05
--- a/pengine/allocate.c
7ebc05
+++ b/pengine/allocate.c
7ebc05
@@ -1274,6 +1274,10 @@ pe_fence_op(node_t * node, const char *op, pe_working_set_t * data_set)
7ebc05
 
7ebc05
     key = g_strdup_printf("%s-%s-%s", CRM_OP_FENCE, node->details->uname, op);
7ebc05
 
7ebc05
+    if(data_set->singletons) {
7ebc05
+        stonith_op = g_hash_table_lookup(data_set->singletons, key);
7ebc05
+    }
7ebc05
+
7ebc05
     if(stonith_op == NULL) {
7ebc05
         stonith_op = custom_action(NULL, key, CRM_OP_FENCE, node, FALSE, TRUE, data_set);
7ebc05