From 8805f9c1a6663da7732637ed60a8b42c360492cd Mon Sep 17 00:00:00 2001
From: David Vossel <dvossel@redhat.com>
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 <utils.h>
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