Blame SOURCES/067-bundle-constraints.patch

60de42
From f9ad81dfee9780a783ea769e22af89045ef673c1 Mon Sep 17 00:00:00 2001
60de42
From: Andrew Beekhof <andrew@beekhof.net>
60de42
Date: Fri, 2 Jun 2017 12:02:28 +1000
60de42
Subject: [PATCH 1/8] PE: Bundles: Implement colocation of primitives and
60de42
 groups with bundles
60de42
60de42
---
60de42
 pengine/container.c | 42 +++++++++++++++++++++++++++++++++++++++++-
60de42
 1 file changed, 41 insertions(+), 1 deletion(-)
60de42
60de42
diff --git a/pengine/container.c b/pengine/container.c
60de42
index 7ec390e..3dc1b35 100644
60de42
--- a/pengine/container.c
60de42
+++ b/pengine/container.c
60de42
@@ -115,6 +115,7 @@ container_color(resource_t * rsc, node_t * prefer, pe_working_set_t * data_set)
60de42
     }
60de42
 
60de42
     clear_bit(rsc->flags, pe_rsc_allocating);
60de42
+    clear_bit(rsc->flags, pe_rsc_provisional);
60de42
     return NULL;
60de42
 }
60de42
 
60de42
@@ -205,7 +206,46 @@ container_rsc_colocation_lh(resource_t * rsc_lh, resource_t * rsc_rh, rsc_coloca
60de42
 void
60de42
 container_rsc_colocation_rh(resource_t * rsc_lh, resource_t * rsc_rh, rsc_colocation_t * constraint)
60de42
 {
60de42
-    pe_err("Container %s cannot be colocated with anything", rsc_rh->id);
60de42
+    GListPtr allocated_rhs = NULL;
60de42
+    container_variant_data_t *container_data = NULL;
60de42
+
60de42
+    CRM_CHECK(constraint != NULL, return);
60de42
+    CRM_CHECK(rsc_lh != NULL, pe_err("rsc_lh was NULL for %s", constraint->id); return);
60de42
+    CRM_CHECK(rsc_rh != NULL, pe_err("rsc_rh was NULL for %s", constraint->id); return);
60de42
+
60de42
+    if (is_set(rsc_rh->flags, pe_rsc_provisional)) {
60de42
+        pe_rsc_trace(rsc_rh, "%s is still provisional", rsc_rh->id);
60de42
+        return;
60de42
+
60de42
+    } else if(rsc_lh->variant > pe_group) {
60de42
+        pe_err("Only basic resources and groups can be colocated with %s", rsc_rh->id);
60de42
+        return;
60de42
+    }
60de42
+
60de42
+    get_container_variant_data(container_data, constraint->rsc_rh);
60de42
+    pe_rsc_trace(rsc_rh, "Processing constraint %s: %s -> %s %d",
60de42
+                 constraint->id, rsc_lh->id, rsc_rh->id, constraint->score);
60de42
+
60de42
+    for (GListPtr gIter = container_data->tuples; gIter != NULL; gIter = gIter->next) {
60de42
+        container_grouping_t *tuple = (container_grouping_t *)gIter->data;
60de42
+
60de42
+        if (constraint->score < INFINITY) {
60de42
+            tuple->docker->cmds->rsc_colocation_rh(rsc_lh, tuple->docker, constraint);
60de42
+
60de42
+        } else {
60de42
+            node_t *chosen = tuple->docker->fns->location(tuple->docker, NULL, FALSE);
60de42
+
60de42
+            if (chosen != NULL && is_set_recursive(tuple->docker, pe_rsc_block, TRUE) == FALSE) {
60de42
+                pe_rsc_trace(rsc_rh, "Allowing %s: %s %d", constraint->id, chosen->details->uname, chosen->weight);
60de42
+                allocated_rhs = g_list_prepend(allocated_rhs, chosen);
60de42
+            }
60de42
+        }
60de42
+    }
60de42
+
60de42
+    if (constraint->score >= INFINITY) {
60de42
+        node_list_exclude(rsc_lh->allowed_nodes, allocated_rhs, FALSE);
60de42
+    }
60de42
+    g_list_free(allocated_rhs);
60de42
 }
60de42
 
60de42
 enum pe_action_flags
60de42
-- 
60de42
1.8.3.1
60de42
60de42
60de42
From 12abb14f516cf53f526b0bbdade1fda9ad612091 Mon Sep 17 00:00:00 2001
60de42
From: Andrew Beekhof <andrew@beekhof.net>
60de42
Date: Fri, 2 Jun 2017 12:40:34 +1000
60de42
Subject: [PATCH 2/8] PE: Bundles: Allow clones to be colocated with bundles
60de42
60de42
---
60de42
 pengine/clone.c     | 61 +++++++++++++++++++---------------
60de42
 pengine/container.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++-------
60de42
 pengine/utils.h     |  2 ++
60de42
 3 files changed, 120 insertions(+), 38 deletions(-)
60de42
60de42
diff --git a/pengine/clone.c b/pengine/clone.c
60de42
index 2b332b1..f8c7503 100644
60de42
--- a/pengine/clone.c
60de42
+++ b/pengine/clone.c
60de42
@@ -925,23 +925,22 @@ clone_internal_constraints(resource_t * rsc, pe_working_set_t * data_set)
60de42
     }
60de42
 }
60de42
 
60de42
-static bool
60de42
+bool
60de42
 assign_node(resource_t * rsc, node_t * node, gboolean force)
60de42
 {
60de42
     bool changed = FALSE;
60de42
 
60de42
     if (rsc->children) {
60de42
 
60de42
-        GListPtr gIter = rsc->children;
60de42
-
60de42
-        for (; gIter != NULL; gIter = gIter->next) {
60de42
+        for (GListPtr gIter = rsc->children; gIter != NULL; gIter = gIter->next) {
60de42
             resource_t *child_rsc = (resource_t *) gIter->data;
60de42
 
60de42
-            changed |= native_assign_node(child_rsc, NULL, node, force);
60de42
+            changed |= assign_node(child_rsc, node, force);
60de42
         }
60de42
 
60de42
         return changed;
60de42
     }
60de42
+
60de42
     if (rsc->allocated_to != NULL) {
60de42
         changed = true;
60de42
     }
60de42
@@ -954,7 +953,6 @@ static resource_t *
60de42
 find_compatible_child_by_node(resource_t * local_child, node_t * local_node, resource_t * rsc,
60de42
                               enum rsc_role_e filter, gboolean current)
60de42
 {
60de42
-    node_t *node = NULL;
60de42
     GListPtr gIter = NULL;
60de42
 
60de42
     if (local_node == NULL) {
60de42
@@ -968,29 +966,11 @@ find_compatible_child_by_node(resource_t * local_child, node_t * local_node, res
60de42
     gIter = rsc->children;
60de42
     for (; gIter != NULL; gIter = gIter->next) {
60de42
         resource_t *child_rsc = (resource_t *) gIter->data;
60de42
-        enum rsc_role_e next_role = child_rsc->fns->state(child_rsc, current);
60de42
 
60de42
-        if (is_set_recursive(child_rsc, pe_rsc_block, TRUE) == FALSE) {
60de42
-            /* We only want instances that haven't failed */
60de42
-            node = child_rsc->fns->location(child_rsc, NULL, current);
60de42
-        }
60de42
-
60de42
-        if (filter != RSC_ROLE_UNKNOWN && next_role != filter) {
60de42
-            crm_trace("Filtered %s", child_rsc->id);
60de42
-            continue;
60de42
-        }
60de42
-
60de42
-        if (node && local_node && node->details == local_node->details) {
60de42
+        if(is_child_compatible(child_rsc, local_node, filter, current)) {
60de42
             crm_trace("Pairing %s with %s on %s",
60de42
-                      local_child->id, child_rsc->id, node->details->uname);
60de42
+                      local_child->id, child_rsc->id, local_node->details->uname);
60de42
             return child_rsc;
60de42
-
60de42
-        } else if (node) {
60de42
-            crm_trace("%s - %s vs %s", child_rsc->id, node->details->uname,
60de42
-                      local_node->details->uname);
60de42
-
60de42
-        } else {
60de42
-            crm_trace("%s - not allocated %d", child_rsc->id, current);
60de42
         }
60de42
     }
60de42
 
60de42
@@ -998,6 +978,35 @@ find_compatible_child_by_node(resource_t * local_child, node_t * local_node, res
60de42
     return NULL;
60de42
 }
60de42
 
60de42
+gboolean
60de42
+is_child_compatible(resource_t *child_rsc, node_t * local_node, enum rsc_role_e filter, gboolean current) 
60de42
+{
60de42
+    node_t *node = NULL;
60de42
+    enum rsc_role_e next_role = child_rsc->fns->state(child_rsc, current);
60de42
+
60de42
+    if (is_set_recursive(child_rsc, pe_rsc_block, TRUE) == FALSE) {
60de42
+        /* We only want instances that haven't failed */
60de42
+        node = child_rsc->fns->location(child_rsc, NULL, current);
60de42
+    }
60de42
+
60de42
+    if (filter != RSC_ROLE_UNKNOWN && next_role != filter) {
60de42
+        crm_trace("Filtered %s", child_rsc->id);
60de42
+        return FALSE;
60de42
+    }
60de42
+
60de42
+    if (node && local_node && node->details == local_node->details) {
60de42
+        return TRUE;
60de42
+
60de42
+    } else if (node) {
60de42
+        crm_trace("%s - %s vs %s", child_rsc->id, node->details->uname,
60de42
+                  local_node->details->uname);
60de42
+
60de42
+    } else {
60de42
+        crm_trace("%s - not allocated %d", child_rsc->id, current);
60de42
+    }
60de42
+    return FALSE;
60de42
+}
60de42
+
60de42
 resource_t *
60de42
 find_compatible_child(resource_t * local_child, resource_t * rsc, enum rsc_role_e filter,
60de42
                       gboolean current)
60de42
diff --git a/pengine/container.c b/pengine/container.c
60de42
index 3dc1b35..67b0052 100644
60de42
--- a/pengine/container.c
60de42
+++ b/pengine/container.c
60de42
@@ -197,34 +197,105 @@ container_internal_constraints(resource_t * rsc, pe_working_set_t * data_set)
60de42
     }
60de42
 }
60de42
 
60de42
+
60de42
+static resource_t *
60de42
+find_compatible_tuple_by_node(resource_t * rsc_lh, node_t * candidate, resource_t * rsc,
60de42
+                              enum rsc_role_e filter, gboolean current)
60de42
+{
60de42
+    container_variant_data_t *container_data = NULL;
60de42
+
60de42
+    CRM_CHECK(candidate != NULL, return NULL);
60de42
+    get_container_variant_data(container_data, rsc);
60de42
+
60de42
+    crm_trace("Looking for compatible child from %s for %s on %s",
60de42
+              rsc_lh->id, rsc->id, candidate->details->uname);
60de42
+
60de42
+    for (GListPtr gIter = container_data->tuples; gIter != NULL; gIter = gIter->next) {
60de42
+        container_grouping_t *tuple = (container_grouping_t *)gIter->data;
60de42
+
60de42
+        if(is_child_compatible(tuple->docker, candidate, filter, current)) {
60de42
+            crm_trace("Pairing %s with %s on %s",
60de42
+                      rsc_lh->id, tuple->docker->id, candidate->details->uname);
60de42
+            return tuple->docker;
60de42
+        }
60de42
+    }
60de42
+
60de42
+    crm_trace("Can't pair %s with %s", rsc_lh->id, rsc->id);
60de42
+    return NULL;
60de42
+}
60de42
+
60de42
+static resource_t *
60de42
+find_compatible_tuple(resource_t *rsc_lh, resource_t * rsc, enum rsc_role_e filter,
60de42
+                      gboolean current)
60de42
+{
60de42
+    GListPtr scratch = NULL;
60de42
+    resource_t *pair = NULL;
60de42
+    node_t *active_node_lh = NULL;
60de42
+
60de42
+    active_node_lh = rsc_lh->fns->location(rsc_lh, NULL, current);
60de42
+    if (active_node_lh) {
60de42
+        return find_compatible_tuple_by_node(rsc_lh, active_node_lh, rsc, filter, current);
60de42
+    }
60de42
+
60de42
+    scratch = g_hash_table_get_values(rsc_lh->allowed_nodes);
60de42
+    scratch = g_list_sort_with_data(scratch, sort_node_weight, NULL);
60de42
+
60de42
+    for (GListPtr gIter = scratch; gIter != NULL; gIter = gIter->next) {
60de42
+        node_t *node = (node_t *) gIter->data;
60de42
+
60de42
+        pair = find_compatible_tuple_by_node(rsc_lh, node, rsc, filter, current);
60de42
+        if (pair) {
60de42
+            goto done;
60de42
+        }
60de42
+    }
60de42
+
60de42
+    pe_rsc_debug(rsc, "Can't pair %s with %s", rsc_lh->id, rsc->id);
60de42
+  done:
60de42
+    g_list_free(scratch);
60de42
+    return pair;
60de42
+}
60de42
+
60de42
 void
60de42
-container_rsc_colocation_lh(resource_t * rsc_lh, resource_t * rsc_rh, rsc_colocation_t * constraint)
60de42
+container_rsc_colocation_lh(resource_t * rsc, resource_t * rsc_rh, rsc_colocation_t * constraint)
60de42
 {
60de42
-    pe_err("Container %s cannot be colocated with anything", rsc_lh->id);
60de42
+    pe_err("Container %s cannot be colocated with anything", rsc->id);
60de42
 }
60de42
 
60de42
 void
60de42
-container_rsc_colocation_rh(resource_t * rsc_lh, resource_t * rsc_rh, rsc_colocation_t * constraint)
60de42
+container_rsc_colocation_rh(resource_t * rsc_lh, resource_t * rsc, rsc_colocation_t * constraint)
60de42
 {
60de42
     GListPtr allocated_rhs = NULL;
60de42
     container_variant_data_t *container_data = NULL;
60de42
 
60de42
     CRM_CHECK(constraint != NULL, return);
60de42
     CRM_CHECK(rsc_lh != NULL, pe_err("rsc_lh was NULL for %s", constraint->id); return);
60de42
-    CRM_CHECK(rsc_rh != NULL, pe_err("rsc_rh was NULL for %s", constraint->id); return);
60de42
+    CRM_CHECK(rsc != NULL, pe_err("rsc was NULL for %s", constraint->id); return);
60de42
 
60de42
-    if (is_set(rsc_rh->flags, pe_rsc_provisional)) {
60de42
-        pe_rsc_trace(rsc_rh, "%s is still provisional", rsc_rh->id);
60de42
+    if (is_set(rsc->flags, pe_rsc_provisional)) {
60de42
+        pe_rsc_trace(rsc, "%s is still provisional", rsc->id);
60de42
         return;
60de42
 
60de42
-    } else if(rsc_lh->variant > pe_group) {
60de42
-        pe_err("Only basic resources and groups can be colocated with %s", rsc_rh->id);
60de42
+    } else if(constraint->rsc_lh->variant > pe_group) {
60de42
+        resource_t *rh_child = find_compatible_tuple(rsc_lh, rsc, RSC_ROLE_UNKNOWN, FALSE);
60de42
+
60de42
+        if (rh_child) {
60de42
+            pe_rsc_debug(rsc, "Pairing %s with %s", rsc_lh->id, rh_child->id);
60de42
+            rsc_lh->cmds->rsc_colocation_lh(rsc_lh, rh_child, constraint);
60de42
+
60de42
+        } else if (constraint->score >= INFINITY) {
60de42
+            crm_notice("Cannot pair %s with instance of %s", rsc_lh->id, rsc->id);
60de42
+            assign_node(rsc_lh, NULL, TRUE);
60de42
+
60de42
+        } else {
60de42
+            pe_rsc_debug(rsc, "Cannot pair %s with instance of %s", rsc_lh->id, rsc->id);
60de42
+        }
60de42
+
60de42
         return;
60de42
     }
60de42
 
60de42
-    get_container_variant_data(container_data, constraint->rsc_rh);
60de42
-    pe_rsc_trace(rsc_rh, "Processing constraint %s: %s -> %s %d",
60de42
-                 constraint->id, rsc_lh->id, rsc_rh->id, constraint->score);
60de42
+    get_container_variant_data(container_data, rsc);
60de42
+    pe_rsc_trace(rsc, "Processing constraint %s: %s -> %s %d",
60de42
+                 constraint->id, rsc_lh->id, rsc->id, constraint->score);
60de42
 
60de42
     for (GListPtr gIter = container_data->tuples; gIter != NULL; gIter = gIter->next) {
60de42
         container_grouping_t *tuple = (container_grouping_t *)gIter->data;
60de42
@@ -236,7 +307,7 @@ container_rsc_colocation_rh(resource_t * rsc_lh, resource_t * rsc_rh, rsc_coloca
60de42
             node_t *chosen = tuple->docker->fns->location(tuple->docker, NULL, FALSE);
60de42
 
60de42
             if (chosen != NULL && is_set_recursive(tuple->docker, pe_rsc_block, TRUE) == FALSE) {
60de42
-                pe_rsc_trace(rsc_rh, "Allowing %s: %s %d", constraint->id, chosen->details->uname, chosen->weight);
60de42
+                pe_rsc_trace(rsc, "Allowing %s: %s %d", constraint->id, chosen->details->uname, chosen->weight);
60de42
                 allocated_rhs = g_list_prepend(allocated_rhs, chosen);
60de42
             }
60de42
         }
60de42
diff --git a/pengine/utils.h b/pengine/utils.h
60de42
index fc503be..79fd33d 100644
60de42
--- a/pengine/utils.h
60de42
+++ b/pengine/utils.h
60de42
@@ -52,6 +52,8 @@ extern void log_action(unsigned int log_level, const char *pre_text,
60de42
 extern gboolean can_run_any(GHashTable * nodes);
60de42
 extern resource_t *find_compatible_child(resource_t * local_child, resource_t * rsc,
60de42
                                          enum rsc_role_e filter, gboolean current);
60de42
+gboolean is_child_compatible(resource_t *child_rsc, node_t * local_node, enum rsc_role_e filter, gboolean current);
60de42
+bool assign_node(resource_t * rsc, node_t * node, gboolean force);
60de42
 
60de42
 
60de42
 enum filter_colocation_res {
60de42
-- 
60de42
1.8.3.1
60de42
60de42
60de42
From 2cc26c662dbbee5a7288c83c71fe172a1d3d4ee1 Mon Sep 17 00:00:00 2001
60de42
From: Andrew Beekhof <andrew@beekhof.net>
60de42
Date: Fri, 2 Jun 2017 12:52:24 +1000
60de42
Subject: [PATCH 3/8] Refactor: PE: Simplify the bundle and clone colocation_lh
60de42
 functions
60de42
60de42
---
60de42
 pengine/clone.c     | 15 +--------------
60de42
 pengine/container.c |  6 +++++-
60de42
 2 files changed, 6 insertions(+), 15 deletions(-)
60de42
60de42
diff --git a/pengine/clone.c b/pengine/clone.c
60de42
index f8c7503..51338d6 100644
60de42
--- a/pengine/clone.c
60de42
+++ b/pengine/clone.c
60de42
@@ -1047,20 +1047,7 @@ clone_rsc_colocation_lh(resource_t * rsc_lh, resource_t * rsc_rh, rsc_colocation
60de42
      *
60de42
      * Instead we add the colocation constraints to the child and call from there
60de42
      */
60de42
-
60de42
-    GListPtr gIter = rsc_lh->children;
60de42
-
60de42
-    CRM_CHECK(FALSE, crm_err("This functionality is not thought to be used. Please report a bug."));
60de42
-    CRM_CHECK(rsc_lh, return);
60de42
-    CRM_CHECK(rsc_rh, return);
60de42
-
60de42
-    for (; gIter != NULL; gIter = gIter->next) {
60de42
-        resource_t *child_rsc = (resource_t *) gIter->data;
60de42
-
60de42
-        child_rsc->cmds->rsc_colocation_lh(child_rsc, rsc_rh, constraint);
60de42
-    }
60de42
-
60de42
-    return;
60de42
+    CRM_ASSERT(FALSE);
60de42
 }
60de42
 
60de42
 void
60de42
diff --git a/pengine/container.c b/pengine/container.c
60de42
index 67b0052..008b2ec 100644
60de42
--- a/pengine/container.c
60de42
+++ b/pengine/container.c
60de42
@@ -258,7 +258,11 @@ find_compatible_tuple(resource_t *rsc_lh, resource_t * rsc, enum rsc_role_e filt
60de42
 void
60de42
 container_rsc_colocation_lh(resource_t * rsc, resource_t * rsc_rh, rsc_colocation_t * constraint)
60de42
 {
60de42
-    pe_err("Container %s cannot be colocated with anything", rsc->id);
60de42
+    /* -- Never called --
60de42
+     *
60de42
+     * Instead we add the colocation constraints to the child and call from there
60de42
+     */
60de42
+    CRM_ASSERT(FALSE);
60de42
 }
60de42
 
60de42
 void
60de42
-- 
60de42
1.8.3.1
60de42
60de42
60de42
From 77a80de9cda4b48ef16f29b42abe5c6d6e7fe179 Mon Sep 17 00:00:00 2001
60de42
From: Andrew Beekhof <andrew@beekhof.net>
60de42
Date: Thu, 8 Jun 2017 21:04:09 +1000
60de42
Subject: [PATCH 4/8] Fix: PE: Bundle location constraints should only apply to
60de42
 the IP and docker resources
60de42
60de42
---
60de42
 pengine/container.c | 14 ++++++++++----
60de42
 1 file changed, 10 insertions(+), 4 deletions(-)
60de42
60de42
diff --git a/pengine/container.c b/pengine/container.c
60de42
index 008b2ec..58f6fca 100644
60de42
--- a/pengine/container.c
60de42
+++ b/pengine/container.c
60de42
@@ -342,16 +342,22 @@ container_update_actions(action_t * first, action_t * then, node_t * node, enum
60de42
 void
60de42
 container_rsc_location(resource_t * rsc, rsc_to_node_t * constraint)
60de42
 {
60de42
-    GListPtr gIter = rsc->children;
60de42
+    container_variant_data_t *container_data = NULL;
60de42
+    get_container_variant_data(container_data, rsc);
60de42
 
60de42
     pe_rsc_trace(rsc, "Processing location constraint %s for %s", constraint->id, rsc->id);
60de42
 
60de42
     native_rsc_location(rsc, constraint);
60de42
 
60de42
-    for (; gIter != NULL; gIter = gIter->next) {
60de42
-        resource_t *child_rsc = (resource_t *) gIter->data;
60de42
+    for (GListPtr gIter = container_data->tuples; gIter != NULL; gIter = gIter->next) {
60de42
+        container_grouping_t *tuple = (container_grouping_t *)gIter->data;
60de42
 
60de42
-        child_rsc->cmds->rsc_location(child_rsc, constraint);
60de42
+        if (tuple->docker) {
60de42
+            tuple->docker->cmds->rsc_location(tuple->docker, constraint);
60de42
+        }
60de42
+        if(tuple->ip) {
60de42
+            tuple->ip->cmds->rsc_location(tuple->ip, constraint);
60de42
+        }
60de42
     }
60de42
 }
60de42
 
60de42
-- 
60de42
1.8.3.1
60de42
60de42
60de42
From 499d2d4d300b45984e2165e75a9bbdb33f8e752d Mon Sep 17 00:00:00 2001
60de42
From: Andrew Beekhof <andrew@beekhof.net>
60de42
Date: Wed, 14 Jun 2017 12:24:12 +1000
60de42
Subject: [PATCH 5/8] Fix: PE: Do not re-add a node's default score for each
60de42
 location constraint
60de42
60de42
---
60de42
 pengine/test10/base-score.scores | 2 +-
60de42
 pengine/utils.c                  | 2 +-
60de42
 2 files changed, 2 insertions(+), 2 deletions(-)
60de42
60de42
diff --git a/pengine/test10/base-score.scores b/pengine/test10/base-score.scores
60de42
index 1c47a9b..7955241 100644
60de42
--- a/pengine/test10/base-score.scores
60de42
+++ b/pengine/test10/base-score.scores
60de42
@@ -1,5 +1,5 @@
60de42
 Allocation scores:
60de42
-native_color: Dummy allocation score on puma1: 210
60de42
+native_color: Dummy allocation score on puma1: 110
60de42
 native_color: Dummy allocation score on puma2: 0
60de42
 native_color: Dummy allocation score on puma3: -2000
60de42
 native_color: Dummy allocation score on puma4: 0
60de42
diff --git a/pengine/utils.c b/pengine/utils.c
60de42
index 755f1c8..a587e58 100644
60de42
--- a/pengine/utils.c
60de42
+++ b/pengine/utils.c
60de42
@@ -96,7 +96,7 @@ rsc2node_new(const char *id, resource_t * rsc,
60de42
         if (foo_node != NULL) {
60de42
             node_t *copy = node_copy(foo_node);
60de42
 
60de42
-            copy->weight = merge_weights(node_weight, foo_node->weight);
60de42
+            copy->weight = node_weight;
60de42
             new_con->node_list_rh = g_list_prepend(NULL, copy);
60de42
         }
60de42
 
60de42
-- 
60de42
1.8.3.1
60de42
60de42
60de42
From 61c6a8acd9c093af333cabe5381c9b7500880c5f Mon Sep 17 00:00:00 2001
60de42
From: Andrew Beekhof <andrew@beekhof.net>
60de42
Date: Thu, 15 Jun 2017 10:40:39 +1000
60de42
Subject: [PATCH 6/8] Fix: PE: Correctly implement
60de42
 pe_order_implies_first_printed
60de42
60de42
---
60de42
 pengine/graph.c | 44 ++++++++++++++++++++++----------------------
60de42
 1 file changed, 22 insertions(+), 22 deletions(-)
60de42
60de42
diff --git a/pengine/graph.c b/pengine/graph.c
60de42
index e3bde09..2a0b4b9 100644
60de42
--- a/pengine/graph.c
60de42
+++ b/pengine/graph.c
60de42
@@ -174,7 +174,8 @@ rsc_expand_action(action_t * action)
60de42
 }
60de42
 
60de42
 static enum pe_graph_flags
60de42
-graph_update_action(action_t * first, action_t * then, node_t * node, enum pe_action_flags flags,
60de42
+graph_update_action(action_t * first, action_t * then, node_t * node,
60de42
+                    enum pe_action_flags first_flags, enum pe_action_flags then_flags,
60de42
                     enum pe_ordering type)
60de42
 {
60de42
     enum pe_graph_flags changed = pe_graph_none;
60de42
@@ -186,10 +187,10 @@ graph_update_action(action_t * first, action_t * then, node_t * node, enum pe_ac
60de42
         processed = TRUE;
60de42
         if (then->rsc) {
60de42
             changed |=
60de42
-                then->rsc->cmds->update_actions(first, then, node, flags & pe_action_optional,
60de42
+                then->rsc->cmds->update_actions(first, then, node, first_flags & pe_action_optional,
60de42
                                                 pe_action_optional, pe_order_implies_then);
60de42
 
60de42
-        } else if (is_set(flags, pe_action_optional) == FALSE) {
60de42
+        } else if (is_set(first_flags, pe_action_optional) == FALSE) {
60de42
             if (update_action_flags(then, pe_action_optional | pe_action_clear, __FUNCTION__, __LINE__)) {
60de42
                 changed |= pe_graph_updated_then;
60de42
             }
60de42
@@ -206,7 +207,7 @@ graph_update_action(action_t * first, action_t * then, node_t * node, enum pe_ac
60de42
 
60de42
         processed = TRUE;
60de42
         changed |=
60de42
-            then->rsc->cmds->update_actions(first, then, node, flags, restart, pe_order_restart);
60de42
+            then->rsc->cmds->update_actions(first, then, node, first_flags, restart, pe_order_restart);
60de42
         if (changed) {
60de42
             pe_rsc_trace(then->rsc, "restart: %s then %s: changed", first->uuid, then->uuid);
60de42
         } else {
60de42
@@ -218,10 +219,10 @@ graph_update_action(action_t * first, action_t * then, node_t * node, enum pe_ac
60de42
         processed = TRUE;
60de42
         if (first->rsc) {
60de42
             changed |=
60de42
-                first->rsc->cmds->update_actions(first, then, node, flags,
60de42
+                first->rsc->cmds->update_actions(first, then, node, first_flags,
60de42
                                                  pe_action_optional, pe_order_implies_first);
60de42
 
60de42
-        } else if (is_set(flags, pe_action_optional) == FALSE) {
60de42
+        } else if (is_set(first_flags, pe_action_optional) == FALSE) {
60de42
             pe_rsc_trace(first->rsc, "first unrunnable: %s then %s", first->uuid, then->uuid);
60de42
             if (update_action_flags(first, pe_action_runnable | pe_action_clear, __FUNCTION__, __LINE__)) {
60de42
                 changed |= pe_graph_updated_first;
60de42
@@ -239,7 +240,7 @@ graph_update_action(action_t * first, action_t * then, node_t * node, enum pe_ac
60de42
         processed = TRUE;
60de42
         if (then->rsc) {
60de42
             changed |=
60de42
-                then->rsc->cmds->update_actions(first, then, node, flags & pe_action_optional,
60de42
+                then->rsc->cmds->update_actions(first, then, node, first_flags & pe_action_optional,
60de42
                                                 pe_action_optional, pe_order_implies_first_master);
60de42
         }
60de42
 
60de42
@@ -257,10 +258,10 @@ graph_update_action(action_t * first, action_t * then, node_t * node, enum pe_ac
60de42
         processed = TRUE;
60de42
         if (then->rsc) {
60de42
             changed |=
60de42
-                then->rsc->cmds->update_actions(first, then, node, flags,
60de42
+                then->rsc->cmds->update_actions(first, then, node, first_flags,
60de42
                                                 pe_action_runnable, pe_order_one_or_more);
60de42
 
60de42
-        } else if (is_set(flags, pe_action_runnable)) {
60de42
+        } else if (is_set(first_flags, pe_action_runnable)) {
60de42
             /* alright. a "first" action is considered runnable, incremente
60de42
              * the 'runnable_before' counter */
60de42
             then->runnable_before++;
60de42
@@ -285,13 +286,13 @@ graph_update_action(action_t * first, action_t * then, node_t * node, enum pe_ac
60de42
         processed = TRUE;
60de42
         if (then->rsc) {
60de42
             changed |=
60de42
-                then->rsc->cmds->update_actions(first, then, node, flags,
60de42
+                then->rsc->cmds->update_actions(first, then, node, first_flags,
60de42
                                                 pe_action_runnable, pe_order_runnable_left);
60de42
 
60de42
-        } else if (is_set(flags, pe_action_runnable) == FALSE) {
60de42
+        } else if (is_set(first_flags, pe_action_runnable) == FALSE) {
60de42
             pe_rsc_trace(then->rsc, "then unrunnable: %s then %s", first->uuid, then->uuid);
60de42
             if (update_action_flags(then, pe_action_runnable | pe_action_clear, __FUNCTION__, __LINE__)) {
60de42
-                changed |= pe_graph_updated_then;
60de42
+                 changed |= pe_graph_updated_then;
60de42
             }
60de42
         }
60de42
         if (changed) {
60de42
@@ -305,7 +306,7 @@ graph_update_action(action_t * first, action_t * then, node_t * node, enum pe_ac
60de42
         processed = TRUE;
60de42
         if (then->rsc) {
60de42
             changed |=
60de42
-                then->rsc->cmds->update_actions(first, then, node, flags,
60de42
+                then->rsc->cmds->update_actions(first, then, node, first_flags,
60de42
                                                 pe_action_optional, pe_order_implies_first_migratable);
60de42
         }
60de42
         if (changed) {
60de42
@@ -319,7 +320,7 @@ graph_update_action(action_t * first, action_t * then, node_t * node, enum pe_ac
60de42
         processed = TRUE;
60de42
         if (then->rsc) {
60de42
             changed |=
60de42
-                then->rsc->cmds->update_actions(first, then, node, flags,
60de42
+                then->rsc->cmds->update_actions(first, then, node, first_flags,
60de42
                                                 pe_action_optional, pe_order_pseudo_left);
60de42
         }
60de42
         if (changed) {
60de42
@@ -333,7 +334,7 @@ graph_update_action(action_t * first, action_t * then, node_t * node, enum pe_ac
60de42
         processed = TRUE;
60de42
         if (then->rsc) {
60de42
             changed |=
60de42
-                then->rsc->cmds->update_actions(first, then, node, flags,
60de42
+                then->rsc->cmds->update_actions(first, then, node, first_flags,
60de42
                                                 pe_action_runnable, pe_order_optional);
60de42
         }
60de42
         if (changed) {
60de42
@@ -347,7 +348,7 @@ graph_update_action(action_t * first, action_t * then, node_t * node, enum pe_ac
60de42
         processed = TRUE;
60de42
         if (then->rsc) {
60de42
             changed |=
60de42
-                then->rsc->cmds->update_actions(first, then, node, flags,
60de42
+                then->rsc->cmds->update_actions(first, then, node, first_flags,
60de42
                                                 pe_action_runnable, pe_order_asymmetrical);
60de42
         }
60de42
 
60de42
@@ -360,13 +361,13 @@ graph_update_action(action_t * first, action_t * then, node_t * node, enum pe_ac
60de42
     }
60de42
 
60de42
     if ((first->flags & pe_action_runnable) && (type & pe_order_implies_then_printed)
60de42
-        && (flags & pe_action_optional) == 0) {
60de42
+        && (first_flags & pe_action_optional) == 0) {
60de42
         processed = TRUE;
60de42
         crm_trace("%s implies %s printed", first->uuid, then->uuid);
60de42
         update_action_flags(then, pe_action_print_always, __FUNCTION__, __LINE__);  /* don't care about changed */
60de42
     }
60de42
 
60de42
-    if ((type & pe_order_implies_first_printed) && (flags & pe_action_optional) == 0) {
60de42
+    if (is_set(type, pe_order_implies_first_printed) && is_set(then_flags, pe_action_optional) == FALSE) {
60de42
         processed = TRUE;
60de42
         crm_trace("%s implies %s printed", then->uuid, first->uuid);
60de42
         update_action_flags(first, pe_action_print_always, __FUNCTION__, __LINE__); /* don't care about changed */
60de42
@@ -510,7 +511,6 @@ update_action(action_t * then)
60de42
                 crm_trace("Then: Found node %s for %s", then_node->details->uname, then->uuid);
60de42
             }
60de42
         }
60de42
-
60de42
         /* Disable constraint if it only applies when on same node, but isn't */
60de42
         if (is_set(other->type, pe_order_same_node) && first_node && then_node
60de42
             && (first_node->details != then_node->details)) {
60de42
@@ -524,8 +524,7 @@ update_action(action_t * then)
60de42
 
60de42
         clear_bit(changed, pe_graph_updated_first);
60de42
 
60de42
-        if (first->rsc != then->rsc
60de42
-            && first->rsc != NULL && then->rsc != NULL && first->rsc != then->rsc->parent) {
60de42
+        if (first->rsc != then->rsc && is_parent(then->rsc, first->rsc) == FALSE) {
60de42
             first = rsc_expand_action(first);
60de42
         }
60de42
         if (first != other->action) {
60de42
@@ -584,7 +583,8 @@ update_action(action_t * then)
60de42
                 node = first->node;
60de42
             }
60de42
             clear_bit(first_flags, pe_action_pseudo);
60de42
-            changed |= graph_update_action(first, then, node, first_flags, otype);
60de42
+
60de42
+            changed |= graph_update_action(first, then, node, first_flags, then_flags, otype);
60de42
 
60de42
             /* 'first' was for a complex resource (clone, group, etc),
60de42
              * create a new dependency if necessary
60de42
-- 
60de42
1.8.3.1
60de42
60de42
60de42
From 44f2c05dcdcf6dd5a1bff5e441ddd845a3063b6b Mon Sep 17 00:00:00 2001
60de42
From: Andrew Beekhof <andrew@beekhof.net>
60de42
Date: Thu, 15 Jun 2017 10:43:47 +1000
60de42
Subject: [PATCH 7/8] Fix: PE: Clones within bundles may also have
60de42
 notifications enabled
60de42
60de42
---
60de42
 pengine/graph.c | 31 +++++++++++++++++++------------
60de42
 1 file changed, 19 insertions(+), 12 deletions(-)
60de42
60de42
diff --git a/pengine/graph.c b/pengine/graph.c
60de42
index 2a0b4b9..0d80e79 100644
60de42
--- a/pengine/graph.c
60de42
+++ b/pengine/graph.c
60de42
@@ -146,25 +146,32 @@ convert_non_atomic_uuid(char *old_uuid, resource_t * rsc, gboolean allow_notify,
60de42
 static action_t *
60de42
 rsc_expand_action(action_t * action)
60de42
 {
60de42
+    gboolean notify = FALSE;
60de42
     action_t *result = action;
60de42
+    resource_t *rsc = action->rsc;
60de42
 
60de42
-    if (action->rsc && action->rsc->variant >= pe_group) {
60de42
+    if (rsc == NULL) {
60de42
+        return action;
60de42
+    }
60de42
+
60de42
+    if(pe_rsc_is_clone(rsc) || rsc->parent == NULL) {
60de42
+        /* Only outermost resources have notification actions.
60de42
+         * The exception is those in bundles.
60de42
+         */
60de42
+        notify = is_set(rsc->flags, pe_rsc_notify);
60de42
+    }
60de42
+
60de42
+    if (rsc->variant >= pe_group) {
60de42
         /* Expand 'start' -> 'started' */
60de42
         char *uuid = NULL;
60de42
-        gboolean notify = FALSE;
60de42
-
60de42
-        if (action->rsc->parent == NULL) {
60de42
-            /* Only outermost resources have notification actions */
60de42
-            notify = is_set(action->rsc->flags, pe_rsc_notify);
60de42
-        }
60de42
 
60de42
-        uuid = convert_non_atomic_uuid(action->uuid, action->rsc, notify, FALSE);
60de42
+        uuid = convert_non_atomic_uuid(action->uuid, rsc, notify, FALSE);
60de42
         if (uuid) {
60de42
-            pe_rsc_trace(action->rsc, "Converting %s to %s %d", action->uuid, uuid,
60de42
-                         is_set(action->rsc->flags, pe_rsc_notify));
60de42
-            result = find_first_action(action->rsc->actions, uuid, NULL, NULL);
60de42
+            pe_rsc_trace(rsc, "Converting %s to %s %d", action->uuid, uuid,
60de42
+                         is_set(rsc->flags, pe_rsc_notify));
60de42
+            result = find_first_action(rsc->actions, uuid, NULL, NULL);
60de42
             if (result == NULL) {
60de42
-                crm_err("Couldn't expand %s", action->uuid);
60de42
+                crm_err("Couldn't expand %s to %s in %s", action->uuid, uuid, rsc->id);
60de42
                 result = action;
60de42
             }
60de42
             free(uuid);
60de42
-- 
60de42
1.8.3.1
60de42
60de42
60de42
From f822f38b15e99005f4ace270b6450443d53f6043 Mon Sep 17 00:00:00 2001
60de42
From: Ken Gaillot <kgaillot@redhat.com>
60de42
Date: Mon, 19 Jun 2017 10:47:24 -0500
60de42
Subject: [PATCH 8/8] Low: pengine: make checks a little safer
60de42
60de42
---
60de42
 pengine/graph.c | 7 +++++--
60de42
 1 file changed, 5 insertions(+), 2 deletions(-)
60de42
60de42
diff --git a/pengine/graph.c b/pengine/graph.c
60de42
index 0d80e79..c93745b 100644
60de42
--- a/pengine/graph.c
60de42
+++ b/pengine/graph.c
60de42
@@ -154,7 +154,8 @@ rsc_expand_action(action_t * action)
60de42
         return action;
60de42
     }
60de42
 
60de42
-    if(pe_rsc_is_clone(rsc) || rsc->parent == NULL) {
60de42
+    if ((rsc->parent == NULL)
60de42
+        || (pe_rsc_is_clone(rsc) && (rsc->parent->variant == pe_container))) {
60de42
         /* Only outermost resources have notification actions.
60de42
          * The exception is those in bundles.
60de42
          */
60de42
@@ -531,7 +532,9 @@ update_action(action_t * then)
60de42
 
60de42
         clear_bit(changed, pe_graph_updated_first);
60de42
 
60de42
-        if (first->rsc != then->rsc && is_parent(then->rsc, first->rsc) == FALSE) {
60de42
+        if (first->rsc && then->rsc && (first->rsc != then->rsc)
60de42
+            && (is_parent(then->rsc, first->rsc) == FALSE)) {
60de42
+
60de42
             first = rsc_expand_action(first);
60de42
         }
60de42
         if (first != other->action) {
60de42
-- 
60de42
1.8.3.1
60de42