From 8805f9c1a6663da7732637ed60a8b42c360492cd Mon Sep 17 00:00:00 2001 From: David Vossel Date: Wed, 18 Feb 2015 13:45:07 -0500 Subject: [PATCH] Fix: ensure if B is colocated with A, B can never run without A --- pengine/allocate.c | 2 ++ pengine/graph.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/pengine/allocate.c b/pengine/allocate.c index 7dd70f1..0994a87 100644 --- a/pengine/allocate.c +++ b/pengine/allocate.c @@ -1620,6 +1620,7 @@ rsc_order_first(resource_t * lh_rsc, order_constraint_t * order, pe_working_set_ } extern gboolean update_action(action_t * action); +extern void update_colo_start_chain(action_t * action); static void apply_remote_node_ordering(pe_working_set_t *data_set) @@ -1805,6 +1806,7 @@ stage7(pe_working_set_t * data_set) for (; gIter != NULL; gIter = gIter->next) { action_t *action = (action_t *) gIter->data; + update_colo_start_chain(action); update_action(action); } diff --git a/pengine/graph.c b/pengine/graph.c index 7160bbf..8decd51 100644 --- a/pengine/graph.c +++ b/pengine/graph.c @@ -30,6 +30,7 @@ #include gboolean update_action(action_t * action); +void update_colo_start_chain(action_t * action); gboolean rsc_update_action(action_t * first, action_t * then, enum pe_ordering type); static enum pe_action_flags @@ -389,6 +390,57 @@ graph_update_action(action_t * first, action_t * then, node_t * node, enum pe_ac return changed; } +static void +mark_start_blocked(resource_t *rsc) +{ + GListPtr gIter = rsc->actions; + + for (; gIter != NULL; gIter = gIter->next) { + action_t *action = (action_t *) gIter->data; + + if (safe_str_neq(action->task, RSC_START)) { + continue; + } + if (is_set(action->flags, pe_action_runnable)) { + clear_bit(action->flags, pe_action_runnable); + update_colo_start_chain(action); + update_action(action); + } + } +} + +void +update_colo_start_chain(action_t *action) +{ + GListPtr gIter = NULL; + resource_t *rsc = NULL; + + if (is_not_set(action->flags, pe_action_runnable) && safe_str_eq(action->task, RSC_START)) { + rsc = uber_parent(action->rsc); + } + + if (rsc == NULL || rsc->rsc_cons_lhs == NULL) { + return; + } + + /* if rsc has children, all the children need to have start set to + * unrunnable before we follow the colo chain for the parent. */ + for (gIter = rsc->children; gIter != NULL; gIter = gIter->next) { + resource_t *child = (resource_t *)gIter->data; + action_t *start = find_first_action(child->actions, NULL, RSC_START, NULL); + if (start == NULL || is_set(start->flags, pe_action_runnable)) { + return; + } + } + + for (gIter = rsc->rsc_cons_lhs; gIter != NULL; gIter = gIter->next) { + rsc_colocation_t *colocate_with = (rsc_colocation_t *)gIter->data; + if (colocate_with->score == INFINITY) { + mark_start_blocked(colocate_with->rsc_lh); + } + } +} + gboolean update_action(action_t * then) { @@ -547,6 +599,9 @@ update_action(action_t * then) pe_action_pseudo) ? "pseudo" : then->node ? then->node->details-> uname : ""); + if (is_set(last_flags, pe_action_runnable) && is_not_set(then->flags, pe_action_runnable)) { + update_colo_start_chain(then); + } update_action(then); for (lpc = then->actions_after; lpc != NULL; lpc = lpc->next) { action_wrapper_t *other = (action_wrapper_t *) lpc->data; -- 1.8.4.2