|
|
5ee7c6 |
From 355461723733acc0f6f9d9cc1318c91ba2a0ae6c Mon Sep 17 00:00:00 2001
|
|
|
5ee7c6 |
From: Ken Gaillot <kgaillot@redhat.com>
|
|
|
5ee7c6 |
Date: Tue, 22 May 2018 15:55:14 -0500
|
|
|
5ee7c6 |
Subject: [PATCH] Fix: all: prefer appropriate node when multiply active
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
---
|
|
|
5ee7c6 |
lib/pengine/container.c | 8 +++----
|
|
|
5ee7c6 |
lib/pengine/native.c | 8 +++----
|
|
|
5ee7c6 |
pengine/allocate.c | 20 ++++++++---------
|
|
|
5ee7c6 |
pengine/clone.c | 51 +++++++++++++++++++-----------------------
|
|
|
5ee7c6 |
pengine/graph.c | 26 +++++++++++++---------
|
|
|
5ee7c6 |
pengine/native.c | 17 +++++++-------
|
|
|
5ee7c6 |
pengine/notif.c | 2 +-
|
|
|
5ee7c6 |
tools/crm_mon.c | 14 ++++--------
|
|
|
5ee7c6 |
tools/crm_resource.c | 21 +++++++++++-------
|
|
|
5ee7c6 |
tools/crm_resource_print.c | 16 ++++++-------
|
|
|
5ee7c6 |
tools/crm_resource_runtime.c | 53 ++++++++++++++++++++++----------------------
|
|
|
5ee7c6 |
11 files changed, 112 insertions(+), 124 deletions(-)
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
diff --git a/lib/pengine/container.c b/lib/pengine/container.c
|
|
|
5ee7c6 |
index b5340bf..d82948a 100644
|
|
|
5ee7c6 |
--- a/lib/pengine/container.c
|
|
|
5ee7c6 |
+++ b/lib/pengine/container.c
|
|
|
5ee7c6 |
@@ -807,11 +807,11 @@ container_fix_remote_addr_in(resource_t *rsc, xmlNode *xml, const char *field)
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
node = tuple->docker->allocated_to;
|
|
|
5ee7c6 |
- if(node == NULL && tuple->docker->running_on) {
|
|
|
5ee7c6 |
+ if (node == NULL) {
|
|
|
5ee7c6 |
/* If it won't be running anywhere after the
|
|
|
5ee7c6 |
* transition, go with where it's running now.
|
|
|
5ee7c6 |
*/
|
|
|
5ee7c6 |
- node = tuple->docker->running_on->data;
|
|
|
5ee7c6 |
+ node = pe__current_node(tuple->docker);
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
if(node == NULL) {
|
|
|
5ee7c6 |
@@ -1289,9 +1289,7 @@ tuple_print(container_grouping_t * tuple, const char *pre_text, long options, vo
|
|
|
5ee7c6 |
offset += snprintf(buffer + offset, LINE_MAX - offset, " (%s)", tuple->ipaddr);
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
- if (tuple->docker->running_on) {
|
|
|
5ee7c6 |
- node = tuple->docker->running_on->data;
|
|
|
5ee7c6 |
- }
|
|
|
5ee7c6 |
+ node = pe__current_node(tuple->docker);
|
|
|
5ee7c6 |
common_print(rsc, pre_text, buffer, node, options, print_data);
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
diff --git a/lib/pengine/native.c b/lib/pengine/native.c
|
|
|
5ee7c6 |
index e01ef17..eda0355 100644
|
|
|
5ee7c6 |
--- a/lib/pengine/native.c
|
|
|
5ee7c6 |
+++ b/lib/pengine/native.c
|
|
|
5ee7c6 |
@@ -457,7 +457,7 @@ native_print_xml(resource_t * rsc, const char *pre_text, long options, void *pri
|
|
|
5ee7c6 |
if (options & pe_print_rsconly) {
|
|
|
5ee7c6 |
status_print("/>\n");
|
|
|
5ee7c6 |
/* do nothing */
|
|
|
5ee7c6 |
- } else if (g_list_length(rsc->running_on) > 0) {
|
|
|
5ee7c6 |
+ } else if (rsc->running_on != NULL) {
|
|
|
5ee7c6 |
GListPtr gIter = rsc->running_on;
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
status_print(">\n");
|
|
|
5ee7c6 |
@@ -529,7 +529,7 @@ common_print(resource_t * rsc, const char *pre_text, const char *name, node_t *n
|
|
|
5ee7c6 |
} else if (is_set(rsc->flags, pe_rsc_failed)) {
|
|
|
5ee7c6 |
status_print("<font color=\"red\">");
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
- } else if (rsc->variant == pe_native && g_list_length(rsc->running_on) == 0) {
|
|
|
5ee7c6 |
+ } else if (rsc->variant == pe_native && (rsc->running_on == NULL)) {
|
|
|
5ee7c6 |
status_print("<font color=\"red\">");
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
} else if (g_list_length(rsc->running_on) > 1) {
|
|
|
5ee7c6 |
@@ -742,9 +742,7 @@ native_print(resource_t * rsc, const char *pre_text, long options, void *print_d
|
|
|
5ee7c6 |
return;
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
- if (rsc->running_on != NULL) {
|
|
|
5ee7c6 |
- node = rsc->running_on->data;
|
|
|
5ee7c6 |
- }
|
|
|
5ee7c6 |
+ node = pe__current_node(rsc);
|
|
|
5ee7c6 |
common_print(rsc, pre_text, rsc_printable_id(rsc), node, options, print_data);
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
diff --git a/pengine/allocate.c b/pengine/allocate.c
|
|
|
5ee7c6 |
index 724736c..427575b 100644
|
|
|
5ee7c6 |
--- a/pengine/allocate.c
|
|
|
5ee7c6 |
+++ b/pengine/allocate.c
|
|
|
5ee7c6 |
@@ -1101,14 +1101,14 @@ sort_rsc_process_order(gconstpointer a, gconstpointer b, gpointer data)
|
|
|
5ee7c6 |
r2_weight = -INFINITY;
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
if (resource1->running_on) {
|
|
|
5ee7c6 |
- r1_node = g_list_nth_data(resource1->running_on, 0);
|
|
|
5ee7c6 |
+ r1_node = pe__current_node(resource1);
|
|
|
5ee7c6 |
r1_node = g_hash_table_lookup(r1_nodes, r1_node->details->id);
|
|
|
5ee7c6 |
if (r1_node != NULL) {
|
|
|
5ee7c6 |
r1_weight = r1_node->weight;
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
if (resource2->running_on) {
|
|
|
5ee7c6 |
- r2_node = g_list_nth_data(resource2->running_on, 0);
|
|
|
5ee7c6 |
+ r2_node = pe__current_node(resource2);
|
|
|
5ee7c6 |
r2_node = g_hash_table_lookup(r2_nodes, r2_node->details->id);
|
|
|
5ee7c6 |
if (r2_node != NULL) {
|
|
|
5ee7c6 |
r2_weight = r2_node->weight;
|
|
|
5ee7c6 |
@@ -1925,10 +1925,7 @@ get_remote_node_state(pe_node_t *node)
|
|
|
5ee7c6 |
remote_rsc = node->details->remote_rsc;
|
|
|
5ee7c6 |
CRM_ASSERT(remote_rsc);
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
- if(remote_rsc->running_on) {
|
|
|
5ee7c6 |
- cluster_node = remote_rsc->running_on->data;
|
|
|
5ee7c6 |
- }
|
|
|
5ee7c6 |
-
|
|
|
5ee7c6 |
+ cluster_node = pe__current_node(remote_rsc);
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
/* If the cluster node the remote connection resource resides on
|
|
|
5ee7c6 |
* is unclean or went offline, we can't process any operations
|
|
|
5ee7c6 |
@@ -1989,11 +1986,14 @@ get_remote_node_state(pe_node_t *node)
|
|
|
5ee7c6 |
return remote_state_alive;
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
+/*!
|
|
|
5ee7c6 |
+ * \internal
|
|
|
5ee7c6 |
+ * \brief Order actions on remote node relative to actions for the connection
|
|
|
5ee7c6 |
+ */
|
|
|
5ee7c6 |
static void
|
|
|
5ee7c6 |
apply_remote_ordering(action_t *action, pe_working_set_t *data_set)
|
|
|
5ee7c6 |
{
|
|
|
5ee7c6 |
resource_t *remote_rsc = NULL;
|
|
|
5ee7c6 |
- node_t *cluster_node = NULL;
|
|
|
5ee7c6 |
enum action_tasks task = text2task(action->task);
|
|
|
5ee7c6 |
enum remote_connection_state state = get_remote_node_state(action->node);
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
@@ -2009,10 +2009,6 @@ apply_remote_ordering(action_t *action, pe_working_set_t *data_set)
|
|
|
5ee7c6 |
remote_rsc = action->node->details->remote_rsc;
|
|
|
5ee7c6 |
CRM_ASSERT(remote_rsc);
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
- if(remote_rsc->running_on) {
|
|
|
5ee7c6 |
- cluster_node = remote_rsc->running_on->data;
|
|
|
5ee7c6 |
- }
|
|
|
5ee7c6 |
-
|
|
|
5ee7c6 |
crm_trace("Order %s action %s relative to %s%s (state: %s)",
|
|
|
5ee7c6 |
action->task, action->uuid,
|
|
|
5ee7c6 |
is_set(remote_rsc->flags, pe_rsc_failed)? "failed " : "",
|
|
|
5ee7c6 |
@@ -2093,6 +2089,8 @@ apply_remote_ordering(action_t *action, pe_working_set_t *data_set)
|
|
|
5ee7c6 |
pe_order_implies_then, data_set);
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
} else {
|
|
|
5ee7c6 |
+ node_t *cluster_node = pe__current_node(remote_rsc);
|
|
|
5ee7c6 |
+
|
|
|
5ee7c6 |
if(task == monitor_rsc && state == remote_state_failed) {
|
|
|
5ee7c6 |
/* We would only be here if we do not know the
|
|
|
5ee7c6 |
* state of the resource on the remote node.
|
|
|
5ee7c6 |
diff --git a/pengine/clone.c b/pengine/clone.c
|
|
|
5ee7c6 |
index 3192412..1de2661 100644
|
|
|
5ee7c6 |
--- a/pengine/clone.c
|
|
|
5ee7c6 |
+++ b/pengine/clone.c
|
|
|
5ee7c6 |
@@ -69,6 +69,10 @@ sort_clone_instance(gconstpointer a, gconstpointer b, gpointer data_set)
|
|
|
5ee7c6 |
int rc = 0;
|
|
|
5ee7c6 |
node_t *node1 = NULL;
|
|
|
5ee7c6 |
node_t *node2 = NULL;
|
|
|
5ee7c6 |
+ node_t *current_node1 = NULL;
|
|
|
5ee7c6 |
+ node_t *current_node2 = NULL;
|
|
|
5ee7c6 |
+ unsigned int nnodes1 = 0;
|
|
|
5ee7c6 |
+ unsigned int nnodes2 = 0;
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
gboolean can1 = TRUE;
|
|
|
5ee7c6 |
gboolean can2 = TRUE;
|
|
|
5ee7c6 |
@@ -87,24 +91,22 @@ sort_clone_instance(gconstpointer a, gconstpointer b, gpointer data_set)
|
|
|
5ee7c6 |
* - inactive instances
|
|
|
5ee7c6 |
*/
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
- if (resource1->running_on && resource2->running_on) {
|
|
|
5ee7c6 |
- if (g_list_length(resource1->running_on) < g_list_length(resource2->running_on)) {
|
|
|
5ee7c6 |
+ current_node1 = pe__find_active_on(resource1, &nnodes1, NULL);
|
|
|
5ee7c6 |
+ current_node2 = pe__find_active_on(resource2, &nnodes2, NULL);
|
|
|
5ee7c6 |
+
|
|
|
5ee7c6 |
+ if (nnodes1 && nnodes2) {
|
|
|
5ee7c6 |
+ if (nnodes1 < nnodes2) {
|
|
|
5ee7c6 |
crm_trace("%s < %s: running_on", resource1->id, resource2->id);
|
|
|
5ee7c6 |
return -1;
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
- } else if (g_list_length(resource1->running_on) > g_list_length(resource2->running_on)) {
|
|
|
5ee7c6 |
+ } else if (nnodes1 > nnodes2) {
|
|
|
5ee7c6 |
crm_trace("%s > %s: running_on", resource1->id, resource2->id);
|
|
|
5ee7c6 |
return 1;
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
- if (resource1->running_on) {
|
|
|
5ee7c6 |
- node1 = resource1->running_on->data;
|
|
|
5ee7c6 |
- }
|
|
|
5ee7c6 |
- if (resource2->running_on) {
|
|
|
5ee7c6 |
- node2 = resource2->running_on->data;
|
|
|
5ee7c6 |
- }
|
|
|
5ee7c6 |
-
|
|
|
5ee7c6 |
+ node1 = current_node1;
|
|
|
5ee7c6 |
+ node2 = current_node2;
|
|
|
5ee7c6 |
if (node1) {
|
|
|
5ee7c6 |
node_t *match = pe_hash_table_lookup(resource1->allowed_nodes, node1->details->id);
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
@@ -216,10 +218,10 @@ sort_clone_instance(gconstpointer a, gconstpointer b, gpointer data_set)
|
|
|
5ee7c6 |
GHashTable *hash2 =
|
|
|
5ee7c6 |
g_hash_table_new_full(crm_str_hash, g_str_equal, NULL, g_hash_destroy_str);
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
- n = node_copy(resource1->running_on->data);
|
|
|
5ee7c6 |
+ n = node_copy(current_node1);
|
|
|
5ee7c6 |
g_hash_table_insert(hash1, (gpointer) n->details->id, n);
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
- n = node_copy(resource2->running_on->data);
|
|
|
5ee7c6 |
+ n = node_copy(current_node2);
|
|
|
5ee7c6 |
g_hash_table_insert(hash2, (gpointer) n->details->id, n);
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
if(resource1->parent) {
|
|
|
5ee7c6 |
@@ -267,11 +269,8 @@ sort_clone_instance(gconstpointer a, gconstpointer b, gpointer data_set)
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
/* Current location score */
|
|
|
5ee7c6 |
- node1 = g_list_nth_data(resource1->running_on, 0);
|
|
|
5ee7c6 |
- node1 = g_hash_table_lookup(hash1, node1->details->id);
|
|
|
5ee7c6 |
-
|
|
|
5ee7c6 |
- node2 = g_list_nth_data(resource2->running_on, 0);
|
|
|
5ee7c6 |
- node2 = g_hash_table_lookup(hash2, node2->details->id);
|
|
|
5ee7c6 |
+ node1 = g_hash_table_lookup(hash1, current_node1->details->id);
|
|
|
5ee7c6 |
+ node2 = g_hash_table_lookup(hash2, current_node2->details->id);
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
if (node1->weight < node2->weight) {
|
|
|
5ee7c6 |
if (node1->weight < 0) {
|
|
|
5ee7c6 |
@@ -295,12 +294,8 @@ sort_clone_instance(gconstpointer a, gconstpointer b, gpointer data_set)
|
|
|
5ee7c6 |
list1 = g_hash_table_get_values(hash1);
|
|
|
5ee7c6 |
list2 = g_hash_table_get_values(hash2);
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
- list1 =
|
|
|
5ee7c6 |
- g_list_sort_with_data(list1, sort_node_weight,
|
|
|
5ee7c6 |
- g_list_nth_data(resource1->running_on, 0));
|
|
|
5ee7c6 |
- list2 =
|
|
|
5ee7c6 |
- g_list_sort_with_data(list2, sort_node_weight,
|
|
|
5ee7c6 |
- g_list_nth_data(resource2->running_on, 0));
|
|
|
5ee7c6 |
+ list1 = g_list_sort_with_data(list1, sort_node_weight, current_node1);
|
|
|
5ee7c6 |
+ list2 = g_list_sort_with_data(list2, sort_node_weight, current_node2);
|
|
|
5ee7c6 |
max = g_list_length(list1);
|
|
|
5ee7c6 |
if (max < g_list_length(list2)) {
|
|
|
5ee7c6 |
max = g_list_length(list2);
|
|
|
5ee7c6 |
@@ -528,8 +523,8 @@ distribute_children(resource_t *rsc, GListPtr children, GListPtr nodes,
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
if (child->running_on && is_set(child->flags, pe_rsc_provisional)
|
|
|
5ee7c6 |
&& is_not_set(child->flags, pe_rsc_failed)) {
|
|
|
5ee7c6 |
- node_t *child_node = child->running_on->data;
|
|
|
5ee7c6 |
- node_t *local_node = parent_node_instance(child, child->running_on->data);
|
|
|
5ee7c6 |
+ node_t *child_node = pe__current_node(child);
|
|
|
5ee7c6 |
+ node_t *local_node = parent_node_instance(child, child_node);
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
pe_rsc_trace(rsc, "Checking pre-allocation of %s to %s (%d remaining of %d)",
|
|
|
5ee7c6 |
child->id, child_node->details->uname, max - allocated, max);
|
|
|
5ee7c6 |
@@ -556,9 +551,9 @@ distribute_children(resource_t *rsc, GListPtr children, GListPtr nodes,
|
|
|
5ee7c6 |
for (GListPtr gIter = children; gIter != NULL; gIter = gIter->next) {
|
|
|
5ee7c6 |
resource_t *child = (resource_t *) gIter->data;
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
- if (g_list_length(child->running_on) > 0) {
|
|
|
5ee7c6 |
- node_t *child_node = child->running_on->data;
|
|
|
5ee7c6 |
- node_t *local_node = parent_node_instance(child, child->running_on->data);
|
|
|
5ee7c6 |
+ if (child->running_on != NULL) {
|
|
|
5ee7c6 |
+ node_t *child_node = pe__current_node(child);
|
|
|
5ee7c6 |
+ node_t *local_node = parent_node_instance(child, child_node);
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
if (local_node == NULL) {
|
|
|
5ee7c6 |
crm_err("%s is running on %s which isn't allowed",
|
|
|
5ee7c6 |
diff --git a/pengine/graph.c b/pengine/graph.c
|
|
|
5ee7c6 |
index 6d4e4c7..236b278 100644
|
|
|
5ee7c6 |
--- a/pengine/graph.c
|
|
|
5ee7c6 |
+++ b/pengine/graph.c
|
|
|
5ee7c6 |
@@ -783,6 +783,7 @@ get_router_node(action_t *action)
|
|
|
5ee7c6 |
node_t *began_on = NULL;
|
|
|
5ee7c6 |
node_t *ended_on = NULL;
|
|
|
5ee7c6 |
node_t *router_node = NULL;
|
|
|
5ee7c6 |
+ bool partial_migration = FALSE;
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
if (safe_str_eq(action->task, CRM_OP_FENCE) || is_remote_node(action->node) == FALSE) {
|
|
|
5ee7c6 |
return NULL;
|
|
|
5ee7c6 |
@@ -790,10 +791,13 @@ get_router_node(action_t *action)
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
CRM_ASSERT(action->node->details->remote_rsc != NULL);
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
- if (action->node->details->remote_rsc->running_on) {
|
|
|
5ee7c6 |
- began_on = action->node->details->remote_rsc->running_on->data;
|
|
|
5ee7c6 |
- }
|
|
|
5ee7c6 |
+ began_on = pe__current_node(action->node->details->remote_rsc);
|
|
|
5ee7c6 |
ended_on = action->node->details->remote_rsc->allocated_to;
|
|
|
5ee7c6 |
+ if (action->node->details->remote_rsc
|
|
|
5ee7c6 |
+ && (action->node->details->remote_rsc->container == NULL)
|
|
|
5ee7c6 |
+ && action->node->details->remote_rsc->partial_migration_target) {
|
|
|
5ee7c6 |
+ partial_migration = TRUE;
|
|
|
5ee7c6 |
+ }
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
/* if there is only one location to choose from,
|
|
|
5ee7c6 |
* this is easy. Check for those conditions first */
|
|
|
5ee7c6 |
@@ -817,6 +821,10 @@ get_router_node(action_t *action)
|
|
|
5ee7c6 |
* are all required before the remote rsc stop action can occur.) In
|
|
|
5ee7c6 |
* this case, we know these actions have to be routed through the initial
|
|
|
5ee7c6 |
* cluster node the connection resource lived on before the move takes place.
|
|
|
5ee7c6 |
+ * The exception is a partial migration of a (non-guest) remote
|
|
|
5ee7c6 |
+ * connection resource; in that case, all actions (even these) will be
|
|
|
5ee7c6 |
+ * ordered after the connection's pseudo-start on the migration target,
|
|
|
5ee7c6 |
+ * so the target is the router node.
|
|
|
5ee7c6 |
*
|
|
|
5ee7c6 |
* 2. Everything else (start, promote, monitor, probe, refresh, clear failcount
|
|
|
5ee7c6 |
* delete ....) must occur after the resource starts on the node it is
|
|
|
5ee7c6 |
@@ -824,10 +832,10 @@ get_router_node(action_t *action)
|
|
|
5ee7c6 |
*/
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
/* 1. before connection rsc moves. */
|
|
|
5ee7c6 |
- if (safe_str_eq(action->task, "stop") ||
|
|
|
5ee7c6 |
+ if ((safe_str_eq(action->task, "stop") ||
|
|
|
5ee7c6 |
safe_str_eq(action->task, "demote") ||
|
|
|
5ee7c6 |
safe_str_eq(action->task, "migrate_from") ||
|
|
|
5ee7c6 |
- safe_str_eq(action->task, "migrate_to")) {
|
|
|
5ee7c6 |
+ safe_str_eq(action->task, "migrate_to")) && !partial_migration) {
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
router_node = began_on;
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
@@ -1234,18 +1242,14 @@ action2xml(action_t * action, gboolean as_input, pe_working_set_t *data_set)
|
|
|
5ee7c6 |
case stopped_rsc:
|
|
|
5ee7c6 |
case action_demote:
|
|
|
5ee7c6 |
case action_demoted:
|
|
|
5ee7c6 |
- if(action->node->details->remote_rsc->container->running_on) {
|
|
|
5ee7c6 |
- host = action->node->details->remote_rsc->container->running_on->data;
|
|
|
5ee7c6 |
- }
|
|
|
5ee7c6 |
+ host = pe__current_node(action->node->details->remote_rsc->container);
|
|
|
5ee7c6 |
break;
|
|
|
5ee7c6 |
case start_rsc:
|
|
|
5ee7c6 |
case started_rsc:
|
|
|
5ee7c6 |
case monitor_rsc:
|
|
|
5ee7c6 |
case action_promote:
|
|
|
5ee7c6 |
case action_promoted:
|
|
|
5ee7c6 |
- if(action->node->details->remote_rsc->container->allocated_to) {
|
|
|
5ee7c6 |
- host = action->node->details->remote_rsc->container->allocated_to;
|
|
|
5ee7c6 |
- }
|
|
|
5ee7c6 |
+ host = action->node->details->remote_rsc->container->allocated_to;
|
|
|
5ee7c6 |
break;
|
|
|
5ee7c6 |
default:
|
|
|
5ee7c6 |
break;
|
|
|
5ee7c6 |
diff --git a/pengine/native.c b/pengine/native.c
|
|
|
5ee7c6 |
index 37ac2e4..1c26642 100644
|
|
|
5ee7c6 |
--- a/pengine/native.c
|
|
|
5ee7c6 |
+++ b/pengine/native.c
|
|
|
5ee7c6 |
@@ -102,7 +102,7 @@ native_choose_node(resource_t * rsc, node_t * prefer, pe_working_set_t * data_se
|
|
|
5ee7c6 |
if (length > 0) {
|
|
|
5ee7c6 |
nodes = g_hash_table_get_values(rsc->allowed_nodes);
|
|
|
5ee7c6 |
nodes = g_list_sort_with_data(nodes, sort_node_weight,
|
|
|
5ee7c6 |
- g_list_nth_data(rsc->running_on, 0));
|
|
|
5ee7c6 |
+ pe__current_node(rsc));
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
// First node in sorted list has the best score
|
|
|
5ee7c6 |
best = g_list_nth_data(nodes, 0);
|
|
|
5ee7c6 |
@@ -158,7 +158,7 @@ native_choose_node(resource_t * rsc, node_t * prefer, pe_working_set_t * data_se
|
|
|
5ee7c6 |
* remaining unallocated instances to prefer a node that's already
|
|
|
5ee7c6 |
* running another instance.
|
|
|
5ee7c6 |
*/
|
|
|
5ee7c6 |
- node_t *running = g_list_nth_data(rsc->running_on, 0);
|
|
|
5ee7c6 |
+ node_t *running = pe__current_node(rsc);
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
if (running && (can_run_resources(running) == FALSE)) {
|
|
|
5ee7c6 |
pe_rsc_trace(rsc, "Current node for %s (%s) can't run resources",
|
|
|
5ee7c6 |
@@ -534,16 +534,14 @@ native_color(resource_t * rsc, node_t * prefer, pe_working_set_t * data_set)
|
|
|
5ee7c6 |
node_t *assign_to = NULL;
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
rsc->next_role = rsc->role;
|
|
|
5ee7c6 |
- if (rsc->running_on == NULL) {
|
|
|
5ee7c6 |
+ assign_to = pe__current_node(rsc);
|
|
|
5ee7c6 |
+ if (assign_to == NULL) {
|
|
|
5ee7c6 |
reason = "inactive";
|
|
|
5ee7c6 |
} else if (rsc->role == RSC_ROLE_MASTER) {
|
|
|
5ee7c6 |
- assign_to = rsc->running_on->data;
|
|
|
5ee7c6 |
reason = "master";
|
|
|
5ee7c6 |
} else if (is_set(rsc->flags, pe_rsc_failed)) {
|
|
|
5ee7c6 |
- assign_to = rsc->running_on->data;
|
|
|
5ee7c6 |
reason = "failed";
|
|
|
5ee7c6 |
} else {
|
|
|
5ee7c6 |
- assign_to = rsc->running_on->data;
|
|
|
5ee7c6 |
reason = "active";
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
pe_rsc_info(rsc, "Unmanaged resource %s allocated to %s: %s", rsc->id,
|
|
|
5ee7c6 |
@@ -1834,7 +1832,9 @@ rsc_ticket_constraint(resource_t * rsc_lh, rsc_ticket_t * rsc_ticket, pe_working
|
|
|
5ee7c6 |
rsc_lh->id, rsc_ticket->ticket->id, rsc_ticket->id,
|
|
|
5ee7c6 |
role2text(rsc_ticket->role_lh));
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
- if (rsc_ticket->ticket->granted == FALSE && g_list_length(rsc_lh->running_on) > 0) {
|
|
|
5ee7c6 |
+ if ((rsc_ticket->ticket->granted == FALSE)
|
|
|
5ee7c6 |
+ && (rsc_lh->running_on != NULL)) {
|
|
|
5ee7c6 |
+
|
|
|
5ee7c6 |
GListPtr gIter = NULL;
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
switch (rsc_ticket->loss_policy) {
|
|
|
5ee7c6 |
@@ -1867,7 +1867,7 @@ rsc_ticket_constraint(resource_t * rsc_lh, rsc_ticket_t * rsc_ticket, pe_working
|
|
|
5ee7c6 |
if (filter_rsc_ticket(rsc_lh, rsc_ticket) == FALSE) {
|
|
|
5ee7c6 |
return;
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
- if (g_list_length(rsc_lh->running_on) > 0) {
|
|
|
5ee7c6 |
+ if (rsc_lh->running_on != NULL) {
|
|
|
5ee7c6 |
clear_bit(rsc_lh->flags, pe_rsc_managed);
|
|
|
5ee7c6 |
set_bit(rsc_lh->flags, pe_rsc_block);
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
@@ -1919,7 +1919,6 @@ native_update_actions(action_t * first, action_t * then, node_t * node, enum pe_
|
|
|
5ee7c6 |
} else if ((then_rsc_role >= RSC_ROLE_STARTED)
|
|
|
5ee7c6 |
&& safe_str_eq(then->task, RSC_START)
|
|
|
5ee7c6 |
&& then->node
|
|
|
5ee7c6 |
- && then_rsc->running_on
|
|
|
5ee7c6 |
&& g_list_length(then_rsc->running_on) == 1
|
|
|
5ee7c6 |
&& then->node->details == ((node_t *) then_rsc->running_on->data)->details) {
|
|
|
5ee7c6 |
/* ignore... if 'then' is supposed to be started after 'first', but
|
|
|
5ee7c6 |
diff --git a/pengine/notif.c b/pengine/notif.c
|
|
|
5ee7c6 |
index 3013ee0..4913249 100644
|
|
|
5ee7c6 |
--- a/pengine/notif.c
|
|
|
5ee7c6 |
+++ b/pengine/notif.c
|
|
|
5ee7c6 |
@@ -113,7 +113,7 @@ expand_node_list(GListPtr list, char **uname, char **metal)
|
|
|
5ee7c6 |
if(node->details->remote_rsc
|
|
|
5ee7c6 |
&& node->details->remote_rsc->container
|
|
|
5ee7c6 |
&& node->details->remote_rsc->container->running_on) {
|
|
|
5ee7c6 |
- node = node->details->remote_rsc->container->running_on->data;
|
|
|
5ee7c6 |
+ node = pe__current_node(node->details->remote_rsc->container);
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
if (node->details->uname == NULL) {
|
|
|
5ee7c6 |
diff --git a/tools/crm_mon.c b/tools/crm_mon.c
|
|
|
5ee7c6 |
index 824b12f..7c63803 100644
|
|
|
5ee7c6 |
--- a/tools/crm_mon.c
|
|
|
5ee7c6 |
+++ b/tools/crm_mon.c
|
|
|
5ee7c6 |
@@ -1953,16 +1953,10 @@ get_node_display_name(node_t *node)
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
/* Host is displayed only if this is a guest node */
|
|
|
5ee7c6 |
if (is_container_remote_node(node)) {
|
|
|
5ee7c6 |
- if (node->details->remote_rsc->running_on) {
|
|
|
5ee7c6 |
- /* running_on is a list, but guest nodes will have exactly one entry
|
|
|
5ee7c6 |
- * unless they are in the process of migrating, in which case they
|
|
|
5ee7c6 |
- * will have two; either way, we can use the first item in the list
|
|
|
5ee7c6 |
- */
|
|
|
5ee7c6 |
- node_t *host_node = (node_t *) node->details->remote_rsc->running_on->data;
|
|
|
5ee7c6 |
-
|
|
|
5ee7c6 |
- if (host_node && host_node->details) {
|
|
|
5ee7c6 |
- node_host = host_node->details->uname;
|
|
|
5ee7c6 |
- }
|
|
|
5ee7c6 |
+ node_t *host_node = pe__current_node(node->details->remote_rsc);
|
|
|
5ee7c6 |
+
|
|
|
5ee7c6 |
+ if (host_node && host_node->details) {
|
|
|
5ee7c6 |
+ node_host = host_node->details->uname;
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
if (node_host == NULL) {
|
|
|
5ee7c6 |
node_host = ""; /* so we at least get "uname@" to indicate guest */
|
|
|
5ee7c6 |
diff --git a/tools/crm_resource.c b/tools/crm_resource.c
|
|
|
5ee7c6 |
index c64432e..0557892 100644
|
|
|
5ee7c6 |
--- a/tools/crm_resource.c
|
|
|
5ee7c6 |
+++ b/tools/crm_resource.c
|
|
|
5ee7c6 |
@@ -1015,23 +1015,27 @@ main(int argc, char **argv)
|
|
|
5ee7c6 |
rc = cli_resource_ban(rsc_id, dest->details->uname, NULL, cib_conn);
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
} else if (rsc_cmd == 'B' || rsc_cmd == 'M') {
|
|
|
5ee7c6 |
+ pe_node_t *current = NULL;
|
|
|
5ee7c6 |
+ unsigned int nactive = 0;
|
|
|
5ee7c6 |
+
|
|
|
5ee7c6 |
rc = -EINVAL;
|
|
|
5ee7c6 |
- if (g_list_length(rsc->running_on) == 1) {
|
|
|
5ee7c6 |
- node_t *current = rsc->running_on->data;
|
|
|
5ee7c6 |
+ current = pe__find_active_requires(rsc, &nactive);
|
|
|
5ee7c6 |
+
|
|
|
5ee7c6 |
+ if (nactive == 1) {
|
|
|
5ee7c6 |
rc = cli_resource_ban(rsc_id, current->details->uname, NULL, cib_conn);
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
} else if(rsc->variant == pe_master) {
|
|
|
5ee7c6 |
int count = 0;
|
|
|
5ee7c6 |
GListPtr iter = NULL;
|
|
|
5ee7c6 |
- node_t *current = NULL;
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
+ current = NULL;
|
|
|
5ee7c6 |
for(iter = rsc->children; iter; iter = iter->next) {
|
|
|
5ee7c6 |
resource_t *child = (resource_t *)iter->data;
|
|
|
5ee7c6 |
enum rsc_role_e child_role = child->fns->state(child, TRUE);
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
if(child_role == RSC_ROLE_MASTER) {
|
|
|
5ee7c6 |
count++;
|
|
|
5ee7c6 |
- current = child->running_on->data;
|
|
|
5ee7c6 |
+ current = pe__current_node(child);
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
@@ -1039,14 +1043,15 @@ main(int argc, char **argv)
|
|
|
5ee7c6 |
rc = cli_resource_ban(rsc_id, current->details->uname, NULL, cib_conn);
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
} else {
|
|
|
5ee7c6 |
- CMD_ERR("Resource '%s' not moved: active in %d locations (promoted in %d).", rsc_id, g_list_length(rsc->running_on), count);
|
|
|
5ee7c6 |
+ CMD_ERR("Resource '%s' not moved: active in %d locations (promoted in %d).",
|
|
|
5ee7c6 |
+ rsc_id, nactive, count);
|
|
|
5ee7c6 |
CMD_ERR("You can prevent '%s' from running on a specific location with: --ban --node <name>", rsc_id);
|
|
|
5ee7c6 |
CMD_ERR("You can prevent '%s' from being promoted at a specific location with:"
|
|
|
5ee7c6 |
" --ban --master --node <name>", rsc_id);
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
} else {
|
|
|
5ee7c6 |
- CMD_ERR("Resource '%s' not moved: active in %d locations.", rsc_id, g_list_length(rsc->running_on));
|
|
|
5ee7c6 |
+ CMD_ERR("Resource '%s' not moved: active in %d locations.", rsc_id, nactive);
|
|
|
5ee7c6 |
CMD_ERR("You can prevent '%s' from running on a specific location with: --ban --node <name>", rsc_id);
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
@@ -1164,12 +1169,12 @@ main(int argc, char **argv)
|
|
|
5ee7c6 |
node_t *node = pe_find_node(data_set.nodes, host_uname);
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
if (node && is_remote_node(node)) {
|
|
|
5ee7c6 |
- if (node->details->remote_rsc == NULL || node->details->remote_rsc->running_on == NULL) {
|
|
|
5ee7c6 |
+ node = pe__current_node(node->details->remote_rsc);
|
|
|
5ee7c6 |
+ if (node == NULL) {
|
|
|
5ee7c6 |
CMD_ERR("No lrmd connection detected to remote node %s", host_uname);
|
|
|
5ee7c6 |
rc = -ENXIO;
|
|
|
5ee7c6 |
goto bail;
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
- node = node->details->remote_rsc->running_on->data;
|
|
|
5ee7c6 |
router_node = node->details->uname;
|
|
|
5ee7c6 |
attr_options |= attrd_opt_remote;
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
diff --git a/tools/crm_resource_print.c b/tools/crm_resource_print.c
|
|
|
5ee7c6 |
index d066c42..2463fb5 100644
|
|
|
5ee7c6 |
--- a/tools/crm_resource_print.c
|
|
|
5ee7c6 |
+++ b/tools/crm_resource_print.c
|
|
|
5ee7c6 |
@@ -68,6 +68,7 @@ cli_resource_print_cts(resource_t * rsc)
|
|
|
5ee7c6 |
const char *rtype = crm_element_value(rsc->xml, XML_ATTR_TYPE);
|
|
|
5ee7c6 |
const char *rprov = crm_element_value(rsc->xml, XML_AGENT_ATTR_PROVIDER);
|
|
|
5ee7c6 |
const char *rclass = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS);
|
|
|
5ee7c6 |
+ pe_node_t *node = pe__current_node(rsc);
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
if (safe_str_eq(rclass, PCMK_RESOURCE_CLASS_STONITH)) {
|
|
|
5ee7c6 |
xmlNode *op = NULL;
|
|
|
5ee7c6 |
@@ -90,10 +91,8 @@ cli_resource_print_cts(resource_t * rsc)
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
- if (rsc->running_on != NULL && g_list_length(rsc->running_on) == 1) {
|
|
|
5ee7c6 |
- node_t *tmp = rsc->running_on->data;
|
|
|
5ee7c6 |
-
|
|
|
5ee7c6 |
- host = tmp->details->uname;
|
|
|
5ee7c6 |
+ if (node != NULL) {
|
|
|
5ee7c6 |
+ host = node->details->uname;
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
printf("Resource: %s %s %s %s %s %s %s %s %d %lld 0x%.16llx\n",
|
|
|
5ee7c6 |
@@ -315,16 +314,15 @@ int
|
|
|
5ee7c6 |
cli_resource_print_attribute(resource_t *rsc, const char *attr, pe_working_set_t * data_set)
|
|
|
5ee7c6 |
{
|
|
|
5ee7c6 |
int rc = -ENXIO;
|
|
|
5ee7c6 |
- node_t *current = NULL;
|
|
|
5ee7c6 |
+ unsigned int count = 0;
|
|
|
5ee7c6 |
GHashTable *params = NULL;
|
|
|
5ee7c6 |
const char *value = NULL;
|
|
|
5ee7c6 |
+ node_t *current = pe__find_active_on(rsc, &count, NULL);
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
- if (g_list_length(rsc->running_on) == 1) {
|
|
|
5ee7c6 |
- current = rsc->running_on->data;
|
|
|
5ee7c6 |
-
|
|
|
5ee7c6 |
- } else if (g_list_length(rsc->running_on) > 1) {
|
|
|
5ee7c6 |
+ if (count > 1) {
|
|
|
5ee7c6 |
CMD_ERR("%s is active on more than one node,"
|
|
|
5ee7c6 |
" returning the default value for %s", rsc->id, crm_str(attr));
|
|
|
5ee7c6 |
+ current = NULL;
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
params = crm_str_table_new();
|
|
|
5ee7c6 |
diff --git a/tools/crm_resource_runtime.c b/tools/crm_resource_runtime.c
|
|
|
5ee7c6 |
index 5e54f9e..5004935 100644
|
|
|
5ee7c6 |
--- a/tools/crm_resource_runtime.c
|
|
|
5ee7c6 |
+++ b/tools/crm_resource_runtime.c
|
|
|
5ee7c6 |
@@ -473,11 +473,11 @@ send_lrm_rsc_op(crm_ipc_t * crmd_channel, const char *op,
|
|
|
5ee7c6 |
node_t *node = pe_find_node(data_set->nodes, host_uname);
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
if (node && is_remote_node(node)) {
|
|
|
5ee7c6 |
- if (node->details->remote_rsc == NULL || node->details->remote_rsc->running_on == NULL) {
|
|
|
5ee7c6 |
+ node = pe__current_node(node->details->remote_rsc);
|
|
|
5ee7c6 |
+ if (node == NULL) {
|
|
|
5ee7c6 |
CMD_ERR("No lrmd connection detected to remote node %s", host_uname);
|
|
|
5ee7c6 |
return -ENXIO;
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
- node = node->details->remote_rsc->running_on->data;
|
|
|
5ee7c6 |
router_node = node->details->uname;
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
@@ -1648,11 +1648,16 @@ cli_resource_move(resource_t *rsc, const char *rsc_id, const char *host_name,
|
|
|
5ee7c6 |
cib_t *cib, pe_working_set_t *data_set)
|
|
|
5ee7c6 |
{
|
|
|
5ee7c6 |
int rc = -EINVAL;
|
|
|
5ee7c6 |
- int count = 0;
|
|
|
5ee7c6 |
+ unsigned int count = 0;
|
|
|
5ee7c6 |
node_t *current = NULL;
|
|
|
5ee7c6 |
node_t *dest = pe_find_node(data_set->nodes, host_name);
|
|
|
5ee7c6 |
bool cur_is_dest = FALSE;
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
+ if (dest == NULL) {
|
|
|
5ee7c6 |
+ CMD_ERR("Error performing operation: node '%s' is unknown", host_name);
|
|
|
5ee7c6 |
+ return -ENXIO;
|
|
|
5ee7c6 |
+ }
|
|
|
5ee7c6 |
+
|
|
|
5ee7c6 |
if (scope_master && rsc->variant != pe_master) {
|
|
|
5ee7c6 |
resource_t *p = uber_parent(rsc);
|
|
|
5ee7c6 |
if(p->variant == pe_master) {
|
|
|
5ee7c6 |
@@ -1667,8 +1672,12 @@ cli_resource_move(resource_t *rsc, const char *rsc_id, const char *host_name,
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
+ current = pe__find_active_requires(rsc, &count);
|
|
|
5ee7c6 |
+
|
|
|
5ee7c6 |
if(rsc->variant == pe_master) {
|
|
|
5ee7c6 |
GListPtr iter = NULL;
|
|
|
5ee7c6 |
+ unsigned int master_count = 0;
|
|
|
5ee7c6 |
+ pe_node_t *master_node = NULL;
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
for(iter = rsc->children; iter; iter = iter->next) {
|
|
|
5ee7c6 |
resource_t *child = (resource_t *)iter->data;
|
|
|
5ee7c6 |
@@ -1676,37 +1685,27 @@ cli_resource_move(resource_t *rsc, const char *rsc_id, const char *host_name,
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
if(child_role == RSC_ROLE_MASTER) {
|
|
|
5ee7c6 |
rsc = child;
|
|
|
5ee7c6 |
- count++;
|
|
|
5ee7c6 |
+ master_node = pe__current_node(child);
|
|
|
5ee7c6 |
+ master_count++;
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
-
|
|
|
5ee7c6 |
- if(scope_master == FALSE && count == 0) {
|
|
|
5ee7c6 |
- count = g_list_length(rsc->running_on);
|
|
|
5ee7c6 |
+ if (scope_master || master_count) {
|
|
|
5ee7c6 |
+ count = master_count;
|
|
|
5ee7c6 |
+ current = master_node;
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
- } else if (pe_rsc_is_clone(rsc)) {
|
|
|
5ee7c6 |
- count = g_list_length(rsc->running_on);
|
|
|
5ee7c6 |
-
|
|
|
5ee7c6 |
- } else if (g_list_length(rsc->running_on) > 1) {
|
|
|
5ee7c6 |
- CMD_ERR("Resource '%s' not moved: active on multiple nodes", rsc_id);
|
|
|
5ee7c6 |
- return rc;
|
|
|
5ee7c6 |
- }
|
|
|
5ee7c6 |
-
|
|
|
5ee7c6 |
- if(dest == NULL) {
|
|
|
5ee7c6 |
- CMD_ERR("Error performing operation: node '%s' is unknown", host_name);
|
|
|
5ee7c6 |
- return -ENXIO;
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
- if(g_list_length(rsc->running_on) == 1) {
|
|
|
5ee7c6 |
- current = rsc->running_on->data;
|
|
|
5ee7c6 |
+ if (count > 1) {
|
|
|
5ee7c6 |
+ if (pe_rsc_is_clone(rsc)) {
|
|
|
5ee7c6 |
+ current = NULL;
|
|
|
5ee7c6 |
+ } else {
|
|
|
5ee7c6 |
+ CMD_ERR("Resource '%s' not moved: active on multiple nodes", rsc_id);
|
|
|
5ee7c6 |
+ return rc;
|
|
|
5ee7c6 |
+ }
|
|
|
5ee7c6 |
}
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
- if(current == NULL) {
|
|
|
5ee7c6 |
- /* Nothing to check */
|
|
|
5ee7c6 |
-
|
|
|
5ee7c6 |
- } else if(scope_master && rsc->fns->state(rsc, TRUE) != RSC_ROLE_MASTER) {
|
|
|
5ee7c6 |
- crm_trace("%s is already active on %s but not in correct state", rsc_id, dest->details->uname);
|
|
|
5ee7c6 |
- } else if (safe_str_eq(current->details->uname, dest->details->uname)) {
|
|
|
5ee7c6 |
+ if (current && (current->details == dest->details)) {
|
|
|
5ee7c6 |
cur_is_dest = TRUE;
|
|
|
5ee7c6 |
if (do_force) {
|
|
|
5ee7c6 |
crm_info("%s is already %s on %s, reinforcing placement with location constraint.",
|
|
|
5ee7c6 |
@@ -1736,7 +1735,7 @@ cli_resource_move(resource_t *rsc, const char *rsc_id, const char *host_name,
|
|
|
5ee7c6 |
(void)cli_resource_ban(rsc_id, current->details->uname, NULL, cib);
|
|
|
5ee7c6 |
|
|
|
5ee7c6 |
} else if(count > 1) {
|
|
|
5ee7c6 |
- CMD_ERR("Resource '%s' is currently %s in %d locations. One may now move one to %s",
|
|
|
5ee7c6 |
+ CMD_ERR("Resource '%s' is currently %s in %d locations. One may now move to %s",
|
|
|
5ee7c6 |
rsc_id, scope_master?"promoted":"active", count, dest->details->uname);
|
|
|
5ee7c6 |
CMD_ERR("You can prevent '%s' from being %s at a specific location with:"
|
|
|
5ee7c6 |
" --ban %s--host <name>", rsc_id, scope_master?"promoted":"active", scope_master?"--master ":"");
|
|
|
5ee7c6 |
--
|
|
|
5ee7c6 |
1.8.3.1
|
|
|
5ee7c6 |
|