diff --git a/pengine/clone.c b/pengine/clone.c index 89e79853a2..048ed43fd5 100644 --- a/pengine/clone.c +++ b/pengine/clone.c @@ -1,1680 +1,1675 @@ /* * Copyright (C) 2004 Andrew Beekhof * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #define VARIANT_CLONE 1 #include gint sort_clone_instance(gconstpointer a, gconstpointer b); void child_stopping_constraints( clone_variant_data_t *clone_data, resource_t *self, resource_t *child, resource_t *last, pe_working_set_t *data_set); void child_starting_constraints( clone_variant_data_t *clone_data, resource_t *self, resource_t *child, resource_t *last, pe_working_set_t *data_set); static node_t * parent_node_instance(const resource_t *rsc, node_t *node) { node_t *ret = NULL; if(node != NULL) { ret = pe_find_node_id( rsc->parent->allowed_nodes, node->details->id); } return ret; } static gboolean did_fail(const resource_t *rsc) { if(is_set(rsc->flags, pe_rsc_failed)) { return TRUE; } slist_iter( child_rsc, resource_t, rsc->children, lpc, if(did_fail(child_rsc)) { return TRUE; } ); return FALSE; } gint sort_clone_instance(gconstpointer a, gconstpointer b) { int level = LOG_DEBUG_3; node_t *node1 = NULL; node_t *node2 = NULL; gboolean can1 = TRUE; gboolean can2 = TRUE; gboolean with_scores = TRUE; const resource_t *resource1 = (const resource_t*)a; const resource_t *resource2 = (const resource_t*)b; CRM_ASSERT(resource1 != NULL); CRM_ASSERT(resource2 != NULL); /* allocation order: * - active instances * - instances running on nodes with the least copies * - active instances on nodes that cant support them or are to be fenced * - failed instances * - inactive instances */ do_crm_log_unlikely(level+1, "%s ? %s", resource1->id, resource2->id); if(resource1->running_on && resource2->running_on) { if(g_list_length(resource1->running_on) < g_list_length(resource2->running_on)) { do_crm_log_unlikely(level, "%s < %s: running_on", resource1->id, resource2->id); return -1; } else if(g_list_length(resource1->running_on) > g_list_length(resource2->running_on)) { do_crm_log_unlikely(level, "%s > %s: running_on", resource1->id, resource2->id); return 1; } } if(resource1->running_on) { node1 = resource1->running_on->data; } if(resource2->running_on) { node2 = resource2->running_on->data; } if(node1) { node_t *match = pe_find_node_id(resource1->allowed_nodes, node1->details->id); if(match == NULL || match->weight < 0) { do_crm_log_unlikely(level, "%s: current location is unavailable", resource1->id); node1 = NULL; can1 = FALSE; } } if(node2) { node_t *match = pe_find_node_id(resource2->allowed_nodes, node2->details->id); if(match == NULL || match->weight < 0) { do_crm_log_unlikely(level, "%s: current location is unavailable", resource2->id); node2 = NULL; can2 = FALSE; } } if(can1 != can2) { if(can1) { do_crm_log_unlikely(level, "%s < %s: availability of current location", resource1->id, resource2->id); return -1; } do_crm_log_unlikely(level, "%s > %s: availability of current location", resource1->id, resource2->id); return 1; } if(resource1->priority < resource2->priority) { do_crm_log_unlikely(level, "%s < %s: priority", resource1->id, resource2->id); return 1; } else if(resource1->priority > resource2->priority) { do_crm_log_unlikely(level, "%s > %s: priority", resource1->id, resource2->id); return -1; } if(node1 == NULL && node2 == NULL) { do_crm_log_unlikely(level, "%s == %s: not active", resource1->id, resource2->id); return 0; } if(node1 != node2) { if(node1 == NULL) { do_crm_log_unlikely(level, "%s > %s: active", resource1->id, resource2->id); return 1; } else if(node2 == NULL) { do_crm_log_unlikely(level, "%s < %s: active", resource1->id, resource2->id); return -1; } } can1 = can_run_resources(node1); can2 = can_run_resources(node2); if(can1 != can2) { if(can1) { do_crm_log_unlikely(level, "%s < %s: can", resource1->id, resource2->id); return -1; } do_crm_log_unlikely(level, "%s > %s: can", resource1->id, resource2->id); return 1; } node1 = parent_node_instance(resource1, node1); node2 = parent_node_instance(resource2, node2); if(node1 != NULL && node2 == NULL) { do_crm_log_unlikely(level, "%s < %s: not allowed", resource1->id, resource2->id); return -1; } else if(node1 == NULL && node2 != NULL) { do_crm_log_unlikely(level, "%s > %s: not allowed", resource1->id, resource2->id); return 1; } if(node1 == NULL) { do_crm_log_unlikely(level, "%s == %s: not allowed", resource1->id, resource2->id); return 0; } if(node1->count < node2->count) { do_crm_log_unlikely(level, "%s < %s: count", resource1->id, resource2->id); return -1; } else if(node1->count > node2->count) { do_crm_log_unlikely(level, "%s > %s: count", resource1->id, resource2->id); return 1; } if(with_scores) { int max = 0; int lpc = 0; GListPtr list1 = node_list_dup(resource1->allowed_nodes, FALSE, FALSE); GListPtr list2 = node_list_dup(resource2->allowed_nodes, FALSE, FALSE); list1 = g_list_sort(list1, sort_node_weight); list2 = g_list_sort(list2, sort_node_weight); max = g_list_length(list1); if(max < g_list_length(list2)) { max = g_list_length(list2); } for(;lpc < max; lpc++) { node1 = g_list_nth_data(list1, lpc); node2 = g_list_nth_data(list2, lpc); if(node1 == NULL) { do_crm_log_unlikely(level, "%s < %s: node score NULL", resource1->id, resource2->id); pe_free_shallow(list1); pe_free_shallow(list2); return 1; } else if(node2 == NULL) { do_crm_log_unlikely(level, "%s > %s: node score NULL", resource1->id, resource2->id); pe_free_shallow(list1); pe_free_shallow(list2); return -1; } if(node1->weight < node2->weight) { do_crm_log_unlikely(level, "%s < %s: node score", resource1->id, resource2->id); pe_free_shallow(list1); pe_free_shallow(list2); return 1; } else if(node1->weight > node2->weight) { do_crm_log_unlikely(level, "%s > %s: node score", resource1->id, resource2->id); pe_free_shallow(list1); pe_free_shallow(list2); return -1; } } pe_free_shallow(list1); pe_free_shallow(list2); } can1 = did_fail(resource1); can2 = did_fail(resource2); if(can1 != can2) { if(can1) { do_crm_log_unlikely(level, "%s > %s: failed", resource1->id, resource2->id); return 1; } do_crm_log_unlikely(level, "%s < %s: failed", resource1->id, resource2->id); return -1; } if(node1 && node2) { int max = 0; int lpc = 0; GListPtr list1 = g_list_append(NULL, node_copy(resource1->running_on->data)); GListPtr list2 = g_list_append(NULL, node_copy(resource2->running_on->data)); /* Possibly a replacement for the with_scores block above */ slist_iter( constraint, rsc_colocation_t, resource1->parent->rsc_cons_lhs, lpc, do_crm_log_unlikely(level+1, "Applying %s to %s", constraint->id, resource1->id); list1 = native_merge_weights( constraint->rsc_lh, resource1->id, list1, constraint->node_attribute, constraint->score/INFINITY, FALSE); ); slist_iter( constraint, rsc_colocation_t, resource2->parent->rsc_cons_lhs, lpc, do_crm_log_unlikely(level+1, "Applying %s to %s", constraint->id, resource2->id); list2 = native_merge_weights( constraint->rsc_lh, resource2->id, list2, constraint->node_attribute, constraint->score/INFINITY, FALSE); ); list1 = g_list_sort(list1, sort_node_weight); list2 = g_list_sort(list2, sort_node_weight); max = g_list_length(list1); if(max < g_list_length(list2)) { max = g_list_length(list2); } for(;lpc < max; lpc++) { node1 = g_list_nth_data(list1, lpc); node2 = g_list_nth_data(list2, lpc); if(node1 == NULL) { do_crm_log_unlikely(level, "%s < %s: colocated score NULL", resource1->id, resource2->id); pe_free_shallow(list1); pe_free_shallow(list2); return 1; } else if(node2 == NULL) { do_crm_log_unlikely(level, "%s > %s: colocated score NULL", resource1->id, resource2->id); pe_free_shallow(list1); pe_free_shallow(list2); return -1; } if(node1->weight < node2->weight) { do_crm_log_unlikely(level, "%s < %s: colocated score", resource1->id, resource2->id); pe_free_shallow(list1); pe_free_shallow(list2); return 1; } else if(node1->weight > node2->weight) { do_crm_log_unlikely(level, "%s > %s: colocated score", resource1->id, resource2->id); pe_free_shallow(list1); pe_free_shallow(list2); return -1; } } pe_free_shallow(list1); pe_free_shallow(list2); } do_crm_log_unlikely(level, "%s == %s: default %d", resource1->id, resource2->id, node2->weight); return 0; } static node_t * can_run_instance(resource_t *rsc, node_t *node) { node_t *local_node = NULL; clone_variant_data_t *clone_data = NULL; if(can_run_resources(node) == FALSE) { goto bail; } else if(is_set(rsc->flags, pe_rsc_orphan)) { goto bail; } local_node = parent_node_instance(rsc, node); get_clone_variant_data(clone_data, rsc->parent); if(local_node == NULL) { crm_warn("%s cannot run on %s: node not allowed", rsc->id, node->details->uname); goto bail; } else if(local_node->count < clone_data->clone_node_max) { return local_node; } else { crm_debug_2("%s cannot run on %s: node full", rsc->id, node->details->uname); } bail: if(node) { common_update_score(rsc, node->details->id, -INFINITY); } return NULL; } static node_t * color_instance(resource_t *rsc, pe_working_set_t *data_set) { node_t *chosen = NULL; node_t *local_node = NULL; crm_debug_2("Processing %s", rsc->id); if(is_not_set(rsc->flags, pe_rsc_provisional)) { return rsc->fns->location(rsc, NULL, FALSE); } else if(is_set(rsc->flags, pe_rsc_allocating)) { crm_debug("Dependancy loop detected involving %s", rsc->id); return NULL; } if(rsc->allowed_nodes) { slist_iter(try_node, node_t, rsc->allowed_nodes, lpc, can_run_instance(rsc, try_node); ); } chosen = rsc->cmds->color(rsc, data_set); if(chosen) { local_node = pe_find_node_id( rsc->parent->allowed_nodes, chosen->details->id); if(local_node) { local_node->count++; } else if(is_set(rsc->flags, pe_rsc_managed)) { /* what to do? we can't enforce per-node limits in this case */ crm_config_err("%s not found in %s (list=%d)", chosen->details->id, rsc->parent->id, g_list_length(rsc->parent->allowed_nodes)); } } return chosen; } static void append_parent_colocation(resource_t *rsc, resource_t *child, gboolean all) { slist_iter(cons, rsc_colocation_t, rsc->rsc_cons, lpc, if(all || cons->score < 0 || cons->score == INFINITY) { child->rsc_cons = g_list_append(child->rsc_cons, cons); } ); slist_iter(cons, rsc_colocation_t, rsc->rsc_cons_lhs, lpc, if(all || cons->score < 0) { child->rsc_cons_lhs = g_list_append(child->rsc_cons_lhs, cons); } ); } node_t * clone_color(resource_t *rsc, pe_working_set_t *data_set) { int allocated = 0; int available_nodes = 0; clone_variant_data_t *clone_data = NULL; get_clone_variant_data(clone_data, rsc); if(is_not_set(rsc->flags, pe_rsc_provisional)) { return NULL; } else if(is_set(rsc->flags, pe_rsc_allocating)) { crm_debug("Dependancy loop detected involving %s", rsc->id); return NULL; } set_bit(rsc->flags, pe_rsc_allocating); crm_debug_2("Processing %s", rsc->id); /* this information is used by sort_clone_instance() when deciding in which * order to allocate clone instances */ slist_iter( constraint, rsc_colocation_t, rsc->rsc_cons_lhs, lpc, rsc->allowed_nodes = constraint->rsc_lh->cmds->merge_weights( constraint->rsc_lh, rsc->id, rsc->allowed_nodes, constraint->node_attribute, constraint->score/INFINITY, TRUE); ); dump_node_scores(show_scores?0:scores_log_level, rsc, __FUNCTION__, rsc->allowed_nodes); /* count now tracks the number of clones currently allocated */ slist_iter(node, node_t, rsc->allowed_nodes, lpc, node->count = 0; ); slist_iter(child, resource_t, rsc->children, lpc, if(g_list_length(child->running_on) > 0) { node_t *child_node = child->running_on->data; node_t *local_node = parent_node_instance( child, child->running_on->data); if(local_node) { local_node->count++; } else { crm_err("%s is running on %s which isn't allowed", child->id, child_node->details->uname); } } ); rsc->children = g_list_sort(rsc->children, sort_clone_instance); /* count now tracks the number of clones we have allocated */ slist_iter(node, node_t, rsc->allowed_nodes, lpc, node->count = 0; ); rsc->allowed_nodes = g_list_sort( rsc->allowed_nodes, sort_node_weight); slist_iter(node, node_t, rsc->allowed_nodes, lpc, if(can_run_resources(node)) { available_nodes++; } ); slist_iter(child, resource_t, rsc->children, lpc, if(allocated >= clone_data->clone_max) { crm_debug("Child %s not allocated - limit reached", child->id); resource_location(child, NULL, -INFINITY, "clone_color:limit_reached", data_set); } else if (clone_data->clone_max < available_nodes) { /* Only include positive colocation preferences of dependant resources * if not every node will get a copy of the clone */ append_parent_colocation(rsc, child, TRUE); } else { append_parent_colocation(rsc, child, FALSE); } if(color_instance(child, data_set)) { allocated++; } ); crm_debug("Allocated %d %s instances of a possible %d", allocated, rsc->id, clone_data->clone_max); clear_bit(rsc->flags, pe_rsc_provisional); clear_bit(rsc->flags, pe_rsc_allocating); return NULL; } static void clone_update_pseudo_status( resource_t *rsc, gboolean *stopping, gboolean *starting, gboolean *active) { if(rsc->children) { slist_iter(child, resource_t, rsc->children, lpc, clone_update_pseudo_status(child, stopping, starting, active) ); return; } CRM_ASSERT(active != NULL); CRM_ASSERT(starting != NULL); CRM_ASSERT(stopping != NULL); if(rsc->running_on) { *active = TRUE; } slist_iter( action, action_t, rsc->actions, lpc, if(*starting && *stopping) { return; } else if(action->optional) { crm_debug_3("Skipping optional: %s", action->uuid); continue; } else if(action->pseudo == FALSE && action->runnable == FALSE){ crm_debug_3("Skipping unrunnable: %s", action->uuid); continue; } else if(safe_str_eq(RSC_STOP, action->task)) { crm_debug_2("Stopping due to: %s", action->uuid); *stopping = TRUE; } else if(safe_str_eq(RSC_START, action->task)) { if(action->runnable == FALSE) { crm_debug_3("Skipping pseudo-op: %s run=%d, pseudo=%d", action->uuid, action->runnable, action->pseudo); } else { crm_debug_2("Starting due to: %s", action->uuid); crm_debug_3("%s run=%d, pseudo=%d", action->uuid, action->runnable, action->pseudo); *starting = TRUE; } } ); } static action_t * find_rsc_action(resource_t *rsc, const char *key, gboolean active_only, GListPtr *list) { action_t *match = NULL; GListPtr possible = NULL; GListPtr active = NULL; possible = find_actions(rsc->actions, key, NULL); if(active_only) { slist_iter(op, action_t, possible, lpc, if(op->optional == FALSE) { active = g_list_append(active, op); } ); if(active && g_list_length(active) == 1) { match = g_list_nth_data(active, 0); } if(list) { *list = active; active = NULL; } } else if(possible && g_list_length(possible) == 1) { match = g_list_nth_data(possible, 0); } if(list) { *list = possible; possible = NULL; } if(possible) { g_list_free(possible); } if(active) { g_list_free(active); } return match; } static void child_ordering_constraints(resource_t *rsc, pe_working_set_t *data_set) { char *key = NULL; action_t *stop = NULL; action_t *start = NULL; action_t *last_stop = NULL; action_t *last_start = NULL; gboolean active_only = TRUE; /* change to false to get the old behavior */ clone_variant_data_t *clone_data = NULL; get_clone_variant_data(clone_data, rsc); if(clone_data->ordered == FALSE) { return; } slist_iter( child, resource_t, rsc->children, lpc, key = stop_key(child); stop = find_rsc_action(child, key, active_only, NULL); crm_free(key); key = start_key(child); start = find_rsc_action(child, key, active_only, NULL); crm_free(key); if(stop) { if(last_stop) { /* child/child relative stop */ order_actions(stop, last_stop, pe_order_implies_left); } last_stop = stop; } if(start) { if(last_start) { /* child/child relative start */ order_actions(last_start, start, pe_order_implies_left); } last_start = start; } ); } void clone_create_actions(resource_t *rsc, pe_working_set_t *data_set) { gboolean child_active = FALSE; gboolean child_starting = FALSE; gboolean child_stopping = FALSE; action_t *stop = NULL; action_t *stopped = NULL; action_t *start = NULL; action_t *started = NULL; resource_t *last_start_rsc = NULL; resource_t *last_stop_rsc = NULL; clone_variant_data_t *clone_data = NULL; get_clone_variant_data(clone_data, rsc); crm_debug_2("Creating actions for %s", rsc->id); slist_iter( child_rsc, resource_t, rsc->children, lpc, child_rsc->cmds->create_actions(child_rsc, data_set); clone_update_pseudo_status( child_rsc, &child_stopping, &child_starting, &child_active); if(is_set(child_rsc->flags, pe_rsc_starting)) { last_start_rsc = child_rsc; } if(is_set(child_rsc->flags, pe_rsc_stopping)) { last_stop_rsc = child_rsc; } ); /* start */ start = start_action(rsc, NULL, !child_starting); started = custom_action(rsc, started_key(rsc), RSC_STARTED, NULL, !child_starting, TRUE, data_set); start->pseudo = TRUE; start->runnable = TRUE; started->pseudo = TRUE; started->priority = INFINITY; if(child_active || child_starting) { started->runnable = TRUE; } child_ordering_constraints(rsc, data_set); child_starting_constraints(clone_data, rsc, NULL, last_start_rsc, data_set); clone_data->start_notify = create_notification_boundaries(rsc, RSC_START, start, started, data_set); /* stop */ stop = stop_action(rsc, NULL, !child_stopping); stopped = custom_action(rsc, stopped_key(rsc), RSC_STOPPED, NULL, !child_stopping, TRUE, data_set); stop->pseudo = TRUE; stop->runnable = TRUE; stopped->pseudo = TRUE; stopped->runnable = TRUE; stopped->priority = INFINITY; child_stopping_constraints(clone_data, rsc, NULL, last_stop_rsc, data_set); clone_data->stop_notify = create_notification_boundaries(rsc, RSC_STOP, stop, stopped, data_set); if(clone_data->stop_notify && clone_data->start_notify) { order_actions(clone_data->stop_notify->post_done, clone_data->start_notify->pre, pe_order_optional); } } void child_starting_constraints( clone_variant_data_t *clone_data, resource_t *rsc, resource_t *child, resource_t *last, pe_working_set_t *data_set) { if(child == NULL && last == NULL) { crm_debug("%s has no active children", rsc->id); return; } if(child != NULL) { order_start_start( rsc, child, pe_order_runnable_left|pe_order_implies_left_printed); new_rsc_order(child, RSC_START, rsc, RSC_STARTED, pe_order_implies_right_printed, data_set); } if(FALSE && clone_data->ordered) { if(child == NULL) { /* last child start before global started */ new_rsc_order(last, RSC_START, rsc, RSC_STARTED, pe_order_runnable_left, data_set); } else if(last == NULL) { /* global start before first child start */ order_start_start( rsc, child, pe_order_implies_left); } else { /* child/child relative start */ order_start_start(last, child, pe_order_implies_left); } } } void child_stopping_constraints( clone_variant_data_t *clone_data, resource_t *rsc, resource_t *child, resource_t *last, pe_working_set_t *data_set) { if(child == NULL && last == NULL) { crm_debug("%s has no active children", rsc->id); return; } if(child != NULL) { order_stop_stop(rsc, child, pe_order_shutdown|pe_order_implies_left_printed); new_rsc_order(child, RSC_STOP, rsc, RSC_STOPPED, pe_order_implies_right_printed, data_set); } if(FALSE && clone_data->ordered) { if(last == NULL) { /* first child stop before global stopped */ new_rsc_order(child, RSC_STOP, rsc, RSC_STOPPED, pe_order_runnable_left, data_set); } else if(child == NULL) { /* global stop before last child stop */ order_stop_stop( rsc, last, pe_order_implies_left); } else { /* child/child relative stop */ order_stop_stop(child, last, pe_order_implies_left); } } } void clone_internal_constraints(resource_t *rsc, pe_working_set_t *data_set) { resource_t *last_rsc = NULL; clone_variant_data_t *clone_data = NULL; get_clone_variant_data(clone_data, rsc); native_internal_constraints(rsc, data_set); /* global stop before stopped */ new_rsc_order(rsc, RSC_STOP, rsc, RSC_STOPPED, pe_order_runnable_left, data_set); /* global start before started */ new_rsc_order(rsc, RSC_START, rsc, RSC_STARTED, pe_order_runnable_left, data_set); /* global stopped before start */ new_rsc_order(rsc, RSC_STOPPED, rsc, RSC_START, pe_order_optional, data_set); slist_iter( child_rsc, resource_t, rsc->children, lpc, child_rsc->cmds->internal_constraints(child_rsc, data_set); child_starting_constraints( clone_data, rsc, child_rsc, last_rsc, data_set); child_stopping_constraints( clone_data, rsc, child_rsc, last_rsc, data_set); last_rsc = child_rsc; ); } resource_t* find_compatible_child( resource_t *local_child, resource_t *rsc, enum rsc_role_e filter, gboolean current) { node_t *local_node = NULL; node_t *node = NULL; clone_variant_data_t *clone_data = NULL; get_clone_variant_data(clone_data, rsc); local_node = local_child->fns->location(local_child, NULL, current); if(local_node == NULL) { crm_debug("Can't colocate unrunnable child %s with %s", local_child->id, rsc->id); return NULL; } slist_iter( child_rsc, resource_t, rsc->children, lpc, enum rsc_role_e next_role = child_rsc->fns->state(child_rsc, current); node = child_rsc->fns->location(child_rsc, NULL, current); if(filter != RSC_ROLE_UNKNOWN && next_role != filter) { crm_debug_2("Filtered %s", child_rsc->id); continue; } if(node && local_node && node->details == local_node->details) { crm_info("Colocating %s with %s on %s", local_child->id, child_rsc->id, node->details->uname); return child_rsc; } ); crm_debug("Can't colocate child %s with %s", local_child->id, rsc->id); return NULL; } void clone_rsc_colocation_lh( resource_t *rsc_lh, resource_t *rsc_rh, rsc_colocation_t *constraint) { gboolean do_interleave = FALSE; resource_t *rsc = constraint->rsc_lh; clone_variant_data_t *clone_data = NULL; clone_variant_data_t *clone_data_rh = NULL; if(rsc == NULL) { pe_err("rsc_lh was NULL for %s", constraint->id); return; } else if(constraint->rsc_rh == NULL) { pe_err("rsc_rh was NULL for %s", constraint->id); return; } else { crm_debug_4("Processing constraints from %s", rsc->id); } get_clone_variant_data(clone_data, rsc); if(constraint->rsc_rh->variant == pe_clone || constraint->rsc_rh->variant == pe_master) { get_clone_variant_data( clone_data_rh, constraint->rsc_rh); if(clone_data->clone_node_max != clone_data_rh->clone_node_max) { crm_config_err("Cannot interleave "XML_CIB_TAG_INCARNATION " %s and %s because" " they do not support the same number of" " resources per node", constraint->rsc_lh->id, constraint->rsc_rh->id); /* only the LHS side needs to be labeled as interleave */ } else if(clone_data->interleave) { do_interleave = TRUE; } else if(constraint->score >= INFINITY) { GListPtr lhs = NULL, rhs = NULL; lhs = rsc_lh->allowed_nodes; slist_iter( child_rsc, resource_t, rsc_rh->children, lpc, node_t *chosen = child_rsc->fns->location(child_rsc, NULL, FALSE); if(chosen != NULL) { rhs = g_list_append(rhs, chosen); } ); rsc_lh->allowed_nodes = node_list_exclude(lhs, rhs); pe_free_shallow_adv(rhs, FALSE); pe_free_shallow(lhs); return; } } else if(constraint->score >= INFINITY) { crm_config_err("Manditory co-location of clones (%s) with other" " non-clone (%s) resources is not supported", rsc_lh->id, rsc_rh->id); return; } if(do_interleave) { resource_t *rh_child = NULL; slist_iter(lh_child, resource_t, rsc->children, lpc, CRM_ASSERT(lh_child != NULL); rh_child = find_compatible_child( lh_child, rsc_rh, RSC_ROLE_UNKNOWN, FALSE); if(rh_child == NULL) { crm_debug_2("No match found for %s", lh_child->id); continue; } crm_debug("Interleaving %s with %s", lh_child->id, rh_child->id); lh_child->cmds->rsc_colocation_lh( lh_child, rh_child, constraint); ); return; } slist_iter( child_rsc, resource_t, rsc->children, lpc, child_rsc->cmds->rsc_colocation_lh(child_rsc, constraint->rsc_rh, constraint); ); } void clone_rsc_colocation_rh( resource_t *rsc_lh, resource_t *rsc_rh, rsc_colocation_t *constraint) { clone_variant_data_t *clone_data = NULL; CRM_CHECK(rsc_lh != NULL, return); CRM_CHECK(rsc_lh->variant == pe_native, return); get_clone_variant_data(clone_data, rsc_rh); crm_debug_3("Processing constraint %s: %d", constraint->id, constraint->score); if(rsc_rh == NULL) { pe_err("rsc_rh was NULL for %s", constraint->id); return; } else if(is_set(rsc_rh->flags, pe_rsc_provisional)) { crm_debug_3("%s is still provisional", rsc_rh->id); return; } else if(constraint->score >= INFINITY) { GListPtr lhs = NULL, rhs = NULL; lhs = rsc_lh->allowed_nodes; slist_iter( child_rsc, resource_t, rsc_rh->children, lpc, node_t *chosen = child_rsc->fns->location(child_rsc, NULL, FALSE); if(chosen != NULL) { rhs = g_list_append(rhs, chosen); } ); rsc_lh->allowed_nodes = node_list_exclude(lhs, rhs); pe_free_shallow_adv(rhs, FALSE); pe_free_shallow(lhs); return; } slist_iter( child_rsc, resource_t, rsc_rh->children, lpc, child_rsc->cmds->rsc_colocation_rh(rsc_lh, child_rsc, constraint); ); } /* Clone <-> Clone ordering S : Start(ed) S' : Stop(ped) P : Promote(d) D : Demote(d) Started == Demoted First A then B A:0 B:0 Old New Old New S' S' S S' S' S' S' - S' S S S+ S' S S' S S S' S S' S S' S' - S S S - S S S' S S' S' P S' S' S' S' - S' P P P+ S' P S' P P S' P S' P S' S' - P P P - P P S' P D D P D D D D - D P P P+ D P D P P D P D P D D - P P P - P P D P Clone <-> Primitive ordering S : Start(ed) S' : Stop(ped) P : Promote(d) D : Demote(d) F : False T : True F' : A good idea? Started == Demoted First A then B A:0 B Old New Old Create Constraint S' S' S F S' S' S' F' S S' S T S S' S' F S' S S T S' S S' T S S S F' S S S' T S' S' S F S' S' S' F' P S' S T P S' S' F S' P S T S' P S' T P P S F' P P S' F S' S' S F S' S' S' F' D S' S T D S' S' F S' D S T S' D S' T D D S F' D D S' T */ static gboolean detect_restart(resource_t *rsc) { gboolean restart = FALSE; /* Look for restarts */ action_t *start = NULL; char *key = start_key(rsc); GListPtr possible_matches = find_actions(rsc->actions, key, NULL); crm_free(key); if(possible_matches) { start = possible_matches->data; g_list_free(possible_matches); } if(start != NULL && start->optional == FALSE) { restart = TRUE; crm_debug_2("Detected a restart for %s", rsc->id); } -#if 1 - /* Shouldn't be required */ - /* Otherwise, look for moves */ if(restart == FALSE) { GListPtr old_hosts = NULL; GListPtr new_hosts = NULL; GListPtr intersection = NULL; rsc->fns->location(rsc, &old_hosts, TRUE); rsc->fns->location(rsc, &new_hosts, FALSE); intersection = node_list_and(old_hosts, new_hosts, FALSE); if(intersection == NULL) { restart = TRUE; /* Actually a move but the result is the same */ crm_debug_2("Detected a move for %s", rsc->id); } g_list_free(intersection); g_list_free(old_hosts); g_list_free(new_hosts); } -#endif + return restart; } void clone_rsc_order_lh(resource_t *rsc, order_constraint_t *order, pe_working_set_t *data_set) { resource_t *r1 = NULL; resource_t *r2 = NULL; gboolean do_interleave = FALSE; clone_variant_data_t *clone_data = NULL; get_clone_variant_data(clone_data, rsc); crm_debug_4("%s->%s", order->lh_action_task, order->rh_action_task); if(order->rh_rsc == NULL) { - order->lh_action_task = convert_non_atomic_task(order->lh_action_task, FALSE, TRUE); + order->lh_action_task = convert_non_atomic_task(order->lh_action_task, rsc, FALSE, TRUE); native_rsc_order_lh(rsc, order, data_set); return; } r1 = uber_parent(rsc); r2 = uber_parent(order->rh_rsc); if(r1 == r2) { native_rsc_order_lh(rsc, order, data_set); return; } if(order->rh_rsc->variant > pe_group) { clone_variant_data_t *clone_data_rh = NULL; get_clone_variant_data(clone_data_rh, order->rh_rsc); if(clone_data->clone_node_max != clone_data_rh->clone_node_max) { crm_config_err("Cannot interleave "XML_CIB_TAG_INCARNATION " %s and %s because they do not support the same" " number of resources per node", rsc->id, order->rh_rsc->id); /* only the LHS side needs to be labeled as interleave */ } else if(clone_data->interleave) { do_interleave = TRUE; } } if(order->rh_rsc == NULL) { do_interleave = FALSE; } if(do_interleave) { resource_t *lh_child = NULL; resource_t *rh_saved = order->rh_rsc; gboolean current = FALSE; if(strstr(order->lh_action_task, "_stop_0") || strstr(order->lh_action_task, "_demote_0")) { current = TRUE; } slist_iter( rh_child, resource_t, rh_saved->children, lpc, CRM_ASSERT(rh_child != NULL); lh_child = find_compatible_child(rh_child, rsc, RSC_ROLE_UNKNOWN, current); if(lh_child == NULL) { crm_debug_2("No match found for %s", rh_child->id); continue; } crm_notice("Interleaving %s with %s", lh_child->id, rh_child->id); order->rh_rsc = rh_child; lh_child->cmds->rsc_order_lh(lh_child, order, data_set); order->rh_rsc = rh_saved; ); } else { #if 0 if(order->type != pe_order_optional) { crm_debug("Upgraded ordering constraint %d - 0x%.6x", order->id, order->type); native_rsc_order_lh(rsc, order, data_set); } #endif if(order->rh_rsc->variant < pe_clone) { GListPtr hosts = NULL; GListPtr rh_hosts = NULL; GListPtr intersection = NULL; const char *reason = "unknown"; enum action_tasks task = start_rsc; enum rsc_role_e lh_role = RSC_ROLE_STARTED; int any_ordered = 0; gboolean down_stack = TRUE; crm_debug_2("Clone-to-* ordering: %s -> %s 0x%.6x", order->lh_action_task, order->rh_action_task, order->type); if(strstr(order->rh_action_task, "_"RSC_STOP"_0") || strstr(order->rh_action_task, "_"RSC_STOPPED"_0")) { task = stop_rsc; reason = "down activity"; lh_role = RSC_ROLE_STOPPED; order->rh_rsc->fns->location(order->rh_rsc, &rh_hosts, down_stack); } else if(strstr(order->rh_action_task, "_"RSC_DEMOTE"_0") || strstr(order->rh_action_task, "_"RSC_DEMOTED"_0")) { task = action_demote; reason = "demotion activity"; lh_role = RSC_ROLE_SLAVE; order->rh_rsc->fns->location(order->rh_rsc, &rh_hosts, down_stack); } else if(strstr(order->lh_action_task, "_"RSC_PROMOTE"_0") || strstr(order->lh_action_task, "_"RSC_PROMOTED"_0")) { task = action_promote; down_stack = FALSE; reason = "promote activity"; order->rh_rsc->fns->location(order->rh_rsc, &rh_hosts, down_stack); lh_role = RSC_ROLE_MASTER; } else if(strstr(order->rh_action_task, "_"RSC_START"_0") || strstr(order->rh_action_task, "_"RSC_STARTED"_0")) { task = start_rsc; down_stack = FALSE; reason = "up activity"; order->rh_rsc->fns->location(order->rh_rsc, &rh_hosts, down_stack); /* if(order->rh_rsc->variant > pe_clone) { */ /* lh_role = RSC_ROLE_SLAVE; */ /* } */ } else { crm_err("WTF: %s", order->rh_action_task); } /* slist_iter(h, node_t, rh_hosts, llpc, crm_info("RHH: %s", h->details->uname)); */ slist_iter( child_rsc, resource_t, rsc->children, lpc, gboolean create = FALSE; gboolean restart = FALSE; enum rsc_role_e lh_role_new = child_rsc->fns->state(child_rsc, FALSE); enum rsc_role_e lh_role_old = child_rsc->fns->state(child_rsc, TRUE); enum rsc_role_e child_role = child_rsc->fns->state(child_rsc, down_stack); crm_info("Testing %s->%s for %s: %s vs. %s %s", order->lh_action_task, order->rh_action_task, child_rsc->id, role2text(lh_role), role2text(child_role), order->lh_action_task); if(rh_hosts == NULL) { crm_info("Terminating search: %s.%d list is empty: no possible %s", order->rh_rsc->id, down_stack, reason); break; } if(lh_role_new == lh_role_old) { - /* TODO: Check for restarts */ - crm_info("Ignoring %s->%s for %s: no relevant %s (no role change)", - order->lh_action_task, order->rh_action_task, child_rsc->id, reason); - continue; + restart = detect_restart(child_rsc); + if(restart == FALSE) { + crm_info("Ignoring %s->%s for %s: no relevant %s (no role change)", + order->lh_action_task, order->rh_action_task, child_rsc->id, reason); + continue; + } } hosts = NULL; child_rsc->fns->location(child_rsc, &hosts, down_stack); intersection = node_list_and(hosts, rh_hosts, FALSE); /* slist_iter(h, node_t, hosts, llpc, crm_info("H: %s %s", child_rsc->id, h->details->uname)); */ if(intersection == NULL) { crm_info("Ignoring %s->%s for %s: no relevant %s", order->lh_action_task, order->rh_action_task, child_rsc->id, reason); g_list_free(hosts); continue; } if(restart) { reason = "restart"; create = TRUE; } else if(down_stack) { if(lh_role_old > lh_role) { create = TRUE; } } else if(down_stack == FALSE) { if(lh_role_old < lh_role) { create = TRUE; } } else { any_ordered++; reason = "role"; crm_notice("Role: %s->%s for %s: %s vs. %s %s", order->lh_action_task, order->rh_action_task, child_rsc->id, role2text(lh_role_old), role2text(lh_role), order->lh_action_task); } if(create) { -#if 1 - native_rsc_order_lh(child_rsc, order, data_set); -#else - enum pe_ordering type = order->type; - child_rsc->cmds->rsc_order_lh(child_rsc, order, data_set); - order->type = pe_order_optional; - native_rsc_order_lh(rsc, order, data_set); - order->type = type; -#endif + char *task = order->lh_action_task; + any_ordered++; - crm_info("Enforced %s->%s for %s on %s: found %s", + crm_info("Enforcing %s->%s for %s on %s: found %s", order->lh_action_task, order->rh_action_task, child_rsc->id, ((node_t*)intersection->data)->details->uname, reason); + + order->lh_action_task = convert_non_atomic_task(task, child_rsc, TRUE, FALSE); + child_rsc->cmds->rsc_order_lh(child_rsc, order, data_set); + crm_free(order->lh_action_task); + order->lh_action_task = task; } crm_info("Processed %s->%s for %s on %s: %s", order->lh_action_task, order->rh_action_task, child_rsc->id, ((node_t*)intersection->data)->details->uname, reason); /* slist_iter(h, node_t, hosts, llpc, */ /* crm_info("H: %s %s", child_rsc->id, h->details->uname)); */ g_list_free(intersection); g_list_free(hosts); ); g_list_free(rh_hosts); if(any_ordered == 0 && down_stack == FALSE) { - crm_err("here"); - order->lh_action_task = convert_non_atomic_task(order->lh_action_task, FALSE, TRUE); + order->lh_action_task = convert_non_atomic_task(order->lh_action_task, rsc, TRUE, TRUE); native_rsc_order_lh(rsc, order, data_set); } order->type = pe_order_optional; } else if(order->type & pe_order_implies_left) { if(rsc->variant == order->rh_rsc->variant) { crm_debug_2("Clone-to-clone ordering: %s -> %s 0x%.6x", order->lh_action_task, order->rh_action_task, order->type); /* stop instances on the same nodes as stopping RHS instances */ slist_iter( child_rsc, resource_t, rsc->children, lpc, native_rsc_order_lh(child_rsc, order, data_set); ); } else { /* stop everything */ slist_iter( child_rsc, resource_t, rsc->children, lpc, native_rsc_order_lh(child_rsc, order, data_set); ); } } } if(do_interleave == FALSE || clone_data->ordered) { - order->lh_action_task = convert_non_atomic_task(order->lh_action_task, FALSE, TRUE); + order->lh_action_task = convert_non_atomic_task(order->lh_action_task, rsc, FALSE, TRUE); native_rsc_order_lh(rsc, order, data_set); } - if(is_set(rsc->flags, pe_rsc_notify)) { order->type = pe_order_optional; - order->lh_action_task = convert_non_atomic_task(order->lh_action_task, TRUE, TRUE); + order->lh_action_task = convert_non_atomic_task(order->lh_action_task, rsc, TRUE, TRUE); native_rsc_order_lh(rsc, order, data_set); } } void clone_rsc_order_rh( action_t *lh_action, resource_t *rsc, order_constraint_t *order) { enum pe_ordering type = order->type; clone_variant_data_t *clone_data = NULL; resource_t *lh_p = uber_parent(lh_action->rsc); get_clone_variant_data(clone_data, rsc); crm_debug_2("%s->%s", order->lh_action_task, order->rh_action_task); if(safe_str_eq(CRM_OP_PROBED, lh_action->uuid)) { slist_iter( child_rsc, resource_t, rsc->children, lpc, child_rsc->cmds->rsc_order_rh(lh_action, child_rsc, order); ); if(rsc->fns->state(rsc, TRUE) < RSC_ROLE_STARTED && rsc->fns->state(rsc, FALSE) > RSC_ROLE_STOPPED) { order->type |= pe_order_implies_right; } } else if(lh_p && lh_p != rsc && lh_p->variant < pe_clone) { GListPtr hosts = NULL; GListPtr lh_hosts = NULL; GListPtr intersection = NULL; const char *reason = "unknown"; gboolean restart = FALSE; gboolean down_stack = TRUE; enum rsc_role_e rh_role = RSC_ROLE_STARTED; enum action_tasks task = start_rsc; enum rsc_role_e lh_role_new = lh_p->fns->state(lh_p, FALSE); enum rsc_role_e lh_role_old = lh_p->fns->state(lh_p, TRUE); if(strstr(order->lh_action_task, "_"RSC_STOP"_0") || strstr(order->lh_action_task, "_"RSC_STOPPED"_0")) { task = stop_rsc; reason = "down activity"; rh_role = RSC_ROLE_STOPPED; lh_p->fns->location(lh_p, &lh_hosts, down_stack); /* These actions are not possible for non-clones } else if(strstr(order->lh_action_task, "_"RSC_DEMOTE"_0") || strstr(order->lh_action_task, "_"RSC_DEMOTED"_0")) { task = action_demote; rh_role = RSC_ROLE_SLAVE; reason = "demotion activity"; lh_p->fns->location(lh_p, &lh_hosts, down_stack); } else if(strstr(order->lh_action_task, "_"RSC_PROMOTE"_0") || strstr(order->lh_action_task, "_"RSC_PROMOTED"_0")) { task = action_promote; down_stack = FALSE; reason = "promote activity"; lh_p->fns->location(lh_p, &lh_hosts, down_stack); rh_role = RSC_ROLE_MASTER; */ } else if(strstr(order->lh_action_task, "_"RSC_START"_0") || strstr(order->lh_action_task, "_"RSC_STARTED"_0")) { task = start_rsc; down_stack = FALSE; reason = "up activity"; lh_p->fns->location(lh_p, &lh_hosts, down_stack); } else { crm_err("WTF: %s", order->lh_action_task); } if(lh_role_new == lh_role_old) { restart = detect_restart(lh_action->rsc); if(FALSE && restart == FALSE) { crm_info("Ignoring %s->%s for %s: no relevant %s (no role change)", lh_action->task, order->lh_action_task, lh_p->id, reason); goto cleanup; } } /* slist_iter(h, node_t, lh_hosts, llpc, crm_info("LHH: %s", h->details->uname)); */ slist_iter( child_rsc, resource_t, rsc->children, lpc, gboolean create = FALSE; enum rsc_role_e child_role = child_rsc->fns->state(child_rsc, down_stack); crm_info("Testing %s->%s for %s: %s vs. %s %s", lh_action->task, order->lh_action_task, child_rsc->id, role2text(rh_role), role2text(child_role), order->lh_action_task); if(lh_hosts == NULL) { crm_info("Terminating search: %s.%d list is empty: no possible %s", order->rh_rsc->id, down_stack, reason); break; } hosts = NULL; child_rsc->fns->location(child_rsc, &hosts, down_stack); intersection = node_list_and(hosts, lh_hosts, FALSE); if(intersection == NULL) { crm_info("Ignoring %s->%s for %s: no relevant %s", lh_action->task, order->lh_action_task, child_rsc->id, reason); g_list_free(hosts); continue; } /* slist_iter(h, node_t, hosts, llpc, crm_info("H: %s %s", child_rsc->id, h->details->uname)); */ if(restart) { reason = "restart"; create = TRUE; } else if(down_stack && lh_role_old >= rh_role) { create = TRUE; } else if(down_stack == FALSE && lh_role_old <= rh_role) { create = TRUE; } else { reason = "role"; } if(create) { enum pe_ordering type = order->type; child_rsc->cmds->rsc_order_rh(lh_action, child_rsc, order); order->type = pe_order_optional; native_rsc_order_rh(lh_action, rsc, order); order->type = type; } crm_info("Processed %s->%s for %s on %s: found %s%s", lh_action->task, order->lh_action_task, child_rsc->id, ((node_t*)intersection->data)->details->uname, reason, create?" - enforced":""); /* slist_iter(h, node_t, hosts, llpc, */ /* crm_info("H: %s %s", child_rsc->id, h->details->uname)); */ g_list_free(intersection); g_list_free(hosts); ); cleanup: g_list_free(lh_hosts); return; } native_rsc_order_rh(lh_action, rsc, order); order->type = type; } void clone_rsc_location(resource_t *rsc, rsc_to_node_t *constraint) { clone_variant_data_t *clone_data = NULL; get_clone_variant_data(clone_data, rsc); crm_debug_3("Processing location constraint %s for %s", constraint->id, rsc->id); native_rsc_location(rsc, constraint); slist_iter( child_rsc, resource_t, rsc->children, lpc, child_rsc->cmds->rsc_location(child_rsc, constraint); ); } void clone_expand(resource_t *rsc, pe_working_set_t *data_set) { clone_variant_data_t *clone_data = NULL; get_clone_variant_data(clone_data, rsc); crm_debug_2("Processing actions from %s", rsc->id); if(clone_data->start_notify) { collect_notification_data(rsc, TRUE, TRUE, clone_data->start_notify); expand_notification_data(clone_data->start_notify); create_notifications(rsc, clone_data->start_notify, data_set); } if(clone_data->stop_notify) { collect_notification_data(rsc, TRUE, TRUE, clone_data->stop_notify); expand_notification_data(clone_data->stop_notify); create_notifications(rsc, clone_data->stop_notify, data_set); } if(clone_data->promote_notify) { collect_notification_data(rsc, TRUE, TRUE, clone_data->promote_notify); expand_notification_data(clone_data->promote_notify); create_notifications(rsc, clone_data->promote_notify, data_set); } if(clone_data->demote_notify) { collect_notification_data(rsc, TRUE, TRUE, clone_data->demote_notify); expand_notification_data(clone_data->demote_notify); create_notifications(rsc, clone_data->demote_notify, data_set); } /* Now that the notifcations have been created we can expand the children */ slist_iter( child_rsc, resource_t, rsc->children, lpc, child_rsc->cmds->expand(child_rsc, data_set)); native_expand(rsc, data_set); /* The notifications are in the graph now, we can destroy the notify_data */ free_notification_data(clone_data->demote_notify); free_notification_data(clone_data->stop_notify); free_notification_data(clone_data->start_notify); free_notification_data(clone_data->promote_notify); } 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 resource_t *find_instance_on(resource_t *rsc, node_t *node) { slist_iter(child, resource_t, rsc->children, lpc, GListPtr known_list = NULL; rsc_known_on(child, &known_list); slist_iter(known, node_t, known_list, lpc2, if(node->details == known->details) { g_list_free(known_list); return child; } ); g_list_free(known_list); ); return NULL; } gboolean clone_create_probe(resource_t *rsc, node_t *node, action_t *complete, gboolean force, pe_working_set_t *data_set) { gboolean any_created = FALSE; clone_variant_data_t *clone_data = NULL; get_clone_variant_data(clone_data, rsc); rsc->children = g_list_sort(rsc->children, sort_rsc_id); if(rsc->children == NULL) { pe_warn("Clone %s has no children", rsc->id); return FALSE; } if(is_not_set(rsc->flags, pe_rsc_unique) && clone_data->clone_node_max == 1) { /* only look for one copy */ resource_t *child = NULL; /* Try whoever we probed last time */ child = find_instance_on(rsc, node); if(child) { return child->cmds->create_probe( child, node, complete, force, data_set); } /* Try whoever we plan on starting there */ slist_iter( child_rsc, resource_t, rsc->children, lpc, node_t *local_node = child_rsc->fns->location(child_rsc, NULL, FALSE); if(local_node == NULL) { continue; } if(local_node->details == node->details) { return child_rsc->cmds->create_probe( child_rsc, node, complete, force, data_set); } ); /* Fall back to the first clone instance */ child = rsc->children->data; return child->cmds->create_probe(child, node, complete, force, data_set); } slist_iter( child_rsc, resource_t, rsc->children, lpc, if(child_rsc->cmds->create_probe( child_rsc, node, complete, force, data_set)) { any_created = TRUE; } if(any_created && is_not_set(rsc->flags, pe_rsc_unique) && clone_data->clone_node_max == 1) { /* only look for one copy (clone :0) */ break; } ); return any_created; } diff --git a/pengine/group.c b/pengine/group.c index 9f60e81a5e..1f2f644389 100644 --- a/pengine/group.c +++ b/pengine/group.c @@ -1,519 +1,518 @@ /* * Copyright (C) 2004 Andrew Beekhof * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #define VARIANT_GROUP 1 #include node_t * group_color(resource_t *rsc, pe_working_set_t *data_set) { node_t *node = NULL; node_t *group_node = NULL; group_variant_data_t *group_data = NULL; get_group_variant_data(group_data, rsc); if(is_not_set(rsc->flags, pe_rsc_provisional)) { return rsc->allocated_to; } crm_debug_2("Processing %s", rsc->id); if(is_set(rsc->flags, pe_rsc_allocating)) { crm_debug("Dependancy loop detected involving %s", rsc->id); return NULL; } if(group_data->first_child == NULL) { /* nothign to allocate */ clear_bit(rsc->flags, pe_rsc_provisional); return NULL; } set_bit(rsc->flags, pe_rsc_allocating); rsc->role = group_data->first_child->role; group_data->first_child->rsc_cons = g_list_concat( group_data->first_child->rsc_cons, rsc->rsc_cons); rsc->rsc_cons = NULL; group_data->first_child->rsc_cons_lhs = g_list_concat( group_data->first_child->rsc_cons_lhs, rsc->rsc_cons_lhs); rsc->rsc_cons_lhs = NULL; dump_node_scores(show_scores?0:scores_log_level, rsc, __PRETTY_FUNCTION__, rsc->allowed_nodes); slist_iter( child_rsc, resource_t, rsc->children, lpc, node = child_rsc->cmds->color(child_rsc, data_set); if(group_node == NULL) { group_node = node; } ); rsc->next_role = group_data->first_child->next_role; clear_bit(rsc->flags, pe_rsc_allocating); clear_bit(rsc->flags, pe_rsc_provisional); if(group_data->colocated) { return group_node; } return NULL; } void group_update_pseudo_status(resource_t *parent, resource_t *child); void group_create_actions(resource_t *rsc, pe_working_set_t *data_set) { action_t *op = NULL; const char *value = NULL; group_variant_data_t *group_data = NULL; get_group_variant_data(group_data, rsc); crm_debug_2("Creating actions for %s", rsc->id); slist_iter( child_rsc, resource_t, rsc->children, lpc, child_rsc->cmds->create_actions(child_rsc, data_set); group_update_pseudo_status(rsc, child_rsc); ); op = start_action(rsc, NULL, TRUE/* !group_data->child_starting */); op->pseudo = TRUE; op->runnable = TRUE; op = custom_action(rsc, started_key(rsc), RSC_STARTED, NULL, TRUE/* !group_data->child_starting */, TRUE, data_set); op->pseudo = TRUE; op->runnable = TRUE; op = stop_action(rsc, NULL, TRUE/* !group_data->child_stopping */); op->pseudo = TRUE; op->runnable = TRUE; op = custom_action(rsc, stopped_key(rsc), RSC_STOPPED, NULL, TRUE/* !group_data->child_stopping */, TRUE, data_set); op->pseudo = TRUE; op->runnable = TRUE; value = g_hash_table_lookup(rsc->meta, "stateful"); if(crm_is_true(value)) { op = custom_action(rsc, demote_key(rsc), RSC_DEMOTE, NULL, TRUE, TRUE, data_set); op->pseudo = TRUE; op->runnable = TRUE; op = custom_action(rsc, demoted_key(rsc), RSC_DEMOTED, NULL, TRUE, TRUE, data_set); op->pseudo = TRUE; op->runnable = TRUE; op = custom_action(rsc, promote_key(rsc), RSC_PROMOTE, NULL, TRUE, TRUE, data_set); op->pseudo = TRUE; op->runnable = TRUE; op = custom_action(rsc, promoted_key(rsc), RSC_PROMOTED, NULL, TRUE, TRUE, data_set); op->pseudo = TRUE; op->runnable = TRUE; } rsc->actions = rsc->actions; /* rsc->actions = NULL; */ } void group_update_pseudo_status(resource_t *parent, resource_t *child) { group_variant_data_t *group_data = NULL; get_group_variant_data(group_data, parent); if(group_data->ordered == FALSE) { /* If this group is not ordered, then leave the meta-actions as optional */ return; } if(group_data->child_stopping && group_data->child_starting) { return; } slist_iter( action, action_t, child->actions, lpc, if(action->optional) { continue; } if(safe_str_eq(RSC_STOP, action->task) && action->runnable) { group_data->child_stopping = TRUE; crm_debug_3("Based on %s the group is stopping", action->uuid); } else if(safe_str_eq(RSC_START, action->task) && action->runnable) { group_data->child_starting = TRUE; crm_debug_3("Based on %s the group is starting", action->uuid); } ); } void group_internal_constraints(resource_t *rsc, pe_working_set_t *data_set) { const char *value = NULL; gboolean stateful = FALSE; resource_t *last_rsc = NULL; group_variant_data_t *group_data = NULL; get_group_variant_data(group_data, rsc); native_internal_constraints(rsc, data_set); value = g_hash_table_lookup(rsc->meta, "stateful"); stateful = crm_is_true(value); new_rsc_order(rsc, RSC_STOPPED, rsc, RSC_START, pe_order_optional, data_set); new_rsc_order(rsc, RSC_STOP, rsc, RSC_STOPPED, pe_order_runnable_left|pe_order_implies_right|pe_order_implies_left, data_set); new_rsc_order(rsc, RSC_START, rsc, RSC_STARTED, pe_order_runnable_left, data_set); slist_iter( child_rsc, resource_t, rsc->children, lpc, int stop = pe_order_shutdown|pe_order_implies_right; int stopped = pe_order_implies_right_printed; int start = pe_order_implies_right|pe_order_runnable_left; int started = pe_order_runnable_left|pe_order_implies_right|pe_order_implies_right_printed; child_rsc->cmds->internal_constraints(child_rsc, data_set); if(last_rsc == NULL) { if(group_data->ordered) { stop |= pe_order_implies_left; stopped = pe_order_implies_right; } } else if(group_data->colocated) { rsc_colocation_new( "group:internal_colocation", NULL, INFINITY, child_rsc, last_rsc, NULL, NULL, data_set); } if(stateful) { new_rsc_order(rsc, RSC_DEMOTE, child_rsc, RSC_DEMOTE, stop|pe_order_implies_left_printed, data_set); new_rsc_order(child_rsc, RSC_DEMOTE, rsc, RSC_DEMOTED, stopped, data_set); new_rsc_order(child_rsc, RSC_PROMOTE, rsc, RSC_PROMOTED, started, data_set); new_rsc_order(rsc, RSC_PROMOTE, child_rsc, RSC_PROMOTE, pe_order_implies_left_printed, data_set); } order_start_start(rsc, child_rsc, pe_order_implies_left_printed); order_stop_stop(rsc, child_rsc, stop|pe_order_implies_left_printed); new_rsc_order(child_rsc, RSC_STOP, rsc, RSC_STOPPED, stopped, data_set); new_rsc_order(child_rsc, RSC_START, rsc, RSC_STARTED, started, data_set); if(group_data->ordered == FALSE) { order_start_start(rsc, child_rsc, start|pe_order_implies_left_printed); if(stateful) { new_rsc_order(rsc, RSC_PROMOTE, child_rsc, RSC_PROMOTE, start|pe_order_implies_left_printed, data_set); } } else if(last_rsc != NULL) { child_rsc->restart_type = pe_restart_restart; order_start_start(last_rsc, child_rsc, start); order_stop_stop(child_rsc, last_rsc, pe_order_implies_left); if(stateful) { new_rsc_order(last_rsc, RSC_PROMOTE, child_rsc, RSC_PROMOTE, start, data_set); new_rsc_order(child_rsc, RSC_DEMOTE, last_rsc, RSC_DEMOTE, pe_order_implies_left, data_set); } } else { /* If anyone in the group is starting, then * pe_order_implies_right will cause _everyone_ in the group * to be sent a start action * But this is safe since starting something that is already * started is required to be "safe" */ int flags = pe_order_implies_left|pe_order_implies_right|pe_order_runnable_right|pe_order_runnable_left; order_start_start(rsc, child_rsc, flags); if(stateful) { new_rsc_order(rsc, RSC_PROMOTE, child_rsc, RSC_PROMOTE, flags, data_set); } } last_rsc = child_rsc; ); if(group_data->ordered && last_rsc != NULL) { int stop_stop_flags = pe_order_implies_right; int stop_stopped_flags = pe_order_implies_left; order_stop_stop(rsc, last_rsc, stop_stop_flags); new_rsc_order(last_rsc, RSC_STOP, rsc, RSC_STOPPED, stop_stopped_flags, data_set); if(stateful) { new_rsc_order(rsc, RSC_DEMOTE, last_rsc, RSC_DEMOTE, stop_stop_flags, data_set); new_rsc_order(last_rsc, RSC_DEMOTE, rsc, RSC_DEMOTED, stop_stopped_flags, data_set); } } } void group_rsc_colocation_lh( resource_t *rsc_lh, resource_t *rsc_rh, rsc_colocation_t *constraint) { group_variant_data_t *group_data = NULL; if(rsc_lh == NULL) { pe_err("rsc_lh was NULL for %s", constraint->id); return; } else if(rsc_rh == NULL) { pe_err("rsc_rh was NULL for %s", constraint->id); return; } crm_debug_4("Processing constraints from %s", rsc_lh->id); get_group_variant_data(group_data, rsc_lh); if(group_data->colocated) { group_data->first_child->cmds->rsc_colocation_lh( group_data->first_child, rsc_rh, constraint); return; } else if(constraint->score >= INFINITY) { crm_config_err("%s: Cannot perform manditory colocation" " between non-colocated group and %s", rsc_lh->id, rsc_rh->id); return; } slist_iter( child_rsc, resource_t, rsc_lh->children, lpc, child_rsc->cmds->rsc_colocation_lh( child_rsc, rsc_rh, constraint); ); } void group_rsc_colocation_rh( resource_t *rsc_lh, resource_t *rsc_rh, rsc_colocation_t *constraint) { group_variant_data_t *group_data = NULL; get_group_variant_data(group_data, rsc_rh); CRM_CHECK(rsc_lh->variant == pe_native, return); crm_debug_3("Processing RH of constraint %s", constraint->id); print_resource(LOG_DEBUG_3, "LHS", rsc_lh, TRUE); if(is_set(rsc_rh->flags, pe_rsc_provisional)) { return; } else if(group_data->colocated && group_data->first_child) { group_data->first_child->cmds->rsc_colocation_rh( rsc_lh, group_data->first_child, constraint); return; } else if(constraint->score >= INFINITY) { crm_config_err("%s: Cannot perform manditory colocation with" " non-colocated group: %s", rsc_lh->id, rsc_rh->id); return; } slist_iter( child_rsc, resource_t, rsc_rh->children, lpc, child_rsc->cmds->rsc_colocation_rh( rsc_lh, child_rsc, constraint); ); } void group_rsc_order_lh(resource_t *rsc, order_constraint_t *order, pe_working_set_t *data_set) { group_variant_data_t *group_data = NULL; get_group_variant_data(group_data, rsc); crm_debug_4("%s->%s", order->lh_action_task, order->rh_action_task); if(order->rh_rsc != NULL && (rsc == order->rh_rsc || rsc == order->rh_rsc->parent)) { native_rsc_order_lh(rsc, order, data_set); return; } #if 0 if(order->type != pe_order_optional) { native_rsc_order_lh(rsc, order, data_set); } if(order->type & pe_order_implies_left) { native_rsc_order_lh(group_data->first_child, order, data_set); } #endif - order->lh_action_task = convert_non_atomic_task( - order->lh_action_task, is_set(rsc->flags, pe_rsc_notify), TRUE); + order->lh_action_task = convert_non_atomic_task(order->lh_action_task, rsc, TRUE, TRUE); native_rsc_order_lh(rsc, order, data_set); } void group_rsc_order_rh( action_t *lh_action, resource_t *rsc, order_constraint_t *order) { enum pe_ordering type = order->type; group_variant_data_t *group_data = NULL; get_group_variant_data(group_data, rsc); crm_debug_3("%s/%p: %s->%s", rsc->id, order, lh_action->uuid, order->rh_action_task); if(rsc == NULL) { return; } if(safe_str_eq(CRM_OP_PROBED, lh_action->uuid)) { slist_iter( child_rsc, resource_t, rsc->children, lpc, child_rsc->cmds->rsc_order_rh(lh_action, child_rsc, order); ); if(rsc->fns->state(rsc, TRUE) < RSC_ROLE_STARTED && rsc->fns->state(rsc, FALSE) > RSC_ROLE_STOPPED) { order->type |= pe_order_implies_right; } } else if(lh_action->rsc != NULL && lh_action->rsc != rsc && lh_action->rsc != rsc->parent && lh_action->rsc->parent != rsc) { char *tmp = NULL; char *task_s = NULL; int interval = 0; enum action_tasks task = 0; parse_op_key(order->lh_action_task, &tmp, &task_s, &interval); task = text2task(task_s); crm_free(task_s); crm_free(tmp); switch(task) { case no_action: case monitor_rsc: case action_notify: case action_notified: case shutdown_crm: case stonith_node: break; case stop_rsc: case stopped_rsc: case action_demote: case action_demoted: order->type |= pe_order_complex_left; break; case start_rsc: case started_rsc: case action_promote: case action_promoted: order->type |= pe_order_complex_right; break; } } native_rsc_order_rh(lh_action, rsc, order); order->type = type; } void group_rsc_location(resource_t *rsc, rsc_to_node_t *constraint) { GListPtr saved = constraint->node_list_rh; GListPtr zero = node_list_dup(constraint->node_list_rh, TRUE, FALSE); gboolean reset_scores = TRUE; group_variant_data_t *group_data = NULL; get_group_variant_data(group_data, rsc); crm_debug("Processing rsc_location %s for %s", constraint->id, rsc->id); native_rsc_location(rsc, constraint); slist_iter( child_rsc, resource_t, rsc->children, lpc, child_rsc->cmds->rsc_location(child_rsc, constraint); if(group_data->colocated && reset_scores) { reset_scores = FALSE; constraint->node_list_rh = zero; } ); constraint->node_list_rh = saved; pe_free_shallow_adv(zero, TRUE); } void group_expand(resource_t *rsc, pe_working_set_t *data_set) { group_variant_data_t *group_data = NULL; get_group_variant_data(group_data, rsc); crm_debug_3("Processing actions from %s", rsc->id); CRM_CHECK(rsc != NULL, return); native_expand(rsc, data_set); slist_iter( child_rsc, resource_t, rsc->children, lpc, child_rsc->cmds->expand(child_rsc, data_set); ); } GListPtr group_merge_weights( resource_t *rsc, const char *rhs, GListPtr nodes, const char *attr, int factor, gboolean allow_rollback) { group_variant_data_t *group_data = NULL; get_group_variant_data(group_data, rsc); if(is_set(rsc->flags, pe_rsc_merging)) { crm_info("Breaking dependancy loop with %s at %s", rsc->id, rhs); return nodes; } set_bit(rsc->flags, pe_rsc_merging); nodes = group_data->first_child->cmds->merge_weights( group_data->first_child, rhs, nodes, attr, factor, allow_rollback); slist_iter( constraint, rsc_colocation_t, rsc->rsc_cons_lhs, lpc, nodes = native_merge_weights( constraint->rsc_lh, rsc->id, nodes, constraint->node_attribute, constraint->score/INFINITY, allow_rollback); ); clear_bit(rsc->flags, pe_rsc_merging); return nodes; } diff --git a/pengine/test10/bug-1572-1.dot b/pengine/test10/bug-1572-1.dot index 7190cf1ad5..5b14f5e938 100644 --- a/pengine/test10/bug-1572-1.dot +++ b/pengine/test10/bug-1572-1.dot @@ -1,160 +1,161 @@ digraph "g" { "IPaddr_147_81_84_133_monitor_25000 arc-tkincaidlx.wsicorp.com" [ style=bold color="green" fontcolor="black" ] "IPaddr_147_81_84_133_start_0 arc-tkincaidlx.wsicorp.com" -> "IPaddr_147_81_84_133_monitor_25000 arc-tkincaidlx.wsicorp.com" [ style = bold] "IPaddr_147_81_84_133_start_0 arc-tkincaidlx.wsicorp.com" -> "grp_pgsql_mirror_running_0" [ style = bold] "IPaddr_147_81_84_133_start_0 arc-tkincaidlx.wsicorp.com" [ style=bold color="green" fontcolor="black" ] "IPaddr_147_81_84_133_stop_0 arc-tkincaidlx.wsicorp.com" -> "IPaddr_147_81_84_133_start_0 arc-tkincaidlx.wsicorp.com" [ style = bold] "IPaddr_147_81_84_133_stop_0 arc-tkincaidlx.wsicorp.com" -> "all_stopped" [ style = bold] "IPaddr_147_81_84_133_stop_0 arc-tkincaidlx.wsicorp.com" -> "grp_pgsql_mirror_stopped_0" [ style = bold] "IPaddr_147_81_84_133_stop_0 arc-tkincaidlx.wsicorp.com" -> "pgsql_5555_stop_0 arc-tkincaidlx.wsicorp.com" [ style = bold] "IPaddr_147_81_84_133_stop_0 arc-tkincaidlx.wsicorp.com" [ style=bold color="green" fontcolor="black" ] "all_stopped" [ style=bold color="green" fontcolor="orange" ] "do_shutdown arc-dknightlx" [ style=bold color="green" fontcolor="black" ] "fs_mirror_start_0 arc-tkincaidlx.wsicorp.com" -> "grp_pgsql_mirror_running_0" [ style = bold] "fs_mirror_start_0 arc-tkincaidlx.wsicorp.com" -> "pgsql_5555_start_0 arc-tkincaidlx.wsicorp.com" [ style = bold] "fs_mirror_start_0 arc-tkincaidlx.wsicorp.com" [ style=bold color="green" fontcolor="black" ] "fs_mirror_stop_0 arc-tkincaidlx.wsicorp.com" -> "all_stopped" [ style = bold] "fs_mirror_stop_0 arc-tkincaidlx.wsicorp.com" -> "fs_mirror_start_0 arc-tkincaidlx.wsicorp.com" [ style = bold] "fs_mirror_stop_0 arc-tkincaidlx.wsicorp.com" -> "grp_pgsql_mirror_stopped_0" [ style = bold] "fs_mirror_stop_0 arc-tkincaidlx.wsicorp.com" [ style=bold color="green" fontcolor="black" ] "grp_pgsql_mirror_running_0" [ style=bold color="green" fontcolor="orange" ] "grp_pgsql_mirror_start_0" -> "IPaddr_147_81_84_133_start_0 arc-tkincaidlx.wsicorp.com" [ style = bold] "grp_pgsql_mirror_start_0" -> "fs_mirror_start_0 arc-tkincaidlx.wsicorp.com" [ style = bold] "grp_pgsql_mirror_start_0" -> "grp_pgsql_mirror_running_0" [ style = bold] "grp_pgsql_mirror_start_0" -> "pgsql_5555_start_0 arc-tkincaidlx.wsicorp.com" [ style = bold] "grp_pgsql_mirror_start_0" [ style=bold color="green" fontcolor="orange" ] "grp_pgsql_mirror_stop_0" -> "IPaddr_147_81_84_133_stop_0 arc-tkincaidlx.wsicorp.com" [ style = bold] "grp_pgsql_mirror_stop_0" -> "fs_mirror_stop_0 arc-tkincaidlx.wsicorp.com" [ style = bold] "grp_pgsql_mirror_stop_0" -> "grp_pgsql_mirror_start_0" [ style = bold] "grp_pgsql_mirror_stop_0" -> "grp_pgsql_mirror_stopped_0" [ style = bold] "grp_pgsql_mirror_stop_0" -> "pgsql_5555_stop_0 arc-tkincaidlx.wsicorp.com" [ style = bold] "grp_pgsql_mirror_stop_0" [ style=bold color="green" fontcolor="orange" ] "grp_pgsql_mirror_stopped_0" -> "grp_pgsql_mirror_start_0" [ style = bold] "grp_pgsql_mirror_stopped_0" -> "ms_drbd_7788_demote_0" [ style = bold] "grp_pgsql_mirror_stopped_0" -> "rsc_drbd_7788:1_demote_0 arc-tkincaidlx.wsicorp.com" [ style = bold] "grp_pgsql_mirror_stopped_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_7788_confirmed-post_notify_demoted_0" -> "ms_drbd_7788_pre_notify_promote_0" [ style = bold] "ms_drbd_7788_confirmed-post_notify_demoted_0" -> "ms_drbd_7788_pre_notify_start_0" [ style = bold] "ms_drbd_7788_confirmed-post_notify_demoted_0" -> "ms_drbd_7788_pre_notify_stop_0" [ style = bold] "ms_drbd_7788_confirmed-post_notify_demoted_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_7788_confirmed-post_notify_promoted_0" -> "grp_pgsql_mirror_start_0" [ style = bold] "ms_drbd_7788_confirmed-post_notify_promoted_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_7788_confirmed-post_notify_running_0" -> "ms_drbd_7788_pre_notify_promote_0" [ style = bold] "ms_drbd_7788_confirmed-post_notify_running_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_7788_confirmed-post_notify_stopped_0" -> "all_stopped" [ style = bold] "ms_drbd_7788_confirmed-post_notify_stopped_0" -> "ms_drbd_7788_pre_notify_promote_0" [ style = bold] "ms_drbd_7788_confirmed-post_notify_stopped_0" -> "ms_drbd_7788_pre_notify_start_0" [ style = bold] "ms_drbd_7788_confirmed-post_notify_stopped_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_7788_confirmed-pre_notify_demote_0" -> "ms_drbd_7788_demote_0" [ style = bold] "ms_drbd_7788_confirmed-pre_notify_demote_0" -> "ms_drbd_7788_post_notify_demoted_0" [ style = bold] "ms_drbd_7788_confirmed-pre_notify_demote_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_7788_confirmed-pre_notify_promote_0" -> "ms_drbd_7788_post_notify_promoted_0" [ style = bold] "ms_drbd_7788_confirmed-pre_notify_promote_0" -> "ms_drbd_7788_promote_0" [ style = bold] "ms_drbd_7788_confirmed-pre_notify_promote_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_7788_confirmed-pre_notify_start_0" -> "ms_drbd_7788_post_notify_running_0" [ style = bold] "ms_drbd_7788_confirmed-pre_notify_start_0" -> "ms_drbd_7788_start_0" [ style = bold] "ms_drbd_7788_confirmed-pre_notify_start_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_7788_confirmed-pre_notify_stop_0" -> "ms_drbd_7788_post_notify_stopped_0" [ style = bold] "ms_drbd_7788_confirmed-pre_notify_stop_0" -> "ms_drbd_7788_stop_0" [ style = bold] "ms_drbd_7788_confirmed-pre_notify_stop_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_7788_demote_0" -> "ms_drbd_7788_demoted_0" [ style = bold] "ms_drbd_7788_demote_0" -> "ms_drbd_7788_stop_0" [ style = bold] "ms_drbd_7788_demote_0" -> "rsc_drbd_7788:1_demote_0 arc-tkincaidlx.wsicorp.com" [ style = bold] "ms_drbd_7788_demote_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_7788_demoted_0" -> "ms_drbd_7788_post_notify_demoted_0" [ style = bold] "ms_drbd_7788_demoted_0" -> "ms_drbd_7788_promote_0" [ style = bold] "ms_drbd_7788_demoted_0" -> "ms_drbd_7788_start_0" [ style = bold] "ms_drbd_7788_demoted_0" -> "ms_drbd_7788_stop_0" [ style = bold] "ms_drbd_7788_demoted_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_7788_post_notify_demoted_0" -> "ms_drbd_7788_confirmed-post_notify_demoted_0" [ style = bold] "ms_drbd_7788_post_notify_demoted_0" -> "rsc_drbd_7788:0_post_notify_demote_0 arc-dknightlx" [ style = bold] "ms_drbd_7788_post_notify_demoted_0" -> "rsc_drbd_7788:1_post_notify_demote_0 arc-tkincaidlx.wsicorp.com" [ style = bold] "ms_drbd_7788_post_notify_demoted_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_7788_post_notify_promoted_0" -> "ms_drbd_7788_confirmed-post_notify_promoted_0" [ style = bold] "ms_drbd_7788_post_notify_promoted_0" -> "rsc_drbd_7788:1_post_notify_promote_0 arc-tkincaidlx.wsicorp.com" [ style = bold] "ms_drbd_7788_post_notify_promoted_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_7788_post_notify_running_0" -> "ms_drbd_7788_confirmed-post_notify_running_0" [ style = bold] "ms_drbd_7788_post_notify_running_0" -> "rsc_drbd_7788:1_post_notify_start_0 arc-tkincaidlx.wsicorp.com" [ style = bold] "ms_drbd_7788_post_notify_running_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_7788_post_notify_stopped_0" -> "ms_drbd_7788_confirmed-post_notify_stopped_0" [ style = bold] "ms_drbd_7788_post_notify_stopped_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_7788_pre_notify_demote_0" -> "ms_drbd_7788_confirmed-pre_notify_demote_0" [ style = bold] "ms_drbd_7788_pre_notify_demote_0" -> "rsc_drbd_7788:0_pre_notify_demote_0 arc-dknightlx" [ style = bold] "ms_drbd_7788_pre_notify_demote_0" -> "rsc_drbd_7788:1_pre_notify_demote_0 arc-tkincaidlx.wsicorp.com" [ style = bold] "ms_drbd_7788_pre_notify_demote_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_7788_pre_notify_promote_0" -> "ms_drbd_7788_confirmed-pre_notify_promote_0" [ style = bold] "ms_drbd_7788_pre_notify_promote_0" -> "rsc_drbd_7788:1_pre_notify_promote_0 arc-tkincaidlx.wsicorp.com" [ style = bold] "ms_drbd_7788_pre_notify_promote_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_7788_pre_notify_start_0" -> "ms_drbd_7788_confirmed-pre_notify_start_0" [ style = bold] "ms_drbd_7788_pre_notify_start_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_7788_pre_notify_stop_0" -> "ms_drbd_7788_confirmed-pre_notify_stop_0" [ style = bold] "ms_drbd_7788_pre_notify_stop_0" -> "rsc_drbd_7788:0_pre_notify_stop_0 arc-dknightlx" [ style = bold] "ms_drbd_7788_pre_notify_stop_0" -> "rsc_drbd_7788:1_pre_notify_stop_0 arc-tkincaidlx.wsicorp.com" [ style = bold] "ms_drbd_7788_pre_notify_stop_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_7788_promote_0" -> "rsc_drbd_7788:1_promote_0 arc-tkincaidlx.wsicorp.com" [ style = bold] "ms_drbd_7788_promote_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_7788_promoted_0" -> "grp_pgsql_mirror_start_0" [ style = bold] "ms_drbd_7788_promoted_0" -> "ms_drbd_7788_post_notify_promoted_0" [ style = bold] "ms_drbd_7788_promoted_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_7788_running_0" -> "ms_drbd_7788_post_notify_running_0" [ style = bold] "ms_drbd_7788_running_0" -> "ms_drbd_7788_promote_0" [ style = bold] "ms_drbd_7788_running_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_7788_start_0" -> "ms_drbd_7788_promote_0" [ style = bold] "ms_drbd_7788_start_0" -> "ms_drbd_7788_running_0" [ style = bold] "ms_drbd_7788_start_0" -> "rsc_drbd_7788:1_start_0 arc-tkincaidlx.wsicorp.com" [ style = bold] "ms_drbd_7788_start_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_7788_stop_0" -> "ms_drbd_7788_start_0" [ style = bold] "ms_drbd_7788_stop_0" -> "ms_drbd_7788_stopped_0" [ style = bold] "ms_drbd_7788_stop_0" -> "rsc_drbd_7788:0_stop_0 arc-dknightlx" [ style = bold] "ms_drbd_7788_stop_0" -> "rsc_drbd_7788:1_stop_0 arc-tkincaidlx.wsicorp.com" [ style = bold] "ms_drbd_7788_stop_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_7788_stopped_0" -> "ms_drbd_7788_post_notify_stopped_0" [ style = bold] "ms_drbd_7788_stopped_0" -> "ms_drbd_7788_promote_0" [ style = bold] "ms_drbd_7788_stopped_0" -> "ms_drbd_7788_start_0" [ style = bold] "ms_drbd_7788_stopped_0" [ style=bold color="green" fontcolor="orange" ] "pgsql_5555_monitor_30000 arc-tkincaidlx.wsicorp.com" [ style=bold color="green" fontcolor="black" ] "pgsql_5555_start_0 arc-tkincaidlx.wsicorp.com" -> "IPaddr_147_81_84_133_start_0 arc-tkincaidlx.wsicorp.com" [ style = bold] "pgsql_5555_start_0 arc-tkincaidlx.wsicorp.com" -> "grp_pgsql_mirror_running_0" [ style = bold] "pgsql_5555_start_0 arc-tkincaidlx.wsicorp.com" -> "pgsql_5555_monitor_30000 arc-tkincaidlx.wsicorp.com" [ style = bold] "pgsql_5555_start_0 arc-tkincaidlx.wsicorp.com" [ style=bold color="green" fontcolor="black" ] "pgsql_5555_stop_0 arc-tkincaidlx.wsicorp.com" -> "all_stopped" [ style = bold] "pgsql_5555_stop_0 arc-tkincaidlx.wsicorp.com" -> "fs_mirror_stop_0 arc-tkincaidlx.wsicorp.com" [ style = bold] "pgsql_5555_stop_0 arc-tkincaidlx.wsicorp.com" -> "grp_pgsql_mirror_stopped_0" [ style = bold] "pgsql_5555_stop_0 arc-tkincaidlx.wsicorp.com" -> "pgsql_5555_start_0 arc-tkincaidlx.wsicorp.com" [ style = bold] "pgsql_5555_stop_0 arc-tkincaidlx.wsicorp.com" [ style=bold color="green" fontcolor="black" ] "rsc_drbd_7788:0_post_notify_demote_0 arc-dknightlx" -> "ms_drbd_7788_confirmed-post_notify_demoted_0" [ style = bold] "rsc_drbd_7788:0_post_notify_demote_0 arc-dknightlx" [ style=bold color="green" fontcolor="black" ] "rsc_drbd_7788:0_pre_notify_demote_0 arc-dknightlx" -> "ms_drbd_7788_confirmed-pre_notify_demote_0" [ style = bold] "rsc_drbd_7788:0_pre_notify_demote_0 arc-dknightlx" [ style=bold color="green" fontcolor="black" ] "rsc_drbd_7788:0_pre_notify_stop_0 arc-dknightlx" -> "ms_drbd_7788_confirmed-pre_notify_stop_0" [ style = bold] "rsc_drbd_7788:0_pre_notify_stop_0 arc-dknightlx" [ style=bold color="green" fontcolor="black" ] "rsc_drbd_7788:0_stop_0 arc-dknightlx" -> "all_stopped" [ style = bold] "rsc_drbd_7788:0_stop_0 arc-dknightlx" -> "do_shutdown arc-dknightlx" [ style = bold] "rsc_drbd_7788:0_stop_0 arc-dknightlx" -> "ms_drbd_7788_stopped_0" [ style = bold] "rsc_drbd_7788:0_stop_0 arc-dknightlx" [ style=bold color="green" fontcolor="black" ] "rsc_drbd_7788:1_demote_0 arc-tkincaidlx.wsicorp.com" -> "ms_drbd_7788_demoted_0" [ style = bold] "rsc_drbd_7788:1_demote_0 arc-tkincaidlx.wsicorp.com" -> "rsc_drbd_7788:1_promote_0 arc-tkincaidlx.wsicorp.com" [ style = bold] "rsc_drbd_7788:1_demote_0 arc-tkincaidlx.wsicorp.com" -> "rsc_drbd_7788:1_stop_0 arc-tkincaidlx.wsicorp.com" [ style = bold] "rsc_drbd_7788:1_demote_0 arc-tkincaidlx.wsicorp.com" [ style=bold color="green" fontcolor="black" ] "rsc_drbd_7788:1_post_notify_demote_0 arc-tkincaidlx.wsicorp.com" -> "ms_drbd_7788_confirmed-post_notify_demoted_0" [ style = bold] "rsc_drbd_7788:1_post_notify_demote_0 arc-tkincaidlx.wsicorp.com" [ style=bold color="green" fontcolor="black" ] "rsc_drbd_7788:1_post_notify_promote_0 arc-tkincaidlx.wsicorp.com" -> "ms_drbd_7788_confirmed-post_notify_promoted_0" [ style = bold] "rsc_drbd_7788:1_post_notify_promote_0 arc-tkincaidlx.wsicorp.com" [ style=bold color="green" fontcolor="black" ] "rsc_drbd_7788:1_post_notify_start_0 arc-tkincaidlx.wsicorp.com" -> "ms_drbd_7788_confirmed-post_notify_running_0" [ style = bold] "rsc_drbd_7788:1_post_notify_start_0 arc-tkincaidlx.wsicorp.com" [ style=bold color="green" fontcolor="black" ] "rsc_drbd_7788:1_pre_notify_demote_0 arc-tkincaidlx.wsicorp.com" -> "ms_drbd_7788_confirmed-pre_notify_demote_0" [ style = bold] "rsc_drbd_7788:1_pre_notify_demote_0 arc-tkincaidlx.wsicorp.com" [ style=bold color="green" fontcolor="black" ] "rsc_drbd_7788:1_pre_notify_promote_0 arc-tkincaidlx.wsicorp.com" -> "ms_drbd_7788_confirmed-pre_notify_promote_0" [ style = bold] "rsc_drbd_7788:1_pre_notify_promote_0 arc-tkincaidlx.wsicorp.com" [ style=bold color="green" fontcolor="black" ] "rsc_drbd_7788:1_pre_notify_stop_0 arc-tkincaidlx.wsicorp.com" -> "ms_drbd_7788_confirmed-pre_notify_stop_0" [ style = bold] "rsc_drbd_7788:1_pre_notify_stop_0 arc-tkincaidlx.wsicorp.com" [ style=bold color="green" fontcolor="black" ] +"rsc_drbd_7788:1_promote_0 arc-tkincaidlx.wsicorp.com" -> "grp_pgsql_mirror_start_0" [ style = bold] "rsc_drbd_7788:1_promote_0 arc-tkincaidlx.wsicorp.com" -> "ms_drbd_7788_promoted_0" [ style = bold] "rsc_drbd_7788:1_promote_0 arc-tkincaidlx.wsicorp.com" [ style=bold color="green" fontcolor="black" ] "rsc_drbd_7788:1_start_0 arc-tkincaidlx.wsicorp.com" -> "ms_drbd_7788_running_0" [ style = bold] "rsc_drbd_7788:1_start_0 arc-tkincaidlx.wsicorp.com" -> "rsc_drbd_7788:1_promote_0 arc-tkincaidlx.wsicorp.com" [ style = bold] "rsc_drbd_7788:1_start_0 arc-tkincaidlx.wsicorp.com" [ style=bold color="green" fontcolor="black" ] "rsc_drbd_7788:1_stop_0 arc-tkincaidlx.wsicorp.com" -> "all_stopped" [ style = bold] "rsc_drbd_7788:1_stop_0 arc-tkincaidlx.wsicorp.com" -> "ms_drbd_7788_stopped_0" [ style = bold] "rsc_drbd_7788:1_stop_0 arc-tkincaidlx.wsicorp.com" -> "rsc_drbd_7788:1_start_0 arc-tkincaidlx.wsicorp.com" [ style = bold] "rsc_drbd_7788:1_stop_0 arc-tkincaidlx.wsicorp.com" [ style=bold color="green" fontcolor="black" ] } diff --git a/pengine/test10/bug-1572-1.exp b/pengine/test10/bug-1572-1.exp index 274b2d61bd..6659f664cc 100644 --- a/pengine/test10/bug-1572-1.exp +++ b/pengine/test10/bug-1572-1.exp @@ -1,809 +1,812 @@ + + + diff --git a/pengine/test10/migrate-start-complex.dot b/pengine/test10/migrate-start-complex.dot index 561495818f..f065bf6001 100644 --- a/pengine/test10/migrate-start-complex.dot +++ b/pengine/test10/migrate-start-complex.dot @@ -1,57 +1,57 @@ digraph "g" { "all_stopped" [ style=bold color="green" fontcolor="orange" ] "bottom:0_monitor_0 dom0-02" -> "probe_complete dom0-02" [ style = bold] "bottom:0_monitor_0 dom0-02" [ style=bold color="green" fontcolor="black" ] "bottom:0_start_0 dom0-02" -> "clone-bottom_running_0" [ style = bold] "bottom:0_start_0 dom0-02" [ style=bold color="green" fontcolor="black" ] "bottom:1_monitor_0 dom0-01" -> "probe_complete dom0-01" [ style = bold] "bottom:1_monitor_0 dom0-01" [ style=bold color="green" fontcolor="black" ] "bottom:1_start_0 dom0-01" -> "clone-bottom_running_0" [ style = bold] "bottom:1_start_0 dom0-01" -> "domU-test01_migrate_from_0 dom0-01" [ style = bold] "bottom:1_start_0 dom0-01" -> "domU-test01_migrate_to_0 dom0-02" [ style = bold] "bottom:1_start_0 dom0-01" [ style=bold color="green" fontcolor="black" ] "clone-bottom_running_0" -> "domU-test01_migrate_from_0 dom0-01" [ style = bold] "clone-bottom_running_0" -> "domU-test01_migrate_to_0 dom0-02" [ style = bold] "clone-bottom_running_0" [ style=bold color="green" fontcolor="orange" ] "clone-bottom_start_0" -> "bottom:0_start_0 dom0-02" [ style = bold] "clone-bottom_start_0" -> "bottom:1_start_0 dom0-01" [ style = bold] "clone-bottom_start_0" -> "clone-bottom_running_0" [ style = bold] "clone-bottom_start_0" [ style=bold color="green" fontcolor="orange" ] "clone-bottom_stop_0" -> "clone-bottom_start_0" [ style = bold] "clone-bottom_stop_0" [ style=bold color="green" fontcolor="orange" ] "clone-dom0-iscsi1_running_0" -> "domU-test01_migrate_from_0 dom0-01" [ style = bold] "clone-dom0-iscsi1_running_0" -> "domU-test01_migrate_to_0 dom0-02" [ style = bold] "clone-dom0-iscsi1_running_0" [ style=bold color="green" fontcolor="orange" ] "clone-dom0-iscsi1_start_0" -> "clone-dom0-iscsi1_running_0" [ style = bold] "clone-dom0-iscsi1_start_0" -> "dom0-iscsi1:1_start_0" [ style = bold] "clone-dom0-iscsi1_start_0" [ style=bold color="green" fontcolor="orange" ] "dom0-iscsi1-cnx1:1_start_0 dom0-01" -> "dom0-iscsi1:1_running_0" [ style = bold] "dom0-iscsi1-cnx1:1_start_0 dom0-01" [ style=bold color="green" fontcolor="black" ] "dom0-iscsi1:1_running_0" -> "clone-dom0-iscsi1_running_0" [ style = bold] +"dom0-iscsi1:1_running_0" -> "domU-test01_migrate_from_0 dom0-01" [ style = bold] +"dom0-iscsi1:1_running_0" -> "domU-test01_migrate_to_0 dom0-02" [ style = bold] "dom0-iscsi1:1_running_0" [ style=bold color="green" fontcolor="orange" ] "dom0-iscsi1:1_start_0" -> "dom0-iscsi1-cnx1:1_start_0 dom0-01" [ style = bold] "dom0-iscsi1:1_start_0" -> "dom0-iscsi1:1_running_0" [ style = bold] -"dom0-iscsi1:1_start_0" -> "domU-test01_migrate_from_0 dom0-01" [ style = bold] -"dom0-iscsi1:1_start_0" -> "domU-test01_migrate_to_0 dom0-02" [ style = bold] "dom0-iscsi1:1_start_0" [ style=bold color="green" fontcolor="orange" ] "domU-test01_migrate_from_0 dom0-01" -> "all_stopped" [ style = bold] "domU-test01_migrate_from_0 dom0-01" -> "top_start_0 dom0-01" [ style = bold] "domU-test01_migrate_from_0 dom0-01" [ style=bold color="green" fontcolor="black" ] "domU-test01_migrate_to_0 dom0-02" -> "all_stopped" [ style = bold] "domU-test01_migrate_to_0 dom0-02" -> "domU-test01_migrate_from_0 dom0-01" [ style = bold] "domU-test01_migrate_to_0 dom0-02" [ style=bold color="green" fontcolor="black" ] "probe_complete dom0-01" -> "probe_complete" [ style = bold] "probe_complete dom0-01" [ style=bold color="green" fontcolor="black" ] "probe_complete dom0-02" -> "probe_complete" [ style = bold] "probe_complete dom0-02" [ style=bold color="green" fontcolor="black" ] "probe_complete" -> "bottom:0_start_0 dom0-02" [ style = bold] "probe_complete" -> "bottom:1_start_0 dom0-01" [ style = bold] "probe_complete" -> "clone-bottom_start_0" [ style = bold] "probe_complete" -> "clone-bottom_stop_0" [ style = bold] "probe_complete" [ style=bold color="green" fontcolor="orange" ] "top_start_0 dom0-01" [ style=bold color="green" fontcolor="black" ] "top_stop_0 dom0-02" -> "all_stopped" [ style = bold] "top_stop_0 dom0-02" -> "domU-test01_migrate_to_0 dom0-02" [ style = bold] "top_stop_0 dom0-02" -> "top_start_0 dom0-01" [ style = bold] "top_stop_0 dom0-02" [ style=bold color="green" fontcolor="black" ] } diff --git a/pengine/test10/migrate-start-complex.exp b/pengine/test10/migrate-start-complex.exp index 593a821ca2..4d752c4b08 100644 --- a/pengine/test10/migrate-start-complex.exp +++ b/pengine/test10/migrate-start-complex.exp @@ -1,293 +1,293 @@ - + - + diff --git a/pengine/test10/migrate-start.dot b/pengine/test10/migrate-start.dot index a164ff795b..1b1086e826 100644 --- a/pengine/test10/migrate-start.dot +++ b/pengine/test10/migrate-start.dot @@ -1,23 +1,23 @@ digraph "g" { "all_stopped" [ style=bold color="green" fontcolor="orange" ] "clone-dom0-iscsi1_running_0" -> "domU-test01_migrate_from_0 dom0-01" [ style = bold] "clone-dom0-iscsi1_running_0" -> "domU-test01_migrate_to_0 dom0-02" [ style = bold] "clone-dom0-iscsi1_running_0" [ style=bold color="green" fontcolor="orange" ] "clone-dom0-iscsi1_start_0" -> "clone-dom0-iscsi1_running_0" [ style = bold] "clone-dom0-iscsi1_start_0" -> "dom0-iscsi1:1_start_0" [ style = bold] "clone-dom0-iscsi1_start_0" [ style=bold color="green" fontcolor="orange" ] "dom0-iscsi1-cnx1:1_start_0 dom0-01" -> "dom0-iscsi1:1_running_0" [ style = bold] "dom0-iscsi1-cnx1:1_start_0 dom0-01" [ style=bold color="green" fontcolor="black" ] "dom0-iscsi1:1_running_0" -> "clone-dom0-iscsi1_running_0" [ style = bold] +"dom0-iscsi1:1_running_0" -> "domU-test01_migrate_from_0 dom0-01" [ style = bold] +"dom0-iscsi1:1_running_0" -> "domU-test01_migrate_to_0 dom0-02" [ style = bold] "dom0-iscsi1:1_running_0" [ style=bold color="green" fontcolor="orange" ] "dom0-iscsi1:1_start_0" -> "dom0-iscsi1-cnx1:1_start_0 dom0-01" [ style = bold] "dom0-iscsi1:1_start_0" -> "dom0-iscsi1:1_running_0" [ style = bold] -"dom0-iscsi1:1_start_0" -> "domU-test01_migrate_from_0 dom0-01" [ style = bold] -"dom0-iscsi1:1_start_0" -> "domU-test01_migrate_to_0 dom0-02" [ style = bold] "dom0-iscsi1:1_start_0" [ style=bold color="green" fontcolor="orange" ] "domU-test01_migrate_from_0 dom0-01" -> "all_stopped" [ style = bold] "domU-test01_migrate_from_0 dom0-01" [ style=bold color="green" fontcolor="black" ] "domU-test01_migrate_to_0 dom0-02" -> "all_stopped" [ style = bold] "domU-test01_migrate_to_0 dom0-02" -> "domU-test01_migrate_from_0 dom0-01" [ style = bold] "domU-test01_migrate_to_0 dom0-02" [ style=bold color="green" fontcolor="black" ] } diff --git a/pengine/test10/migrate-start.exp b/pengine/test10/migrate-start.exp index 4a64c89f22..81dd6c289e 100644 --- a/pengine/test10/migrate-start.exp +++ b/pengine/test10/migrate-start.exp @@ -1,116 +1,116 @@ - + - + diff --git a/pengine/test10/migrate-stop_start.dot b/pengine/test10/migrate-stop_start.dot index ced9d982db..738b5e8a3d 100644 --- a/pengine/test10/migrate-stop_start.dot +++ b/pengine/test10/migrate-stop_start.dot @@ -1,38 +1,39 @@ digraph "g" { "all_stopped" [ style=bold color="green" fontcolor="orange" ] "clone-dom0-iscsi1_running_0" -> "domU-test01_start_0 dom0-01" [ style = bold] "clone-dom0-iscsi1_running_0" [ style=bold color="green" fontcolor="orange" ] "clone-dom0-iscsi1_start_0" -> "clone-dom0-iscsi1_running_0" [ style = bold] "clone-dom0-iscsi1_start_0" -> "dom0-iscsi1:0_start_0" [ style = bold] "clone-dom0-iscsi1_start_0" [ style=bold color="green" fontcolor="orange" ] "clone-dom0-iscsi1_stop_0" -> "clone-dom0-iscsi1_start_0" [ style = bold] "clone-dom0-iscsi1_stop_0" -> "clone-dom0-iscsi1_stopped_0" [ style = bold] "clone-dom0-iscsi1_stop_0" -> "dom0-iscsi1:0_stop_0" [ style = bold] "clone-dom0-iscsi1_stop_0" [ style=bold color="green" fontcolor="orange" ] "clone-dom0-iscsi1_stopped_0" -> "clone-dom0-iscsi1_start_0" [ style = bold] "clone-dom0-iscsi1_stopped_0" [ style=bold color="green" fontcolor="orange" ] "dom0-iscsi1-cnx1:0_start_0 dom0-01" -> "dom0-iscsi1:0_running_0" [ style = bold] "dom0-iscsi1-cnx1:0_start_0 dom0-01" [ style=bold color="green" fontcolor="black" ] "dom0-iscsi1-cnx1:0_stop_0 dom0-02" -> "all_stopped" [ style = bold] "dom0-iscsi1-cnx1:0_stop_0 dom0-02" -> "dom0-iscsi1-cnx1:0_start_0 dom0-01" [ style = bold] "dom0-iscsi1-cnx1:0_stop_0 dom0-02" -> "dom0-iscsi1:0_stopped_0" [ style = bold] "dom0-iscsi1-cnx1:0_stop_0 dom0-02" [ style=bold color="green" fontcolor="black" ] "dom0-iscsi1:0_running_0" -> "clone-dom0-iscsi1_running_0" [ style = bold] +"dom0-iscsi1:0_running_0" -> "domU-test01_start_0 dom0-01" [ style = bold] "dom0-iscsi1:0_running_0" [ style=bold color="green" fontcolor="orange" ] "dom0-iscsi1:0_start_0" -> "dom0-iscsi1-cnx1:0_start_0 dom0-01" [ style = bold] "dom0-iscsi1:0_start_0" -> "dom0-iscsi1:0_running_0" [ style = bold] "dom0-iscsi1:0_start_0" [ style=bold color="green" fontcolor="orange" ] "dom0-iscsi1:0_stop_0" -> "dom0-iscsi1-cnx1:0_stop_0 dom0-02" [ style = bold] "dom0-iscsi1:0_stop_0" -> "dom0-iscsi1:0_start_0" [ style = bold] "dom0-iscsi1:0_stop_0" -> "dom0-iscsi1:0_stopped_0" [ style = bold] "dom0-iscsi1:0_stop_0" [ style=bold color="green" fontcolor="orange" ] "dom0-iscsi1:0_stopped_0" -> "clone-dom0-iscsi1_stopped_0" [ style = bold] "dom0-iscsi1:0_stopped_0" -> "dom0-iscsi1:0_start_0" [ style = bold] "dom0-iscsi1:0_stopped_0" [ style=bold color="green" fontcolor="orange" ] "domU-test01_start_0 dom0-01" [ style=bold color="green" fontcolor="black" ] "domU-test01_stop_0 dom0-02" -> "all_stopped" [ style = bold] "domU-test01_stop_0 dom0-02" -> "clone-dom0-iscsi1_stop_0" [ style = bold] "domU-test01_stop_0 dom0-02" -> "dom0-iscsi1:0_stop_0" [ style = bold] "domU-test01_stop_0 dom0-02" -> "domU-test01_start_0 dom0-01" [ style = bold] "domU-test01_stop_0 dom0-02" [ style=bold color="green" fontcolor="black" ] } diff --git a/pengine/test10/migrate-stop_start.exp b/pengine/test10/migrate-stop_start.exp index 2bd2729a34..cae086914e 100644 --- a/pengine/test10/migrate-stop_start.exp +++ b/pengine/test10/migrate-stop_start.exp @@ -1,192 +1,195 @@ + + + diff --git a/pengine/test10/novell-252693-3.dot b/pengine/test10/novell-252693-3.dot index 07cd03d999..716c4775ec 100644 --- a/pengine/test10/novell-252693-3.dot +++ b/pengine/test10/novell-252693-3.dot @@ -1,172 +1,173 @@ digraph "g" { "all_stopped" [ style=bold color="green" fontcolor="orange" ] "configstoreclone:0_post_notify_start_0 node2" -> "configstorecloneset_confirmed-post_notify_running_0" [ style = bold] "configstoreclone:0_post_notify_start_0 node2" [ style=bold color="green" fontcolor="black" ] "configstoreclone:0_pre_notify_start_0 node2" -> "configstorecloneset_confirmed-pre_notify_start_0" [ style = bold] "configstoreclone:0_pre_notify_start_0 node2" [ style=bold color="green" fontcolor="black" ] "configstoreclone:1_monitor_0 node1" -> "probe_complete node1" [ style = bold] "configstoreclone:1_monitor_0 node1" [ style=bold color="green" fontcolor="black" ] "configstoreclone:1_monitor_20000 node1" [ style=bold color="green" fontcolor="black" ] "configstoreclone:1_post_notify_start_0 node1" -> "configstorecloneset_confirmed-post_notify_running_0" [ style = bold] "configstoreclone:1_post_notify_start_0 node1" [ style=bold color="green" fontcolor="black" ] "configstoreclone:1_start_0 node1" -> "configstoreclone:1_monitor_20000 node1" [ style = bold] "configstoreclone:1_start_0 node1" -> "configstorecloneset_running_0" [ style = bold] "configstoreclone:1_start_0 node1" -> "sles10_start_0 node1" [ style = bold] "configstoreclone:1_start_0 node1" [ style=bold color="green" fontcolor="black" ] "configstorecloneset_confirmed-post_notify_running_0" -> "configstoreclone:1_monitor_20000 node1" [ style = bold] "configstorecloneset_confirmed-post_notify_running_0" -> "sles10_start_0 node1" [ style = bold] "configstorecloneset_confirmed-post_notify_running_0" [ style=bold color="green" fontcolor="orange" ] "configstorecloneset_confirmed-pre_notify_start_0" -> "configstorecloneset_post_notify_running_0" [ style = bold] "configstorecloneset_confirmed-pre_notify_start_0" -> "configstorecloneset_start_0" [ style = bold] "configstorecloneset_confirmed-pre_notify_start_0" [ style=bold color="green" fontcolor="orange" ] "configstorecloneset_post_notify_running_0" -> "configstoreclone:0_post_notify_start_0 node2" [ style = bold] "configstorecloneset_post_notify_running_0" -> "configstoreclone:1_post_notify_start_0 node1" [ style = bold] "configstorecloneset_post_notify_running_0" -> "configstorecloneset_confirmed-post_notify_running_0" [ style = bold] "configstorecloneset_post_notify_running_0" [ style=bold color="green" fontcolor="orange" ] "configstorecloneset_pre_notify_start_0" -> "configstoreclone:0_pre_notify_start_0 node2" [ style = bold] "configstorecloneset_pre_notify_start_0" -> "configstorecloneset_confirmed-pre_notify_start_0" [ style = bold] "configstorecloneset_pre_notify_start_0" [ style=bold color="green" fontcolor="orange" ] "configstorecloneset_running_0" -> "configstorecloneset_post_notify_running_0" [ style = bold] "configstorecloneset_running_0" -> "sles10_start_0 node1" [ style = bold] "configstorecloneset_running_0" [ style=bold color="green" fontcolor="orange" ] "configstorecloneset_start_0" -> "configstoreclone:1_start_0 node1" [ style = bold] "configstorecloneset_start_0" -> "configstorecloneset_running_0" [ style = bold] "configstorecloneset_start_0" [ style=bold color="green" fontcolor="orange" ] "evmsclone:0_post_notify_start_0 node2" -> "evmscloneset_confirmed-post_notify_running_0" [ style = bold] "evmsclone:0_post_notify_start_0 node2" [ style=bold color="green" fontcolor="black" ] "evmsclone:0_pre_notify_start_0 node2" -> "evmscloneset_confirmed-pre_notify_start_0" [ style = bold] "evmsclone:0_pre_notify_start_0 node2" [ style=bold color="green" fontcolor="black" ] "evmsclone:1_monitor_0 node1" -> "probe_complete node1" [ style = bold] "evmsclone:1_monitor_0 node1" [ style=bold color="green" fontcolor="black" ] "evmsclone:1_post_notify_start_0 node1" -> "evmscloneset_confirmed-post_notify_running_0" [ style = bold] "evmsclone:1_post_notify_start_0 node1" [ style=bold color="green" fontcolor="black" ] "evmsclone:1_start_0 node1" -> "evmscloneset_running_0" [ style = bold] "evmsclone:1_start_0 node1" [ style=bold color="green" fontcolor="black" ] "evmscloneset_confirmed-post_notify_running_0" -> "configstorecloneset_start_0" [ style = bold] "evmscloneset_confirmed-post_notify_running_0" -> "imagestorecloneset_start_0" [ style = bold] "evmscloneset_confirmed-post_notify_running_0" [ style=bold color="green" fontcolor="orange" ] "evmscloneset_confirmed-pre_notify_start_0" -> "evmscloneset_post_notify_running_0" [ style = bold] "evmscloneset_confirmed-pre_notify_start_0" -> "evmscloneset_start_0" [ style = bold] "evmscloneset_confirmed-pre_notify_start_0" [ style=bold color="green" fontcolor="orange" ] "evmscloneset_post_notify_running_0" -> "evmsclone:0_post_notify_start_0 node2" [ style = bold] "evmscloneset_post_notify_running_0" -> "evmsclone:1_post_notify_start_0 node1" [ style = bold] "evmscloneset_post_notify_running_0" -> "evmscloneset_confirmed-post_notify_running_0" [ style = bold] "evmscloneset_post_notify_running_0" [ style=bold color="green" fontcolor="orange" ] "evmscloneset_pre_notify_start_0" -> "evmsclone:0_pre_notify_start_0 node2" [ style = bold] "evmscloneset_pre_notify_start_0" -> "evmscloneset_confirmed-pre_notify_start_0" [ style = bold] "evmscloneset_pre_notify_start_0" [ style=bold color="green" fontcolor="orange" ] "evmscloneset_running_0" -> "configstorecloneset_start_0" [ style = bold] "evmscloneset_running_0" -> "evmscloneset_post_notify_running_0" [ style = bold] "evmscloneset_running_0" -> "imagestorecloneset_start_0" [ style = bold] "evmscloneset_running_0" [ style=bold color="green" fontcolor="orange" ] "evmscloneset_start_0" -> "evmsclone:1_start_0 node1" [ style = bold] "evmscloneset_start_0" -> "evmscloneset_running_0" [ style = bold] "evmscloneset_start_0" [ style=bold color="green" fontcolor="orange" ] "evmsdclone:1_monitor_0 node1" -> "probe_complete node1" [ style = bold] "evmsdclone:1_monitor_0 node1" [ style=bold color="green" fontcolor="black" ] "evmsdclone:1_monitor_5000 node1" [ style=bold color="green" fontcolor="black" ] "evmsdclone:1_start_0 node1" -> "evmsdclone:1_monitor_5000 node1" [ style = bold] "evmsdclone:1_start_0 node1" -> "evmsdcloneset_running_0" [ style = bold] "evmsdclone:1_start_0 node1" [ style=bold color="green" fontcolor="black" ] "evmsdcloneset_running_0" -> "evmscloneset_start_0" [ style = bold] "evmsdcloneset_running_0" [ style=bold color="green" fontcolor="orange" ] "evmsdcloneset_start_0" -> "evmsdclone:1_start_0 node1" [ style = bold] "evmsdcloneset_start_0" -> "evmsdcloneset_running_0" [ style = bold] "evmsdcloneset_start_0" [ style=bold color="green" fontcolor="orange" ] "imagestoreclone:0_monitor_0 node1" -> "probe_complete node1" [ style = bold] "imagestoreclone:0_monitor_0 node1" [ style=bold color="green" fontcolor="black" ] "imagestoreclone:0_monitor_20000 node1" [ style=bold color="green" fontcolor="black" ] "imagestoreclone:0_post_notify_start_0 node1" -> "imagestorecloneset_confirmed-post_notify_running_0" [ style = bold] "imagestoreclone:0_post_notify_start_0 node1" [ style=bold color="green" fontcolor="black" ] "imagestoreclone:0_pre_notify_stop_0 node2" -> "imagestorecloneset_confirmed-pre_notify_stop_0" [ style = bold] "imagestoreclone:0_pre_notify_stop_0 node2" [ style=bold color="green" fontcolor="black" ] "imagestoreclone:0_start_0 node1" -> "imagestoreclone:0_monitor_20000 node1" [ style = bold] "imagestoreclone:0_start_0 node1" -> "imagestorecloneset_running_0" [ style = bold] +"imagestoreclone:0_start_0 node1" -> "sles10_start_0 node1" [ style = bold] "imagestoreclone:0_start_0 node1" [ style=bold color="green" fontcolor="black" ] "imagestoreclone:0_stop_0 node2" -> "all_stopped" [ style = bold] "imagestoreclone:0_stop_0 node2" -> "imagestoreclone:0_start_0 node1" [ style = bold] "imagestoreclone:0_stop_0 node2" -> "imagestorecloneset_stopped_0" [ style = bold] "imagestoreclone:0_stop_0 node2" [ style=bold color="green" fontcolor="black" ] "imagestoreclone:1_monitor_20000 node2" [ style=bold color="green" fontcolor="black" ] "imagestoreclone:1_post_notify_start_0 node2" -> "imagestorecloneset_confirmed-post_notify_running_0" [ style = bold] "imagestoreclone:1_post_notify_start_0 node2" [ style=bold color="green" fontcolor="black" ] "imagestoreclone:1_start_0 node2" -> "imagestoreclone:1_monitor_20000 node2" [ style = bold] "imagestoreclone:1_start_0 node2" -> "imagestorecloneset_running_0" [ style = bold] "imagestoreclone:1_start_0 node2" [ style=bold color="green" fontcolor="black" ] "imagestorecloneset_confirmed-post_notify_running_0" -> "imagestoreclone:0_monitor_20000 node1" [ style = bold] "imagestorecloneset_confirmed-post_notify_running_0" -> "imagestoreclone:1_monitor_20000 node2" [ style = bold] "imagestorecloneset_confirmed-post_notify_running_0" -> "sles10_start_0 node1" [ style = bold] "imagestorecloneset_confirmed-post_notify_running_0" [ style=bold color="green" fontcolor="orange" ] "imagestorecloneset_confirmed-post_notify_stopped_0" -> "all_stopped" [ style = bold] "imagestorecloneset_confirmed-post_notify_stopped_0" -> "imagestorecloneset_pre_notify_start_0" [ style = bold] "imagestorecloneset_confirmed-post_notify_stopped_0" [ style=bold color="green" fontcolor="orange" ] "imagestorecloneset_confirmed-pre_notify_start_0" -> "imagestorecloneset_post_notify_running_0" [ style = bold] "imagestorecloneset_confirmed-pre_notify_start_0" -> "imagestorecloneset_start_0" [ style = bold] "imagestorecloneset_confirmed-pre_notify_start_0" [ style=bold color="green" fontcolor="orange" ] "imagestorecloneset_confirmed-pre_notify_stop_0" -> "imagestorecloneset_post_notify_stopped_0" [ style = bold] "imagestorecloneset_confirmed-pre_notify_stop_0" -> "imagestorecloneset_stop_0" [ style = bold] "imagestorecloneset_confirmed-pre_notify_stop_0" [ style=bold color="green" fontcolor="orange" ] "imagestorecloneset_post_notify_running_0" -> "imagestoreclone:0_post_notify_start_0 node1" [ style = bold] "imagestorecloneset_post_notify_running_0" -> "imagestoreclone:1_post_notify_start_0 node2" [ style = bold] "imagestorecloneset_post_notify_running_0" -> "imagestorecloneset_confirmed-post_notify_running_0" [ style = bold] "imagestorecloneset_post_notify_running_0" [ style=bold color="green" fontcolor="orange" ] "imagestorecloneset_post_notify_stopped_0" -> "imagestorecloneset_confirmed-post_notify_stopped_0" [ style = bold] "imagestorecloneset_post_notify_stopped_0" [ style=bold color="green" fontcolor="orange" ] "imagestorecloneset_pre_notify_start_0" -> "imagestorecloneset_confirmed-pre_notify_start_0" [ style = bold] "imagestorecloneset_pre_notify_start_0" [ style=bold color="green" fontcolor="orange" ] "imagestorecloneset_pre_notify_stop_0" -> "imagestoreclone:0_pre_notify_stop_0 node2" [ style = bold] "imagestorecloneset_pre_notify_stop_0" -> "imagestorecloneset_confirmed-pre_notify_stop_0" [ style = bold] "imagestorecloneset_pre_notify_stop_0" [ style=bold color="green" fontcolor="orange" ] "imagestorecloneset_running_0" -> "imagestorecloneset_post_notify_running_0" [ style = bold] "imagestorecloneset_running_0" -> "sles10_start_0 node1" [ style = bold] "imagestorecloneset_running_0" [ style=bold color="green" fontcolor="orange" ] "imagestorecloneset_start_0" -> "imagestoreclone:0_start_0 node1" [ style = bold] "imagestorecloneset_start_0" -> "imagestoreclone:1_start_0 node2" [ style = bold] "imagestorecloneset_start_0" -> "imagestorecloneset_running_0" [ style = bold] "imagestorecloneset_start_0" [ style=bold color="green" fontcolor="orange" ] "imagestorecloneset_stop_0" -> "imagestoreclone:0_stop_0 node2" [ style = bold] "imagestorecloneset_stop_0" -> "imagestorecloneset_start_0" [ style = bold] "imagestorecloneset_stop_0" -> "imagestorecloneset_stopped_0" [ style = bold] "imagestorecloneset_stop_0" [ style=bold color="green" fontcolor="orange" ] "imagestorecloneset_stopped_0" -> "imagestorecloneset_post_notify_stopped_0" [ style = bold] "imagestorecloneset_stopped_0" -> "imagestorecloneset_start_0" [ style = bold] "imagestorecloneset_stopped_0" [ style=bold color="green" fontcolor="orange" ] "probe_complete node1" -> "probe_complete" [ style = bold] "probe_complete node1" [ style=bold color="green" fontcolor="black" ] "probe_complete" -> "configstoreclone:1_start_0 node1" [ style = bold] "probe_complete" -> "configstorecloneset_start_0" [ style = bold] "probe_complete" -> "evmsclone:1_start_0 node1" [ style = bold] "probe_complete" -> "evmscloneset_start_0" [ style = bold] "probe_complete" -> "evmsdclone:1_start_0 node1" [ style = bold] "probe_complete" -> "evmsdcloneset_start_0" [ style = bold] "probe_complete" -> "imagestoreclone:0_start_0 node1" [ style = bold] "probe_complete" -> "imagestoreclone:0_stop_0 node2" [ style = bold] "probe_complete" -> "imagestoreclone:1_start_0 node2" [ style = bold] "probe_complete" -> "imagestorecloneset_start_0" [ style = bold] "probe_complete" -> "imagestorecloneset_stop_0" [ style = bold] "probe_complete" -> "sles10_start_0 node1" [ style = bold] "probe_complete" -> "sles10_stop_0 node2" [ style = bold] "probe_complete" -> "stonithclone:1_start_0 node1" [ style = bold] "probe_complete" -> "stonithcloneset_start_0" [ style = bold] "probe_complete" [ style=bold color="green" fontcolor="orange" ] "sles10_monitor_0 node1" -> "probe_complete node1" [ style = bold] "sles10_monitor_0 node1" [ style=bold color="green" fontcolor="black" ] "sles10_monitor_10000 node1" [ style=bold color="green" fontcolor="black" ] "sles10_start_0 node1" -> "sles10_monitor_10000 node1" [ style = bold] "sles10_start_0 node1" [ style=bold color="green" fontcolor="black" ] "sles10_stop_0 node2" -> "all_stopped" [ style = bold] "sles10_stop_0 node2" -> "imagestoreclone:0_stop_0 node2" [ style = bold] "sles10_stop_0 node2" -> "imagestorecloneset_stop_0" [ style = bold] "sles10_stop_0 node2" -> "sles10_start_0 node1" [ style = bold] "sles10_stop_0 node2" [ style=bold color="green" fontcolor="black" ] "stonithclone:1_monitor_0 node1" -> "probe_complete node1" [ style = bold] "stonithclone:1_monitor_0 node1" [ style=bold color="green" fontcolor="black" ] "stonithclone:1_monitor_5000 node1" [ style=bold color="green" fontcolor="black" ] "stonithclone:1_start_0 node1" -> "stonithclone:1_monitor_5000 node1" [ style = bold] "stonithclone:1_start_0 node1" -> "stonithcloneset_running_0" [ style = bold] "stonithclone:1_start_0 node1" [ style=bold color="green" fontcolor="black" ] "stonithcloneset_running_0" [ style=bold color="green" fontcolor="orange" ] "stonithcloneset_start_0" -> "stonithclone:1_start_0 node1" [ style = bold] "stonithcloneset_start_0" -> "stonithcloneset_running_0" [ style = bold] "stonithcloneset_start_0" [ style=bold color="green" fontcolor="orange" ] } diff --git a/pengine/test10/novell-252693-3.exp b/pengine/test10/novell-252693-3.exp index 4afa58135d..a2f32e3432 100644 --- a/pengine/test10/novell-252693-3.exp +++ b/pengine/test10/novell-252693-3.exp @@ -1,900 +1,903 @@ + + + diff --git a/pengine/utils.c b/pengine/utils.c index 33411f003d..bd843d711d 100644 --- a/pengine/utils.c +++ b/pengine/utils.c @@ -1,533 +1,533 @@ /* * Copyright (C) 2004 Andrew Beekhof * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include void print_rsc_to_node(const char *pre_text, rsc_to_node_t *cons, gboolean details) { if(cons == NULL) { crm_debug_4("%s%s: ", pre_text==NULL?"":pre_text, pre_text==NULL?"":": "); return; } crm_debug_4("%s%s%s Constraint %s (%p) - %d nodes:", pre_text==NULL?"":pre_text, pre_text==NULL?"":": ", "rsc_to_node", cons->id, cons, g_list_length(cons->node_list_rh)); if(details == FALSE) { crm_debug_4("\t%s (node placement rule)", safe_val3(NULL, cons, rsc_lh, id)); slist_iter( node, node_t, cons->node_list_rh, lpc, print_node("\t\t-->", node, FALSE) ); } } void print_rsc_colocation(const char *pre_text, rsc_colocation_t *cons, gboolean details) { if(cons == NULL) { crm_debug_4("%s%s: ", pre_text==NULL?"":pre_text, pre_text==NULL?"":": "); return; } crm_debug_4("%s%s%s Constraint %s (%p):", pre_text==NULL?"":pre_text, pre_text==NULL?"":": ", XML_CONS_TAG_RSC_DEPEND, cons->id, cons); if(details == FALSE) { crm_debug_4("\t%s --> %s, %d", safe_val3(NULL, cons, rsc_lh, id), safe_val3(NULL, cons, rsc_rh, id), cons->score); } } void pe_free_ordering(GListPtr constraints) { GListPtr iterator = constraints; while(iterator != NULL) { order_constraint_t *order = iterator->data; iterator = iterator->next; crm_free(order->lh_action_task); crm_free(order->rh_action_task); crm_free(order); } if(constraints != NULL) { g_list_free(constraints); } } void pe_free_rsc_to_node(GListPtr constraints) { GListPtr iterator = constraints; while(iterator != NULL) { rsc_to_node_t *cons = iterator->data; iterator = iterator->next; pe_free_shallow(cons->node_list_rh); crm_free(cons); } if(constraints != NULL) { g_list_free(constraints); } } rsc_to_node_t * rsc2node_new(const char *id, resource_t *rsc, int node_weight, node_t *foo_node, pe_working_set_t *data_set) { rsc_to_node_t *new_con = NULL; if(rsc == NULL || id == NULL) { pe_err("Invalid constraint %s for rsc=%p", crm_str(id), rsc); return NULL; } else if(foo_node == NULL) { CRM_CHECK(node_weight == 0, return NULL); } crm_malloc0(new_con, sizeof(rsc_to_node_t)); if(new_con != NULL) { new_con->id = id; new_con->rsc_lh = rsc; new_con->node_list_rh = NULL; new_con->role_filter = RSC_ROLE_UNKNOWN; if(foo_node != NULL) { node_t *copy = node_copy(foo_node); copy->weight = node_weight; new_con->node_list_rh = g_list_append(NULL, copy); } data_set->placement_constraints = g_list_append( data_set->placement_constraints, new_con); rsc->rsc_location = g_list_append(rsc->rsc_location, new_con); } return new_con; } const char * ordering_type2text(enum pe_ordering type) { const char *result = ""; if(type & pe_order_implies_left) { /* was: mandatory */ result = "right_implies_left"; } else if(type & pe_order_implies_right) { /* was: recover */ result = "left_implies_right"; } else if(type & pe_order_optional) { /* pure ordering, nothing implied */ result = "optional"; } else if(type & pe_order_runnable_left) { result = "runnable"; /* } else { */ /* crm_err("Unknown ordering type: %.3x", type); */ } return result; } gboolean can_run_resources(const node_t *node) { if(node == NULL) { return FALSE; } if(node->details->online == FALSE || node->details->shutdown || node->details->unclean || node->details->standby) { crm_debug_2("%s: online=%d, unclean=%d, standby=%d", node->details->uname, node->details->online, node->details->unclean, node->details->standby); return FALSE; } return TRUE; } /* return -1 if 'a' is more preferred * return 1 if 'b' is more preferred */ gint sort_node_weight(gconstpointer a, gconstpointer b) { int level = LOG_DEBUG_3; const node_t *node1 = (const node_t*)a; const node_t *node2 = (const node_t*)b; int node1_weight = 0; int node2_weight = 0; if(a == NULL) { return 1; } if(b == NULL) { return -1; } node1_weight = node1->weight; node2_weight = node2->weight; if(can_run_resources(node1) == FALSE) { node1_weight = -INFINITY; } if(can_run_resources(node2) == FALSE) { node2_weight = -INFINITY; } if(node1_weight > node2_weight) { do_crm_log_unlikely(level, "%s (%d) > %s (%d) : weight", node1->details->uname, node1_weight, node2->details->uname, node2_weight); return -1; } if(node1_weight < node2_weight) { do_crm_log_unlikely(level, "%s (%d) < %s (%d) : weight", node1->details->uname, node1_weight, node2->details->uname, node2_weight); return 1; } do_crm_log_unlikely(level, "%s (%d) == %s (%d) : weight", node1->details->uname, node1_weight, node2->details->uname, node2_weight); /* now try to balance resources across the cluster */ if(node1->details->num_resources < node2->details->num_resources) { do_crm_log_unlikely(level, "%s (%d) < %s (%d) : resources", node1->details->uname, node1->details->num_resources, node2->details->uname, node2->details->num_resources); return -1; } else if(node1->details->num_resources > node2->details->num_resources) { do_crm_log_unlikely(level, "%s (%d) > %s (%d) : resources", node1->details->uname, node1->details->num_resources, node2->details->uname, node2->details->num_resources); return 1; } do_crm_log_unlikely(level, "%s = %s", node1->details->uname, node2->details->uname); return 0; } gboolean native_assign_node(resource_t *rsc, GListPtr nodes, node_t *chosen, gboolean force) { CRM_ASSERT(rsc->variant == pe_native); clear_bit(rsc->flags, pe_rsc_provisional); if(chosen == NULL) { crm_debug("Could not allocate a node for %s", rsc->id); rsc->next_role = RSC_ROLE_STOPPED; return FALSE; } else if(force == FALSE && (can_run_resources(chosen) == FALSE || chosen->weight < 0)) { crm_debug("All nodes for resource %s are unavailable" ", unclean or shutting down (%s: %d, %d)", rsc->id, chosen->details->uname, can_run_resources(chosen), chosen->weight); rsc->next_role = RSC_ROLE_STOPPED; return FALSE; } /* todo: update the old node for each resource to reflect its * new resource count */ if(rsc->allocated_to) { node_t *old = rsc->allocated_to; old->details->allocated_rsc = g_list_remove( old->details->allocated_rsc, rsc); old->details->num_resources--; old->count--; } crm_debug("Assigning %s to %s", chosen->details->uname, rsc->id); crm_free(rsc->allocated_to); rsc->allocated_to = node_copy(chosen); chosen->details->allocated_rsc = g_list_append(chosen->details->allocated_rsc, rsc); chosen->details->num_resources++; chosen->count++; return TRUE; } char * -convert_non_atomic_task(char *old_uuid, int with_notify, gboolean free_original) +convert_non_atomic_task(char *old_uuid, resource_t *rsc, gboolean allow_notify, gboolean free_original) { int interval = 0; char *uuid = NULL; char *rid = NULL; char *raw_task = NULL; int task = no_action; crm_debug_3("Processing %s", old_uuid); if(old_uuid == NULL) { return NULL; } else if(strstr(old_uuid, "notify") != NULL) { goto done; /* no conversion */ - } + + } else if(rsc->variant < pe_group) { + goto done; /* no conversion */ + } CRM_ASSERT(parse_op_key(old_uuid, &rid, &raw_task, &interval)); if(interval > 0) { goto done; /* no conversion */ } task = text2task(raw_task); switch(task) { case stop_rsc: case start_rsc: case action_notify: case action_promote: case action_demote: break; case stopped_rsc: case started_rsc: case action_notified: case action_promoted: case action_demoted: task--; break; case monitor_rsc: case shutdown_crm: case stonith_node: task = no_action; break; default: crm_err("Unknown action: %s", raw_task); task = no_action; break; } if(task != no_action) { - if(with_notify == 1) { + if(is_set(rsc->flags, pe_rsc_notify) && allow_notify) { uuid = generate_notify_key(rid, "confirmed-post", task2text(task+1)); - - } else if(with_notify == -1) { - uuid = generate_notify_key(rid, "pre", task2text(task)); } else { uuid = generate_op_key(rid, task2text(task+1), 0); } crm_debug_2("Converted %s -> %s", old_uuid, uuid); } done: if(uuid == NULL) { uuid = crm_strdup(old_uuid); } if(free_original) { crm_free(old_uuid); } crm_free(raw_task); crm_free(rid); return uuid; } void order_actions( action_t *lh_action, action_t *rh_action, enum pe_ordering order) { action_wrapper_t *wrapper = NULL; GListPtr list = NULL; crm_debug_3("Ordering Action %s before %s", lh_action->uuid, rh_action->uuid); log_action(LOG_DEBUG_4, "LH (order_actions)", lh_action, FALSE); log_action(LOG_DEBUG_4, "RH (order_actions)", rh_action, FALSE); crm_malloc0(wrapper, sizeof(action_wrapper_t)); wrapper->action = rh_action; wrapper->type = order; list = lh_action->actions_after; list = g_list_append(list, wrapper); lh_action->actions_after = list; wrapper = NULL; /* order |= pe_order_implies_right; */ /* order ^= pe_order_implies_right; */ crm_malloc0(wrapper, sizeof(action_wrapper_t)); wrapper->action = lh_action; wrapper->type = order; list = rh_action->actions_before; list = g_list_append(list, wrapper); rh_action->actions_before = list; } void log_action(unsigned int log_level, const char *pre_text, action_t *action, gboolean details) { const char *node_uname = NULL; const char *node_uuid = NULL; if(action == NULL) { do_crm_log_unlikely(log_level, "%s%s: ", pre_text==NULL?"":pre_text, pre_text==NULL?"":": "); return; } if(action->pseudo) { node_uname = NULL; node_uuid = NULL; } else if(action->node != NULL) { node_uname = action->node->details->uname; node_uuid = action->node->details->id; } else { node_uname = ""; node_uuid = NULL; } switch(text2task(action->task)) { case stonith_node: case shutdown_crm: do_crm_log_unlikely(log_level, "%s%s%sAction %d: %s%s%s%s%s%s", pre_text==NULL?"":pre_text, pre_text==NULL?"":": ", action->pseudo?"Pseduo ":action->optional?"Optional ":action->runnable?action->processed?"":"(Provisional) ":"!!Non-Startable!! ", action->id, action->uuid, node_uname?"\ton ":"", node_uname?node_uname:"", node_uuid?"\t\t(":"", node_uuid?node_uuid:"", node_uuid?")":""); break; default: do_crm_log_unlikely(log_level, "%s%s%sAction %d: %s %s%s%s%s%s%s", pre_text==NULL?"":pre_text, pre_text==NULL?"":": ", action->optional?"Optional ":action->pseudo?"Pseduo ":action->runnable?action->processed?"":"(Provisional) ":"!!Non-Startable!! ", action->id, action->uuid, safe_val3("", action, rsc, id), node_uname?"\ton ":"", node_uname?node_uname:"", node_uuid?"\t\t(":"", node_uuid?node_uuid:"", node_uuid?")":""); break; } if(details) { do_crm_log_unlikely(log_level+1, "\t\t====== Preceeding Actions"); slist_iter( other, action_wrapper_t, action->actions_before, lpc, log_action(log_level+1, "\t\t", other->action, FALSE); ); do_crm_log_unlikely(log_level+1, "\t\t====== Subsequent Actions"); slist_iter( other, action_wrapper_t, action->actions_after, lpc, log_action(log_level+1, "\t\t", other->action, FALSE); ); do_crm_log_unlikely(log_level+1, "\t\t====== End"); } else { do_crm_log_unlikely(log_level, "\t\t(seen=%d, before=%d, after=%d)", action->seen_count, g_list_length(action->actions_before), g_list_length(action->actions_after)); } } action_t *get_pseudo_op(const char *name, pe_working_set_t *data_set) { action_t *op = NULL; const char *op_s = name; GListPtr possible_matches = NULL; possible_matches = find_actions(data_set->actions, name, NULL); if(possible_matches != NULL) { if(g_list_length(possible_matches) > 1) { pe_warn("Action %s exists %d times", name, g_list_length(possible_matches)); } op = g_list_nth_data(possible_matches, 0); g_list_free(possible_matches); } else { op = custom_action(NULL, crm_strdup(op_s), op_s, NULL, TRUE, TRUE, data_set); op->pseudo = TRUE; op->runnable = TRUE; } return op; } gboolean can_run_any(GListPtr nodes) { if(nodes == NULL) { return FALSE; } slist_iter( node, node_t, nodes, lpc, if(can_run_resources(node) && node->weight >= 0) { return TRUE; } ); return FALSE; } diff --git a/pengine/utils.h b/pengine/utils.h index 31fc7f771e..d1de56edc7 100644 --- a/pengine/utils.h +++ b/pengine/utils.h @@ -1,70 +1,70 @@ /* * Copyright (C) 2004 Andrew Beekhof * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef PENGINE_AUTILS__H #define PENGINE_AUTILS__H /* Constraint helper functions */ extern rsc_colocation_t *invert_constraint(rsc_colocation_t *constraint); extern rsc_to_node_t *copy_constraint(rsc_to_node_t *constraint); extern void print_rsc_to_node( const char *pre_text, rsc_to_node_t *cons, gboolean details); extern void print_rsc_colocation( const char *pre_text, rsc_colocation_t *cons, gboolean details); extern rsc_to_node_t *rsc2node_new( const char *id, resource_t *rsc, int weight, node_t *node, pe_working_set_t *data_set); extern void pe_free_rsc_to_node(GListPtr constraints); extern void pe_free_ordering(GListPtr constraints); extern const char *ordering_type2text(enum pe_ordering type); extern gboolean rsc_colocation_new( const char *id, const char *node_attr, int score, resource_t *rsc_lh, resource_t *rsc_rh, const char *state_lh, const char *state_rh, pe_working_set_t *data_set); extern rsc_to_node_t *generate_location_rule( resource_t *rsc, xmlNode *location_rule, pe_working_set_t *data_set); extern gint sort_node_weight(gconstpointer a, gconstpointer b); extern gboolean can_run_resources(const node_t *node); extern gboolean native_assign_node(resource_t *rsc, GListPtr candidates, node_t *chosen, gboolean force); -extern char *convert_non_atomic_task(char *old_uuid, int with_notify, gboolean free_original); +extern char *convert_non_atomic_task(char *old_uuid, resource_t *rsc, gboolean allow_notify, gboolean free_original); extern void order_actions(action_t *lh_action, action_t *rh_action, enum pe_ordering order); extern void log_action(unsigned int log_level, const char *pre_text, action_t *action, gboolean details); extern action_t *get_pseudo_op(const char *name, pe_working_set_t *data_set); extern gboolean can_run_any(GListPtr nodes); extern resource_t *find_compatible_child( resource_t *local_child, resource_t *rsc, enum rsc_role_e filter, gboolean current); #define STONITH_UP "stonith_up" #define STONITH_DONE "stonith_complete" #define ALL_STOPPED "all_stopped" #endif