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