diff --git a/crm/pengine/allocate.c b/crm/pengine/allocate.c index 6605432e55..d000e5d1b5 100644 --- a/crm/pengine/allocate.c +++ b/crm/pengine/allocate.c @@ -1,1421 +1,1423 @@ /* * 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 #include #include #include #include #include #include #include #include void set_alloc_actions(pe_working_set_t *data_set); void migrate_reload_madness(pe_working_set_t *data_set); resource_alloc_functions_t resource_class_alloc_functions[] = { { native_set_cmds, native_num_allowed_nodes, native_color, native_create_actions, native_create_probe, native_internal_constraints, native_agent_constraints, native_rsc_colocation_lh, native_rsc_colocation_rh, native_rsc_order_lh, native_rsc_order_rh, native_rsc_location, native_expand, native_migrate_reload, native_stonith_ordering, native_create_notify_element, }, { group_set_cmds, group_num_allowed_nodes, group_color, group_create_actions, group_create_probe, group_internal_constraints, group_agent_constraints, group_rsc_colocation_lh, group_rsc_colocation_rh, group_rsc_order_lh, group_rsc_order_rh, group_rsc_location, group_expand, group_migrate_reload, group_stonith_ordering, group_create_notify_element, }, { clone_set_cmds, clone_num_allowed_nodes, clone_color, clone_create_actions, clone_create_probe, clone_internal_constraints, clone_agent_constraints, clone_rsc_colocation_lh, clone_rsc_colocation_rh, clone_rsc_order_lh, clone_rsc_order_rh, clone_rsc_location, clone_expand, clone_migrate_reload, clone_stonith_ordering, clone_create_notify_element, }, { clone_set_cmds, clone_num_allowed_nodes, master_color, master_create_actions, clone_create_probe, master_internal_constraints, clone_agent_constraints, clone_rsc_colocation_lh, master_rsc_colocation_rh, clone_rsc_order_lh, clone_rsc_order_rh, clone_rsc_location, clone_expand, clone_migrate_reload, clone_stonith_ordering, clone_create_notify_element, } }; static gboolean check_rsc_parameters(resource_t *rsc, node_t *node, crm_data_t *rsc_entry, pe_working_set_t *data_set) { int attr_lpc = 0; gboolean force_restart = FALSE; gboolean delete_resource = FALSE; const char *value = NULL; const char *old_value = NULL; const char *attr_list[] = { XML_ATTR_TYPE, XML_AGENT_ATTR_CLASS, XML_AGENT_ATTR_PROVIDER }; for(; attr_lpc < DIMOF(attr_list); attr_lpc++) { value = crm_element_value(rsc->xml, attr_list[attr_lpc]); old_value = crm_element_value(rsc_entry, attr_list[attr_lpc]); if(value == old_value /* ie. NULL */ || crm_str_eq(value, old_value, TRUE)) { continue; } force_restart = TRUE; crm_notice("Forcing restart of %s on %s, %s changed: %s -> %s", rsc->id, node->details->uname, attr_list[attr_lpc], crm_str(old_value), crm_str(value)); } if(force_restart) { /* make sure the restart happens */ stop_action(rsc, node, FALSE); rsc->start_pending = TRUE; delete_resource = TRUE; } return delete_resource; } static gboolean check_action_definition(resource_t *rsc, node_t *active_node, crm_data_t *xml_op, pe_working_set_t *data_set) { char *key = NULL; int interval = 0; const char *interval_s = NULL; gboolean did_change = FALSE; gboolean start_op = FALSE; crm_data_t *params_all = NULL; crm_data_t *params_restart = NULL; GHashTable *local_rsc_params = NULL; char *digest_all_calc = NULL; const char *digest_all = NULL; const char *restart_list = NULL; const char *digest_restart = NULL; char *digest_restart_calc = NULL; action_t *action = NULL; const char *task = crm_element_value(xml_op, XML_LRM_ATTR_TASK); const char *op_version = crm_element_value(xml_op, XML_ATTR_CRM_VERSION); CRM_CHECK(active_node != NULL, return FALSE); interval_s = crm_element_value(xml_op, XML_LRM_ATTR_INTERVAL); interval = crm_parse_int(interval_s, "0"); /* we need to reconstruct the key because of the way we used to construct resource IDs */ key = generate_op_key(rsc->id, task, interval); if(interval > 0) { crm_data_t *op_match = NULL; crm_debug_2("Checking parameters for %s", key); op_match = find_rsc_op_entry(rsc, key); if(op_match == NULL && data_set->stop_action_orphans) { /* create a cancel action */ action_t *cancel = NULL; char *cancel_key = NULL; const char *call_id = crm_element_value(xml_op, XML_LRM_ATTR_CALLID); crm_info("Orphan action will be stopped: %s on %s", key, active_node->details->uname); cancel_key = generate_op_key( rsc->id, CRMD_ACTION_CANCEL, interval); cancel = custom_action( rsc, cancel_key, CRMD_ACTION_CANCEL, active_node, FALSE, TRUE, data_set); add_hash_param(cancel->meta, XML_LRM_ATTR_TASK, task); add_hash_param(cancel->meta, XML_LRM_ATTR_CALLID, call_id); add_hash_param(cancel->meta, XML_LRM_ATTR_INTERVAL, interval_s); custom_action_order( rsc, stop_key(rsc), NULL, rsc, NULL, cancel, pe_order_optional, data_set); } else if(op_match == NULL) { crm_debug("Orphan action detected: %s on %s", key, active_node->details->uname); crm_free(key); key = NULL; return TRUE; } } action = custom_action(rsc, key, task, active_node, TRUE, FALSE, data_set); local_rsc_params = g_hash_table_new_full( g_str_hash, g_str_equal, g_hash_destroy_str, g_hash_destroy_str); unpack_instance_attributes( rsc->xml, XML_TAG_ATTR_SETS, active_node->details->attrs, local_rsc_params, NULL, data_set->now); params_all = create_xml_node(NULL, XML_TAG_PARAMS); g_hash_table_foreach(action->extra, hash2field, params_all); g_hash_table_foreach(rsc->parameters, hash2field, params_all); g_hash_table_foreach(local_rsc_params, hash2field, params_all); filter_action_parameters(params_all, op_version); digest_all_calc = calculate_xml_digest(params_all, TRUE); digest_all = crm_element_value(xml_op, XML_LRM_ATTR_OP_DIGEST); digest_restart = crm_element_value(xml_op, XML_LRM_ATTR_RESTART_DIGEST); restart_list = crm_element_value(xml_op, XML_LRM_ATTR_OP_RESTART); if(crm_str_eq(task, CRMD_ACTION_START, TRUE)) { start_op = TRUE; } if(start_op && digest_restart) { params_restart = copy_xml(params_all); if(restart_list) { filter_reload_parameters(params_restart, restart_list); } digest_restart_calc = calculate_xml_digest(params_restart, TRUE); if(safe_str_neq(digest_restart_calc, digest_restart)) { did_change = TRUE; crm_log_xml_info(params_restart, "params:restart"); crm_warn("Parameters to %s on %s changed: recorded %s vs. calculated (restart) %s", key, active_node->details->uname, crm_str(digest_restart), digest_restart_calc); key = generate_op_key(rsc->id, task, interval); custom_action(rsc, key, task, NULL, FALSE, TRUE, data_set); goto cleanup; } } if(safe_str_neq(digest_all_calc, digest_all)) { action_t *op = NULL; did_change = TRUE; crm_log_xml_info(params_all, "params:all"); crm_warn("Parameters to %s on %s changed: recorded %s vs. calculated (all) %s", key, active_node->details->uname, crm_str(digest_all), digest_all_calc); key = generate_op_key(rsc->id, task, interval); op = custom_action(rsc, key, task, NULL, FALSE, TRUE, data_set); if(start_op && digest_restart) { op->allow_reload_conversion = TRUE; } else if(interval > 0) { custom_action_order(rsc, start_key(rsc), NULL, NULL, crm_strdup(op->task), op, pe_order_runnable_left, data_set); } } cleanup: free_xml(params_all); free_xml(params_restart); crm_free(digest_all_calc); crm_free(digest_restart_calc); g_hash_table_destroy(local_rsc_params); pe_free_action(action); return did_change; } extern gboolean DeleteRsc(resource_t *rsc, node_t *node, gboolean optional, pe_working_set_t *data_set); static void check_actions_for(crm_data_t *rsc_entry, node_t *node, pe_working_set_t *data_set) { const char *id = NULL; const char *task = NULL; int interval = 0; const char *interval_s = NULL; GListPtr op_list = NULL; GListPtr sorted_op_list = NULL; const char *rsc_id = ID(rsc_entry); gboolean is_probe = FALSE; int start_index = 0, stop_index = 0; resource_t *rsc = pe_find_resource(data_set->resources, rsc_id); CRM_CHECK(rsc != NULL, return); CRM_CHECK(node != NULL, return); CRM_CHECK(rsc_id != NULL, return); if(rsc->orphan) { crm_debug_2("Skipping param check for %s: orphan", rsc->id); return; } else if(pe_find_node_id(rsc->running_on, node->details->id) == NULL) { crm_debug_2("Skipping param check for %s: no longer active on %s", rsc->id, node->details->uname); return; } crm_debug_3("Processing %s on %s", rsc->id, node->details->uname); if(check_rsc_parameters(rsc, node, rsc_entry, data_set)) { DeleteRsc(rsc, node, FALSE, data_set); } xml_child_iter_filter( rsc_entry, rsc_op, XML_LRM_TAG_RSC_OP, op_list = g_list_append(op_list, rsc_op); ); sorted_op_list = g_list_sort(op_list, sort_op_by_callid); calculate_active_ops(sorted_op_list, &start_index, &stop_index); slist_iter( rsc_op, crm_data_t, sorted_op_list, lpc, if(start_index < stop_index) { /* stopped */ continue; } else if(lpc < start_index) { /* action occurred prior to a start */ continue; } id = ID(rsc_op); is_probe = FALSE; task = crm_element_value(rsc_op, XML_LRM_ATTR_TASK); interval_s = crm_element_value(rsc_op, XML_LRM_ATTR_INTERVAL); interval = crm_parse_int(interval_s, "0"); if(interval == 0 && safe_str_eq(task, CRMD_ACTION_STATUS)) { is_probe = TRUE; } if(is_probe || safe_str_eq(task, CRMD_ACTION_START) || interval > 0) { check_action_definition(rsc, node, rsc_op, data_set); } ); g_list_free(sorted_op_list); } static void check_actions(pe_working_set_t *data_set) { const char *id = NULL; node_t *node = NULL; crm_data_t *lrm_rscs = NULL; crm_data_t *status = get_object_root(XML_CIB_TAG_STATUS, data_set->input); xml_child_iter_filter( status, node_state, XML_CIB_TAG_STATE, id = crm_element_value(node_state, XML_ATTR_ID); lrm_rscs = find_xml_node(node_state, XML_CIB_TAG_LRM, FALSE); lrm_rscs = find_xml_node(lrm_rscs, XML_LRM_TAG_RESOURCES, FALSE); node = pe_find_node_id(data_set->nodes, id); if(node == NULL) { continue; } else if(can_run_resources(node) == FALSE) { crm_debug_2("Skipping param check for %s: cant run resources", node->details->uname); continue; } crm_debug_2("Processing node %s", node->details->uname); if(node->details->online || data_set->stonith_enabled) { xml_child_iter_filter( lrm_rscs, rsc_entry, XML_LRM_TAG_RESOURCE, if(xml_has_children(rsc_entry)) { check_actions_for(rsc_entry, node, data_set); } ); } ); } static gboolean apply_placement_constraints(pe_working_set_t *data_set) { crm_debug_3("Applying constraints..."); slist_iter( cons, rsc_to_node_t, data_set->placement_constraints, lpc, cons->rsc_lh->cmds->rsc_location(cons->rsc_lh, cons); ); return TRUE; } void set_alloc_actions(pe_working_set_t *data_set) { slist_iter( rsc, resource_t, data_set->resources, lpc, rsc->cmds = &resource_class_alloc_functions[rsc->variant]; rsc->cmds->set_cmds(rsc); ); } gboolean stage0(pe_working_set_t *data_set) { crm_data_t * cib_constraints = get_object_root( XML_CIB_TAG_CONSTRAINTS, data_set->input); if(data_set->input == NULL) { return FALSE; } cluster_status(data_set); set_alloc_actions(data_set); unpack_constraints(cib_constraints, data_set); return TRUE; } /* * Check nodes for resources started outside of the LRM */ gboolean stage1(pe_working_set_t *data_set) { action_t *probe_complete = NULL; action_t *probe_node_complete = NULL; slist_iter( node, node_t, data_set->nodes, lpc, gboolean force_probe = FALSE; const char *probed = g_hash_table_lookup( node->details->attrs, CRM_OP_PROBED); crm_debug_2("%s probed: %s", node->details->uname, probed); if(node->details->online == FALSE) { continue; } else if(node->details->unclean) { continue; } else if(probe_complete == NULL) { probe_complete = custom_action( NULL, crm_strdup(CRM_OP_PROBED), CRM_OP_PROBED, NULL, FALSE, TRUE, data_set); probe_complete->pseudo = TRUE; probe_complete->optional = TRUE; } if(probed != NULL && crm_is_true(probed) == FALSE) { force_probe = TRUE; } probe_node_complete = custom_action( NULL, crm_strdup(CRM_OP_PROBED), CRM_OP_PROBED, node, FALSE, TRUE, data_set); probe_node_complete->optional = crm_is_true(probed); probe_node_complete->priority = INFINITY; add_hash_param(probe_node_complete->meta, XML_ATTR_TE_NOWAIT, XML_BOOLEAN_TRUE); custom_action_order(NULL, NULL, probe_node_complete, NULL, NULL, probe_complete, pe_order_optional, data_set); slist_iter( rsc, resource_t, data_set->resources, lpc2, if(rsc->cmds->create_probe( rsc, node, probe_node_complete, force_probe, data_set)) { probe_complete->optional = FALSE; probe_node_complete->optional = FALSE; custom_action_order( NULL, NULL, probe_complete, rsc, start_key(rsc), NULL, pe_order_optional, data_set); } ); ); return TRUE; } /* * Count how many valid nodes we have (so we know the maximum number of * colors we can resolve). * * Apply node constraints (ie. filter the "allowed_nodes" part of resources */ gboolean stage2(pe_working_set_t *data_set) { crm_debug_3("Applying placement constraints"); slist_iter( node, node_t, data_set->nodes, lpc, if(node == NULL) { /* error */ } else if(node->weight >= 0.0 /* global weight */ && node->details->online && node->details->type == node_member) { data_set->max_valid_nodes++; } ); apply_placement_constraints(data_set); return TRUE; } /* * Create internal resource constraints before allocation */ gboolean stage3(pe_working_set_t *data_set) { slist_iter( rsc, resource_t, data_set->resources, lpc, rsc->cmds->internal_constraints(rsc, data_set); ); return TRUE; } /* * Check for orphaned or redefined actions */ gboolean stage4(pe_working_set_t *data_set) { check_actions(data_set); return TRUE; } gboolean stage5(pe_working_set_t *data_set) { /* Take (next) highest resource, assign it and create its actions */ slist_iter( rsc, resource_t, data_set->resources, lpc, rsc->cmds->color(rsc, data_set); rsc->cmds->create_actions(rsc, data_set); ); return TRUE; } /* * Create dependancies for stonith and shutdown operations */ gboolean stage6(pe_working_set_t *data_set) { action_t *dc_down = NULL; action_t *stonith_op = NULL; action_t *last_stonith = NULL; gboolean integrity_lost = FALSE; crm_debug_3("Processing fencing and shutdown cases"); slist_iter( node, node_t, data_set->nodes, lpc, stonith_op = NULL; if(node->details->unclean && data_set->stonith_enabled && (data_set->have_quorum || data_set->no_quorum_policy == no_quorum_ignore)) { + action_t *ready = get_stonith_up(data_set); pe_warn("Scheduling Node %s for STONITH", node->details->uname); stonith_op = custom_action( NULL, crm_strdup(CRM_OP_FENCE), CRM_OP_FENCE, node, FALSE, TRUE, data_set); add_hash_param( stonith_op->meta, XML_LRM_ATTR_TARGET, node->details->uname); add_hash_param( stonith_op->meta, XML_LRM_ATTR_TARGET_UUID, node->details->id); add_hash_param( stonith_op->meta, "stonith_action", data_set->stonith_action); stonith_constraints(node, stonith_op, data_set); + order_actions(ready, stonith_op, pe_order_implies_left); if(node->details->is_dc) { dc_down = stonith_op; } else { if(last_stonith) { order_actions(last_stonith, stonith_op, pe_order_implies_left); } last_stonith = stonith_op; } } else if(node->details->online && node->details->shutdown) { action_t *down_op = NULL; crm_info("Scheduling Node %s for shutdown", node->details->uname); down_op = custom_action( NULL, crm_strdup(CRM_OP_SHUTDOWN), CRM_OP_SHUTDOWN, node, FALSE, TRUE, data_set); shutdown_constraints(node, down_op, data_set); if(node->details->is_dc) { dc_down = down_op; } } if(node->details->unclean && stonith_op == NULL) { integrity_lost = TRUE; pe_warn("Node %s is unclean!", node->details->uname); } ); if(last_stonith != NULL) { action_t *all_stopped = get_all_stopped(data_set); order_actions(last_stonith, all_stopped, pe_order_implies_right); } if(integrity_lost) { if(data_set->have_quorum == FALSE) { crm_notice("Cannot fence unclean nodes until quorum is" " attained (or no_quorum_policy is set to ignore)"); } else if(data_set->stonith_enabled == FALSE) { pe_warn("YOUR RESOURCES ARE NOW LIKELY COMPROMISED"); pe_err("ENABLE STONITH TO KEEP YOUR RESOURCES SAFE"); } } if(dc_down != NULL) { GListPtr shutdown_matches = find_actions( data_set->actions, CRM_OP_SHUTDOWN, NULL); crm_debug_2("Ordering shutdowns before %s on %s (DC)", dc_down->task, dc_down->node->details->uname); add_hash_param(dc_down->meta, XML_ATTR_TE_NOWAIT, XML_BOOLEAN_TRUE); slist_iter( node_stop, action_t, shutdown_matches, lpc, if(node_stop->node->details->is_dc) { continue; } crm_debug("Ordering shutdown on %s before %s on %s", node_stop->node->details->uname, dc_down->task, dc_down->node->details->uname); order_actions(node_stop, dc_down, pe_order_implies_left); ); if(last_stonith && dc_down != last_stonith) { order_actions(last_stonith, dc_down, pe_order_implies_left); } g_list_free(shutdown_matches); } return TRUE; } /* * Determin the sets of independant actions and the correct order for the * actions in each set. * * Mark dependencies of un-runnable actions un-runnable * */ gboolean stage7(pe_working_set_t *data_set) { crm_debug_4("Applying ordering constraints"); slist_iter( order, order_constraint_t, data_set->ordering_constraints, lpc, resource_t *rsc = order->lh_rsc; crm_debug_2("Applying ordering constraint: %d", order->id); if(rsc != NULL) { crm_debug_4("rsc_action-to-*"); rsc->cmds->rsc_order_lh(rsc, order, data_set); continue; } rsc = order->rh_rsc; if(rsc != NULL) { crm_debug_4("action-to-rsc_action"); rsc->cmds->rsc_order_rh(order->lh_action, rsc, order); } else { crm_debug_4("action-to-action"); order_actions( order->lh_action, order->rh_action, order->type); } ); update_action_states(data_set->actions); slist_iter( rsc, resource_t, data_set->resources, lpc, rsc->cmds->migrate_reload(rsc, data_set); ); return TRUE; } int transition_id = -1; /* * Create a dependency graph to send to the transitioner (via the CRMd) */ gboolean stage8(pe_working_set_t *data_set) { const char *value = NULL; char *transition_id_s = NULL; transition_id++; transition_id_s = crm_itoa(transition_id); value = pe_pref(data_set->config_hash, "cluster-delay"); crm_debug_2("Creating transition graph %d.", transition_id); data_set->graph = create_xml_node(NULL, XML_TAG_GRAPH); crm_xml_add(data_set->graph, "cluster-delay", value); crm_xml_add(data_set->graph, "transition_id", transition_id_s); crm_free(transition_id_s); /* errors... slist_iter(action, action_t, action_list, lpc, if(action->optional == FALSE && action->runnable == FALSE) { print_action("Ignoring", action, TRUE); } ); */ slist_iter( rsc, resource_t, data_set->resources, lpc, crm_debug_4("processing actions for rsc=%s", rsc->id); rsc->cmds->expand(rsc, data_set); ); crm_log_xml_debug_3( data_set->graph, "created resource-driven action list"); /* catch any non-resource specific actions */ crm_debug_4("processing non-resource actions"); slist_iter( action, action_t, data_set->actions, lpc, graph_element_from_action(action, data_set); ); crm_log_xml_debug_3(data_set->graph, "created generic action list"); crm_debug_2("Created transition graph %d.", transition_id); return TRUE; } void cleanup_alloc_calculations(pe_working_set_t *data_set) { if(data_set == NULL) { return; } crm_debug_3("deleting order cons: %p", data_set->ordering_constraints); pe_free_ordering(data_set->ordering_constraints); data_set->ordering_constraints = NULL; crm_debug_3("deleting node cons: %p", data_set->placement_constraints); pe_free_rsc_to_node(data_set->placement_constraints); data_set->placement_constraints = NULL; cleanup_calculations(data_set); } gboolean unpack_constraints(crm_data_t * xml_constraints, pe_working_set_t *data_set) { crm_data_t *lifetime = NULL; xml_child_iter( xml_constraints, xml_obj, const char *id = crm_element_value(xml_obj, XML_ATTR_ID); if(id == NULL) { crm_config_err("Constraint <%s...> must have an id", crm_element_name(xml_obj)); continue; } crm_debug_3("Processing constraint %s %s", crm_element_name(xml_obj),id); lifetime = cl_get_struct(xml_obj, "lifetime"); if(test_ruleset(lifetime, NULL, data_set->now) == FALSE) { crm_info("Constraint %s %s is not active", crm_element_name(xml_obj), id); } else if(safe_str_eq(XML_CONS_TAG_RSC_ORDER, crm_element_name(xml_obj))) { unpack_rsc_order(xml_obj, data_set); } else if(safe_str_eq(XML_CONS_TAG_RSC_DEPEND, crm_element_name(xml_obj))) { unpack_rsc_colocation(xml_obj, data_set); } else if(safe_str_eq(XML_CONS_TAG_RSC_LOCATION, crm_element_name(xml_obj))) { unpack_rsc_location(xml_obj, data_set); } else { pe_err("Unsupported constraint type: %s", crm_element_name(xml_obj)); } ); return TRUE; } static const char * invert_action(const char *action) { if(safe_str_eq(action, CRMD_ACTION_START)) { return CRMD_ACTION_STOP; } else if(safe_str_eq(action, CRMD_ACTION_STOP)) { return CRMD_ACTION_START; } else if(safe_str_eq(action, CRMD_ACTION_PROMOTE)) { return CRMD_ACTION_DEMOTE; } else if(safe_str_eq(action, CRMD_ACTION_DEMOTE)) { return CRMD_ACTION_PROMOTE; } else if(safe_str_eq(action, CRMD_ACTION_PROMOTED)) { return CRMD_ACTION_DEMOTED; } else if(safe_str_eq(action, CRMD_ACTION_DEMOTED)) { return CRMD_ACTION_PROMOTED; } else if(safe_str_eq(action, CRMD_ACTION_STARTED)) { return CRMD_ACTION_STOPPED; } else if(safe_str_eq(action, CRMD_ACTION_STOPPED)) { return CRMD_ACTION_STARTED; } crm_config_warn("Unknown action: %s", action); return NULL; } gboolean unpack_rsc_order(crm_data_t * xml_obj, pe_working_set_t *data_set) { int score_i = 0; int order_id = 0; resource_t *rsc_lh = NULL; resource_t *rsc_rh = NULL; gboolean symmetrical_bool = TRUE; enum pe_ordering cons_weight = pe_order_optional; const char *id_rh = NULL; const char *id_lh = NULL; const char *action = NULL; const char *action_rh = NULL; const char *id = crm_element_value(xml_obj, XML_ATTR_ID); const char *type = crm_element_value(xml_obj, XML_ATTR_TYPE); const char *score = crm_element_value(xml_obj, XML_RULE_ATTR_SCORE); const char *symmetrical = crm_element_value( xml_obj, XML_CONS_ATTR_SYMMETRICAL); cl_str_to_boolean(symmetrical, &symmetrical_bool); if(xml_obj == NULL) { crm_config_err("No constraint object to process."); return FALSE; } else if(id == NULL) { crm_config_err("%s constraint must have an id", crm_element_name(xml_obj)); return FALSE; } if(safe_str_eq(type, "before")) { id_lh = crm_element_value(xml_obj, XML_CONS_ATTR_TO); id_rh = crm_element_value(xml_obj, XML_CONS_ATTR_FROM); action = crm_element_value(xml_obj, XML_CONS_ATTR_ACTION); action_rh = crm_element_value(xml_obj, XML_CONS_ATTR_TOACTION); } else { type="before"; id_rh = crm_element_value(xml_obj, XML_CONS_ATTR_TO); id_lh = crm_element_value(xml_obj, XML_CONS_ATTR_FROM); action = crm_element_value(xml_obj, XML_CONS_ATTR_TOACTION); action_rh = crm_element_value(xml_obj, XML_CONS_ATTR_ACTION); if(action == NULL) { action = action_rh; } } if(id_lh == NULL || id_rh == NULL) { crm_config_err("Constraint %s needs two sides lh: %s rh: %s", id, crm_str(id_lh), crm_str(id_rh)); return FALSE; } if(action == NULL) { action = CRMD_ACTION_START; } if(action_rh == NULL) { action_rh = action; } rsc_lh = pe_find_resource(data_set->resources, id_rh); rsc_rh = pe_find_resource(data_set->resources, id_lh); if(rsc_lh == NULL) { crm_config_err("Constraint %s: no resource found for LHS (%s)", id, id_rh); return FALSE; } else if(rsc_rh == NULL) { crm_config_err("Constraint %s: no resource found for RHS of (%s)", id, id_lh); return FALSE; } score_i = char2score(score); cons_weight = pe_order_optional; if(score == 0 && rsc_rh->restart_type == pe_restart_restart) { crm_debug_2("Upgrade : recovery - implies right"); cons_weight |= pe_order_implies_right; } if(score_i < 0) { crm_debug_2("Upgrade : implies left"); cons_weight |= pe_order_implies_left; } else if(score_i > 0) { crm_debug_2("Upgrade : implies right"); cons_weight |= pe_order_implies_right; if(safe_str_eq(action, CRMD_ACTION_START) || safe_str_eq(action, CRMD_ACTION_PROMOTE)) { crm_debug_2("Upgrade : runnable"); cons_weight |= pe_order_runnable_left; } } order_id = custom_action_order( rsc_lh, generate_op_key(rsc_lh->id, action, 0), NULL, rsc_rh, generate_op_key(rsc_rh->id, action_rh, 0), NULL, cons_weight, data_set); crm_debug("order-%d (%s): %s_%s %s %s_%s flags=0x%.6x", order_id, id, rsc_lh->id, action, type, rsc_rh->id, action_rh, cons_weight); if(symmetrical_bool == FALSE) { return TRUE; } action = invert_action(action); action_rh = invert_action(action_rh); cons_weight = pe_order_optional; if(score == 0 && rsc_rh->restart_type == pe_restart_restart) { crm_debug_2("Upgrade : recovery - implies left"); cons_weight |= pe_order_implies_left; } score_i *= -1; if(score_i < 0) { crm_debug_2("Upgrade : implies left"); cons_weight |= pe_order_implies_left; } else if(score_i > 0) { crm_debug_2("Upgrade : implies right"); cons_weight |= pe_order_implies_right; if(safe_str_eq(action, CRMD_ACTION_START) || safe_str_eq(action, CRMD_ACTION_PROMOTE)) { crm_debug_2("Upgrade : runnable"); cons_weight |= pe_order_runnable_left; } } if(action == NULL || action_rh == NULL) { crm_config_err("Cannot invert rsc_order constraint %s." " Please specify the inverse manually.", id); return TRUE; } order_id = custom_action_order( rsc_rh, generate_op_key(rsc_rh->id, action_rh, 0), NULL, rsc_lh, generate_op_key(rsc_lh->id, action, 0), NULL, cons_weight, data_set); crm_debug("order-%d (%s): %s_%s %s %s_%s flags=0x%.6x", order_id, id, rsc_rh->id, action_rh, type, rsc_lh->id, action, cons_weight); return TRUE; } gboolean unpack_rsc_location(crm_data_t * xml_obj, pe_working_set_t *data_set) { gboolean empty = TRUE; const char *id_lh = crm_element_value(xml_obj, "rsc"); const char *id = crm_element_value(xml_obj, XML_ATTR_ID); resource_t *rsc_lh = pe_find_resource(data_set->resources, id_lh); if(rsc_lh == NULL) { /* only a warn as BSC adds the constraint then the resource */ crm_config_warn("No resource (con=%s, rsc=%s)", id, id_lh); return FALSE; } else if(rsc_lh->is_managed == FALSE) { crm_debug_2("Ignoring constraint %s: resource %s not managed", id, id_lh); return FALSE; } xml_child_iter_filter( xml_obj, rule_xml, XML_TAG_RULE, empty = FALSE; crm_debug_2("Unpacking %s/%s", id, ID(rule_xml)); generate_location_rule(rsc_lh, rule_xml, data_set); ); if(empty) { crm_config_err("Invalid location constraint %s:" " rsc_location must contain at least one rule", ID(xml_obj)); } return TRUE; } static int get_node_score(const char *rule, const char *score, gboolean raw, node_t *node) { int score_f = 0; if(score == NULL) { pe_err("Rule %s: no score specified. Assuming 0.", rule); } else if(raw) { score_f = char2score(score); } else { const char *attr_score = g_hash_table_lookup( node->details->attrs, score); if(attr_score == NULL) { crm_debug("Rule %s: node %s did not have a value for %s", rule, node->details->uname, score); score_f = -INFINITY; } else { crm_debug("Rule %s: node %s had value %s for %s", rule, node->details->uname, attr_score, score); score_f = char2score(attr_score); } } return score_f; } rsc_to_node_t * generate_location_rule( resource_t *rsc, crm_data_t *rule_xml, pe_working_set_t *data_set) { const char *rule_id = NULL; const char *score = NULL; const char *boolean = NULL; const char *role = NULL; GListPtr match_L = NULL; int score_f = 0; gboolean do_and = TRUE; gboolean accept = TRUE; gboolean raw_score = TRUE; rsc_to_node_t *location_rule = NULL; rule_id = crm_element_value(rule_xml, XML_ATTR_ID); boolean = crm_element_value(rule_xml, XML_RULE_ATTR_BOOLEAN_OP); role = crm_element_value(rule_xml, XML_RULE_ATTR_ROLE); crm_debug_2("Processing rule: %s", rule_id); if(role != NULL && text2role(role) == RSC_ROLE_UNKNOWN) { pe_err("Bad role specified for %s: %s", rule_id, role); return NULL; } score = crm_element_value(rule_xml, XML_RULE_ATTR_SCORE); if(score != NULL) { score_f = char2score(score); } else { score = crm_element_value( rule_xml, XML_RULE_ATTR_SCORE_ATTRIBUTE); if(score == NULL) { score = crm_element_value( rule_xml, XML_RULE_ATTR_SCORE_MANGLED); } if(score != NULL) { raw_score = FALSE; } } if(safe_str_eq(boolean, "or")) { do_and = FALSE; } location_rule = rsc2node_new(rule_id, rsc, 0, NULL, data_set); if(location_rule == NULL) { return NULL; } if(role != NULL) { crm_debug_2("Setting role filter: %s", role); location_rule->role_filter = text2role(role); } if(do_and) { match_L = node_list_dup(data_set->nodes, TRUE, FALSE); slist_iter( node, node_t, match_L, lpc, node->weight = get_node_score(rule_id, score, raw_score, node); ); } xml_child_iter( rule_xml, expr, enum expression_type type = find_expression_type(expr); crm_debug_2("Processing expression: %s", ID(expr)); if(type == not_expr) { pe_err("Expression <%s id=%s...> is not valid", crm_element_name(expr), crm_str(ID(expr))); continue; } slist_iter( node, node_t, data_set->nodes, lpc, if(type == nested_rule) { accept = test_rule( expr, node->details->attrs, RSC_ROLE_UNKNOWN, data_set->now); } else { accept = test_expression( expr, node->details->attrs, RSC_ROLE_UNKNOWN, data_set->now); } score_f = get_node_score(rule_id, score, raw_score, node); /* if(accept && score_f == -INFINITY) { */ /* accept = FALSE; */ /* } */ if(accept) { node_t *local = pe_find_node_id( match_L, node->details->id); if(local == NULL && do_and) { continue; } else if(local == NULL) { local = node_copy(node); match_L = g_list_append(match_L, local); } if(do_and == FALSE) { local->weight = merge_weights( local->weight, score_f); } crm_debug_2("node %s now has weight %d", node->details->uname, local->weight); } else if(do_and && !accept) { /* remove it */ node_t *delete = pe_find_node_id( match_L, node->details->id); if(delete != NULL) { match_L = g_list_remove(match_L,delete); crm_debug_5("node %s did not match", node->details->uname); } crm_free(delete); } ); ); location_rule->node_list_rh = match_L; if(location_rule->node_list_rh == NULL) { crm_debug_2("No matching nodes for rule %s", rule_id); return NULL; } crm_debug_3("%s: %d nodes matched", rule_id, g_list_length(location_rule->node_list_rh)); return location_rule; } 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) { rsc_colocation_t *new_con = NULL; if(rsc_lh == NULL){ crm_config_err("No resource found for LHS %s", id); return FALSE; } else if(rsc_rh == NULL){ crm_config_err("No resource found for RHS of %s", id); return FALSE; } crm_malloc0(new_con, sizeof(rsc_colocation_t)); if(new_con == NULL) { return FALSE; } if(state_lh == NULL || safe_str_eq(state_lh, RSC_ROLE_STARTED_S)) { state_lh = RSC_ROLE_UNKNOWN_S; } if(state_rh == NULL || safe_str_eq(state_rh, RSC_ROLE_STARTED_S)) { state_rh = RSC_ROLE_UNKNOWN_S; } new_con->id = id; new_con->rsc_lh = rsc_lh; new_con->rsc_rh = rsc_rh; new_con->score = score; new_con->role_lh = text2role(state_lh); new_con->role_rh = text2role(state_rh); new_con->node_attribute = node_attr; crm_debug_4("Adding constraint %s (%p) to %s", new_con->id, new_con, rsc_lh->id); rsc_lh->rsc_cons = g_list_insert_sorted( rsc_lh->rsc_cons, new_con, sort_cons_strength); return TRUE; } /* LHS before RHS */ int custom_action_order( resource_t *lh_rsc, char *lh_action_task, action_t *lh_action, resource_t *rh_rsc, char *rh_action_task, action_t *rh_action, enum pe_ordering type, pe_working_set_t *data_set) { order_constraint_t *order = NULL; if(lh_rsc == NULL && lh_action) { lh_rsc = lh_action->rsc; } if(rh_rsc == NULL && rh_action) { rh_rsc = rh_action->rsc; } if((lh_action == NULL && lh_rsc == NULL) || (rh_action == NULL && rh_rsc == NULL)){ crm_config_err("Invalid inputs %p.%p %p.%p", lh_rsc, lh_action, rh_rsc, rh_action); crm_free(lh_action_task); crm_free(rh_action_task); return -1; } crm_malloc0(order, sizeof(order_constraint_t)); crm_debug_3("Creating ordering constraint %d", data_set->order_id); order->id = data_set->order_id++; order->type = type; order->lh_rsc = lh_rsc; order->rh_rsc = rh_rsc; order->lh_action = lh_action; order->rh_action = rh_action; order->lh_action_task = lh_action_task; order->rh_action_task = rh_action_task; data_set->ordering_constraints = g_list_append( data_set->ordering_constraints, order); if(lh_rsc != NULL && rh_rsc != NULL) { crm_debug_4("Created ordering constraint %d (%s):" " %s/%s before %s/%s", order->id, ordering_type2text(order->type), lh_rsc->id, lh_action_task, rh_rsc->id, rh_action_task); } else if(lh_rsc != NULL) { crm_debug_4("Created ordering constraint %d (%s):" " %s/%s before action %d (%s)", order->id, ordering_type2text(order->type), lh_rsc->id, lh_action_task, rh_action->id, rh_action_task); } else if(rh_rsc != NULL) { crm_debug_4("Created ordering constraint %d (%s):" " action %d (%s) before %s/%s", order->id, ordering_type2text(order->type), lh_action->id, lh_action_task, rh_rsc->id, rh_action_task); } else { crm_debug_4("Created ordering constraint %d (%s):" " action %d (%s) before action %d (%s)", order->id, ordering_type2text(order->type), lh_action->id, lh_action_task, rh_action->id, rh_action_task); } return order->id; } gboolean unpack_rsc_colocation(crm_data_t * xml_obj, pe_working_set_t *data_set) { int score_i = 0; const char *id = crm_element_value(xml_obj, XML_ATTR_ID); const char *id_rh = crm_element_value(xml_obj, XML_CONS_ATTR_TO); const char *id_lh = crm_element_value(xml_obj, XML_CONS_ATTR_FROM); const char *score = crm_element_value(xml_obj, XML_RULE_ATTR_SCORE); const char *state_lh = crm_element_value(xml_obj, XML_RULE_ATTR_FROMSTATE); const char *state_rh = crm_element_value(xml_obj, XML_RULE_ATTR_TOSTATE); const char *attr = crm_element_value(xml_obj, "node_attribute"); const char *symmetrical = crm_element_value(xml_obj, XML_CONS_ATTR_SYMMETRICAL); resource_t *rsc_lh = pe_find_resource(data_set->resources, id_lh); resource_t *rsc_rh = pe_find_resource(data_set->resources, id_rh); if(rsc_lh == NULL) { crm_config_err("No resource (con=%s, rsc=%s)", id, id_lh); return FALSE; } else if(rsc_rh == NULL) { crm_config_err("No resource (con=%s, rsc=%s)", id, id_rh); return FALSE; } if(score) { score_i = char2score(score); } rsc_colocation_new( id, attr, score_i, rsc_lh, rsc_rh, state_lh, state_rh); if(crm_is_true(symmetrical)) { rsc_colocation_new( id, attr, score_i, rsc_rh, rsc_lh, state_rh, state_lh); } return TRUE; } gboolean is_active(rsc_to_node_t *cons) { return TRUE; } diff --git a/crm/pengine/native.c b/crm/pengine/native.c index 994511438d..35adae233a 100644 --- a/crm/pengine/native.c +++ b/crm/pengine/native.c @@ -1,1739 +1,1740 @@ /* * 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 #include #define DELETE_THEN_REFRESH 1 #define VARIANT_NATIVE 1 #include resource_t *ultimate_parent(resource_t *rsc); void node_list_update(GListPtr list1, GListPtr list2, int factor); void native_rsc_colocation_rh_must(resource_t *rsc_lh, gboolean update_lh, resource_t *rsc_rh, gboolean update_rh); void native_rsc_colocation_rh_mustnot(resource_t *rsc_lh, gboolean update_lh, resource_t *rsc_rh, gboolean update_rh); void create_notifications(resource_t *rsc, pe_working_set_t *data_set); void Recurring(resource_t *rsc, action_t *start, node_t *node, pe_working_set_t *data_set); void RecurringOp(resource_t *rsc, action_t *start, node_t *node, crm_data_t *operation, pe_working_set_t *data_set); void pe_pre_notify( resource_t *rsc, node_t *node, action_t *op, notify_data_t *n_data, pe_working_set_t *data_set); void pe_post_notify( resource_t *rsc, node_t *node, action_t *op, notify_data_t *n_data, pe_working_set_t *data_set); void NoRoleChange (resource_t *rsc, node_t *current, node_t *next, pe_working_set_t *data_set); gboolean DeleteRsc (resource_t *rsc, node_t *node, gboolean optional, pe_working_set_t *data_set); gboolean StopRsc (resource_t *rsc, node_t *next, gboolean optional, pe_working_set_t *data_set); gboolean StartRsc (resource_t *rsc, node_t *next, gboolean optional, pe_working_set_t *data_set); gboolean DemoteRsc (resource_t *rsc, node_t *next, gboolean optional, pe_working_set_t *data_set); gboolean PromoteRsc(resource_t *rsc, node_t *next, gboolean optional, pe_working_set_t *data_set); gboolean RoleError (resource_t *rsc, node_t *next, gboolean optional, pe_working_set_t *data_set); gboolean NullOp (resource_t *rsc, node_t *next, gboolean optional, pe_working_set_t *data_set); enum rsc_role_e rsc_state_matrix[RSC_ROLE_MAX][RSC_ROLE_MAX] = { /* Current State */ /* Next State: Unknown Stopped Started Slave Master */ /* Unknown */ { RSC_ROLE_UNKNOWN, RSC_ROLE_STOPPED, RSC_ROLE_STOPPED, RSC_ROLE_STOPPED, RSC_ROLE_STOPPED, }, /* Stopped */ { RSC_ROLE_STOPPED, RSC_ROLE_STOPPED, RSC_ROLE_STARTED, RSC_ROLE_SLAVE, RSC_ROLE_SLAVE, }, /* Started */ { RSC_ROLE_STOPPED, RSC_ROLE_STOPPED, RSC_ROLE_STARTED, RSC_ROLE_SLAVE, RSC_ROLE_MASTER, }, /* Slave */ { RSC_ROLE_STOPPED, RSC_ROLE_STOPPED, RSC_ROLE_UNKNOWN, RSC_ROLE_SLAVE, RSC_ROLE_MASTER, }, /* Master */ { RSC_ROLE_STOPPED, RSC_ROLE_SLAVE, RSC_ROLE_UNKNOWN, RSC_ROLE_SLAVE, RSC_ROLE_MASTER, }, }; gboolean (*rsc_action_matrix[RSC_ROLE_MAX][RSC_ROLE_MAX])(resource_t*,node_t*,gboolean,pe_working_set_t*) = { /* Current State */ /* Next State: Unknown Stopped Started Slave Master */ /* Unknown */ { RoleError, StopRsc, RoleError, RoleError, RoleError, }, /* Stopped */ { RoleError, NullOp, StartRsc, StartRsc, RoleError, }, /* Started */ { RoleError, StopRsc, NullOp, NullOp, PromoteRsc, }, /* Slave */ { RoleError, StopRsc, RoleError, NullOp, PromoteRsc, }, /* Master */ { RoleError, RoleError, RoleError, DemoteRsc, NullOp, }, }; static gboolean native_choose_node(resource_t *rsc) { /* 1. Sort by weight 2. color.chosen_node = the node (of those with the highest wieght) with the fewest resources 3. remove color.chosen_node from all other colors */ GListPtr nodes = NULL; node_t *chosen = NULL; if(rsc->provisional == FALSE) { return rsc->allocated_to?TRUE:FALSE; } crm_debug_3("Choosing node for %s from %d candidates", rsc->id, g_list_length(rsc->allowed_nodes)); if(rsc->allowed_nodes) { rsc->allowed_nodes = g_list_sort( rsc->allowed_nodes, sort_node_weight); nodes = rsc->allowed_nodes; chosen = g_list_nth_data(nodes, 0); } return native_assign_node(rsc, nodes, chosen); } void native_set_cmds(resource_t *rsc) { } int native_num_allowed_nodes(resource_t *rsc) { gboolean unimplimented = FALSE; CRM_ASSERT(unimplimented); return 0; } resource_t * ultimate_parent(resource_t *rsc) { resource_t *parent = rsc; while(parent->parent) { parent = parent->parent; } return parent; } node_t * native_color(resource_t *rsc, pe_working_set_t *data_set) { if(rsc->parent && rsc->parent->is_allocating == FALSE) { /* never allocate children on their own */ crm_debug("Escalating allocation of %s to its parent: %s", rsc->id, rsc->parent->id); rsc->parent->cmds->color(rsc->parent, data_set); } print_resource(LOG_DEBUG_2, "Allocating: ", rsc, FALSE); if(rsc->provisional == FALSE) { return rsc->allocated_to; } if(rsc->is_allocating) { crm_debug("Dependancy loop detected involving %s", rsc->id); return NULL; } rsc->is_allocating = TRUE; rsc->rsc_cons = g_list_sort(rsc->rsc_cons, sort_cons_strength); slist_iter( constraint, rsc_colocation_t, rsc->rsc_cons, lpc, crm_debug_3("%s: Pre-Processing %s", rsc->id, constraint->id); if(rsc->provisional && constraint->rsc_rh->provisional) { crm_debug_2("Combine scores from %s and %s", rsc->id, constraint->rsc_rh->id); node_list_update(constraint->rsc_rh->allowed_nodes, rsc->allowed_nodes, constraint->score/INFINITY); } constraint->rsc_rh->cmds->color( constraint->rsc_rh, data_set); rsc->cmds->rsc_colocation_lh( rsc, constraint->rsc_rh, constraint); ); print_resource(LOG_DEBUG, "Allocating: ", rsc, FALSE); if(rsc->next_role == RSC_ROLE_STOPPED) { crm_debug_2("Making sure %s doesn't get allocated", rsc->id); /* make sure it doesnt come up again */ resource_location( rsc, NULL, -INFINITY, "target_role", data_set); } if(rsc->provisional && native_choose_node(rsc) ) { crm_debug_3("Allocated resource %s to %s", rsc->id, rsc->allocated_to->details->uname); } else if(rsc->allocated_to == NULL) { if(rsc->orphan == FALSE) { pe_warn("Resource %s cannot run anywhere", rsc->id); } else { crm_info("Stopping orphan resource %s", rsc->id); } } else { crm_debug("Pre-Allocated resource %s to %s", rsc->id, rsc->allocated_to->details->uname); } rsc->is_allocating = FALSE; print_resource(LOG_DEBUG_3, "Allocated ", rsc, TRUE); return rsc->allocated_to; } void RecurringOp(resource_t *rsc, action_t *start, node_t *node, crm_data_t *operation, pe_working_set_t *data_set) { char *key = NULL; const char *name = NULL; const char *value = NULL; const char *interval = NULL; const char *node_uname = NULL; int interval_ms = 0; action_t *mon = NULL; gboolean is_optional = TRUE; GListPtr possible_matches = NULL; crm_debug_2("Creating recurring actions for %s", rsc->id); if(node != NULL) { node_uname = node->details->uname; } interval = crm_element_value(operation, XML_LRM_ATTR_INTERVAL); interval_ms = crm_get_msec(interval); if(interval_ms == 0) { return; } else if(interval_ms < 0) { crm_config_warn("%s contains an invalid interval: %s", ID(operation), interval); return; } value = crm_element_value(operation, "disabled"); if(crm_is_true(value)) { return; } name = crm_element_value(operation, "name"); key = generate_op_key(rsc->id, name, interval_ms); if(start != NULL) { crm_debug_3("Marking %s %s due to %s", key, start->optional?"optional":"manditory", start->uuid); is_optional = start->optional; } else { crm_debug_2("Marking %s optional", key); is_optional = TRUE; } /* start a monitor for an already active resource */ possible_matches = find_actions_exact(rsc->actions, key, node); if(possible_matches == NULL) { is_optional = FALSE; crm_debug_3("Marking %s manditory: not active", key); } else { g_list_free(possible_matches); } value = crm_element_value(operation, "role"); if((rsc->next_role == RSC_ROLE_MASTER && value == NULL) || (value != NULL && text2role(value) != rsc->next_role)) { int log_level = LOG_DEBUG_2; const char *result = "Ignoring"; if(is_optional) { char *local_key = crm_strdup(key); log_level = LOG_INFO; result = "Cancelling"; /* its running : cancel it */ mon = custom_action( rsc, local_key, CRMD_ACTION_CANCEL, node, FALSE, TRUE, data_set); crm_free(mon->task); mon->task = crm_strdup(CRMD_ACTION_CANCEL); add_hash_param(mon->meta, XML_LRM_ATTR_INTERVAL, interval); add_hash_param(mon->meta, XML_LRM_ATTR_TASK, name); custom_action_order( rsc, NULL, mon, rsc, promote_key(rsc), NULL, pe_order_runnable_left, data_set); mon = NULL; } do_crm_log(log_level, "%s action %s (%s vs. %s)", result , key, value?value:role2text(RSC_ROLE_SLAVE), role2text(rsc->next_role)); crm_free(key); key = NULL; return; } mon = custom_action(rsc, key, name, node, is_optional, TRUE, data_set); key = mon->uuid; if(is_optional) { crm_debug_2("%s\t %s (optional)", crm_str(node_uname), mon->uuid); } if(start == NULL || start->runnable == FALSE) { crm_debug("%s\t %s (cancelled : start un-runnable)", crm_str(node_uname), mon->uuid); mon->runnable = FALSE; } else if(node == NULL || node->details->online == FALSE || node->details->unclean) { crm_debug("%s\t %s (cancelled : no node available)", crm_str(node_uname), mon->uuid); mon->runnable = FALSE; } else if(mon->optional == FALSE) { crm_notice("%s\t %s", crm_str(node_uname),mon->uuid); } custom_action_order(rsc, start_key(rsc), NULL, NULL, crm_strdup(key), mon, pe_order_implies_right|pe_order_runnable_left, data_set); if(rsc->next_role == RSC_ROLE_MASTER) { char *running_master = crm_itoa(EXECRA_RUNNING_MASTER); add_hash_param(mon->meta, XML_ATTR_TE_TARGET_RC, running_master); custom_action_order( rsc, promote_key(rsc), NULL, rsc, NULL, mon, pe_order_optional|pe_order_runnable_left, data_set); crm_free(running_master); } } void Recurring(resource_t *rsc, action_t *start, node_t *node, pe_working_set_t *data_set) { xml_child_iter_filter( rsc->ops_xml, operation, "op", RecurringOp(rsc, start, node, operation, data_set); ); } void native_create_actions(resource_t *rsc, pe_working_set_t *data_set) { action_t *start = NULL; node_t *chosen = NULL; enum rsc_role_e role = RSC_ROLE_UNKNOWN; enum rsc_role_e next_role = RSC_ROLE_UNKNOWN; crm_debug_2("Creating actions for %s", rsc->id); chosen = rsc->allocated_to; if(chosen != NULL) { CRM_CHECK(rsc->next_role != RSC_ROLE_UNKNOWN, rsc->next_role = RSC_ROLE_STARTED); } unpack_instance_attributes( rsc->xml, XML_TAG_ATTR_SETS, chosen?chosen->details->attrs:NULL, rsc->parameters, NULL, data_set->now); crm_debug_2("%s: %s->%s", rsc->id, role2text(rsc->role), role2text(rsc->next_role)); if(g_list_length(rsc->running_on) > 1) { if(rsc->recovery_type == recovery_stop_start) { pe_proc_err("Attempting recovery of resource %s", rsc->id); StopRsc(rsc, NULL, FALSE, data_set); rsc->role = RSC_ROLE_STOPPED; } } else if(rsc->running_on != NULL) { node_t *current = rsc->running_on->data; NoRoleChange(rsc, current, chosen, data_set); } else if(rsc->role == RSC_ROLE_STOPPED && rsc->next_role == RSC_ROLE_STOPPED) { char *key = start_key(rsc); GListPtr possible_matches = find_actions(rsc->actions, key, NULL); slist_iter( action, action_t, possible_matches, lpc, action->optional = TRUE; /* action->pseudo = TRUE; */ ); g_list_free(possible_matches); crm_debug_2("Stopping a stopped resource"); crm_free(key); return; } role = rsc->role; while(role != rsc->next_role) { next_role = rsc_state_matrix[role][rsc->next_role]; crm_debug_2("Executing: %s->%s (%s)", role2text(role), role2text(next_role), rsc->id); if(rsc_action_matrix[role][next_role]( rsc, chosen, FALSE, data_set) == FALSE) { break; } role = next_role; } if(rsc->next_role != RSC_ROLE_STOPPED && rsc->is_managed) { start = start_action(rsc, chosen, TRUE); Recurring(rsc, start, chosen, data_set); } } void native_internal_constraints(resource_t *rsc, pe_working_set_t *data_set) { int type = pe_order_optional; if(rsc->variant == pe_native) { type |= pe_order_implies_right; } custom_action_order(rsc, stop_key(rsc), NULL, rsc, start_key(rsc), NULL, type, data_set); custom_action_order(rsc, demote_key(rsc), NULL, rsc, stop_key(rsc), NULL, pe_order_optional, data_set); custom_action_order(rsc, start_key(rsc), NULL, rsc, promote_key(rsc), NULL, pe_order_runnable_left, data_set); custom_action_order( rsc, delete_key(rsc), NULL, rsc, start_key(rsc), NULL, pe_order_optional, data_set); if(rsc->notify) { char *key1 = NULL; char *key2 = NULL; key1 = generate_op_key(rsc->id, "confirmed-post_notify_start", 0); key2 = generate_op_key(rsc->id, "pre_notify_promote", 0); custom_action_order( rsc, key1, NULL, rsc, key2, NULL, pe_order_optional, data_set); key1 = generate_op_key(rsc->id, "confirmed-post_notify_demote", 0); key2 = generate_op_key(rsc->id, "pre_notify_stop", 0); custom_action_order( rsc, key1, NULL, rsc, key2, NULL, pe_order_optional, data_set); } } void native_rsc_colocation_lh( resource_t *rsc_lh, resource_t *rsc_rh, rsc_colocation_t *constraint) { if(rsc_lh == 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; } crm_debug_2("Processing colocation constraint between %s and %s", rsc_lh->id, rsc_rh->id); rsc_rh->cmds->rsc_colocation_rh(rsc_lh, rsc_rh, constraint); } static gboolean filter_colocation_constraint( resource_t *rsc_lh, resource_t *rsc_rh, rsc_colocation_t *constraint) { if(constraint->score == 0){ return FALSE; } if(constraint->role_lh != RSC_ROLE_UNKNOWN && constraint->role_lh != rsc_lh->next_role) { crm_debug_4("RH: Skipping constraint: \"%s\" state filter", role2text(constraint->role_rh)); return FALSE; } if(constraint->role_rh != RSC_ROLE_UNKNOWN && constraint->role_rh != rsc_rh->next_role) { crm_debug_4("RH: Skipping constraint: \"%s\" state filter", role2text(constraint->role_rh)); return FALSE; } return TRUE; } static void colocation_match( resource_t *rsc_lh, resource_t *rsc_rh, rsc_colocation_t *constraint) { const char *tmp = NULL; const char *value = NULL; gboolean do_check = FALSE; const char *attribute = "#id"; if(constraint->node_attribute != NULL) { attribute = constraint->node_attribute; } if(rsc_rh->allocated_to) { value = g_hash_table_lookup( rsc_rh->allocated_to->details->attrs, attribute); do_check = TRUE; } else if(constraint->score < 0) { /* nothing to do: * anti-colocation with something thats not running */ return; } slist_iter( node, node_t, rsc_lh->allowed_nodes, lpc, tmp = g_hash_table_lookup(node->details->attrs, attribute); if(do_check && safe_str_eq(tmp, value)) { crm_debug_2("%s: %s.%s += %d", constraint->id, rsc_lh->id, node->details->uname, constraint->score); node->weight = merge_weights( constraint->score, node->weight); } else if(do_check == FALSE || constraint->score >= INFINITY) { crm_debug_2("%s: %s.%s = -INFINITY (%s)", constraint->id, rsc_lh->id, node->details->uname, do_check?"failed":"unallocated"); node->weight = -INFINITY; } ); } void native_rsc_colocation_rh( resource_t *rsc_lh, resource_t *rsc_rh, rsc_colocation_t *constraint) { crm_debug_2("%sColocating %s with %s (%s, weight=%d)", constraint->score >= 0?"":"Anti-", rsc_lh->id, rsc_rh->id, constraint->id, constraint->score); if(filter_colocation_constraint(rsc_lh, rsc_rh, constraint) == FALSE) { return; } if(rsc_rh->provisional) { return; } else if(rsc_lh->provisional == FALSE) { /* error check */ struct node_shared_s *details_lh; struct node_shared_s *details_rh; if((constraint->score > -INFINITY) && (constraint->score < INFINITY)) { return; } details_rh = rsc_rh->allocated_to?rsc_rh->allocated_to->details:NULL; details_lh = rsc_lh->allocated_to?rsc_lh->allocated_to->details:NULL; if(constraint->score == INFINITY && details_lh != details_rh) { crm_err("%s and %s are both allocated" " but to different nodes: %s vs. %s", rsc_lh->id, rsc_rh->id, details_lh?details_lh->uname:"n/a", details_rh?details_rh->uname:"n/a"); } else if(constraint->score == -INFINITY && details_lh == details_rh) { crm_err("%s and %s are both allocated" " but to the SAME node: %s", rsc_lh->id, rsc_rh->id, details_rh?details_rh->uname:"n/a"); } return; } else { colocation_match(rsc_lh, rsc_rh, constraint); } } void node_list_update(GListPtr list1, GListPtr list2, int factor) { node_t *other_node = NULL; slist_iter( node, node_t, list1, lpc, if(node == NULL) { continue; } other_node = (node_t*)pe_find_node_id( list2, node->details->id); if(other_node != NULL) { crm_debug_2("%s: %d + %d", node->details->uname, node->weight, other_node->weight); node->weight = merge_weights( factor*other_node->weight, node->weight); } ); } void native_rsc_order_lh(resource_t *lh_rsc, order_constraint_t *order, pe_working_set_t *data_set) { GListPtr lh_actions = NULL; action_t *lh_action = order->lh_action; resource_t *rh_rsc = order->rh_rsc; crm_debug_2("Processing LH of ordering constraint %d", order->id); CRM_ASSERT(lh_rsc != NULL); if(lh_action != NULL) { lh_actions = g_list_append(NULL, lh_action); } else if(lh_action == NULL) { lh_actions = find_actions( lh_rsc->actions, order->lh_action_task, NULL); } if(lh_actions == NULL && lh_rsc != rh_rsc) { char *key = NULL; char *rsc_id = NULL; char *op_type = NULL; int interval = 0; crm_debug_2("No LH-Side (%s/%s) found for constraint %d with %s - creating", lh_rsc->id, order->lh_action_task, order->id, order->rh_action_task); parse_op_key( order->lh_action_task, &rsc_id, &op_type, &interval); key = generate_op_key(lh_rsc->id, op_type, interval); lh_action = custom_action(lh_rsc, key, op_type, NULL, TRUE, TRUE, data_set); if(lh_rsc->fns->state(lh_rsc, TRUE) == RSC_ROLE_STOPPED && safe_str_eq(op_type, CRMD_ACTION_STOP)) { lh_action->pseudo = TRUE; lh_action->runnable = TRUE; } lh_actions = g_list_append(NULL, lh_action); crm_free(op_type); crm_free(rsc_id); } slist_iter( lh_action_iter, action_t, lh_actions, lpc, if(rh_rsc == NULL && order->rh_action) { rh_rsc = order->rh_action->rsc; } if(rh_rsc) { rh_rsc->cmds->rsc_order_rh( lh_action_iter, rh_rsc, order); } else if(order->rh_action) { order_actions( lh_action_iter, order->rh_action, order->type); } ); pe_free_shallow_adv(lh_actions, FALSE); } void native_rsc_order_rh( action_t *lh_action, resource_t *rsc, order_constraint_t *order) { GListPtr rh_actions = NULL; action_t *rh_action = NULL; CRM_CHECK(rsc != NULL, return); CRM_CHECK(order != NULL, return); rh_action = order->rh_action; crm_debug_3("Processing RH of ordering constraint %d", order->id); if(rh_action != NULL) { rh_actions = g_list_append(NULL, rh_action); } else if(rsc != NULL) { rh_actions = find_actions( rsc->actions, order->rh_action_task, NULL); } if(rh_actions == NULL) { crm_debug_4("No RH-Side (%s/%s) found for constraint..." " ignoring", rsc->id,order->rh_action_task); if(lh_action) { crm_debug_4("LH-Side was: %s", lh_action->uuid); } return; } slist_iter( rh_action_iter, action_t, rh_actions, lpc, if(lh_action) { order_actions(lh_action, rh_action_iter, order->type); } else if(order->type & pe_order_implies_right) { rh_action_iter->runnable = FALSE; crm_warn("Unrunnable %s 0x%.6x", rh_action_iter->uuid, order->type); } else { crm_warn("neither %s 0x%.6x", rh_action_iter->uuid, order->type); } ); pe_free_shallow_adv(rh_actions, FALSE); } void native_rsc_location(resource_t *rsc, rsc_to_node_t *constraint) { GListPtr or_list; crm_debug_2("Applying %s (%s) to %s", constraint->id, role2text(constraint->role_filter), rsc->id); /* take "lifetime" into account */ if(constraint == NULL) { pe_err("Constraint is NULL"); return; } else if(rsc == NULL) { pe_err("LHS of rsc_to_node (%s) is NULL", constraint->id); return; } else if(constraint->role_filter > 0 && constraint->role_filter != rsc->next_role) { crm_debug("Constraint (%s) is not active (role : %s)", constraint->id, role2text(constraint->role_filter)); return; } else if(is_active(constraint) == FALSE) { crm_debug_2("Constraint (%s) is not active", constraint->id); return; } if(constraint->node_list_rh == NULL) { crm_debug_2("RHS of constraint %s is NULL", constraint->id); return; } or_list = node_list_or( rsc->allowed_nodes, constraint->node_list_rh, FALSE); pe_free_shallow(rsc->allowed_nodes); rsc->allowed_nodes = or_list; slist_iter(node, node_t, or_list, lpc, crm_debug_3("%s + %s : %d", rsc->id, node->details->uname, node->weight); ); } void native_expand(resource_t *rsc, pe_working_set_t *data_set) { slist_iter( action, action_t, rsc->actions, lpc, crm_debug_4("processing action %d for rsc=%s", action->id, rsc->id); graph_element_from_action(action, data_set); ); } void native_agent_constraints(resource_t *rsc) { } void create_notifications(resource_t *rsc, pe_working_set_t *data_set) { if(rsc->notify == FALSE) { return; } /* slist_iter( */ /* action, action_t, rsc->actions, lpc, */ /* ); */ } static void register_activity(resource_t *rsc, enum action_tasks task, node_t *node, notify_data_t *n_data) { notify_entry_t *entry = NULL; crm_malloc0(entry, sizeof(notify_entry_t)); entry->rsc = rsc; entry->node = node; switch(task) { case start_rsc: n_data->start = g_list_append(n_data->start, entry); break; case stop_rsc: n_data->stop = g_list_append(n_data->stop, entry); break; case action_promote: n_data->promote = g_list_append(n_data->promote, entry); break; case action_demote: n_data->demote = g_list_append(n_data->demote, entry); break; default: crm_err("Unsupported notify action: %s", task2text(task)); crm_free(entry); break; } } static void register_state(resource_t *rsc, node_t *on_node, notify_data_t *n_data) { notify_entry_t *entry = NULL; crm_malloc0(entry, sizeof(notify_entry_t)); entry->rsc = rsc; entry->node = on_node; crm_debug_2("%s state: %s", rsc->id, role2text(rsc->next_role)); switch(rsc->next_role) { case RSC_ROLE_STOPPED: /* n_data->inactive = g_list_append(n_data->inactive, entry); */ crm_free(entry); break; case RSC_ROLE_STARTED: n_data->active = g_list_append(n_data->active, entry); break; case RSC_ROLE_SLAVE: n_data->slave = g_list_append(n_data->slave, entry); break; case RSC_ROLE_MASTER: n_data->master = g_list_append(n_data->master, entry); break; default: crm_err("Unsupported notify role"); crm_free(entry); break; } } void native_create_notify_element(resource_t *rsc, action_t *op, notify_data_t *n_data, pe_working_set_t *data_set) { node_t *next_node = NULL; gboolean registered = FALSE; char *op_key = NULL; GListPtr possible_matches = NULL; enum action_tasks task = text2task(op->task); if(op->pre_notify == NULL || op->post_notify == NULL) { /* no notifications required */ crm_debug_4("No notificaitons required for %s", op->task); return; } next_node = rsc->allocated_to; op_key = generate_op_key(rsc->id, op->task, 0); possible_matches = find_actions(rsc->actions, op_key, NULL); crm_debug_2("Creating notificaitons for: %s (%s->%s)", op->uuid, role2text(rsc->role), role2text(rsc->next_role)); if(rsc->role == rsc->next_role) { register_state(rsc, next_node, n_data); } slist_iter( local_op, action_t, possible_matches, lpc, local_op->notify_keys = n_data->keys; if(local_op->optional == FALSE) { registered = TRUE; register_activity(rsc, task, local_op->node, n_data); } ); /* stop / demote */ if(rsc->role != RSC_ROLE_STOPPED) { if(task == stop_rsc || task == action_demote) { slist_iter( current_node, node_t, rsc->running_on, lpc, pe_pre_notify(rsc, current_node, op, n_data, data_set); if(task == action_demote || registered == FALSE) { pe_post_notify(rsc, current_node, op, n_data, data_set); } ); } } /* start / promote */ if(rsc->next_role != RSC_ROLE_STOPPED) { CRM_CHECK(next_node != NULL,;); if(next_node == NULL) { pe_proc_err("next role: %s", role2text(rsc->next_role)); } else if(task == start_rsc || task == action_promote) { if(task != start_rsc || registered == FALSE) { pe_pre_notify(rsc, next_node, op, n_data, data_set); } pe_post_notify(rsc, next_node, op, n_data, data_set); } } crm_free(op_key); g_list_free(possible_matches); } static void dup_attr(gpointer key, gpointer value, gpointer user_data) { char *meta_key = crm_concat(CRM_META, key, '_'); g_hash_table_replace(user_data, meta_key, crm_strdup(value)); } static action_t * pe_notify(resource_t *rsc, node_t *node, action_t *op, action_t *confirm, notify_data_t *n_data, pe_working_set_t *data_set) { char *key = NULL; action_t *trigger = NULL; const char *value = NULL; const char *task = NULL; if(op == NULL || confirm == NULL) { crm_debug_2("Op=%p confirm=%p", op, confirm); return NULL; } CRM_CHECK(node != NULL, return NULL); if(node->details->online == FALSE) { crm_info("Skipping notification for %s", rsc->id); return NULL; } value = g_hash_table_lookup(op->meta, "notify_type"); task = g_hash_table_lookup(op->meta, "notify_operation"); crm_debug_2("Creating actions for %s: %s (%s-%s)", op->uuid, rsc->id, value, task); key = generate_notify_key(rsc->id, value, task); trigger = custom_action(rsc, key, op->task, node, op->optional, TRUE, data_set); g_hash_table_foreach(op->meta, dup_attr, trigger->extra); trigger->notify_keys = n_data->keys; /* pseudo_notify before notify */ crm_debug_3("Ordering %s before %s (%d->%d)", op->uuid, trigger->uuid, trigger->id, op->id); order_actions(op, trigger, pe_order_implies_left); value = g_hash_table_lookup(op->meta, "notify_confirm"); if(crm_is_true(value)) { /* notify before pseudo_notified */ crm_debug_3("Ordering %s before %s (%d->%d)", trigger->uuid, confirm->uuid, confirm->id, trigger->id); order_actions(trigger, confirm, pe_order_implies_left); } return trigger; } void pe_pre_notify(resource_t *rsc, node_t *node, action_t *op, notify_data_t *n_data, pe_working_set_t *data_set) { crm_debug_2("%s: %s", rsc->id, op->uuid); pe_notify(rsc, node, op->pre_notify, op->pre_notified, n_data, data_set); } void pe_post_notify(resource_t *rsc, node_t *node, action_t *op, notify_data_t *n_data, pe_working_set_t *data_set) { action_t *notify = NULL; CRM_CHECK(op != NULL, return); CRM_CHECK(rsc != NULL, return); crm_debug_2("%s: %s", rsc->id, op->uuid); notify = pe_notify(rsc, node, op->post_notify, op->post_notified, n_data, data_set); if(notify != NULL) { /* crm_err("Upgrading priority for %s to INFINITY", notify->uuid); */ notify->priority = INFINITY; } notify = op->post_notified; if(notify != NULL) { slist_iter( mon, action_t, rsc->actions, lpc, const char *interval = g_hash_table_lookup(mon->meta, "interval"); if(interval == NULL || safe_str_eq(interval, "0")) { crm_debug_3("Skipping %s: interval", mon->uuid); continue; } else if(safe_str_eq(mon->task, "cancel")) { crm_debug_3("Skipping %s: cancel", mon->uuid); continue; } order_actions(notify, mon, pe_order_optional); ); } } void NoRoleChange(resource_t *rsc, node_t *current, node_t *next, pe_working_set_t *data_set) { action_t *stop = NULL; action_t *start = NULL; GListPtr possible_matches = NULL; crm_debug_2("Executing: %s (role=%s)",rsc->id, role2text(rsc->next_role)); if(current == NULL || next == NULL) { return; } if(rsc->failed || safe_str_neq(current->details->id, next->details->id)) { if(rsc->failed) { crm_notice("Recover resource %s\t(%s)", rsc->id, next->details->uname); } else { crm_notice("Move resource %s\t(%s -> %s)", rsc->id, current->details->uname, next->details->uname); } if(rsc->role == RSC_ROLE_MASTER) { DemoteRsc(rsc, current, FALSE, data_set); } StopRsc(rsc, current, FALSE, data_set); StartRsc(rsc, next, FALSE, data_set); if(rsc->next_role == RSC_ROLE_MASTER) { PromoteRsc(rsc, next, FALSE, data_set); } possible_matches = find_recurring_actions(rsc->actions, next); slist_iter(match, action_t, possible_matches, lpc, if(match->optional == FALSE) { crm_debug("Fixing recurring action: %s", match->uuid); match->optional = TRUE; } ); g_list_free(possible_matches); } else if(rsc->start_pending) { action_t *start = start_action(rsc, next, TRUE); if(start->runnable) { /* wait for StartRsc() to be called */ rsc->role = RSC_ROLE_STOPPED; } else { /* wait for StopRsc() to be called */ rsc->next_role = RSC_ROLE_STOPPED; } } else { stop = stop_action(rsc, current, TRUE); start = start_action(rsc, next, TRUE); stop->optional = start->optional; if(rsc->role == RSC_ROLE_MASTER) { DemoteRsc(rsc, current, start->optional, data_set); } StopRsc(rsc, current, start->optional, data_set); StartRsc(rsc, current, start->optional, data_set); if(rsc->next_role == RSC_ROLE_MASTER) { PromoteRsc(rsc, next, start->optional, data_set); } if(start->runnable == FALSE) { rsc->next_role = RSC_ROLE_STOPPED; } else if(start->optional) { crm_notice("Leave resource %s\t(%s)", rsc->id, next->details->uname); } else { crm_notice("Restart resource %s\t(%s)", rsc->id, next->details->uname); } } } gboolean StopRsc(resource_t *rsc, node_t *next, gboolean optional, pe_working_set_t *data_set) { action_t *stop = NULL; crm_debug_2("Executing: %s", rsc->id); slist_iter( current, node_t, rsc->running_on, lpc, stop = stop_action(rsc, current, optional); if(stop->runnable && stop->optional == FALSE) { crm_notice(" %s\tStop %s", current->details->uname, rsc->id); } if(data_set->remove_after_stop) { DeleteRsc(rsc, current, optional, data_set); } ); return TRUE; } gboolean StartRsc(resource_t *rsc, node_t *next, gboolean optional, pe_working_set_t *data_set) { action_t *start = NULL; crm_debug_2("Executing: %s", rsc->id); start = start_action(rsc, next, TRUE); if(start->runnable && optional == FALSE) { crm_notice(" %s\tStart %s", next->details->uname, rsc->id); start->optional = FALSE; } return TRUE; } gboolean PromoteRsc(resource_t *rsc, node_t *next, gboolean optional, pe_working_set_t *data_set) { char *key = NULL; gboolean runnable = TRUE; GListPtr action_list = NULL; crm_debug_2("Executing: %s", rsc->id); CRM_CHECK(rsc->next_role == RSC_ROLE_MASTER, crm_err("Next role: %s", role2text(rsc->next_role)); return FALSE); key = start_key(rsc); action_list = find_actions_exact(rsc->actions, key, next); crm_free(key); slist_iter(start, action_t, action_list, lpc, if(start->runnable == FALSE) { runnable = FALSE; } ); g_list_free(action_list); if(runnable) { promote_action(rsc, next, optional); if(optional == FALSE) { crm_notice("%s\tPromote %s", next->details->uname, rsc->id); } return TRUE; } crm_debug("%s\tPromote %s (canceled)", next->details->uname, rsc->id); key = promote_key(rsc); action_list = find_actions_exact(rsc->actions, key, next); crm_free(key); slist_iter(promote, action_t, action_list, lpc, promote->runnable = FALSE; ); g_list_free(action_list); return TRUE; } gboolean DemoteRsc(resource_t *rsc, node_t *next, gboolean optional, pe_working_set_t *data_set) { crm_debug_2("Executing: %s", rsc->id); /* CRM_CHECK(rsc->next_role == RSC_ROLE_SLAVE, return FALSE); */ slist_iter( current, node_t, rsc->running_on, lpc, crm_notice("%s\tDemote %s", current->details->uname, rsc->id); demote_action(rsc, current, optional); ); return TRUE; } gboolean RoleError(resource_t *rsc, node_t *next, gboolean optional, pe_working_set_t *data_set) { crm_debug("Executing: %s", rsc->id); CRM_CHECK(FALSE, return FALSE); return FALSE; } gboolean NullOp(resource_t *rsc, node_t *next, gboolean optional, pe_working_set_t *data_set) { crm_debug("Executing: %s", rsc->id); return FALSE; } gboolean DeleteRsc(resource_t *rsc, node_t *node, gboolean optional, pe_working_set_t *data_set) { action_t *delete = NULL; action_t *refresh = NULL; if(rsc->failed) { crm_debug_2("Resource %s not deleted from %s: failed", rsc->id, node->details->uname); return FALSE; } else if(node == NULL) { crm_debug_2("Resource %s not deleted: NULL node", rsc->id); return FALSE; } else if(node->details->unclean || node->details->online == FALSE) { crm_debug_2("Resource %s not deleted from %s: unrunnable", rsc->id, node->details->uname); return FALSE; } crm_notice("Removing %s from %s", rsc->id, node->details->uname); delete = delete_action(rsc, node, optional); custom_action_order( rsc, stop_key(rsc), NULL, rsc, delete_key(rsc), NULL, optional?pe_order_implies_right:pe_order_implies_left, data_set); #if DELETE_THEN_REFRESH refresh = custom_action( NULL, crm_strdup(CRM_OP_LRM_REFRESH), CRM_OP_LRM_REFRESH, node, FALSE, TRUE, data_set); add_hash_param(refresh->meta, XML_ATTR_TE_NOWAIT, XML_BOOLEAN_TRUE); order_actions(delete, refresh, pe_order_optional); #endif return TRUE; } gboolean native_create_probe(resource_t *rsc, node_t *node, action_t *complete, gboolean force, pe_working_set_t *data_set) { char *key = NULL; char *target_rc = NULL; action_t *probe = NULL; node_t *running = NULL; CRM_CHECK(node != NULL, return FALSE); if(rsc->orphan) { crm_debug_2("Skipping orphan: %s", rsc->id); return FALSE; } running = pe_find_node_id(rsc->known_on, node->details->id); if(force == FALSE && running != NULL) { /* we already know the status of the resource on this node */ crm_debug_3("Skipping active: %s", rsc->id); return FALSE; } key = generate_op_key(rsc->id, CRMD_ACTION_STATUS, 0); probe = custom_action(rsc, key, CRMD_ACTION_STATUS, node, FALSE, TRUE, data_set); probe->optional = FALSE; running = pe_find_node_id(rsc->running_on, node->details->id); if(running == NULL) { target_rc = crm_itoa(EXECRA_NOT_RUNNING); add_hash_param(probe->meta, XML_ATTR_TE_TARGET_RC, target_rc); crm_free(target_rc); } crm_debug_2("Probing %s on %s", rsc->id, node->details->uname); custom_action_order(rsc, NULL, probe, rsc, NULL, complete, pe_order_implies_right, data_set); return TRUE; } static void native_start_constraints( resource_t *rsc, action_t *stonith_op, gboolean is_stonith, pe_working_set_t *data_set) { node_t *target = stonith_op?stonith_op->node:NULL; gboolean is_unprotected = FALSE; gboolean run_unprotected = TRUE; if(is_stonith) { char *key = start_key(rsc); + action_t *ready = get_stonith_up(data_set); crm_debug_2("Ordering %s action before stonith events", key); custom_action_order( rsc, key, NULL, - NULL, crm_strdup(CRM_OP_FENCE), stonith_op, - pe_order_optional, data_set); + NULL, crm_strdup(ready->task), ready, + pe_order_implies_right, data_set); } else { slist_iter(action, action_t, rsc->actions, lpc2, if(target != NULL && target->details->expected_up && safe_str_eq(action->task, CRMD_ACTION_START) && NULL == pe_find_node_id( rsc->known_on, target->details->id)) { /* if expected_up == TRUE, then we've seen * the node before and it has failed (as * opposed to just hasn't started up yet) * * if known == NULL, then we dont know if * the resource is active on the node * we're about to shoot * * in this case, regardless of action->needs, * the only safe option is to wait until * the node is shot before doing anything * to with the resource * * its analogous to waiting for all the probes * for rscX to complete before starting rscX * * the most likely explaination is that the * DC died and took its status with it */ crm_info("Ordering %s after %s recovery", action->uuid, target->details->uname); } else if(action->needs != rsc_req_stonith) { crm_debug_3("%s doesnt need to wait for stonith events", action->uuid); continue; } crm_debug_2("Ordering %s after stonith events", action->uuid); if(stonith_op != NULL) { custom_action_order( NULL, crm_strdup(CRM_OP_FENCE), stonith_op, rsc, NULL, action, pe_order_optional, data_set); } else if(run_unprotected == FALSE) { /* mark the start unrunnable */ action->runnable = FALSE; } else { is_unprotected = TRUE; } ); } if(is_unprotected) { pe_err("SHARED RESOURCE %s IS NOT PROTECTED:" " Stonith disabled", rsc->id); } } static void native_stop_constraints( resource_t *rsc, action_t *stonith_op, gboolean is_stonith, pe_working_set_t *data_set) { char *key = NULL; GListPtr action_list = NULL; node_t *node = stonith_op->node; action_t *all_stopped = get_all_stopped(data_set); key = stop_key(rsc); action_list = find_actions(rsc->actions, key, node); crm_free(key); /* add the stonith OP as a stop pre-req and the mark the stop * as a pseudo op - since its now redundant */ slist_iter( action, action_t, action_list, lpc2, if(node->details->online == FALSE || node->details->unclean || rsc->failed) { resource_t *parent = NULL; if(rsc->failed) { crm_warn("Stop of failed resource %s is" " implicit after %s is fenced", rsc->id, node->details->uname); } else { crm_info("%s is implicit after %s is fenced", action->uuid, node->details->uname); } /* the stop would never complete and is * now implied by the stonith operation */ action->pseudo = TRUE; action->runnable = TRUE; if(is_stonith == FALSE) { custom_action_order( NULL, crm_strdup(CRM_OP_FENCE),stonith_op, rsc, stop_key(rsc), NULL, pe_order_optional, data_set); } /* find the top-most resource */ parent = rsc->parent; while(parent != NULL && parent->parent != NULL) { parent = parent->parent; } if(parent) { crm_info("Re-creating actions for %s", parent->id); parent->cmds->create_actions(parent, data_set); /* make sure we dont mess anything up in create_actions */ CRM_CHECK(action->pseudo, action->pseudo = TRUE); CRM_CHECK(action->runnable, action->runnable = TRUE); } /* From Bug #1601, successful fencing must be an input to a failed resources stop action. However given group(A, B) running on nodeX and B.stop has failed, A := stop healthy resource (A.stop) B := stop failed resource (pseudo operation B.stop) C := stonith nodeX A requires B, B requires C, C requires A This loop would prevent the cluster from making progress. This block creates the "C requires A" dependancy and therefore must (at least for now) be disabled. Instead, run the block above and treat all resources on nodeX as B would be (marked as a pseudo op depending on the STONITH). } else if(is_stonith == FALSE) { crm_info("Moving healthy resource %s" " off %s before fencing", rsc->id, node->details->uname); * stop healthy resources before the * stonith op * custom_action_order( rsc, stop_key(rsc), NULL, NULL,crm_strdup(CRM_OP_FENCE),stonith_op, pe_order_optional, data_set); */ } ); g_list_free(action_list); key = demote_key(rsc); action_list = find_actions(rsc->actions, key, node); crm_free(key); slist_iter( action, action_t, action_list, lpc2, if(node->details->online == FALSE || rsc->failed) { crm_info("Demote of failed resource %s is" " implict after %s is fenced", rsc->id, node->details->uname); /* the stop would never complete and is * now implied by the stonith operation */ action->pseudo = TRUE; action->runnable = TRUE; if(is_stonith == FALSE) { custom_action_order( NULL, crm_strdup(CRM_OP_FENCE), stonith_op, rsc, demote_key(rsc), NULL, pe_order_optional, data_set); } } ); if(is_stonith) { custom_action_order( NULL, crm_strdup(all_stopped->task), all_stopped, rsc, stop_key(rsc), NULL, pe_order_implies_left, data_set); } else { custom_action_order( rsc, stop_key(rsc), NULL, NULL, crm_strdup(all_stopped->task), all_stopped, pe_order_implies_right, data_set); } g_list_free(action_list); } void native_stonith_ordering( resource_t *rsc, action_t *stonith_op, pe_working_set_t *data_set) { gboolean is_stonith = FALSE; const char *class = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS); if(rsc->is_managed == FALSE) { crm_debug_3("Skipping fencing constraints for unmanaged resource: %s", rsc->id); return; } if(stonith_op != NULL && safe_str_eq(class, "stonith")) { is_stonith = TRUE; } /* Start constraints */ native_start_constraints(rsc, stonith_op, is_stonith, data_set); /* Stop constraints */ native_stop_constraints(rsc, stonith_op, is_stonith, data_set); } void native_migrate_reload(resource_t *rsc, pe_working_set_t *data_set) { char *key = NULL; int level = LOG_DEBUG_2; GListPtr action_list = NULL; action_t *stop = NULL; action_t *start = NULL; action_t *other = NULL; action_t *action = NULL; const char *value = NULL; CRM_CHECK(rsc->variant == pe_native, return); if(rsc->is_managed == FALSE || rsc->failed || rsc->start_pending || rsc->next_role != RSC_ROLE_STARTED || g_list_length(rsc->running_on) != 1) { do_crm_log(level, "%s: resource", rsc->id); return; } key = start_key(rsc); action_list = find_actions(rsc->actions, key, NULL); crm_free(key); if(action_list == NULL) { do_crm_log(level, "%s: no start action", rsc->id); return; } start = action_list->data; g_list_free(action_list); value = g_hash_table_lookup(rsc->meta, "allow_migrate"); if(crm_is_true(value)) { rsc->can_migrate = TRUE; } if(rsc->can_migrate == FALSE && start->allow_reload_conversion == FALSE) { do_crm_log(level, "%s: no need to continue", rsc->id); return; } key = stop_key(rsc); action_list = find_actions(rsc->actions, key, NULL); crm_free(key); if(action_list == NULL) { do_crm_log(level, "%s: no stop action", rsc->id); return; } stop = action_list->data; g_list_free(action_list); action = start; if(action->pseudo || action->optional || action->node == NULL || action->runnable == FALSE) { do_crm_log(level, "%s: %s", rsc->id, action->task); return; } action = stop; if(action->pseudo || action->optional || action->node == NULL || action->runnable == FALSE) { do_crm_log(level, "%s: %s", rsc->id, action->task); return; } slist_iter( other_w, action_wrapper_t, start->actions_before, lpc, gboolean can_migrate = TRUE; resource_t *parent = NULL; other = other_w->action; parent = uber_parent(other->rsc); if(other->optional == TRUE || other->rsc == rsc || parent == NULL) { continue; } if(parent->variant == pe_native || parent->variant == pe_group) { /* clones are the only ones that can be "moved" * and still allow resources sitting on top of * them (ie. us) to be migrated */ can_migrate = FALSE; } else if(safe_str_eq(other->task, CRMD_ACTION_MIGRATE) || safe_str_eq(other->task, CRMD_ACTION_MIGRATED)) { /* we depend on something that is already migrating... * we cant both migrate */ can_migrate = FALSE; } else { /* is the clone also moving moved around? * * if so, then we can't yet be completely sure the * resource can safely migrate since the node we're * moving too may not have the clone instance started * yet * * in theory we can figure out if the clone instance we * will run on is already there, but there that would * involve too much knowledge of internal clone code. * maybe later... */ do_crm_log(level, "%s: start depends on clone %s", rsc->id, parent->id); key = stop_key(parent); action_list = find_actions(parent->actions, key, NULL); crm_free(key); slist_iter( other_stop, action_t, action_list,lpc, if(other_stop && other_stop->optional == FALSE) { do_crm_log(LOG_INFO, "%s: start depends on %s", rsc->id, other_stop->uuid); can_migrate = FALSE; } ); g_list_free(action_list); } if(can_migrate == FALSE) { do_crm_log(LOG_INFO, "%s: start depends on %s", rsc->id, other->uuid); return; } ); if(rsc->can_migrate && stop->node->details != start->node->details) { crm_info("Migrating %s from %s to %s", rsc->id, stop->node->details->uname, start->node->details->uname); crm_free(stop->uuid); crm_free(stop->task); stop->task = crm_strdup(CRMD_ACTION_MIGRATE); stop->uuid = generate_op_key(rsc->id, stop->task, 0); add_hash_param(stop->meta, "migrate_source", stop->node->details->uname); add_hash_param(stop->meta, "migrate_target", start->node->details->uname); slist_iter( other_w, action_wrapper_t, start->actions_before, lpc, other = other_w->action; if(other->optional == FALSE && other->rsc != NULL && other->rsc != rsc) { order_actions(other, stop, other_w->type); } ); crm_free(start->uuid); crm_free(start->task); start->task = crm_strdup(CRMD_ACTION_MIGRATED); start->uuid = generate_op_key(rsc->id, start->task, 0); add_hash_param(start->meta, "migrate_source_uuid", stop->node->details->id); add_hash_param(start->meta, "migrate_source", stop->node->details->uname); add_hash_param(start->meta, "migrate_target", start->node->details->uname); } else if(start->allow_reload_conversion && stop->node->details == start->node->details) { crm_info("Rewriting restart of %s on %s as a reload", rsc->id, start->node->details->uname); crm_free(start->uuid); crm_free(start->task); start->task = crm_strdup("reload"); start->uuid = generate_op_key(rsc->id, start->task, 0); stop->pseudo = TRUE; /* easier than trying to delete it from the graph */ } else { do_crm_log(level, "%s nothing to do", rsc->id); } } diff --git a/crm/pengine/testcases/594.dot b/crm/pengine/testcases/594.dot index 11e1d4bdfb..c6f752655a 100644 --- a/crm/pengine/testcases/594.dot +++ b/crm/pengine/testcases/594.dot @@ -1,50 +1,52 @@ digraph "g" { "DcIPaddr_monitor_0 hadev1" -> "probe_complete hadev1" [ style = bold] "DcIPaddr_monitor_0 hadev1" [ style=bold color="green" fontcolor="black" ] "DcIPaddr_monitor_5000 hadev1" [ style=bold color="green" fontcolor="black" ] "DcIPaddr_start_0 hadev1" -> "DcIPaddr_monitor_5000 hadev1" [ style = bold] "DcIPaddr_start_0 hadev1" [ style=bold color="green" fontcolor="black" ] "DcIPaddr_stop_0 hadev2" -> "DcIPaddr_start_0 hadev1" [ style = bold] "DcIPaddr_stop_0 hadev2" -> "all_stopped" [ style = bold] "DcIPaddr_stop_0 hadev2" -> "do_shutdown hadev2" [ style = bold] "DcIPaddr_stop_0 hadev2" [ style=bold color="green" fontcolor="black" ] "DoFencing_stop_0" -> "DoFencing_stopped_0" [ style = bold] "DoFencing_stop_0" -> "child_DoFencing:0_stop_0 hadev2" [ style = bold] "DoFencing_stop_0" -> "child_DoFencing:2_stop_0 hadev1" [ style = bold] "DoFencing_stop_0" [ style=bold color="green" fontcolor="orange" ] "DoFencing_stopped_0" [ style=bold color="green" fontcolor="orange" ] "all_stopped" -> "child_DoFencing:0_stop_0 hadev2" [ style = bold] "all_stopped" -> "child_DoFencing:2_stop_0 hadev1" [ style = bold] "all_stopped" [ style=bold color="green" fontcolor="orange" ] "child_DoFencing:0_monitor_0 hadev1" -> "probe_complete hadev1" [ style = bold] "child_DoFencing:0_monitor_0 hadev1" [ style=bold color="green" fontcolor="black" ] "child_DoFencing:0_stop_0 hadev2" -> "DoFencing_stopped_0" [ style = bold] "child_DoFencing:0_stop_0 hadev2" -> "do_shutdown hadev2" [ style = bold] "child_DoFencing:0_stop_0 hadev2" [ style=bold color="green" fontcolor="black" ] "child_DoFencing:2_monitor_0 hadev2" -> "probe_complete hadev2" [ style = bold] "child_DoFencing:2_monitor_0 hadev2" [ style=bold color="green" fontcolor="black" ] "child_DoFencing:2_stop_0 hadev1" -> "DoFencing_stopped_0" [ style = bold] "child_DoFencing:2_stop_0 hadev1" [ style=bold color="green" fontcolor="black" ] "do_shutdown hadev2" [ style=bold color="green" fontcolor="black" ] "probe_complete hadev1" -> "probe_complete" [ style = bold] "probe_complete hadev1" [ style=bold color="green" fontcolor="black" ] "probe_complete hadev2" -> "probe_complete" [ style = bold] "probe_complete hadev2" [ style=bold color="green" fontcolor="black" ] "probe_complete" -> "DcIPaddr_start_0 hadev1" [ style = bold] "probe_complete" -> "rsc_hadev2_start_0 hadev1" [ style = bold] "probe_complete" [ style=bold color="green" fontcolor="orange" ] "rsc_hadev2_monitor_0 hadev1" -> "probe_complete hadev1" [ style = bold] "rsc_hadev2_monitor_0 hadev1" [ style=bold color="green" fontcolor="black" ] "rsc_hadev2_monitor_5000 hadev1" [ style=bold color="green" fontcolor="black" ] "rsc_hadev2_start_0 hadev1" -> "rsc_hadev2_monitor_5000 hadev1" [ style = bold] "rsc_hadev2_start_0 hadev1" [ style=bold color="green" fontcolor="black" ] "rsc_hadev2_stop_0 hadev2" -> "all_stopped" [ style = bold] "rsc_hadev2_stop_0 hadev2" -> "do_shutdown hadev2" [ style = bold] "rsc_hadev2_stop_0 hadev2" -> "rsc_hadev2_start_0 hadev1" [ style = bold] "rsc_hadev2_stop_0 hadev2" [ style=bold color="green" fontcolor="black" ] "rsc_hadev3_monitor_0 hadev2" -> "probe_complete hadev2" [ style = bold] "rsc_hadev3_monitor_0 hadev2" [ style=bold color="green" fontcolor="black" ] "stonith hadev3" -> "all_stopped" [ style = bold] "stonith hadev3" -> "rsc_hadev2_start_0 hadev1" [ style = bold] "stonith hadev3" [ style=bold color="green" fontcolor="black" ] +"stonith_up" -> "stonith hadev3" [ style = bold] +"stonith_up" [ style=bold color="green" fontcolor="orange" ] } diff --git a/crm/pengine/testcases/594.exp b/crm/pengine/testcases/594.exp index edfc59ccd8..4979133a36 100644 --- a/crm/pengine/testcases/594.exp +++ b/crm/pengine/testcases/594.exp @@ -1,311 +1,323 @@ - + - + - + - - - + + + - + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + diff --git a/crm/pengine/testcases/829.dot b/crm/pengine/testcases/829.dot index f8bb2f8711..054ffb233b 100644 --- a/crm/pengine/testcases/829.dot +++ b/crm/pengine/testcases/829.dot @@ -1,61 +1,63 @@ digraph "g" { "DcIPaddr_monitor_0 c001n01" -> "probe_complete c001n01" [ style = bold] "DcIPaddr_monitor_0 c001n01" [ style=bold color="green" fontcolor="black" ] "DcIPaddr_monitor_0 c001n03" -> "probe_complete c001n03" [ style = bold] "DcIPaddr_monitor_0 c001n03" [ style=bold color="green" fontcolor="black" ] "DoFencing_stop_0" -> "DoFencing_stopped_0" [ style = bold] "DoFencing_stop_0" -> "child_DoFencing:0_stop_0 c001n02" [ style = bold] "DoFencing_stop_0" [ style=bold color="green" fontcolor="orange" ] "DoFencing_stopped_0" [ style=bold color="green" fontcolor="orange" ] "all_stopped" -> "child_DoFencing:0_stop_0 c001n02" [ style = bold] "all_stopped" [ style=bold color="green" fontcolor="orange" ] "child_DoFencing:0_monitor_0 c001n01" -> "probe_complete c001n01" [ style = bold] "child_DoFencing:0_monitor_0 c001n01" [ style=bold color="green" fontcolor="black" ] "child_DoFencing:0_stop_0 c001n02" -> "DoFencing_stopped_0" [ style = bold] "child_DoFencing:0_stop_0 c001n02" [ style=bold color="green" fontcolor="orange" ] "child_DoFencing:1_monitor_0 c001n01" -> "probe_complete c001n01" [ style = bold] "child_DoFencing:1_monitor_0 c001n01" [ style=bold color="green" fontcolor="black" ] "child_DoFencing:2_monitor_0 c001n03" -> "probe_complete c001n03" [ style = bold] "child_DoFencing:2_monitor_0 c001n03" [ style=bold color="green" fontcolor="black" ] "child_DoFencing:2_monitor_0 c001n08" -> "probe_complete c001n08" [ style = bold] "child_DoFencing:2_monitor_0 c001n08" [ style=bold color="green" fontcolor="black" ] "child_DoFencing:3_monitor_0 c001n01" -> "probe_complete c001n01" [ style = bold] "child_DoFencing:3_monitor_0 c001n01" [ style=bold color="green" fontcolor="black" ] "child_DoFencing:3_monitor_0 c001n03" -> "probe_complete c001n03" [ style = bold] "child_DoFencing:3_monitor_0 c001n03" [ style=bold color="green" fontcolor="black" ] "probe_complete c001n01" -> "probe_complete" [ style = bold] "probe_complete c001n01" [ style=bold color="green" fontcolor="black" ] "probe_complete c001n03" -> "probe_complete" [ style = bold] "probe_complete c001n03" [ style=bold color="green" fontcolor="black" ] "probe_complete c001n08" -> "probe_complete" [ style = bold] "probe_complete c001n08" [ style=bold color="green" fontcolor="black" ] "probe_complete" -> "rsc_c001n02_start_0 c001n03" [ style = bold] "probe_complete" [ style=bold color="green" fontcolor="orange" ] "rsc_c001n01_monitor_0 c001n03" -> "probe_complete c001n03" [ style = bold] "rsc_c001n01_monitor_0 c001n03" [ style=bold color="green" fontcolor="black" ] "rsc_c001n01_monitor_0 c001n08" -> "probe_complete c001n08" [ style = bold] "rsc_c001n01_monitor_0 c001n08" [ style=bold color="green" fontcolor="black" ] "rsc_c001n02_monitor_0 c001n01" -> "probe_complete c001n01" [ style = bold] "rsc_c001n02_monitor_0 c001n01" [ style=bold color="green" fontcolor="black" ] "rsc_c001n02_monitor_0 c001n03" -> "probe_complete c001n03" [ style = bold] "rsc_c001n02_monitor_0 c001n03" [ style=bold color="green" fontcolor="black" ] "rsc_c001n02_monitor_0 c001n08" -> "probe_complete c001n08" [ style = bold] "rsc_c001n02_monitor_0 c001n08" [ style=bold color="green" fontcolor="black" ] "rsc_c001n02_monitor_5000 c001n03" [ style=bold color="green" fontcolor="black" ] "rsc_c001n02_start_0 c001n03" -> "rsc_c001n02_monitor_5000 c001n03" [ style = bold] "rsc_c001n02_start_0 c001n03" [ style=bold color="green" fontcolor="black" ] "rsc_c001n02_stop_0 c001n02" -> "all_stopped" [ style = bold] "rsc_c001n02_stop_0 c001n02" -> "rsc_c001n02_start_0 c001n03" [ style = bold] "rsc_c001n02_stop_0 c001n02" [ style=bold color="green" fontcolor="orange" ] "rsc_c001n03_monitor_0 c001n01" -> "probe_complete c001n01" [ style = bold] "rsc_c001n03_monitor_0 c001n01" [ style=bold color="green" fontcolor="black" ] "rsc_c001n03_monitor_0 c001n08" -> "probe_complete c001n08" [ style = bold] "rsc_c001n03_monitor_0 c001n08" [ style=bold color="green" fontcolor="black" ] "rsc_c001n08_monitor_0 c001n01" -> "probe_complete c001n01" [ style = bold] "rsc_c001n08_monitor_0 c001n01" [ style=bold color="green" fontcolor="black" ] "rsc_c001n08_monitor_0 c001n03" -> "probe_complete c001n03" [ style = bold] "rsc_c001n08_monitor_0 c001n03" [ style=bold color="green" fontcolor="black" ] "stonith c001n02" -> "all_stopped" [ style = bold] "stonith c001n02" -> "rsc_c001n02_stop_0 c001n02" [ style = bold] "stonith c001n02" [ style=bold color="green" fontcolor="black" ] +"stonith_up" -> "stonith c001n02" [ style = bold] +"stonith_up" [ style=bold color="green" fontcolor="orange" ] } diff --git a/crm/pengine/testcases/829.exp b/crm/pengine/testcases/829.exp index 3f814ba693..2d70f26b86 100644 --- a/crm/pengine/testcases/829.exp +++ b/crm/pengine/testcases/829.exp @@ -1,371 +1,383 @@ - + - + - - - + + + - + + + + + + + + + + + + + - + - + - + - + - + diff --git a/crm/pengine/testcases/master-7.dot b/crm/pengine/testcases/master-7.dot index 0ef41adff1..0c2095f0db 100644 --- a/crm/pengine/testcases/master-7.dot +++ b/crm/pengine/testcases/master-7.dot @@ -1,128 +1,130 @@ digraph "g" { "DcIPaddr_monitor_5000 c001n03" [ style=bold color="green" fontcolor="black" ] "DcIPaddr_start_0 c001n03" -> "DcIPaddr_monitor_5000 c001n03" [ style = bold] "DcIPaddr_start_0 c001n03" [ style=bold color="green" fontcolor="black" ] "DcIPaddr_stop_0 c001n01" -> "DcIPaddr_start_0 c001n03" [ style = bold] "DcIPaddr_stop_0 c001n01" -> "all_stopped" [ style = bold] "DcIPaddr_stop_0 c001n01" [ style=bold color="green" fontcolor="orange" ] "DoFencing_stop_0" -> "DoFencing_stopped_0" [ style = bold] "DoFencing_stop_0" -> "child_DoFencing:0_stop_0 c001n01" [ style = bold] "DoFencing_stop_0" [ style=bold color="green" fontcolor="orange" ] "DoFencing_stopped_0" [ style=bold color="green" fontcolor="orange" ] "all_stopped" -> "child_DoFencing:0_stop_0 c001n01" [ style = bold] "all_stopped" [ style=bold color="green" fontcolor="orange" ] "child_DoFencing:0_stop_0 c001n01" -> "DoFencing_stopped_0" [ style = bold] "child_DoFencing:0_stop_0 c001n01" [ style=bold color="green" fontcolor="orange" ] "child_DoFencing:2_monitor_0 c001n03" -> "probe_complete c001n03" [ style = bold] "child_DoFencing:2_monitor_0 c001n03" [ style=bold color="green" fontcolor="black" ] "child_DoFencing:2_monitor_0 c001n08" -> "probe_complete c001n08" [ style = bold] "child_DoFencing:2_monitor_0 c001n08" [ style=bold color="green" fontcolor="black" ] "child_DoFencing:3_monitor_0 c001n02" -> "probe_complete c001n02" [ style = bold] "child_DoFencing:3_monitor_0 c001n02" [ style=bold color="green" fontcolor="black" ] "child_DoFencing:3_monitor_0 c001n03" -> "probe_complete c001n03" [ style = bold] "child_DoFencing:3_monitor_0 c001n03" [ style=bold color="green" fontcolor="black" ] "group-1_running_0" [ style=bold color="green" fontcolor="orange" ] "group-1_start_0" -> "group-1_running_0" [ style = bold] "group-1_start_0" -> "ocf_192.168.100.181_start_0 c001n02" [ style = bold] "group-1_start_0" [ style=bold color="green" fontcolor="orange" ] "group-1_stop_0" -> "group-1_start_0" [ style = bold] "group-1_stop_0" -> "group-1_stopped_0" [ style = bold] "group-1_stop_0" -> "heartbeat_192.168.100.182_stop_0 c001n03" [ style = bold] "group-1_stop_0" -> "ocf_192.168.100.181_stop_0 c001n03" [ style = bold] "group-1_stop_0" -> "ocf_192.168.100.183_stop_0 c001n03" [ style = bold] "group-1_stop_0" [ style=bold color="green" fontcolor="orange" ] "group-1_stopped_0" -> "group-1_start_0" [ style = bold] "group-1_stopped_0" [ style=bold color="green" fontcolor="orange" ] "heartbeat_192.168.100.182_monitor_5000 c001n02" [ style=bold color="green" fontcolor="black" ] "heartbeat_192.168.100.182_start_0 c001n02" -> "group-1_running_0" [ style = bold] "heartbeat_192.168.100.182_start_0 c001n02" -> "heartbeat_192.168.100.182_monitor_5000 c001n02" [ style = bold] "heartbeat_192.168.100.182_start_0 c001n02" -> "ocf_192.168.100.183_start_0 c001n02" [ style = bold] "heartbeat_192.168.100.182_start_0 c001n02" [ style=bold color="green" fontcolor="black" ] "heartbeat_192.168.100.182_stop_0 c001n03" -> "all_stopped" [ style = bold] "heartbeat_192.168.100.182_stop_0 c001n03" -> "group-1_stopped_0" [ style = bold] "heartbeat_192.168.100.182_stop_0 c001n03" -> "heartbeat_192.168.100.182_start_0 c001n02" [ style = bold] "heartbeat_192.168.100.182_stop_0 c001n03" -> "ocf_192.168.100.181_stop_0 c001n03" [ style = bold] "heartbeat_192.168.100.182_stop_0 c001n03" [ style=bold color="green" fontcolor="black" ] "lsb_dummy_monitor_5000 c001n08" [ style=bold color="green" fontcolor="black" ] "lsb_dummy_start_0 c001n08" -> "lsb_dummy_monitor_5000 c001n08" [ style = bold] "lsb_dummy_start_0 c001n08" [ style=bold color="green" fontcolor="black" ] "lsb_dummy_stop_0 c001n02" -> "all_stopped" [ style = bold] "lsb_dummy_stop_0 c001n02" -> "lsb_dummy_start_0 c001n08" [ style = bold] "lsb_dummy_stop_0 c001n02" [ style=bold color="green" fontcolor="black" ] "master_rsc_1_demote_0" -> "master_rsc_1_demoted_0" [ style = bold] "master_rsc_1_demote_0" -> "master_rsc_1_stop_0" [ style = bold] "master_rsc_1_demote_0" -> "ocf_msdummy:0_demote_0 c001n01" [ style = bold] "master_rsc_1_demote_0" [ style=bold color="green" fontcolor="orange" ] "master_rsc_1_demoted_0" -> "master_rsc_1_stop_0" [ style = bold] "master_rsc_1_demoted_0" [ style=bold color="green" fontcolor="orange" ] "master_rsc_1_stop_0" -> "master_rsc_1_stopped_0" [ style = bold] "master_rsc_1_stop_0" -> "ocf_msdummy:0_stop_0 c001n01" [ style = bold] "master_rsc_1_stop_0" -> "ocf_msdummy:4_stop_0 c001n01" [ style = bold] "master_rsc_1_stop_0" [ style=bold color="green" fontcolor="orange" ] "master_rsc_1_stopped_0" [ style=bold color="green" fontcolor="orange" ] "ocf_192.168.100.181_monitor_5000 c001n02" [ style=bold color="green" fontcolor="black" ] "ocf_192.168.100.181_start_0 c001n02" -> "group-1_running_0" [ style = bold] "ocf_192.168.100.181_start_0 c001n02" -> "heartbeat_192.168.100.182_start_0 c001n02" [ style = bold] "ocf_192.168.100.181_start_0 c001n02" -> "ocf_192.168.100.181_monitor_5000 c001n02" [ style = bold] "ocf_192.168.100.181_start_0 c001n02" [ style=bold color="green" fontcolor="black" ] "ocf_192.168.100.181_stop_0 c001n03" -> "all_stopped" [ style = bold] "ocf_192.168.100.181_stop_0 c001n03" -> "group-1_stopped_0" [ style = bold] "ocf_192.168.100.181_stop_0 c001n03" -> "ocf_192.168.100.181_start_0 c001n02" [ style = bold] "ocf_192.168.100.181_stop_0 c001n03" [ style=bold color="green" fontcolor="black" ] "ocf_192.168.100.183_monitor_5000 c001n02" [ style=bold color="green" fontcolor="black" ] "ocf_192.168.100.183_start_0 c001n02" -> "group-1_running_0" [ style = bold] "ocf_192.168.100.183_start_0 c001n02" -> "ocf_192.168.100.183_monitor_5000 c001n02" [ style = bold] "ocf_192.168.100.183_start_0 c001n02" [ style=bold color="green" fontcolor="black" ] "ocf_192.168.100.183_stop_0 c001n03" -> "all_stopped" [ style = bold] "ocf_192.168.100.183_stop_0 c001n03" -> "group-1_stopped_0" [ style = bold] "ocf_192.168.100.183_stop_0 c001n03" -> "heartbeat_192.168.100.182_stop_0 c001n03" [ style = bold] "ocf_192.168.100.183_stop_0 c001n03" -> "ocf_192.168.100.183_start_0 c001n02" [ style = bold] "ocf_192.168.100.183_stop_0 c001n03" [ style=bold color="green" fontcolor="black" ] "ocf_msdummy:0_demote_0 c001n01" -> "master_rsc_1_demoted_0" [ style = bold] "ocf_msdummy:0_demote_0 c001n01" -> "ocf_msdummy:0_stop_0 c001n01" [ style = bold] "ocf_msdummy:0_demote_0 c001n01" [ style=bold color="green" fontcolor="orange" ] "ocf_msdummy:0_stop_0 c001n01" -> "all_stopped" [ style = bold] "ocf_msdummy:0_stop_0 c001n01" -> "master_rsc_1_stopped_0" [ style = bold] "ocf_msdummy:0_stop_0 c001n01" [ style=bold color="green" fontcolor="orange" ] "ocf_msdummy:4_monitor_0 c001n02" -> "probe_complete c001n02" [ style = bold] "ocf_msdummy:4_monitor_0 c001n02" [ style=bold color="green" fontcolor="black" ] "ocf_msdummy:4_monitor_0 c001n03" -> "probe_complete c001n03" [ style = bold] "ocf_msdummy:4_monitor_0 c001n03" [ style=bold color="green" fontcolor="black" ] "ocf_msdummy:4_monitor_0 c001n08" -> "probe_complete c001n08" [ style = bold] "ocf_msdummy:4_monitor_0 c001n08" [ style=bold color="green" fontcolor="black" ] "ocf_msdummy:4_stop_0 c001n01" -> "all_stopped" [ style = bold] "ocf_msdummy:4_stop_0 c001n01" -> "master_rsc_1_stopped_0" [ style = bold] "ocf_msdummy:4_stop_0 c001n01" [ style=bold color="green" fontcolor="orange" ] "ocf_msdummy:5_monitor_0 c001n02" -> "probe_complete c001n02" [ style = bold] "ocf_msdummy:5_monitor_0 c001n02" [ style=bold color="green" fontcolor="black" ] "ocf_msdummy:5_monitor_0 c001n08" -> "probe_complete c001n08" [ style = bold] "ocf_msdummy:5_monitor_0 c001n08" [ style=bold color="green" fontcolor="black" ] "ocf_msdummy:6_monitor_0 c001n03" -> "probe_complete c001n03" [ style = bold] "ocf_msdummy:6_monitor_0 c001n03" [ style=bold color="green" fontcolor="black" ] "ocf_msdummy:6_monitor_0 c001n08" -> "probe_complete c001n08" [ style = bold] "ocf_msdummy:6_monitor_0 c001n08" [ style=bold color="green" fontcolor="black" ] "ocf_msdummy:7_monitor_0 c001n02" -> "probe_complete c001n02" [ style = bold] "ocf_msdummy:7_monitor_0 c001n02" [ style=bold color="green" fontcolor="black" ] "ocf_msdummy:7_monitor_0 c001n03" -> "probe_complete c001n03" [ style = bold] "ocf_msdummy:7_monitor_0 c001n03" [ style=bold color="green" fontcolor="black" ] "probe_complete c001n02" -> "probe_complete" [ style = bold] "probe_complete c001n02" [ style=bold color="green" fontcolor="black" ] "probe_complete c001n03" -> "probe_complete" [ style = bold] "probe_complete c001n03" [ style=bold color="green" fontcolor="black" ] "probe_complete c001n08" -> "probe_complete" [ style = bold] "probe_complete c001n08" [ style=bold color="green" fontcolor="black" ] "probe_complete" [ style=bold color="green" fontcolor="orange" ] "rsc_c001n01_monitor_5000 c001n03" [ style=bold color="green" fontcolor="black" ] "rsc_c001n01_start_0 c001n03" -> "rsc_c001n01_monitor_5000 c001n03" [ style = bold] "rsc_c001n01_start_0 c001n03" [ style=bold color="green" fontcolor="black" ] "rsc_c001n01_stop_0 c001n01" -> "all_stopped" [ style = bold] "rsc_c001n01_stop_0 c001n01" -> "rsc_c001n01_start_0 c001n03" [ style = bold] "rsc_c001n01_stop_0 c001n01" [ style=bold color="green" fontcolor="orange" ] "stonith c001n01" -> "DcIPaddr_stop_0 c001n01" [ style = bold] "stonith c001n01" -> "all_stopped" [ style = bold] "stonith c001n01" -> "ocf_msdummy:0_demote_0 c001n01" [ style = bold] "stonith c001n01" -> "ocf_msdummy:0_stop_0 c001n01" [ style = bold] "stonith c001n01" -> "ocf_msdummy:4_stop_0 c001n01" [ style = bold] "stonith c001n01" -> "rsc_c001n01_stop_0 c001n01" [ style = bold] "stonith c001n01" [ style=bold color="green" fontcolor="black" ] +"stonith_up" -> "stonith c001n01" [ style = bold] +"stonith_up" [ style=bold color="green" fontcolor="orange" ] } diff --git a/crm/pengine/testcases/master-7.exp b/crm/pengine/testcases/master-7.exp index 10df847e62..d94813239a 100644 --- a/crm/pengine/testcases/master-7.exp +++ b/crm/pengine/testcases/master-7.exp @@ -1,778 +1,790 @@ - + - + - + - + - + - + - - - + + + - - - + + + - + - + - + - + - + - + - + - + + + + + - + + + + + + + + + - + - + - + - + - + diff --git a/crm/pengine/testcases/master-8.dot b/crm/pengine/testcases/master-8.dot index 5f0901eb17..203db64398 100644 --- a/crm/pengine/testcases/master-8.dot +++ b/crm/pengine/testcases/master-8.dot @@ -1,138 +1,140 @@ digraph "g" { "DcIPaddr_monitor_5000 c001n03" [ style=bold color="green" fontcolor="black" ] "DcIPaddr_start_0 c001n03" -> "DcIPaddr_monitor_5000 c001n03" [ style = bold] "DcIPaddr_start_0 c001n03" [ style=bold color="green" fontcolor="black" ] "DcIPaddr_stop_0 c001n01" -> "DcIPaddr_start_0 c001n03" [ style = bold] "DcIPaddr_stop_0 c001n01" -> "all_stopped" [ style = bold] "DcIPaddr_stop_0 c001n01" [ style=bold color="green" fontcolor="orange" ] "DoFencing_stop_0" -> "DoFencing_stopped_0" [ style = bold] "DoFencing_stop_0" -> "child_DoFencing:0_stop_0 c001n01" [ style = bold] "DoFencing_stop_0" [ style=bold color="green" fontcolor="orange" ] "DoFencing_stopped_0" [ style=bold color="green" fontcolor="orange" ] "all_stopped" -> "child_DoFencing:0_stop_0 c001n01" [ style = bold] "all_stopped" [ style=bold color="green" fontcolor="orange" ] "child_DoFencing:0_stop_0 c001n01" -> "DoFencing_stopped_0" [ style = bold] "child_DoFencing:0_stop_0 c001n01" [ style=bold color="green" fontcolor="orange" ] "child_DoFencing:2_monitor_0 c001n03" -> "probe_complete c001n03" [ style = bold] "child_DoFencing:2_monitor_0 c001n03" [ style=bold color="green" fontcolor="black" ] "child_DoFencing:2_monitor_0 c001n08" -> "probe_complete c001n08" [ style = bold] "child_DoFencing:2_monitor_0 c001n08" [ style=bold color="green" fontcolor="black" ] "child_DoFencing:3_monitor_0 c001n02" -> "probe_complete c001n02" [ style = bold] "child_DoFencing:3_monitor_0 c001n02" [ style=bold color="green" fontcolor="black" ] "child_DoFencing:3_monitor_0 c001n03" -> "probe_complete c001n03" [ style = bold] "child_DoFencing:3_monitor_0 c001n03" [ style=bold color="green" fontcolor="black" ] "group-1_running_0" [ style=bold color="green" fontcolor="orange" ] "group-1_start_0" -> "group-1_running_0" [ style = bold] "group-1_start_0" -> "ocf_192.168.100.181_start_0 c001n02" [ style = bold] "group-1_start_0" [ style=bold color="green" fontcolor="orange" ] "group-1_stop_0" -> "group-1_start_0" [ style = bold] "group-1_stop_0" -> "group-1_stopped_0" [ style = bold] "group-1_stop_0" -> "heartbeat_192.168.100.182_stop_0 c001n03" [ style = bold] "group-1_stop_0" -> "ocf_192.168.100.181_stop_0 c001n03" [ style = bold] "group-1_stop_0" -> "ocf_192.168.100.183_stop_0 c001n03" [ style = bold] "group-1_stop_0" [ style=bold color="green" fontcolor="orange" ] "group-1_stopped_0" -> "group-1_start_0" [ style = bold] "group-1_stopped_0" [ style=bold color="green" fontcolor="orange" ] "heartbeat_192.168.100.182_monitor_5000 c001n02" [ style=bold color="green" fontcolor="black" ] "heartbeat_192.168.100.182_start_0 c001n02" -> "group-1_running_0" [ style = bold] "heartbeat_192.168.100.182_start_0 c001n02" -> "heartbeat_192.168.100.182_monitor_5000 c001n02" [ style = bold] "heartbeat_192.168.100.182_start_0 c001n02" -> "ocf_192.168.100.183_start_0 c001n02" [ style = bold] "heartbeat_192.168.100.182_start_0 c001n02" [ style=bold color="green" fontcolor="black" ] "heartbeat_192.168.100.182_stop_0 c001n03" -> "all_stopped" [ style = bold] "heartbeat_192.168.100.182_stop_0 c001n03" -> "group-1_stopped_0" [ style = bold] "heartbeat_192.168.100.182_stop_0 c001n03" -> "heartbeat_192.168.100.182_start_0 c001n02" [ style = bold] "heartbeat_192.168.100.182_stop_0 c001n03" -> "ocf_192.168.100.181_stop_0 c001n03" [ style = bold] "heartbeat_192.168.100.182_stop_0 c001n03" [ style=bold color="green" fontcolor="black" ] "lsb_dummy_monitor_5000 c001n08" [ style=bold color="green" fontcolor="black" ] "lsb_dummy_start_0 c001n08" -> "lsb_dummy_monitor_5000 c001n08" [ style = bold] "lsb_dummy_start_0 c001n08" [ style=bold color="green" fontcolor="black" ] "lsb_dummy_stop_0 c001n02" -> "all_stopped" [ style = bold] "lsb_dummy_stop_0 c001n02" -> "lsb_dummy_start_0 c001n08" [ style = bold] "lsb_dummy_stop_0 c001n02" [ style=bold color="green" fontcolor="black" ] "master_rsc_1_demote_0" -> "master_rsc_1_demoted_0" [ style = bold] "master_rsc_1_demote_0" -> "master_rsc_1_stop_0" [ style = bold] "master_rsc_1_demote_0" -> "ocf_msdummy:0_demote_0 c001n01" [ style = bold] "master_rsc_1_demote_0" [ style=bold color="green" fontcolor="orange" ] "master_rsc_1_demoted_0" -> "master_rsc_1_start_0" [ style = bold] "master_rsc_1_demoted_0" -> "master_rsc_1_stop_0" [ style = bold] "master_rsc_1_demoted_0" [ style=bold color="green" fontcolor="orange" ] "master_rsc_1_running_0" [ style=bold color="green" fontcolor="orange" ] "master_rsc_1_start_0" -> "master_rsc_1_running_0" [ style = bold] "master_rsc_1_start_0" -> "ocf_msdummy:0_start_0 c001n03" [ style = bold] "master_rsc_1_start_0" [ style=bold color="green" fontcolor="orange" ] "master_rsc_1_stop_0" -> "master_rsc_1_start_0" [ style = bold] "master_rsc_1_stop_0" -> "master_rsc_1_stopped_0" [ style = bold] "master_rsc_1_stop_0" -> "ocf_msdummy:0_stop_0 c001n01" [ style = bold] "master_rsc_1_stop_0" [ style=bold color="green" fontcolor="orange" ] "master_rsc_1_stopped_0" -> "master_rsc_1_start_0" [ style = bold] "master_rsc_1_stopped_0" [ style=bold color="green" fontcolor="orange" ] "ocf_192.168.100.181_monitor_5000 c001n02" [ style=bold color="green" fontcolor="black" ] "ocf_192.168.100.181_start_0 c001n02" -> "group-1_running_0" [ style = bold] "ocf_192.168.100.181_start_0 c001n02" -> "heartbeat_192.168.100.182_start_0 c001n02" [ style = bold] "ocf_192.168.100.181_start_0 c001n02" -> "ocf_192.168.100.181_monitor_5000 c001n02" [ style = bold] "ocf_192.168.100.181_start_0 c001n02" [ style=bold color="green" fontcolor="black" ] "ocf_192.168.100.181_stop_0 c001n03" -> "all_stopped" [ style = bold] "ocf_192.168.100.181_stop_0 c001n03" -> "group-1_stopped_0" [ style = bold] "ocf_192.168.100.181_stop_0 c001n03" -> "ocf_192.168.100.181_start_0 c001n02" [ style = bold] "ocf_192.168.100.181_stop_0 c001n03" [ style=bold color="green" fontcolor="black" ] "ocf_192.168.100.183_monitor_5000 c001n02" [ style=bold color="green" fontcolor="black" ] "ocf_192.168.100.183_start_0 c001n02" -> "group-1_running_0" [ style = bold] "ocf_192.168.100.183_start_0 c001n02" -> "ocf_192.168.100.183_monitor_5000 c001n02" [ style = bold] "ocf_192.168.100.183_start_0 c001n02" [ style=bold color="green" fontcolor="black" ] "ocf_192.168.100.183_stop_0 c001n03" -> "all_stopped" [ style = bold] "ocf_192.168.100.183_stop_0 c001n03" -> "group-1_stopped_0" [ style = bold] "ocf_192.168.100.183_stop_0 c001n03" -> "heartbeat_192.168.100.182_stop_0 c001n03" [ style = bold] "ocf_192.168.100.183_stop_0 c001n03" -> "ocf_192.168.100.183_start_0 c001n02" [ style = bold] "ocf_192.168.100.183_stop_0 c001n03" [ style=bold color="green" fontcolor="black" ] "ocf_msdummy:0_demote_0 c001n01" -> "master_rsc_1_demoted_0" [ style = bold] "ocf_msdummy:0_demote_0 c001n01" -> "ocf_msdummy:0_stop_0 c001n01" [ style = bold] "ocf_msdummy:0_demote_0 c001n01" [ style=bold color="green" fontcolor="orange" ] "ocf_msdummy:0_monitor_5000 c001n03" [ style=bold color="green" fontcolor="black" ] "ocf_msdummy:0_start_0 c001n03" -> "master_rsc_1_running_0" [ style = bold] "ocf_msdummy:0_start_0 c001n03" -> "ocf_msdummy:0_monitor_5000 c001n03" [ style = bold] "ocf_msdummy:0_start_0 c001n03" [ style=bold color="green" fontcolor="black" ] "ocf_msdummy:0_stop_0 c001n01" -> "all_stopped" [ style = bold] "ocf_msdummy:0_stop_0 c001n01" -> "master_rsc_1_stopped_0" [ style = bold] "ocf_msdummy:0_stop_0 c001n01" -> "ocf_msdummy:0_start_0 c001n03" [ style = bold] "ocf_msdummy:0_stop_0 c001n01" [ style=bold color="green" fontcolor="orange" ] "ocf_msdummy:4_monitor_0 c001n02" -> "probe_complete c001n02" [ style = bold] "ocf_msdummy:4_monitor_0 c001n02" [ style=bold color="green" fontcolor="black" ] "ocf_msdummy:4_monitor_0 c001n03" -> "probe_complete c001n03" [ style = bold] "ocf_msdummy:4_monitor_0 c001n03" [ style=bold color="green" fontcolor="black" ] "ocf_msdummy:4_monitor_0 c001n08" -> "probe_complete c001n08" [ style = bold] "ocf_msdummy:4_monitor_0 c001n08" [ style=bold color="green" fontcolor="black" ] "ocf_msdummy:5_monitor_0 c001n02" -> "probe_complete c001n02" [ style = bold] "ocf_msdummy:5_monitor_0 c001n02" [ style=bold color="green" fontcolor="black" ] "ocf_msdummy:5_monitor_0 c001n03" -> "probe_complete c001n03" [ style = bold] "ocf_msdummy:5_monitor_0 c001n03" [ style=bold color="green" fontcolor="black" ] "ocf_msdummy:5_monitor_0 c001n08" -> "probe_complete c001n08" [ style = bold] "ocf_msdummy:5_monitor_0 c001n08" [ style=bold color="green" fontcolor="black" ] "ocf_msdummy:6_monitor_0 c001n03" -> "probe_complete c001n03" [ style = bold] "ocf_msdummy:6_monitor_0 c001n03" [ style=bold color="green" fontcolor="black" ] "ocf_msdummy:6_monitor_0 c001n08" -> "probe_complete c001n08" [ style = bold] "ocf_msdummy:6_monitor_0 c001n08" [ style=bold color="green" fontcolor="black" ] "ocf_msdummy:7_monitor_0 c001n02" -> "probe_complete c001n02" [ style = bold] "ocf_msdummy:7_monitor_0 c001n02" [ style=bold color="green" fontcolor="black" ] "ocf_msdummy:7_monitor_0 c001n03" -> "probe_complete c001n03" [ style = bold] "ocf_msdummy:7_monitor_0 c001n03" [ style=bold color="green" fontcolor="black" ] "probe_complete c001n02" -> "probe_complete" [ style = bold] "probe_complete c001n02" [ style=bold color="green" fontcolor="black" ] "probe_complete c001n03" -> "probe_complete" [ style = bold] "probe_complete c001n03" [ style=bold color="green" fontcolor="black" ] "probe_complete c001n08" -> "probe_complete" [ style = bold] "probe_complete c001n08" [ style=bold color="green" fontcolor="black" ] "probe_complete" -> "master_rsc_1_start_0" [ style = bold] "probe_complete" [ style=bold color="green" fontcolor="orange" ] "rsc_c001n01_monitor_5000 c001n03" [ style=bold color="green" fontcolor="black" ] "rsc_c001n01_start_0 c001n03" -> "rsc_c001n01_monitor_5000 c001n03" [ style = bold] "rsc_c001n01_start_0 c001n03" [ style=bold color="green" fontcolor="black" ] "rsc_c001n01_stop_0 c001n01" -> "all_stopped" [ style = bold] "rsc_c001n01_stop_0 c001n01" -> "rsc_c001n01_start_0 c001n03" [ style = bold] "rsc_c001n01_stop_0 c001n01" [ style=bold color="green" fontcolor="orange" ] "stonith c001n01" -> "DcIPaddr_stop_0 c001n01" [ style = bold] "stonith c001n01" -> "all_stopped" [ style = bold] "stonith c001n01" -> "ocf_msdummy:0_demote_0 c001n01" [ style = bold] "stonith c001n01" -> "ocf_msdummy:0_stop_0 c001n01" [ style = bold] "stonith c001n01" -> "rsc_c001n01_stop_0 c001n01" [ style = bold] "stonith c001n01" [ style=bold color="green" fontcolor="black" ] +"stonith_up" -> "stonith c001n01" [ style = bold] +"stonith_up" [ style=bold color="green" fontcolor="orange" ] } diff --git a/crm/pengine/testcases/master-8.exp b/crm/pengine/testcases/master-8.exp index d8fe483e46..a7e245d70d 100644 --- a/crm/pengine/testcases/master-8.exp +++ b/crm/pengine/testcases/master-8.exp @@ -1,825 +1,837 @@ - + - + - + - + - + - - - + + + - - - + + + - + - + - + - + - + - + - + - + + + + + - + + + + + + + + + - + - + - + diff --git a/crm/pengine/testcases/rec-node-11.dot b/crm/pengine/testcases/rec-node-11.dot index 35fda2d2c4..378d231b76 100644 --- a/crm/pengine/testcases/rec-node-11.dot +++ b/crm/pengine/testcases/rec-node-11.dot @@ -1,48 +1,50 @@ digraph "g" { "all_stopped" [ style=bold color="green" fontcolor="orange" ] "group1_running_0" [ style=bold color="green" fontcolor="orange" ] "group1_start_0" -> "group1_running_0" [ style = bold] "group1_start_0" -> "rsc1_start_0 node2" [ style = bold] "group1_start_0" [ style=bold color="green" fontcolor="orange" ] "group1_stop_0" -> "group1_start_0" [ style = bold] "group1_stop_0" -> "group1_stopped_0" [ style = bold] "group1_stop_0" -> "rsc1_stop_0 node1" [ style = bold] "group1_stop_0" -> "rsc2_stop_0 node1" [ style = bold] "group1_stop_0" -> "rsc3_stop_0 node2" [ style = bold] "group1_stop_0" [ style=bold color="green" fontcolor="orange" ] "group1_stopped_0" -> "group1_start_0" [ style = bold] "group1_stopped_0" -> "rsc3_stop_0 node2" [ style = bold] "group1_stopped_0" [ style=bold color="green" fontcolor="orange" ] "probe_complete node2" -> "probe_complete" [ style = bold] "probe_complete node2" [ style=bold color="green" fontcolor="black" ] "probe_complete" -> "group1_start_0" [ style = bold] "probe_complete" [ style=bold color="green" fontcolor="orange" ] "rsc1_monitor_0 node2" -> "probe_complete node2" [ style = bold] "rsc1_monitor_0 node2" [ style=bold color="green" fontcolor="black" ] "rsc1_start_0 node2" -> "group1_running_0" [ style = bold] "rsc1_start_0 node2" -> "rsc2_start_0 node2" [ style = bold] "rsc1_start_0 node2" [ style=bold color="green" fontcolor="black" ] "rsc1_stop_0 node1" -> "all_stopped" [ style = bold] "rsc1_stop_0 node1" -> "group1_stopped_0" [ style = bold] "rsc1_stop_0 node1" -> "rsc1_start_0 node2" [ style = bold] "rsc1_stop_0 node1" [ style=bold color="green" fontcolor="orange" ] "rsc2_monitor_0 node2" -> "probe_complete node2" [ style = bold] "rsc2_monitor_0 node2" [ style=bold color="green" fontcolor="black" ] "rsc2_start_0 node2" -> "group1_running_0" [ style = bold] "rsc2_start_0 node2" [ style=bold color="green" fontcolor="black" ] "rsc2_stop_0 node1" -> "all_stopped" [ style = bold] "rsc2_stop_0 node1" -> "group1_stopped_0" [ style = bold] "rsc2_stop_0 node1" -> "rsc1_stop_0 node1" [ style = bold] "rsc2_stop_0 node1" -> "rsc2_start_0 node2" [ style = bold] "rsc2_stop_0 node1" [ style=bold color="green" fontcolor="orange" ] "rsc3_start_0 node2" -> "group1_start_0" [ style = bold] "rsc3_start_0 node2" [ style=bold color="green" fontcolor="black" ] "rsc3_stop_0 node2" -> "all_stopped" [ style = bold] "rsc3_stop_0 node2" -> "rsc3_start_0 node2" [ style = bold] "rsc3_stop_0 node2" [ style=bold color="green" fontcolor="black" ] "stonith node1" -> "all_stopped" [ style = bold] "stonith node1" -> "rsc1_stop_0 node1" [ style = bold] "stonith node1" -> "rsc2_stop_0 node1" [ style = bold] "stonith node1" -> "rsc3_start_0 node2" [ style = bold] "stonith node1" [ style=bold color="green" fontcolor="black" ] +"stonith_up" -> "stonith node1" [ style = bold] +"stonith_up" [ style=bold color="green" fontcolor="orange" ] } diff --git a/crm/pengine/testcases/rec-node-11.exp b/crm/pengine/testcases/rec-node-11.exp index 3fc745a10c..dfb5f6e371 100644 --- a/crm/pengine/testcases/rec-node-11.exp +++ b/crm/pengine/testcases/rec-node-11.exp @@ -1,266 +1,278 @@ - + - + - + - - - + + + - - - + + + - + - + - + - + + + + + + + + + + + + + diff --git a/crm/pengine/testcases/rec-node-12.dot b/crm/pengine/testcases/rec-node-12.dot index dc26269b00..a67fb43a21 100644 --- a/crm/pengine/testcases/rec-node-12.dot +++ b/crm/pengine/testcases/rec-node-12.dot @@ -1,108 +1,110 @@ digraph "g" { "DcIPaddr_monitor_0 c001n01" -> "probe_complete c001n01" [ style = bold] "DcIPaddr_monitor_0 c001n01" [ style=bold color="green" fontcolor="black" ] "DcIPaddr_monitor_0 c001n03" -> "probe_complete c001n03" [ style = bold] "DcIPaddr_monitor_0 c001n03" [ style=bold color="green" fontcolor="black" ] "DcIPaddr_monitor_0 c001n08" -> "probe_complete c001n08" [ style = bold] "DcIPaddr_monitor_0 c001n08" [ style=bold color="green" fontcolor="black" ] "DcIPaddr_monitor_5000 c001n08" [ style=bold color="green" fontcolor="black" ] "DcIPaddr_start_0 c001n08" -> "DcIPaddr_monitor_5000 c001n08" [ style = bold] "DcIPaddr_start_0 c001n08" [ style=bold color="green" fontcolor="black" ] "DoFencing_running_0" [ style=bold color="green" fontcolor="orange" ] "DoFencing_start_0" -> "DoFencing_running_0" [ style = bold] "DoFencing_start_0" -> "child_DoFencing:0_start_0 c001n01" [ style = bold] "DoFencing_start_0" -> "child_DoFencing:1_start_0 c001n08" [ style = bold] "DoFencing_start_0" -> "child_DoFencing:2_start_0 c001n03" [ style = bold] "DoFencing_start_0" [ style=bold color="green" fontcolor="orange" ] "all_stopped" [ style=bold color="green" fontcolor="orange" ] "child_DoFencing:0_monitor_0 c001n01" -> "probe_complete c001n01" [ style = bold] "child_DoFencing:0_monitor_0 c001n01" [ style=bold color="green" fontcolor="black" ] "child_DoFencing:0_monitor_0 c001n03" -> "probe_complete c001n03" [ style = bold] "child_DoFencing:0_monitor_0 c001n03" [ style=bold color="green" fontcolor="black" ] "child_DoFencing:0_monitor_0 c001n08" -> "probe_complete c001n08" [ style = bold] "child_DoFencing:0_monitor_0 c001n08" [ style=bold color="green" fontcolor="black" ] "child_DoFencing:0_monitor_5000 c001n01" [ style=bold color="green" fontcolor="black" ] "child_DoFencing:0_start_0 c001n01" -> "DoFencing_running_0" [ style = bold] "child_DoFencing:0_start_0 c001n01" -> "child_DoFencing:0_monitor_5000 c001n01" [ style = bold] -"child_DoFencing:0_start_0 c001n01" -> "stonith c001n02" [ style = bold] +"child_DoFencing:0_start_0 c001n01" -> "stonith_up" [ style = bold] "child_DoFencing:0_start_0 c001n01" [ style=bold color="green" fontcolor="black" ] "child_DoFencing:1_monitor_0 c001n01" -> "probe_complete c001n01" [ style = bold] "child_DoFencing:1_monitor_0 c001n01" [ style=bold color="green" fontcolor="black" ] "child_DoFencing:1_monitor_0 c001n03" -> "probe_complete c001n03" [ style = bold] "child_DoFencing:1_monitor_0 c001n03" [ style=bold color="green" fontcolor="black" ] "child_DoFencing:1_monitor_0 c001n08" -> "probe_complete c001n08" [ style = bold] "child_DoFencing:1_monitor_0 c001n08" [ style=bold color="green" fontcolor="black" ] "child_DoFencing:1_monitor_5000 c001n08" [ style=bold color="green" fontcolor="black" ] "child_DoFencing:1_start_0 c001n08" -> "DoFencing_running_0" [ style = bold] "child_DoFencing:1_start_0 c001n08" -> "child_DoFencing:1_monitor_5000 c001n08" [ style = bold] -"child_DoFencing:1_start_0 c001n08" -> "stonith c001n02" [ style = bold] +"child_DoFencing:1_start_0 c001n08" -> "stonith_up" [ style = bold] "child_DoFencing:1_start_0 c001n08" [ style=bold color="green" fontcolor="black" ] "child_DoFencing:2_monitor_0 c001n01" -> "probe_complete c001n01" [ style = bold] "child_DoFencing:2_monitor_0 c001n01" [ style=bold color="green" fontcolor="black" ] "child_DoFencing:2_monitor_0 c001n03" -> "probe_complete c001n03" [ style = bold] "child_DoFencing:2_monitor_0 c001n03" [ style=bold color="green" fontcolor="black" ] "child_DoFencing:2_monitor_0 c001n08" -> "probe_complete c001n08" [ style = bold] "child_DoFencing:2_monitor_0 c001n08" [ style=bold color="green" fontcolor="black" ] "child_DoFencing:2_monitor_5000 c001n03" [ style=bold color="green" fontcolor="black" ] "child_DoFencing:2_start_0 c001n03" -> "DoFencing_running_0" [ style = bold] "child_DoFencing:2_start_0 c001n03" -> "child_DoFencing:2_monitor_5000 c001n03" [ style = bold] -"child_DoFencing:2_start_0 c001n03" -> "stonith c001n02" [ style = bold] +"child_DoFencing:2_start_0 c001n03" -> "stonith_up" [ style = bold] "child_DoFencing:2_start_0 c001n03" [ style=bold color="green" fontcolor="black" ] "child_DoFencing:3_monitor_0 c001n01" -> "probe_complete c001n01" [ style = bold] "child_DoFencing:3_monitor_0 c001n01" [ style=bold color="green" fontcolor="black" ] "child_DoFencing:3_monitor_0 c001n03" -> "probe_complete c001n03" [ style = bold] "child_DoFencing:3_monitor_0 c001n03" [ style=bold color="green" fontcolor="black" ] "child_DoFencing:3_monitor_0 c001n08" -> "probe_complete c001n08" [ style = bold] "child_DoFencing:3_monitor_0 c001n08" [ style=bold color="green" fontcolor="black" ] "probe_complete c001n01" -> "probe_complete" [ style = bold] "probe_complete c001n01" [ style=bold color="green" fontcolor="black" ] "probe_complete c001n03" -> "probe_complete" [ style = bold] "probe_complete c001n03" [ style=bold color="green" fontcolor="black" ] "probe_complete c001n08" -> "probe_complete" [ style = bold] "probe_complete c001n08" [ style=bold color="green" fontcolor="black" ] "probe_complete" -> "DcIPaddr_start_0 c001n08" [ style = bold] "probe_complete" -> "DoFencing_start_0" [ style = bold] "probe_complete" -> "rsc_c001n01_start_0 c001n01" [ style = bold] "probe_complete" -> "rsc_c001n02_start_0 c001n03" [ style = bold] "probe_complete" -> "rsc_c001n03_start_0 c001n03" [ style = bold] "probe_complete" -> "rsc_c001n08_start_0 c001n08" [ style = bold] "probe_complete" [ style=bold color="green" fontcolor="orange" ] "rsc_c001n01_monitor_0 c001n01" -> "probe_complete c001n01" [ style = bold] "rsc_c001n01_monitor_0 c001n01" [ style=bold color="green" fontcolor="black" ] "rsc_c001n01_monitor_0 c001n03" -> "probe_complete c001n03" [ style = bold] "rsc_c001n01_monitor_0 c001n03" [ style=bold color="green" fontcolor="black" ] "rsc_c001n01_monitor_0 c001n08" -> "probe_complete c001n08" [ style = bold] "rsc_c001n01_monitor_0 c001n08" [ style=bold color="green" fontcolor="black" ] "rsc_c001n01_monitor_5000 c001n01" [ style=bold color="green" fontcolor="black" ] "rsc_c001n01_start_0 c001n01" -> "rsc_c001n01_monitor_5000 c001n01" [ style = bold] "rsc_c001n01_start_0 c001n01" [ style=bold color="green" fontcolor="black" ] "rsc_c001n02_monitor_0 c001n01" -> "probe_complete c001n01" [ style = bold] "rsc_c001n02_monitor_0 c001n01" [ style=bold color="green" fontcolor="black" ] "rsc_c001n02_monitor_0 c001n03" -> "probe_complete c001n03" [ style = bold] "rsc_c001n02_monitor_0 c001n03" [ style=bold color="green" fontcolor="black" ] "rsc_c001n02_monitor_0 c001n08" -> "probe_complete c001n08" [ style = bold] "rsc_c001n02_monitor_0 c001n08" [ style=bold color="green" fontcolor="black" ] "rsc_c001n02_monitor_5000 c001n03" [ style=bold color="green" fontcolor="black" ] "rsc_c001n02_start_0 c001n03" -> "rsc_c001n02_monitor_5000 c001n03" [ style = bold] "rsc_c001n02_start_0 c001n03" [ style=bold color="green" fontcolor="black" ] "rsc_c001n03_monitor_0 c001n01" -> "probe_complete c001n01" [ style = bold] "rsc_c001n03_monitor_0 c001n01" [ style=bold color="green" fontcolor="black" ] "rsc_c001n03_monitor_0 c001n03" -> "probe_complete c001n03" [ style = bold] "rsc_c001n03_monitor_0 c001n03" [ style=bold color="green" fontcolor="black" ] "rsc_c001n03_monitor_0 c001n08" -> "probe_complete c001n08" [ style = bold] "rsc_c001n03_monitor_0 c001n08" [ style=bold color="green" fontcolor="black" ] "rsc_c001n03_monitor_5000 c001n03" [ style=bold color="green" fontcolor="black" ] "rsc_c001n03_start_0 c001n03" -> "rsc_c001n03_monitor_5000 c001n03" [ style = bold] "rsc_c001n03_start_0 c001n03" [ style=bold color="green" fontcolor="black" ] "rsc_c001n08_monitor_0 c001n01" -> "probe_complete c001n01" [ style = bold] "rsc_c001n08_monitor_0 c001n01" [ style=bold color="green" fontcolor="black" ] "rsc_c001n08_monitor_0 c001n03" -> "probe_complete c001n03" [ style = bold] "rsc_c001n08_monitor_0 c001n03" [ style=bold color="green" fontcolor="black" ] "rsc_c001n08_monitor_0 c001n08" -> "probe_complete c001n08" [ style = bold] "rsc_c001n08_monitor_0 c001n08" [ style=bold color="green" fontcolor="black" ] "rsc_c001n08_monitor_5000 c001n08" [ style=bold color="green" fontcolor="black" ] "rsc_c001n08_start_0 c001n08" -> "rsc_c001n08_monitor_5000 c001n08" [ style = bold] "rsc_c001n08_start_0 c001n08" [ style=bold color="green" fontcolor="black" ] "stonith c001n02" -> "all_stopped" [ style = bold] "stonith c001n02" [ style=bold color="green" fontcolor="black" ] +"stonith_up" -> "stonith c001n02" [ style = bold] +"stonith_up" [ style=bold color="green" fontcolor="orange" ] } diff --git a/crm/pengine/testcases/rec-node-12.exp b/crm/pengine/testcases/rec-node-12.exp index 796abb7028..0340d8c017 100644 --- a/crm/pengine/testcases/rec-node-12.exp +++ b/crm/pengine/testcases/rec-node-12.exp @@ -1,643 +1,681 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + diff --git a/crm/pengine/testcases/rec-node-13.dot b/crm/pengine/testcases/rec-node-13.dot index e4505e0f05..ad5ed6bb6c 100644 --- a/crm/pengine/testcases/rec-node-13.dot +++ b/crm/pengine/testcases/rec-node-13.dot @@ -1,12 +1,14 @@ digraph "g" { "all_stopped" [ style=bold color="green" fontcolor="orange" ] "master_rsc_1_stop_0" -> "master_rsc_1_stopped_0" [ style = bold] "master_rsc_1_stop_0" -> "ocf_msdummy:6_stop_0 c001n04" [ style = bold] "master_rsc_1_stop_0" [ style=bold color="green" fontcolor="orange" ] "master_rsc_1_stopped_0" [ style=bold color="green" fontcolor="orange" ] "ocf_msdummy:6_stop_0 c001n04" -> "all_stopped" [ style = bold] "ocf_msdummy:6_stop_0 c001n04" -> "master_rsc_1_stopped_0" [ style = bold] "ocf_msdummy:6_stop_0 c001n04" [ style=bold color="green" fontcolor="orange" ] "stonith c001n04" -> "ocf_msdummy:6_stop_0 c001n04" [ style = bold] "stonith c001n04" [ style=bold color="green" fontcolor="black" ] +"stonith_up" -> "stonith c001n04" [ style = bold] +"stonith_up" [ style=bold color="green" fontcolor="orange" ] } diff --git a/crm/pengine/testcases/rec-node-13.exp b/crm/pengine/testcases/rec-node-13.exp index 388bddd1cd..5818a2e9b9 100644 --- a/crm/pengine/testcases/rec-node-13.exp +++ b/crm/pengine/testcases/rec-node-13.exp @@ -1,61 +1,73 @@ - + - - - + + + - + + + + + + + + + + + + + diff --git a/crm/pengine/testcases/rec-node-14.dot b/crm/pengine/testcases/rec-node-14.dot index 0184d363ec..a383876e48 100644 --- a/crm/pengine/testcases/rec-node-14.dot +++ b/crm/pengine/testcases/rec-node-14.dot @@ -1,9 +1,13 @@ digraph "g" { "all_stopped" [ style=bold color="green" fontcolor="orange" ] "stonith node1" -> "stonith node3" [ style = bold] "stonith node1" [ style=bold color="green" fontcolor="black" ] "stonith node2" [ style=bold color="green" fontcolor="black" ] "stonith node3" -> "all_stopped" [ style = bold] "stonith node3" -> "stonith node2" [ style = bold] "stonith node3" [ style=bold color="green" fontcolor="black" ] +"stonith_up" -> "stonith node1" [ style = bold] +"stonith_up" -> "stonith node2" [ style = bold] +"stonith_up" -> "stonith node3" [ style = bold] +"stonith_up" [ style=bold color="green" fontcolor="orange" ] } diff --git a/crm/pengine/testcases/rec-node-14.exp b/crm/pengine/testcases/rec-node-14.exp index 0ef66c6832..900830268e 100644 --- a/crm/pengine/testcases/rec-node-14.exp +++ b/crm/pengine/testcases/rec-node-14.exp @@ -1,47 +1,81 @@ - + + + + + + + + + + + + + + + + + + + + + - + - + - + + + + - + - + + + + + + + + + - + + + + - + - + - + diff --git a/crm/pengine/testcases/rec-node-15.dot b/crm/pengine/testcases/rec-node-15.dot index 9c6b56085c..8a8fb2de97 100644 --- a/crm/pengine/testcases/rec-node-15.dot +++ b/crm/pengine/testcases/rec-node-15.dot @@ -1,80 +1,82 @@ digraph "g" { "Filesystem_13_monitor_120000 sapcl01" [ style=bold color="green" fontcolor="black" ] "Filesystem_13_start_0 sapcl01" -> "Filesystem_13_monitor_120000 sapcl01" [ style = bold] "Filesystem_13_start_0 sapcl01" -> "app02_running_0" [ style = bold] "Filesystem_13_start_0 sapcl01" [ style=bold color="green" fontcolor="black" ] "Filesystem_13_stop_0 sapcl02" -> "Filesystem_13_start_0 sapcl01" [ style = bold] "Filesystem_13_stop_0 sapcl02" -> "LVM_12_stop_0 sapcl02" [ style = bold] "Filesystem_13_stop_0 sapcl02" -> "all_stopped" [ style = bold] "Filesystem_13_stop_0 sapcl02" -> "app02_stopped_0" [ style = bold] "Filesystem_13_stop_0 sapcl02" [ style=bold color="green" fontcolor="black" ] "Filesystem_23_monitor_120000 sapcl01" [ style=bold color="green" fontcolor="black" ] "Filesystem_23_start_0 sapcl01" -> "Filesystem_23_monitor_120000 sapcl01" [ style = bold] "Filesystem_23_start_0 sapcl01" -> "oracle_24_start_0 sapcl01" [ style = bold] "Filesystem_23_start_0 sapcl01" -> "oracle_running_0" [ style = bold] "Filesystem_23_start_0 sapcl01" [ style=bold color="green" fontcolor="black" ] "IPaddr_192_168_1_102_monitor_5000 sapcl01" [ style=bold color="green" fontcolor="black" ] "IPaddr_192_168_1_102_start_0 sapcl01" -> "IPaddr_192_168_1_102_monitor_5000 sapcl01" [ style = bold] "IPaddr_192_168_1_102_start_0 sapcl01" -> "LVM_12_start_0 sapcl01" [ style = bold] "IPaddr_192_168_1_102_start_0 sapcl01" -> "app02_running_0" [ style = bold] "IPaddr_192_168_1_102_start_0 sapcl01" [ style=bold color="green" fontcolor="black" ] "IPaddr_192_168_1_102_stop_0 sapcl02" -> "IPaddr_192_168_1_102_start_0 sapcl01" [ style = bold] "IPaddr_192_168_1_102_stop_0 sapcl02" -> "all_stopped" [ style = bold] "IPaddr_192_168_1_102_stop_0 sapcl02" -> "app02_stopped_0" [ style = bold] "IPaddr_192_168_1_102_stop_0 sapcl02" [ style=bold color="green" fontcolor="black" ] "IPaddr_192_168_1_104_monitor_5000 sapcl01" [ style=bold color="green" fontcolor="black" ] "IPaddr_192_168_1_104_start_0 sapcl01" -> "IPaddr_192_168_1_104_monitor_5000 sapcl01" [ style = bold] "IPaddr_192_168_1_104_start_0 sapcl01" -> "LVM_22_start_0 sapcl01" [ style = bold] "IPaddr_192_168_1_104_start_0 sapcl01" -> "oracle_running_0" [ style = bold] "IPaddr_192_168_1_104_start_0 sapcl01" [ style=bold color="green" fontcolor="black" ] "LVM_12_monitor_120000 sapcl01" [ style=bold color="green" fontcolor="black" ] "LVM_12_start_0 sapcl01" -> "Filesystem_13_start_0 sapcl01" [ style = bold] "LVM_12_start_0 sapcl01" -> "LVM_12_monitor_120000 sapcl01" [ style = bold] "LVM_12_start_0 sapcl01" -> "app02_running_0" [ style = bold] "LVM_12_start_0 sapcl01" [ style=bold color="green" fontcolor="black" ] "LVM_12_stop_0 sapcl02" -> "IPaddr_192_168_1_102_stop_0 sapcl02" [ style = bold] "LVM_12_stop_0 sapcl02" -> "LVM_12_start_0 sapcl01" [ style = bold] "LVM_12_stop_0 sapcl02" -> "all_stopped" [ style = bold] "LVM_12_stop_0 sapcl02" -> "app02_stopped_0" [ style = bold] "LVM_12_stop_0 sapcl02" [ style=bold color="green" fontcolor="black" ] "LVM_22_monitor_120000 sapcl01" [ style=bold color="green" fontcolor="black" ] "LVM_22_start_0 sapcl01" -> "Filesystem_23_start_0 sapcl01" [ style = bold] "LVM_22_start_0 sapcl01" -> "LVM_22_monitor_120000 sapcl01" [ style = bold] "LVM_22_start_0 sapcl01" -> "oracle_running_0" [ style = bold] "LVM_22_start_0 sapcl01" [ style=bold color="green" fontcolor="black" ] "all_stopped" [ style=bold color="green" fontcolor="orange" ] "app02_running_0" [ style=bold color="green" fontcolor="orange" ] "app02_start_0" -> "IPaddr_192_168_1_102_start_0 sapcl01" [ style = bold] "app02_start_0" -> "app02_running_0" [ style = bold] "app02_start_0" [ style=bold color="green" fontcolor="orange" ] "app02_stop_0" -> "Filesystem_13_stop_0 sapcl02" [ style = bold] "app02_stop_0" -> "IPaddr_192_168_1_102_stop_0 sapcl02" [ style = bold] "app02_stop_0" -> "LVM_12_stop_0 sapcl02" [ style = bold] "app02_stop_0" -> "app02_start_0" [ style = bold] "app02_stop_0" -> "app02_stopped_0" [ style = bold] "app02_stop_0" [ style=bold color="green" fontcolor="orange" ] "app02_stopped_0" -> "app02_start_0" [ style = bold] "app02_stopped_0" [ style=bold color="green" fontcolor="orange" ] "oracle_24_monitor_120000 sapcl01" [ style=bold color="green" fontcolor="black" ] "oracle_24_start_0 sapcl01" -> "oracle_24_monitor_120000 sapcl01" [ style = bold] "oracle_24_start_0 sapcl01" -> "oracle_running_0" [ style = bold] "oracle_24_start_0 sapcl01" -> "oralsnr_25_start_0 sapcl01" [ style = bold] "oracle_24_start_0 sapcl01" [ style=bold color="green" fontcolor="black" ] "oracle_running_0" [ style=bold color="green" fontcolor="orange" ] "oracle_start_0" -> "IPaddr_192_168_1_104_start_0 sapcl01" [ style = bold] "oracle_start_0" -> "oracle_running_0" [ style = bold] "oracle_start_0" [ style=bold color="green" fontcolor="orange" ] "oralsnr_25_monitor_120000 sapcl01" [ style=bold color="green" fontcolor="black" ] "oralsnr_25_start_0 sapcl01" -> "oracle_running_0" [ style = bold] "oralsnr_25_start_0 sapcl01" -> "oralsnr_25_monitor_120000 sapcl01" [ style = bold] "oralsnr_25_start_0 sapcl01" [ style=bold color="green" fontcolor="black" ] "stonith sapcl03" -> "Filesystem_13_start_0 sapcl01" [ style = bold] "stonith sapcl03" -> "Filesystem_23_start_0 sapcl01" [ style = bold] "stonith sapcl03" -> "IPaddr_192_168_1_102_start_0 sapcl01" [ style = bold] "stonith sapcl03" -> "IPaddr_192_168_1_104_start_0 sapcl01" [ style = bold] "stonith sapcl03" -> "LVM_12_start_0 sapcl01" [ style = bold] "stonith sapcl03" -> "LVM_22_start_0 sapcl01" [ style = bold] "stonith sapcl03" -> "oracle_24_start_0 sapcl01" [ style = bold] "stonith sapcl03" -> "oralsnr_25_start_0 sapcl01" [ style = bold] "stonith sapcl03" [ style=bold color="green" fontcolor="black" ] +"stonith_up" -> "stonith sapcl03" [ style = bold] +"stonith_up" [ style=bold color="green" fontcolor="orange" ] } diff --git a/crm/pengine/testcases/rec-node-15.exp b/crm/pengine/testcases/rec-node-15.exp index 1691a2ecda..861cf3ee8d 100644 --- a/crm/pengine/testcases/rec-node-15.exp +++ b/crm/pengine/testcases/rec-node-15.exp @@ -1,433 +1,445 @@ - + - + - + - + - + - + - + - + - - - + + + - - - + + + - + - + + + + + + + + + + + + + diff --git a/crm/pengine/testcases/rec-node-2.dot b/crm/pengine/testcases/rec-node-2.dot index ffa31edb57..f9efe58fb1 100644 --- a/crm/pengine/testcases/rec-node-2.dot +++ b/crm/pengine/testcases/rec-node-2.dot @@ -1,46 +1,48 @@ digraph "g" { "all_stopped" [ style=bold color="green" fontcolor="orange" ] "group1_running_0" [ style=bold color="green" fontcolor="orange" ] "group1_start_0" -> "group1_running_0" [ style = bold] "group1_start_0" -> "rsc3_start_0 node2" [ style = bold] "group1_start_0" [ style=bold color="green" fontcolor="orange" ] "group2_running_0" [ style=bold color="green" fontcolor="orange" ] "group2_start_0" -> "group2_running_0" [ style = bold] "group2_start_0" -> "rsc5_start_0 node2" [ style = bold] "group2_start_0" [ style=bold color="green" fontcolor="orange" ] "probe_complete node2" -> "probe_complete" [ style = bold] "probe_complete node2" [ style=bold color="green" fontcolor="black" ] "probe_complete" -> "group1_start_0" [ style = bold] "probe_complete" -> "group2_start_0" [ style = bold] "probe_complete" -> "rsc1_start_0 node2" [ style = bold] "probe_complete" -> "rsc2_start_0 node2" [ style = bold] "probe_complete" [ style=bold color="green" fontcolor="orange" ] "rsc1_monitor_0 node2" -> "probe_complete node2" [ style = bold] "rsc1_monitor_0 node2" [ style=bold color="green" fontcolor="black" ] "rsc1_start_0 node2" [ style=bold color="green" fontcolor="black" ] "rsc2_monitor_0 node2" -> "probe_complete node2" [ style = bold] "rsc2_monitor_0 node2" [ style=bold color="green" fontcolor="black" ] "rsc2_start_0 node2" [ style=bold color="green" fontcolor="black" ] "rsc3_monitor_0 node2" -> "probe_complete node2" [ style = bold] "rsc3_monitor_0 node2" [ style=bold color="green" fontcolor="black" ] "rsc3_start_0 node2" -> "group1_running_0" [ style = bold] "rsc3_start_0 node2" -> "rsc4_start_0 node2" [ style = bold] "rsc3_start_0 node2" [ style=bold color="green" fontcolor="black" ] "rsc4_monitor_0 node2" -> "probe_complete node2" [ style = bold] "rsc4_monitor_0 node2" [ style=bold color="green" fontcolor="black" ] "rsc4_start_0 node2" -> "group1_running_0" [ style = bold] "rsc4_start_0 node2" [ style=bold color="green" fontcolor="black" ] "rsc5_monitor_0 node2" -> "probe_complete node2" [ style = bold] "rsc5_monitor_0 node2" [ style=bold color="green" fontcolor="black" ] "rsc5_start_0 node2" -> "group2_running_0" [ style = bold] "rsc5_start_0 node2" -> "rsc6_start_0 node2" [ style = bold] "rsc5_start_0 node2" [ style=bold color="green" fontcolor="black" ] "rsc6_monitor_0 node2" -> "probe_complete node2" [ style = bold] "rsc6_monitor_0 node2" [ style=bold color="green" fontcolor="black" ] "rsc6_start_0 node2" -> "group2_running_0" [ style = bold] "rsc6_start_0 node2" [ style=bold color="green" fontcolor="black" ] "stonith node1" -> "all_stopped" [ style = bold] "stonith node1" -> "rsc2_start_0 node2" [ style = bold] "stonith node1" -> "rsc5_start_0 node2" [ style = bold] "stonith node1" [ style=bold color="green" fontcolor="black" ] +"stonith_up" -> "stonith node1" [ style = bold] +"stonith_up" [ style=bold color="green" fontcolor="orange" ] } diff --git a/crm/pengine/testcases/rec-node-2.exp b/crm/pengine/testcases/rec-node-2.exp index 0e533dab72..89896d53f4 100644 --- a/crm/pengine/testcases/rec-node-2.exp +++ b/crm/pengine/testcases/rec-node-2.exp @@ -1,260 +1,272 @@ - + - + - - - + + + - + + + + + + + + + + + + + - + diff --git a/crm/pengine/testcases/rec-node-4.dot b/crm/pengine/testcases/rec-node-4.dot index 4c7424dabe..d631f208f0 100644 --- a/crm/pengine/testcases/rec-node-4.dot +++ b/crm/pengine/testcases/rec-node-4.dot @@ -1,24 +1,26 @@ digraph "g" { "all_stopped" [ style=bold color="green" fontcolor="orange" ] "probe_complete node2" -> "probe_complete" [ style = bold] "probe_complete node2" [ style=bold color="green" fontcolor="black" ] "probe_complete" -> "rsc1_start_0 node2" [ style = bold] "probe_complete" -> "rsc2_start_0 node2" [ style = bold] "probe_complete" [ style=bold color="green" fontcolor="orange" ] "rsc1_monitor_0 node2" -> "probe_complete node2" [ style = bold] "rsc1_monitor_0 node2" [ style=bold color="green" fontcolor="black" ] "rsc1_start_0 node2" [ style=bold color="green" fontcolor="black" ] "rsc1_stop_0 node1" -> "all_stopped" [ style = bold] "rsc1_stop_0 node1" -> "rsc1_start_0 node2" [ style = bold] "rsc1_stop_0 node1" [ style=bold color="green" fontcolor="orange" ] "rsc2_monitor_0 node2" -> "probe_complete node2" [ style = bold] "rsc2_monitor_0 node2" [ style=bold color="green" fontcolor="black" ] "rsc2_start_0 node2" [ style=bold color="green" fontcolor="black" ] "rsc2_stop_0 node1" -> "all_stopped" [ style = bold] "rsc2_stop_0 node1" -> "rsc2_start_0 node2" [ style = bold] "rsc2_stop_0 node1" [ style=bold color="green" fontcolor="orange" ] "stonith node1" -> "all_stopped" [ style = bold] "stonith node1" -> "rsc1_stop_0 node1" [ style = bold] "stonith node1" -> "rsc2_stop_0 node1" [ style = bold] "stonith node1" [ style=bold color="green" fontcolor="black" ] +"stonith_up" -> "stonith node1" [ style = bold] +"stonith_up" [ style=bold color="green" fontcolor="orange" ] } diff --git a/crm/pengine/testcases/rec-node-4.exp b/crm/pengine/testcases/rec-node-4.exp index 423d789c37..a69b690fff 100644 --- a/crm/pengine/testcases/rec-node-4.exp +++ b/crm/pengine/testcases/rec-node-4.exp @@ -1,148 +1,160 @@ - + - + - - - + + + - - - + + + - + - + - + + + + + + + + + + + + + diff --git a/crm/pengine/testcases/rec-node-6.dot b/crm/pengine/testcases/rec-node-6.dot index 4c7424dabe..d631f208f0 100644 --- a/crm/pengine/testcases/rec-node-6.dot +++ b/crm/pengine/testcases/rec-node-6.dot @@ -1,24 +1,26 @@ digraph "g" { "all_stopped" [ style=bold color="green" fontcolor="orange" ] "probe_complete node2" -> "probe_complete" [ style = bold] "probe_complete node2" [ style=bold color="green" fontcolor="black" ] "probe_complete" -> "rsc1_start_0 node2" [ style = bold] "probe_complete" -> "rsc2_start_0 node2" [ style = bold] "probe_complete" [ style=bold color="green" fontcolor="orange" ] "rsc1_monitor_0 node2" -> "probe_complete node2" [ style = bold] "rsc1_monitor_0 node2" [ style=bold color="green" fontcolor="black" ] "rsc1_start_0 node2" [ style=bold color="green" fontcolor="black" ] "rsc1_stop_0 node1" -> "all_stopped" [ style = bold] "rsc1_stop_0 node1" -> "rsc1_start_0 node2" [ style = bold] "rsc1_stop_0 node1" [ style=bold color="green" fontcolor="orange" ] "rsc2_monitor_0 node2" -> "probe_complete node2" [ style = bold] "rsc2_monitor_0 node2" [ style=bold color="green" fontcolor="black" ] "rsc2_start_0 node2" [ style=bold color="green" fontcolor="black" ] "rsc2_stop_0 node1" -> "all_stopped" [ style = bold] "rsc2_stop_0 node1" -> "rsc2_start_0 node2" [ style = bold] "rsc2_stop_0 node1" [ style=bold color="green" fontcolor="orange" ] "stonith node1" -> "all_stopped" [ style = bold] "stonith node1" -> "rsc1_stop_0 node1" [ style = bold] "stonith node1" -> "rsc2_stop_0 node1" [ style = bold] "stonith node1" [ style=bold color="green" fontcolor="black" ] +"stonith_up" -> "stonith node1" [ style = bold] +"stonith_up" [ style=bold color="green" fontcolor="orange" ] } diff --git a/crm/pengine/testcases/rec-node-6.exp b/crm/pengine/testcases/rec-node-6.exp index 423d789c37..a69b690fff 100644 --- a/crm/pengine/testcases/rec-node-6.exp +++ b/crm/pengine/testcases/rec-node-6.exp @@ -1,148 +1,160 @@ - + - + - - - + + + - - - + + + - + - + - + + + + + + + + + + + + + diff --git a/crm/pengine/testcases/rec-node-7.dot b/crm/pengine/testcases/rec-node-7.dot index 4c7424dabe..d631f208f0 100644 --- a/crm/pengine/testcases/rec-node-7.dot +++ b/crm/pengine/testcases/rec-node-7.dot @@ -1,24 +1,26 @@ digraph "g" { "all_stopped" [ style=bold color="green" fontcolor="orange" ] "probe_complete node2" -> "probe_complete" [ style = bold] "probe_complete node2" [ style=bold color="green" fontcolor="black" ] "probe_complete" -> "rsc1_start_0 node2" [ style = bold] "probe_complete" -> "rsc2_start_0 node2" [ style = bold] "probe_complete" [ style=bold color="green" fontcolor="orange" ] "rsc1_monitor_0 node2" -> "probe_complete node2" [ style = bold] "rsc1_monitor_0 node2" [ style=bold color="green" fontcolor="black" ] "rsc1_start_0 node2" [ style=bold color="green" fontcolor="black" ] "rsc1_stop_0 node1" -> "all_stopped" [ style = bold] "rsc1_stop_0 node1" -> "rsc1_start_0 node2" [ style = bold] "rsc1_stop_0 node1" [ style=bold color="green" fontcolor="orange" ] "rsc2_monitor_0 node2" -> "probe_complete node2" [ style = bold] "rsc2_monitor_0 node2" [ style=bold color="green" fontcolor="black" ] "rsc2_start_0 node2" [ style=bold color="green" fontcolor="black" ] "rsc2_stop_0 node1" -> "all_stopped" [ style = bold] "rsc2_stop_0 node1" -> "rsc2_start_0 node2" [ style = bold] "rsc2_stop_0 node1" [ style=bold color="green" fontcolor="orange" ] "stonith node1" -> "all_stopped" [ style = bold] "stonith node1" -> "rsc1_stop_0 node1" [ style = bold] "stonith node1" -> "rsc2_stop_0 node1" [ style = bold] "stonith node1" [ style=bold color="green" fontcolor="black" ] +"stonith_up" -> "stonith node1" [ style = bold] +"stonith_up" [ style=bold color="green" fontcolor="orange" ] } diff --git a/crm/pengine/testcases/rec-node-7.exp b/crm/pengine/testcases/rec-node-7.exp index 423d789c37..a69b690fff 100644 --- a/crm/pengine/testcases/rec-node-7.exp +++ b/crm/pengine/testcases/rec-node-7.exp @@ -1,148 +1,160 @@ - + - + - - - + + + - - - + + + - + - + - + + + + + + + + + + + + + diff --git a/crm/pengine/testcases/rec-rsc-5.dot b/crm/pengine/testcases/rec-rsc-5.dot index f5b20e58d6..244aca5902 100644 --- a/crm/pengine/testcases/rec-rsc-5.dot +++ b/crm/pengine/testcases/rec-rsc-5.dot @@ -1,24 +1,26 @@ digraph "g" { "all_stopped" [ style=bold color="green" fontcolor="orange" ] "probe_complete node1" -> "probe_complete" [ style = bold] "probe_complete node1" [ style=bold color="green" fontcolor="black" ] "probe_complete" -> "rsc1_start_0 node1" [ style = bold] "probe_complete" -> "rsc2_start_0 node1" [ style = bold] "probe_complete" [ style=bold color="green" fontcolor="orange" ] "rsc1_monitor_0 node1" -> "probe_complete node1" [ style = bold] "rsc1_monitor_0 node1" [ style=bold color="green" fontcolor="black" ] "rsc1_start_0 node1" [ style=bold color="green" fontcolor="black" ] "rsc1_stop_0 node2" -> "all_stopped" [ style = bold] "rsc1_stop_0 node2" -> "rsc1_start_0 node1" [ style = bold] "rsc1_stop_0 node2" [ style=bold color="green" fontcolor="orange" ] "rsc2_monitor_0 node1" -> "probe_complete node1" [ style = bold] "rsc2_monitor_0 node1" [ style=bold color="green" fontcolor="black" ] "rsc2_start_0 node1" [ style=bold color="green" fontcolor="black" ] "rsc2_stop_0 node2" -> "all_stopped" [ style = bold] "rsc2_stop_0 node2" -> "rsc2_start_0 node1" [ style = bold] "rsc2_stop_0 node2" [ style=bold color="green" fontcolor="orange" ] "stonith node2" -> "all_stopped" [ style = bold] "stonith node2" -> "rsc1_stop_0 node2" [ style = bold] "stonith node2" -> "rsc2_stop_0 node2" [ style = bold] "stonith node2" [ style=bold color="green" fontcolor="black" ] +"stonith_up" -> "stonith node2" [ style = bold] +"stonith_up" [ style=bold color="green" fontcolor="orange" ] } diff --git a/crm/pengine/testcases/rec-rsc-5.exp b/crm/pengine/testcases/rec-rsc-5.exp index 710d0aa828..eec82a4ec3 100644 --- a/crm/pengine/testcases/rec-rsc-5.exp +++ b/crm/pengine/testcases/rec-rsc-5.exp @@ -1,148 +1,160 @@ - + - + - - - + + + - - - + + + - + - + - + + + + + + + + + + + + + diff --git a/crm/pengine/testcases/stonith-0.dot b/crm/pengine/testcases/stonith-0.dot index 47f24ab0d0..8a9bcce2e1 100644 --- a/crm/pengine/testcases/stonith-0.dot +++ b/crm/pengine/testcases/stonith-0.dot @@ -1,83 +1,86 @@ digraph "g" { "all_stopped" [ style=bold color="green" fontcolor="orange" ] "child_DoFencing:4_monitor_20000 c001n08" [ style=bold color="green" fontcolor="black" ] "group-1_running_0" [ style=bold color="green" fontcolor="orange" ] "group-1_start_0" -> "group-1_running_0" [ style = bold] "group-1_start_0" -> "ocf_192.168.100.181_start_0 c001n02" [ style = bold] "group-1_start_0" [ style=bold color="green" fontcolor="orange" ] "group-1_stop_0" -> "group-1_start_0" [ style = bold] "group-1_stop_0" -> "group-1_stopped_0" [ style = bold] "group-1_stop_0" -> "heartbeat_192.168.100.182_stop_0 c001n03" [ style = bold] "group-1_stop_0" -> "ocf_192.168.100.181_stop_0 c001n03" [ style = bold] "group-1_stop_0" -> "ocf_192.168.100.181_stop_0 c001n05" [ style = bold] "group-1_stop_0" -> "ocf_192.168.100.183_stop_0 c001n03" [ style = bold] "group-1_stop_0" -> "ocf_192.168.100.183_stop_0 c001n05" [ style = bold] "group-1_stop_0" [ style=bold color="green" fontcolor="orange" ] "group-1_stopped_0" -> "group-1_start_0" [ style = bold] "group-1_stopped_0" [ style=bold color="green" fontcolor="orange" ] "heartbeat_192.168.100.182_monitor_5000 c001n02" [ style=bold color="green" fontcolor="black" ] "heartbeat_192.168.100.182_start_0 c001n02" -> "group-1_running_0" [ style = bold] "heartbeat_192.168.100.182_start_0 c001n02" -> "heartbeat_192.168.100.182_monitor_5000 c001n02" [ style = bold] "heartbeat_192.168.100.182_start_0 c001n02" -> "ocf_192.168.100.183_start_0 c001n02" [ style = bold] "heartbeat_192.168.100.182_start_0 c001n02" [ style=bold color="green" fontcolor="black" ] "heartbeat_192.168.100.182_stop_0 c001n03" -> "all_stopped" [ style = bold] "heartbeat_192.168.100.182_stop_0 c001n03" -> "group-1_stopped_0" [ style = bold] "heartbeat_192.168.100.182_stop_0 c001n03" -> "heartbeat_192.168.100.182_start_0 c001n02" [ style = bold] "heartbeat_192.168.100.182_stop_0 c001n03" -> "ocf_192.168.100.181_stop_0 c001n03" [ style = bold] "heartbeat_192.168.100.182_stop_0 c001n03" -> "ocf_192.168.100.181_stop_0 c001n05" [ style = bold] "heartbeat_192.168.100.182_stop_0 c001n03" [ style=bold color="green" fontcolor="orange" ] "ocf_192.168.100.181_monitor_5000 c001n02" [ style=bold color="green" fontcolor="black" ] "ocf_192.168.100.181_start_0 c001n02" -> "group-1_running_0" [ style = bold] "ocf_192.168.100.181_start_0 c001n02" -> "heartbeat_192.168.100.182_start_0 c001n02" [ style = bold] "ocf_192.168.100.181_start_0 c001n02" -> "ocf_192.168.100.181_monitor_5000 c001n02" [ style = bold] "ocf_192.168.100.181_start_0 c001n02" [ style=bold color="green" fontcolor="black" ] "ocf_192.168.100.181_stop_0 c001n03" -> "all_stopped" [ style = bold] "ocf_192.168.100.181_stop_0 c001n03" -> "group-1_stopped_0" [ style = bold] "ocf_192.168.100.181_stop_0 c001n03" -> "ocf_192.168.100.181_start_0 c001n02" [ style = bold] "ocf_192.168.100.181_stop_0 c001n03" [ style=bold color="green" fontcolor="orange" ] "ocf_192.168.100.181_stop_0 c001n05" -> "all_stopped" [ style = bold] "ocf_192.168.100.181_stop_0 c001n05" -> "group-1_stopped_0" [ style = bold] "ocf_192.168.100.181_stop_0 c001n05" -> "ocf_192.168.100.181_start_0 c001n02" [ style = bold] "ocf_192.168.100.181_stop_0 c001n05" [ style=bold color="green" fontcolor="orange" ] "ocf_192.168.100.183_monitor_5000 c001n02" [ style=bold color="green" fontcolor="black" ] "ocf_192.168.100.183_start_0 c001n02" -> "group-1_running_0" [ style = bold] "ocf_192.168.100.183_start_0 c001n02" -> "ocf_192.168.100.183_monitor_5000 c001n02" [ style = bold] "ocf_192.168.100.183_start_0 c001n02" [ style=bold color="green" fontcolor="black" ] "ocf_192.168.100.183_stop_0 c001n03" -> "all_stopped" [ style = bold] "ocf_192.168.100.183_stop_0 c001n03" -> "group-1_stopped_0" [ style = bold] "ocf_192.168.100.183_stop_0 c001n03" -> "heartbeat_192.168.100.182_stop_0 c001n03" [ style = bold] "ocf_192.168.100.183_stop_0 c001n03" -> "ocf_192.168.100.183_start_0 c001n02" [ style = bold] "ocf_192.168.100.183_stop_0 c001n03" [ style=bold color="green" fontcolor="orange" ] "ocf_192.168.100.183_stop_0 c001n05" -> "all_stopped" [ style = bold] "ocf_192.168.100.183_stop_0 c001n05" -> "group-1_stopped_0" [ style = bold] "ocf_192.168.100.183_stop_0 c001n05" -> "heartbeat_192.168.100.182_stop_0 c001n03" [ style = bold] "ocf_192.168.100.183_stop_0 c001n05" -> "ocf_192.168.100.183_start_0 c001n02" [ style = bold] "ocf_192.168.100.183_stop_0 c001n05" [ style=bold color="green" fontcolor="orange" ] "rsc_c001n05_monitor_5000 c001n07" [ style=bold color="green" fontcolor="black" ] "rsc_c001n05_start_0 c001n07" -> "rsc_c001n05_monitor_5000 c001n07" [ style = bold] "rsc_c001n05_start_0 c001n07" [ style=bold color="green" fontcolor="black" ] "rsc_c001n05_stop_0 c001n05" -> "all_stopped" [ style = bold] "rsc_c001n05_stop_0 c001n05" -> "rsc_c001n05_start_0 c001n07" [ style = bold] "rsc_c001n05_stop_0 c001n05" [ style=bold color="green" fontcolor="orange" ] "rsc_c001n07_monitor_5000 c001n07" [ style=bold color="green" fontcolor="black" ] "rsc_c001n07_start_0 c001n07" -> "rsc_c001n07_monitor_5000 c001n07" [ style = bold] "rsc_c001n07_start_0 c001n07" [ style=bold color="green" fontcolor="black" ] "rsc_c001n07_stop_0 c001n03" -> "all_stopped" [ style = bold] "rsc_c001n07_stop_0 c001n03" -> "rsc_c001n07_start_0 c001n07" [ style = bold] "rsc_c001n07_stop_0 c001n03" [ style=bold color="green" fontcolor="orange" ] "stonith c001n03" -> "heartbeat_192.168.100.182_stop_0 c001n03" [ style = bold] "stonith c001n03" -> "ocf_192.168.100.181_stop_0 c001n03" [ style = bold] "stonith c001n03" -> "ocf_192.168.100.181_stop_0 c001n05" [ style = bold] "stonith c001n03" -> "ocf_192.168.100.183_stop_0 c001n03" [ style = bold] "stonith c001n03" -> "ocf_192.168.100.183_stop_0 c001n05" [ style = bold] "stonith c001n03" -> "rsc_c001n07_stop_0 c001n03" [ style = bold] "stonith c001n03" [ style=bold color="green" fontcolor="black" ] "stonith c001n05" -> "all_stopped" [ style = bold] "stonith c001n05" -> "ocf_192.168.100.181_stop_0 c001n03" [ style = bold] "stonith c001n05" -> "ocf_192.168.100.181_stop_0 c001n05" [ style = bold] "stonith c001n05" -> "ocf_192.168.100.183_stop_0 c001n03" [ style = bold] "stonith c001n05" -> "ocf_192.168.100.183_stop_0 c001n05" [ style = bold] "stonith c001n05" -> "rsc_c001n05_stop_0 c001n05" [ style = bold] "stonith c001n05" -> "stonith c001n03" [ style = bold] "stonith c001n05" [ style=bold color="green" fontcolor="black" ] +"stonith_up" -> "stonith c001n03" [ style = bold] +"stonith_up" -> "stonith c001n05" [ style = bold] +"stonith_up" [ style=bold color="green" fontcolor="orange" ] } diff --git a/crm/pengine/testcases/stonith-0.exp b/crm/pengine/testcases/stonith-0.exp index 3fa76646a7..d9f3e428ec 100644 --- a/crm/pengine/testcases/stonith-0.exp +++ b/crm/pengine/testcases/stonith-0.exp @@ -1,515 +1,538 @@ - + - + - + - + - + - + - + - + - + - + - + - + + + + + + + + + - + + + + - + - + - + - + - + - + - + - + - + - + - + - + + + + + + + + + - + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/crm/pengine/utils.c b/crm/pengine/utils.c index 046a68a604..577bfa4f58 100644 --- a/crm/pengine/utils.c +++ b/crm/pengine/utils.c @@ -1,544 +1,554 @@ /* * 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 gint sort_cons_strength(gconstpointer a, gconstpointer b) { const rsc_colocation_t *rsc_constraint1 = (const rsc_colocation_t*)a; const rsc_colocation_t *rsc_constraint2 = (const rsc_colocation_t*)b; if(a == NULL) { return 1; } if(b == NULL) { return -1; } if(rsc_constraint1->score > rsc_constraint2->score) { return 1; } if(rsc_constraint1->score < rsc_constraint2->score) { return -1; } return 0; } 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(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(level, "%s (%d) < %s (%d) : weight", node1->details->uname, node1_weight, node2->details->uname, node2_weight); return 1; } do_crm_log(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(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(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(level, "%s = %s", node1->details->uname, node2->details->uname); return 0; } gboolean native_assign_node(resource_t *rsc, GListPtr nodes, node_t *chosen) { int multiple = 0; CRM_ASSERT(rsc->variant == pe_native); rsc->provisional = FALSE; slist_iter(candidate, node_t, nodes, lpc, crm_debug("Color %s, Node[%d] %s: %d", rsc->id, lpc, candidate->details->uname, candidate->weight); if(chosen->weight > 0 && candidate->details->unclean == FALSE && candidate->weight == chosen->weight) { multiple++; } ); if(chosen == NULL) { crm_debug("Could not allocate a node for %s", rsc->id); rsc->next_role = RSC_ROLE_STOPPED; return FALSE; } else if(can_run_resources(chosen) == FALSE || chosen->weight < 0) { crm_debug("All nodes for resource %s are unavailable" ", unclean or shutting down", rsc->id); rsc->next_role = RSC_ROLE_STOPPED; return FALSE; } if(rsc->next_role == RSC_ROLE_UNKNOWN) { rsc->next_role = RSC_ROLE_STARTED; } if(multiple > 1) { int log_level = LOG_INFO; char *score = score2char(chosen->weight); if(chosen->weight >= INFINITY) { log_level = LOG_WARNING; } do_crm_log(log_level, "%d nodes with equal score (%s) for" " running the listed resources (chose %s):", multiple, score, chosen->details->uname); crm_free(score); } /* 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; } void convert_non_atomic_task(resource_t *rsc, order_constraint_t *order) { int interval = 0; char *rid = NULL; char *raw_task = NULL; int task = no_action; char *old_uuid = order->lh_action_task; crm_debug("Processing %s", old_uuid); if(order->lh_action_task == NULL || strstr(order->lh_action_task, "notify") != NULL) { /* no conversion */ return; } CRM_ASSERT(parse_op_key(old_uuid, &rid, &raw_task, &interval)); 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(rsc->notify) { order->lh_action_task = generate_notify_key( rsc->id, "confirmed-post", task2text(task)); } else { order->lh_action_task = generate_op_key( rsc->id, task2text(task+1), 0); } crm_debug("Converted %s -> %s", old_uuid, order->lh_action_task); crm_free(old_uuid); } crm_free(raw_task); crm_free(rid); } 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_2("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(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(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(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(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(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(log_level+1, "\t\t====== End"); } else { do_crm_log(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)); } } resource_t *uber_parent(resource_t *rsc) { resource_t *parent = rsc; while(parent != NULL && parent->parent != NULL) { parent = parent->parent; } return parent; } +action_t *get_stonith_up(pe_working_set_t *data_set) +{ + action_t *op = NULL; + const char *op_s = "stonith_up"; + op = custom_action(NULL, crm_strdup(op_s), op_s, + NULL, TRUE, TRUE, data_set); + op->pseudo = TRUE; + op->runnable = TRUE; + return op; +} + action_t *get_all_stopped(pe_working_set_t *data_set) { - action_t *all_stopped = NULL; - const char *all_stopped_s = "all_stopped"; - all_stopped = custom_action( - NULL, crm_strdup(all_stopped_s), all_stopped_s, - NULL, TRUE, TRUE, data_set); - all_stopped->pseudo = TRUE; - all_stopped->runnable = TRUE; - return all_stopped; + action_t *op = NULL; + const char *op_s = "all_stopped"; + op = custom_action(NULL, crm_strdup(op_s), op_s, + NULL, TRUE, TRUE, data_set); + op->pseudo = TRUE; + op->runnable = TRUE; + return op; } diff --git a/crm/pengine/utils.h b/crm/pengine/utils.h index eb418bbd4a..beb7fec8a9 100644 --- a/crm/pengine/utils.h +++ b/crm/pengine/utils.h @@ -1,66 +1,67 @@ /* * 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); extern rsc_to_node_t *generate_location_rule( resource_t *rsc, crm_data_t *location_rule, pe_working_set_t *data_set); extern gint sort_cons_strength(gconstpointer a, gconstpointer b); 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); extern void convert_non_atomic_task(resource_t *rsc, order_constraint_t *order); 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 resource_t *uber_parent(resource_t *rsc); extern action_t *get_all_stopped(pe_working_set_t *data_set); +extern action_t *get_stonith_up(pe_working_set_t *data_set); #endif