Blob Blame History Raw
From 020ff3810c12bbc6ef6ec212958871bb36b5859a Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Sun, 12 Jun 2016 13:37:59 -0500
Subject: [PATCH 1/5] Fix: tools: correctly count starting resources when doing
 crm_resource --restart

---
 tools/crm_resource_runtime.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/tools/crm_resource_runtime.c b/tools/crm_resource_runtime.c
index 82856ad..b246e34 100644
--- a/tools/crm_resource_runtime.c
+++ b/tools/crm_resource_runtime.c
@@ -1178,7 +1178,7 @@ cli_resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t *
             dump_list(list_delta, "Delta");
         }
 
-        crm_trace("%d (was %d) resources remaining", before, g_list_length(list_delta));
+        crm_trace("%d (was %d) resources remaining", g_list_length(list_delta), before);
         if(before == g_list_length(list_delta)) {
             /* aborted during stop phase, print the contents of list_delta */
             fprintf(stderr, "Could not complete shutdown of %s, %d resources remaining\n", rsc_id, g_list_length(list_delta));
@@ -1209,6 +1209,7 @@ cli_resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t *
 
     step_timeout_s = timeout / sleep_interval;
     while(g_list_length(list_delta) > 0) {
+        before = g_list_length(list_delta);
         if(timeout_ms == 0) {
             step_timeout_s = max_delay_in(&data_set, list_delta) / sleep_interval;
         }
@@ -1241,7 +1242,7 @@ cli_resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t *
             goto failure;
         }
 
-    } while(g_list_length(list_delta) > 0);
+    }
 
     free(rsc_id);
     return pcmk_ok;
-- 
1.8.3.1


From 06cc891dd16b1e1b8a004ed364a9f46c64127ffd Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Sun, 12 Jun 2016 15:05:04 -0500
Subject: [PATCH 2/5] Fix: tools: remember any existing target-role when doing
 crm_resource --restart

---
 tools/crm_resource_runtime.c | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/tools/crm_resource_runtime.c b/tools/crm_resource_runtime.c
index b246e34..1567559 100644
--- a/tools/crm_resource_runtime.c
+++ b/tools/crm_resource_runtime.c
@@ -1070,6 +1070,7 @@ cli_resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t *
 
     bool is_clone = FALSE;
     char *rsc_id = NULL;
+    char *orig_target_role = NULL;
 
     GList *list_delta = NULL;
     GList *target_active = NULL;
@@ -1088,7 +1089,9 @@ cli_resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t *
         return -ENXIO;
     }
 
+    /* We might set the target-role meta-attribute */
     attr_set_type = XML_TAG_META_SETS;
+
     rsc_id = strdup(rsc->id);
     if(rsc->variant > pe_group) {
         is_clone = TRUE;
@@ -1127,10 +1130,20 @@ cli_resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t *
     dump_list(current_active, "Origin");
 
     if(is_clone && host) {
+        /* Stop the clone instance by banning it from the host */
         BE_QUIET = TRUE;
         rc = cli_resource_ban(rsc_id, host, NULL, cib);
 
     } else {
+        /* Stop the resource by setting target-role to Stopped.
+         * Remember any existing target-role so we can restore it later
+         * (though it only makes any difference if it's Slave).
+         */
+        char *lookup_id = clone_strip(rsc->id);
+
+        find_resource_attr(cib, XML_NVPAIR_ATTR_VALUE, lookup_id, NULL, NULL,
+                           NULL, XML_RSC_ATTR_TARGET_ROLE, &orig_target_role);
+        free(lookup_id);
         rc = cli_resource_update_attribute(rsc_id, NULL, NULL, XML_RSC_ATTR_TARGET_ROLE, RSC_STOPPED, FALSE, cib, &data_set);
     }
     if(rc != pcmk_ok) {
@@ -1192,6 +1205,13 @@ cli_resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t *
     if(is_clone && host) {
         rc = cli_resource_clear(rsc_id, host, NULL, cib);
 
+    } else if (orig_target_role) {
+        rc = cli_resource_update_attribute(rsc_id, NULL, NULL,
+                                           XML_RSC_ATTR_TARGET_ROLE,
+                                           orig_target_role, FALSE, cib,
+                                           &data_set);
+        free(orig_target_role);
+        orig_target_role = NULL;
     } else {
         rc = cli_resource_delete_attribute(rsc_id, NULL, NULL, XML_RSC_ATTR_TARGET_ROLE, cib, &data_set);
     }
@@ -1250,7 +1270,11 @@ cli_resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t *
   failure:
     if(is_clone && host) {
         cli_resource_clear(rsc_id, host, NULL, cib);
-
+    } else if (orig_target_role) {
+        cli_resource_update_attribute(rsc_id, NULL, NULL,
+                                      XML_RSC_ATTR_TARGET_ROLE,
+                                      orig_target_role, FALSE, cib, &data_set);
+        free(orig_target_role);
     } else {
         cli_resource_delete_attribute(rsc_id, NULL, NULL, XML_RSC_ATTR_TARGET_ROLE, cib, &data_set);
     }
-- 
1.8.3.1


From aaed9569272a5d4704aede32d9d1cf5d76085e6b Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Sun, 12 Jun 2016 15:36:56 -0500
Subject: [PATCH 3/5] Fix: tools: avoid memory leaks in crm_resource --restart

---
 tools/crm_resource_runtime.c | 39 +++++++++++++++++++++++++++++++++++++--
 1 file changed, 37 insertions(+), 2 deletions(-)

diff --git a/tools/crm_resource_runtime.c b/tools/crm_resource_runtime.c
index 1567559..6126e3c 100644
--- a/tools/crm_resource_runtime.c
+++ b/tools/crm_resource_runtime.c
@@ -1148,6 +1148,12 @@ cli_resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t *
     }
     if(rc != pcmk_ok) {
         fprintf(stderr, "Could not set target-role for %s: %s (%d)\n", rsc_id, pcmk_strerror(rc), rc);
+        if (current_active) {
+            g_list_free_full(current_active, free);
+        }
+        if (restart_target_active) {
+            g_list_free_full(restart_target_active, free);
+        }
         free(rsc_id);
         return crm_exit(rc);
     }
@@ -1185,7 +1191,11 @@ cli_resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t *
                 goto failure;
             }
 
+            if (current_active) {
+                g_list_free_full(current_active, free);
+            }
             current_active = get_active_resources(host, &data_set);
+            g_list_free(list_delta);
             list_delta = subtract_lists(current_active, target_active);
             dump_list(current_active, "Current");
             dump_list(list_delta, "Delta");
@@ -1222,7 +1232,13 @@ cli_resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t *
         return crm_exit(rc);
     }
 
+    if (target_active) {
+        g_list_free_full(target_active, free);
+    }
     target_active = restart_target_active;
+    if (list_delta) {
+        g_list_free(list_delta);
+    }
     list_delta = subtract_lists(target_active, current_active);
     fprintf(stdout, "Waiting for %d resources to start again:\n", g_list_length(list_delta));
     display_list(list_delta, " * ");
@@ -1248,7 +1264,11 @@ cli_resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t *
                 goto failure;
             }
 
+            if (current_active) {
+                g_list_free_full(current_active, free);
+            }
             current_active = get_active_resources(host, &data_set);
+            g_list_free(list_delta);
             list_delta = subtract_lists(target_active, current_active);
             dump_list(current_active, "Current");
             dump_list(list_delta, "Delta");
@@ -1264,8 +1284,8 @@ cli_resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t *
 
     }
 
-    free(rsc_id);
-    return pcmk_ok;
+    rc = pcmk_ok;
+    goto done;
 
   failure:
     if(is_clone && host) {
@@ -1278,6 +1298,21 @@ cli_resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t *
     } else {
         cli_resource_delete_attribute(rsc_id, NULL, NULL, XML_RSC_ATTR_TARGET_ROLE, cib, &data_set);
     }
+
+done:
+    if (list_delta) {
+        g_list_free(list_delta);
+    }
+    if (current_active) {
+        g_list_free_full(current_active, free);
+    }
+    if (target_active && (target_active != restart_target_active)) {
+        g_list_free_full(target_active, free);
+    }
+    if (restart_target_active) {
+        g_list_free_full(restart_target_active, free);
+    }
+    cleanup_alloc_calculations(&data_set);
     free(rsc_id);
     return rc;
 }
-- 
1.8.3.1


From 847723f7175a0f008eeebe2d3b333fea4570a228 Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Sun, 12 Jun 2016 16:10:00 -0500
Subject: [PATCH 4/5] Fix: tools: don't assume all resources restart on same
 node with crm_resource --restart

---
 tools/crm_resource_runtime.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/tools/crm_resource_runtime.c b/tools/crm_resource_runtime.c
index 6126e3c..753ba2d 100644
--- a/tools/crm_resource_runtime.c
+++ b/tools/crm_resource_runtime.c
@@ -1044,6 +1044,9 @@ max_delay_in(pe_working_set_t * data_set, GList *resources)
     return 5 + (max_delay / 1000);
 }
 
+#define waiting_for_starts(d, r, h) ((g_list_length(d) > 0) || \
+                                    (resource_is_running_on((r), (h)) == FALSE))
+
 /*!
  * \internal
  * \brief Restart a resource (on a particular host if requested).
@@ -1244,14 +1247,15 @@ cli_resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t *
     display_list(list_delta, " * ");
 
     step_timeout_s = timeout / sleep_interval;
-    while(g_list_length(list_delta) > 0) {
+    while (waiting_for_starts(list_delta, rsc, host)) {
         before = g_list_length(list_delta);
         if(timeout_ms == 0) {
             step_timeout_s = max_delay_in(&data_set, list_delta) / sleep_interval;
         }
 
         /* We probably don't need the entire step timeout */
-        for(lpc = 0; lpc < step_timeout_s && g_list_length(list_delta) > 0; lpc++) {
+        for (lpc = 0; (lpc < step_timeout_s) && waiting_for_starts(list_delta, rsc, host); lpc++) {
+
             sleep(sleep_interval);
             if(timeout) {
                 timeout -= sleep_interval;
@@ -1267,7 +1271,11 @@ cli_resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t *
             if (current_active) {
                 g_list_free_full(current_active, free);
             }
-            current_active = get_active_resources(host, &data_set);
+
+            /* It's OK if dependent resources moved to a different node,
+             * so we check active resources on all nodes.
+             */
+            current_active = get_active_resources(NULL, &data_set);
             g_list_free(list_delta);
             list_delta = subtract_lists(target_active, current_active);
             dump_list(current_active, "Current");
-- 
1.8.3.1


From f5afdc1badbe38781d049c86e8a2f51b17636072 Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Mon, 13 Jun 2016 16:12:28 -0500
Subject: [PATCH 5/5] Fix: tools: properly handle crm_resource --restart with a
 resource in a group

---
 tools/crm_resource_runtime.c | 34 +++++++++++++++++++++++++---------
 1 file changed, 25 insertions(+), 9 deletions(-)

diff --git a/tools/crm_resource_runtime.c b/tools/crm_resource_runtime.c
index 753ba2d..b714a96 100644
--- a/tools/crm_resource_runtime.c
+++ b/tools/crm_resource_runtime.c
@@ -817,19 +817,35 @@ static bool resource_is_running_on(resource_t *rsc, const char *host)
     return found;
 }
 
-static GList *get_active_resources(const char *host, pe_working_set_t *data_set) 
+/*!
+ * \internal
+ * \brief Create a list of all resources active on host from a given list
+ *
+ * \param[in] host      Name of host to check whether resources are active
+ * \param[in] rsc_list  List of resources to check
+ *
+ * \return New list of resources from list that are active on host
+ */
+static GList *
+get_active_resources(const char *host, GList *rsc_list)
 {
     GList *rIter = NULL;
     GList *active = NULL;
 
-    for (rIter = data_set->resources; rIter != NULL; rIter = rIter->next) {
+    for (rIter = rsc_list; rIter != NULL; rIter = rIter->next) {
         resource_t *rsc = (resource_t *) rIter->data;
 
-        if(resource_is_running_on(rsc, host)) {
+        /* Expand groups to their members, because if we're restarting a member
+         * other than the first, we can't otherwise tell which resources are
+         * stopping and starting.
+         */
+        if (rsc->variant == pe_group) {
+            active = g_list_concat(active,
+                                   get_active_resources(host, rsc->children));
+        } else if (resource_is_running_on(rsc, host)) {
             active = g_list_append(active, strdup(rsc->id));
         }
     }
-
     return active;
 }
 
@@ -1127,8 +1143,8 @@ cli_resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t *
         return rc;
     }
 
-    restart_target_active = get_active_resources(host, &data_set);
-    current_active = get_active_resources(host, &data_set);
+    restart_target_active = get_active_resources(host, data_set.resources);
+    current_active = get_active_resources(host, data_set.resources);
 
     dump_list(current_active, "Origin");
 
@@ -1167,7 +1183,7 @@ cli_resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t *
         goto failure;
     }
 
-    target_active = get_active_resources(host, &data_set);
+    target_active = get_active_resources(host, data_set.resources);
     dump_list(target_active, "Target");
 
     list_delta = subtract_lists(current_active, target_active);
@@ -1197,7 +1213,7 @@ cli_resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t *
             if (current_active) {
                 g_list_free_full(current_active, free);
             }
-            current_active = get_active_resources(host, &data_set);
+            current_active = get_active_resources(host, data_set.resources);
             g_list_free(list_delta);
             list_delta = subtract_lists(current_active, target_active);
             dump_list(current_active, "Current");
@@ -1275,7 +1291,7 @@ cli_resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t *
             /* It's OK if dependent resources moved to a different node,
              * so we check active resources on all nodes.
              */
-            current_active = get_active_resources(NULL, &data_set);
+            current_active = get_active_resources(NULL, data_set.resources);
             g_list_free(list_delta);
             list_delta = subtract_lists(target_active, current_active);
             dump_list(current_active, "Current");
-- 
1.8.3.1