commit 3544fb711731cb6ebcd48c2af808e4ec25e5eaed Author: Andrew Beekhof 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);