Blob Blame History Raw
commit ce507c2a598086b16bfbc1d937c656de4e73ffa6
Author: David Vossel <dvossel@redhat.com>
Date:   Wed Mar 19 21:43:43 2014 -0400

    Fix: pengine: fixes invalid transition caused by clones with more than 10 instances
    
    (cherry picked from commit 9e0b496b269ce0e792370e9c2b22446dfaf3e64a)

diff --git a/pengine/clone.c b/pengine/clone.c
index 9113e9d..52a84df 100644
--- a/pengine/clone.c
+++ b/pengine/clone.c
@@ -28,6 +28,18 @@
 gint sort_clone_instance(gconstpointer a, gconstpointer b, gpointer data_set);
 static void append_parent_colocation(resource_t * rsc, resource_t * child, gboolean all);
 
+static gint
+sort_rsc_id(gconstpointer a, gconstpointer b)
+{
+    const resource_t *resource1 = (const resource_t *)a;
+    const resource_t *resource2 = (const resource_t *)b;
+
+    CRM_ASSERT(resource1 != NULL);
+    CRM_ASSERT(resource2 != NULL);
+
+    return strcmp(resource1->id, resource2->id);
+}
+
 static node_t *
 parent_node_instance(const resource_t * rsc, node_t * node)
 {
@@ -749,7 +761,7 @@ child_ordering_constraints(resource_t * rsc, pe_working_set_t * data_set)
     action_t *start = NULL;
     action_t *last_stop = NULL;
     action_t *last_start = NULL;
-    GListPtr gIter = rsc->children;
+    GListPtr gIter = NULL;
     gboolean active_only = TRUE;        /* change to false to get the old behavior */
     clone_variant_data_t *clone_data = NULL;
 
@@ -758,8 +770,10 @@ child_ordering_constraints(resource_t * rsc, pe_working_set_t * data_set)
     if (clone_data->ordered == FALSE) {
         return;
     }
+    /* we have to maintain a consistent sorted child list when building order constraints */
+    rsc->children = g_list_sort(rsc->children, sort_rsc_id);
 
-    for (; gIter != NULL; gIter = gIter->next) {
+    for (gIter = rsc->children; gIter != NULL; gIter = gIter->next) {
         resource_t *child = (resource_t *) gIter->data;
 
         key = stop_key(child);
@@ -857,7 +871,7 @@ void
 clone_internal_constraints(resource_t * rsc, pe_working_set_t * data_set)
 {
     resource_t *last_rsc = NULL;
-    GListPtr gIter = rsc->children;
+    GListPtr gIter;
     clone_variant_data_t *clone_data = NULL;
 
     get_clone_variant_data(clone_data, rsc);
@@ -872,7 +886,11 @@ clone_internal_constraints(resource_t * rsc, pe_working_set_t * data_set)
         new_rsc_order(rsc, RSC_STARTED, rsc, RSC_PROMOTE, pe_order_runnable_left, data_set);
     }
 
-    for (; gIter != NULL; gIter = gIter->next) {
+    if (clone_data->ordered) {
+        /* we have to maintain a consistent sorted child list when building order constraints */
+        rsc->children = g_list_sort(rsc->children, sort_rsc_id);
+    }
+    for (gIter = rsc->children; gIter != NULL; gIter = gIter->next) {
         resource_t *child_rsc = (resource_t *) gIter->data;
 
         child_rsc->cmds->internal_constraints(child_rsc, data_set);
@@ -1400,18 +1418,6 @@ clone_expand(resource_t * rsc, pe_working_set_t * data_set)
     clone_data->promote_notify = NULL;
 }
 
-static gint
-sort_rsc_id(gconstpointer a, gconstpointer b)
-{
-    const resource_t *resource1 = (const resource_t *)a;
-    const resource_t *resource2 = (const resource_t *)b;
-
-    CRM_ASSERT(resource1 != NULL);
-    CRM_ASSERT(resource2 != NULL);
-
-    return strcmp(resource1->id, resource2->id);
-}
-
 node_t *
 rsc_known_on(resource_t * rsc, GListPtr * list)
 {