Blob Blame History Raw
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