Blame SOURCES/bz902407-pcmk-crm_resource_observe_master_modifier_for_move.patch

ed0026
commit 04c1373e2758744d53e83f8013c84c3517a028ce
ed0026
Author: Andrew Beekhof <andrew@beekhof.net>
ed0026
Date:   Tue Oct 1 20:47:07 2013 +1000
ed0026
ed0026
    Fix: crm_resource: Observe --master modifier for --move
ed0026
    
ed0026
    Also ensure role=Master is overwritten for --ban
ed0026
    Do something sane for --move when called for a clone
ed0026
    
ed0026
    (cherry picked from commit f36c32b47b58254caf580e7fe56e6b5a8eef7639)
ed0026
ed0026
diff --git a/tools/crm_resource.c b/tools/crm_resource.c
ed0026
index 6ded13d..44d96b0 100644
ed0026
--- a/tools/crm_resource.c
ed0026
+++ b/tools/crm_resource.c
ed0026
@@ -917,6 +917,8 @@ ban_resource(const char *rsc_id, const char *host, GListPtr allnodes, cib_t * ci
ed0026
     crm_xml_add(location, XML_COLOC_ATTR_SOURCE, rsc_id);
ed0026
     if(scope_master) {
ed0026
         crm_xml_add(location, XML_RULE_ATTR_ROLE, RSC_ROLE_MASTER_S);
ed0026
+    } else {
ed0026
+        crm_xml_add(location, XML_RULE_ATTR_ROLE, RSC_ROLE_STARTED_S);
ed0026
     }
ed0026
 
ed0026
     if (later_s == NULL) {
ed0026
@@ -982,6 +984,11 @@ prefer_resource(const char *rsc_id, const char *host, cib_t * cib_conn)
ed0026
     free(id);
ed0026
 
ed0026
     crm_xml_add(location, XML_COLOC_ATTR_SOURCE, rsc_id);
ed0026
+    if(scope_master) {
ed0026
+        crm_xml_add(location, XML_RULE_ATTR_ROLE, RSC_ROLE_MASTER_S);
ed0026
+    } else {
ed0026
+        crm_xml_add(location, XML_RULE_ATTR_ROLE, RSC_ROLE_STARTED_S);
ed0026
+    }
ed0026
 
ed0026
     if (later_s == NULL) {
ed0026
         /* Short form */
ed0026
@@ -1924,8 +1931,11 @@ main(int argc, char **argv)
ed0026
         }
ed0026
 
ed0026
     } else if (rsc_cmd == 'M' && host_uname) {
ed0026
-        resource_t *rsc = pe_find_resource(data_set.resources, rsc_id);
ed0026
+
ed0026
+        int count = 0;
ed0026
+        node_t *current = NULL;
ed0026
         node_t *dest = pe_find_node(data_set.nodes, host_uname);
ed0026
+        resource_t *rsc = pe_find_resource(data_set.resources, rsc_id);
ed0026
 
ed0026
         rc = -EINVAL;
ed0026
 
ed0026
@@ -1934,23 +1944,40 @@ main(int argc, char **argv)
ed0026
             rc = -ENXIO;
ed0026
             goto bail;
ed0026
 
ed0026
-        } else if(rsc->variant == pe_clone) {
ed0026
-            CMD_ERR("Resource '%s' not moved: moving a clone makes no sense\n", rsc_id);
ed0026
-            goto bail;
ed0026
-
ed0026
-        } else if (rsc->variant < pe_clone && g_list_length(rsc->running_on) > 1) {
ed0026
-            CMD_ERR("Resource '%s' not moved: active on multiple nodes\n", rsc_id);
ed0026
-            goto bail;
ed0026
-
ed0026
-        } else if (rsc->variant < pe_clone && scope_master) {
ed0026
+        } else if (scope_master && rsc->variant < pe_master) {
ed0026
             resource_t *p = uber_parent(rsc);
ed0026
             if(p->variant == pe_master) {
ed0026
-                CMD_ERR("Resource '%s' not moved: The --master option is not a valid for %s resources."
ed0026
-                        "  Did you mean '%s'?\n", rsc_id, get_resource_typename(rsc->variant), p->id);
ed0026
+                CMD_ERR("Using parent '%s' for --move command instead of '%s'.\n", rsc->id, rsc_id);
ed0026
+                rsc_id = p->id;
ed0026
+                rsc = p;
ed0026
+
ed0026
             } else {
ed0026
-                CMD_ERR("Resource '%s' not moved: The --master option is not a valid for %s resources.\n",
ed0026
-                        rsc_id, get_resource_typename(rsc->variant));
ed0026
+                CMD_ERR("Ignoring '--master' option: not valid for %s resources.\n",
ed0026
+                        get_resource_typename(rsc->variant));
ed0026
+                scope_master = FALSE;
ed0026
             }
ed0026
+        }
ed0026
+
ed0026
+        if(rsc->variant == pe_master) {
ed0026
+            GListPtr iter = NULL;
ed0026
+
ed0026
+            for(iter = rsc->children; iter; iter = iter->next) {
ed0026
+                resource_t *child = (resource_t *)iter->data;
ed0026
+                if(child->role == RSC_ROLE_MASTER) {
ed0026
+                    rsc = child;
ed0026
+                    count++;
ed0026
+                }
ed0026
+            }
ed0026
+
ed0026
+            if(scope_master == FALSE && count == 0) {
ed0026
+                count = g_list_length(rsc->running_on);
ed0026
+            }
ed0026
+
ed0026
+        } else if (rsc->variant > pe_group) {
ed0026
+            count = g_list_length(rsc->running_on);
ed0026
+
ed0026
+        } else if (g_list_length(rsc->running_on) > 1) {
ed0026
+            CMD_ERR("Resource '%s' not moved: active on multiple nodes\n", rsc_id);
ed0026
             goto bail;
ed0026
         }
ed0026
 
ed0026
@@ -1961,13 +1988,19 @@ main(int argc, char **argv)
ed0026
         }
ed0026
 
ed0026
         if(g_list_length(rsc->running_on) == 1) {
ed0026
-            node_t *current = rsc->running_on->data;
ed0026
+            current = rsc->running_on->data;
ed0026
+        }
ed0026
 
ed0026
-            if (safe_str_eq(current->details->uname, dest->details->uname)) {
ed0026
-                CMD_ERR("Error performing operation: %s is already active on %s\n", rsc_id, dest->details->uname);
ed0026
-                goto bail;
ed0026
-            }
ed0026
-            /* } else if (rsc->variant == pe_master) { Find the master and ban it */
ed0026
+        if(current == NULL) {
ed0026
+            /* Nothing to check */
ed0026
+
ed0026
+        } else if(scope_master && rsc->role != RSC_ROLE_MASTER) {
ed0026
+            crm_trace("%s is already active on %s but not in correct state", rsc_id, dest->details->uname);
ed0026
+
ed0026
+        } else if (safe_str_eq(current->details->uname, dest->details->uname)) {
ed0026
+            CMD_ERR("Error performing operation: %s is already %s on %s\n",
ed0026
+                    rsc_id, scope_master?"promoted":"active", dest->details->uname);
ed0026
+            goto bail;
ed0026
         }
ed0026
 
ed0026
         /* Clear any previous constraints for 'dest' */
ed0026
@@ -1976,11 +2009,23 @@ main(int argc, char **argv)
ed0026
         /* Record an explicit preference for 'dest' */
ed0026
         rc = prefer_resource(rsc_id, dest->details->uname, cib_conn);
ed0026
 
ed0026
-        if(do_force && g_list_length(rsc->running_on) == 1) {
ed0026
-            node_t *current = rsc->running_on->data;
ed0026
+        crm_trace("%s%s now prefers node %s%s",
ed0026
+                  rsc->id, scope_master?" (master)":"", dest->details->uname, do_force?"(forced)":"");
ed0026
 
ed0026
-            /* Ban the original location */
ed0026
-            ban_resource(rsc_id, current->details->uname, NULL, cib_conn);
ed0026
+        if(do_force) {
ed0026
+            /* Ban the original location if possible */
ed0026
+            if(current) {
ed0026
+                ban_resource(rsc_id, current->details->uname, NULL, cib_conn);
ed0026
+
ed0026
+            } else if(count > 1) {
ed0026
+                CMD_ERR("Resource '%s' is currently %s in %d locations.  One may now move one to %s\n",
ed0026
+                        rsc_id, scope_master?"promoted":"active", count, dest->details->uname);
ed0026
+                CMD_ERR("You can prevent '%s' from being %s at a specific location with:"
ed0026
+                        " --ban %s--host <name>\n", rsc_id, scope_master?"promoted":"active", scope_master?"--master ":"");
ed0026
+
ed0026
+            } else {
ed0026
+                crm_trace("Not banning %s from it's current location: not active", rsc_id);
ed0026
+            }
ed0026
         }
ed0026
 
ed0026
     } else if (rsc_cmd == 'B' && host_uname) {
ed0026
@@ -2034,7 +2079,8 @@ main(int argc, char **argv)
ed0026
                 rc = ban_resource(rsc_id, current->details->uname, NULL, cib_conn);
ed0026
 
ed0026
             } else {
ed0026
-                CMD_ERR("Resource '%s' not moved: currently promoted in %d locations.\n", rsc_id, count);
ed0026
+                CMD_ERR("Resource '%s' not moved: active in %d locations (promoted in %d).\n", rsc_id, g_list_length(rsc->running_on), count);
ed0026
+                CMD_ERR("You can prevent '%s' from running on a specific location with: --ban --host <name>\n", rsc_id);
ed0026
                 CMD_ERR("You can prevent '%s' from being promoted at a specific location with:"
ed0026
                         " --ban --master --host <name>\n", rsc_id);
ed0026
             }
ed0026
@@ -2042,12 +2088,6 @@ main(int argc, char **argv)
ed0026
         } else {
ed0026
             CMD_ERR("Resource '%s' not moved: active in %d locations.\n", rsc_id, g_list_length(rsc->running_on));
ed0026
             CMD_ERR("You can prevent '%s' from running on a specific location with: --ban --host <name>\n", rsc_id);
ed0026
-
ed0026
-            if(rsc->variant == pe_master && g_list_length(rsc->running_on) > 0) {
ed0026
-                CMD_ERR("You can prevent '%s' from being promoted at its current location with: --ban --master\n", rsc_id);
ed0026
-                CMD_ERR("You can prevent '%s' from being promoted at a specific location with:"
ed0026
-                        " --ban --master --host <name>\n", rsc_id);
ed0026
-            }
ed0026
         }
ed0026
 
ed0026
     } else if (rsc_cmd == 'G') {