diff --git a/pengine/constraints.c b/pengine/constraints.c index 863610c504..cacad5e8d3 100644 --- a/pengine/constraints.c +++ b/pengine/constraints.c @@ -1,1113 +1,1154 @@ /* * 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 gboolean unpack_constraints(xmlNode * xml_constraints, pe_working_set_t *data_set) { xmlNode *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 = first_named_child(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, RSC_START)) { return RSC_STOP; } else if(safe_str_eq(action, RSC_STOP)) { return RSC_START; } else if(safe_str_eq(action, RSC_PROMOTE)) { return RSC_DEMOTE; } else if(safe_str_eq(action, RSC_DEMOTE)) { return RSC_PROMOTE; } else if(safe_str_eq(action, RSC_PROMOTED)) { return RSC_DEMOTED; } else if(safe_str_eq(action, RSC_DEMOTED)) { return RSC_PROMOTED; } else if(safe_str_eq(action, RSC_STARTED)) { return RSC_STOPPED; } else if(safe_str_eq(action, RSC_STOPPED)) { return RSC_STARTED; } crm_config_warn("Unknown action: %s", action); return NULL; } enum pe_order_kind { pe_order_kind_optional, pe_order_kind_mandatory, pe_order_kind_serialize, }; +static enum pe_order_kind get_ordering_type(xmlNode *xml_obj) +{ + enum pe_order_kind kind_e = pe_order_kind_mandatory; + const char *kind = crm_element_value(xml_obj, XML_ORDER_ATTR_KIND); + + if(kind == NULL) { + const char *score = crm_element_value(xml_obj, XML_RULE_ATTR_SCORE); + kind_e = pe_order_kind_mandatory; + + if(score) { + int score_i = char2score(score); + if(score_i == 0) { + kind_e = pe_order_kind_optional; + } + + /* } else if(rsc_then->variant == pe_native && rsc_first->variant > pe_group) { */ + /* kind_e = pe_order_kind_optional; */ + } + + } else if(safe_str_eq(kind, "Mandatory")) { + kind_e = pe_order_kind_mandatory; + + } else if(safe_str_eq(kind, "Optional")) { + kind_e = pe_order_kind_optional; + + } else if(safe_str_eq(kind, "Serialize")) { + kind_e = pe_order_kind_serialize; + + } else { + const char *id = crm_element_value(xml_obj, XML_ATTR_ID); + crm_config_err("Constraint %s: Unknown type '%s'", id, kind); + } + return kind_e; +} + static gboolean unpack_simple_rsc_order(xmlNode * xml_obj, pe_working_set_t *data_set) { - int score_i = 0; int order_id = 0; resource_t *rsc_then = NULL; resource_t *rsc_first = NULL; gboolean invert_bool = TRUE; enum pe_order_kind kind = pe_order_kind_mandatory; enum pe_ordering cons_weight = pe_order_optional; const char *id_first = NULL; const char *id_then = NULL; const char *action_then = NULL; const char *action_first = NULL; const char *id = crm_element_value(xml_obj, XML_ATTR_ID); - const char *score = crm_element_value(xml_obj, XML_RULE_ATTR_SCORE); - const char *kind_s = crm_element_value(xml_obj, XML_ORDER_ATTR_KIND); const char *invert = crm_element_value(xml_obj, XML_CONS_ATTR_SYMMETRICAL); crm_str_to_boolean(invert, &invert_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; } id_then = crm_element_value(xml_obj, XML_ORDER_ATTR_THEN); id_first = crm_element_value(xml_obj, XML_ORDER_ATTR_FIRST); action_then = crm_element_value(xml_obj, XML_ORDER_ATTR_THEN_ACTION); action_first = crm_element_value(xml_obj, XML_ORDER_ATTR_FIRST_ACTION); if(action_first == NULL) { action_first = RSC_START; } if(action_then == NULL) { action_then = action_first; } if(id_then == NULL || id_first == NULL) { crm_config_err("Constraint %s needs two sides lh: %s rh: %s", id, crm_str(id_then), crm_str(id_first)); return FALSE; } rsc_then = pe_find_resource(data_set->resources, id_then); rsc_first = pe_find_resource(data_set->resources, id_first); if(rsc_then == NULL) { crm_config_err("Constraint %s: no resource found for name '%s'", id, id_then); return FALSE; } else if(rsc_first == NULL) { crm_config_err("Constraint %s: no resource found for name '%s'", id, id_first); return FALSE; } cons_weight = pe_order_optional; - if(kind_s == NULL && score) { - kind = pe_order_kind_mandatory; - score_i = char2score(score); - if(score_i == 0 - || (rsc_then->variant == pe_native && rsc_first->variant > pe_group)) { - kind = pe_order_kind_optional; - } - - } else if(kind_s == NULL || safe_str_eq(kind_s, "Mandatory")) { - kind = pe_order_kind_mandatory; - - } else if(safe_str_eq(kind_s, "Optional")) { - kind = pe_order_kind_optional; - - } else if(safe_str_eq(kind_s, "Serialize")) { - kind = pe_order_kind_serialize; - - } else { - crm_config_err("Constraint %s: Unknown type '%s'", id, kind_s); - kind = pe_order_kind_mandatory; - } + kind = get_ordering_type(xml_obj); if(kind == pe_order_kind_optional && rsc_then->restart_type == pe_restart_restart) { crm_debug_2("Upgrade : recovery - implies right"); cons_weight |= pe_order_implies_right; } if(kind == pe_order_kind_mandatory) { crm_debug_2("Upgrade : implies right"); cons_weight |= pe_order_implies_right; if(safe_str_eq(action_then, RSC_START) || safe_str_eq(action_then, RSC_PROMOTE)) { crm_debug_2("Upgrade : runnable"); cons_weight |= pe_order_runnable_left; } } else if(kind == pe_order_kind_serialize) { cons_weight |= pe_order_serialize_only; } order_id = new_rsc_order(rsc_first, action_first, rsc_then, action_then, cons_weight, data_set); crm_debug_2("order-%d (%s): %s_%s before %s_%s flags=0x%.6x", order_id, id, rsc_first->id, action_first, rsc_then->id, action_then, cons_weight); if(invert_bool == FALSE) { return TRUE; + + } else if(invert && kind == pe_order_kind_serialize) { + crm_config_warn("Cannot invert serialized constraint set %s", id); + return TRUE; + + } else if(kind == pe_order_kind_serialize) { + return TRUE; } action_then = invert_action(action_then); action_first = invert_action(action_first); cons_weight = pe_order_optional; if(kind == pe_order_kind_optional && rsc_then->restart_type == pe_restart_restart) { crm_debug_2("Upgrade : recovery - implies left"); cons_weight |= pe_order_implies_left; } if(kind == pe_order_kind_mandatory) { crm_debug_2("Upgrade : implies left"); cons_weight |= pe_order_implies_left; if(safe_str_eq(action_then, RSC_DEMOTE)) { crm_debug_2("Upgrade : demote"); cons_weight |= pe_order_demote; } } else if(kind == pe_order_kind_serialize) { cons_weight |= pe_order_serialize_only; } if(action_then == NULL || action_first == NULL) { crm_config_err("Cannot invert rsc_order constraint %s." " Please specify the inverse manually.", id); return TRUE; } order_id = new_rsc_order( rsc_then, action_then, rsc_first, action_first, cons_weight, data_set); crm_debug_2("order-%d (%s): %s_%s before %s_%s flags=0x%.6x", order_id, id, rsc_then->id, action_then, rsc_first->id, action_first, cons_weight); return TRUE; } gboolean unpack_rsc_location(xmlNode * 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); const char *node = crm_element_value(xml_obj, "node"); const char *score = crm_element_value(xml_obj, XML_RULE_ATTR_SCORE); 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; } if(node != NULL && score != NULL) { int score_i = char2score(score); node_t *match = pe_find_node(data_set->nodes, node); if(match) { rsc2node_new(id, rsc_lh, score_i, match, data_set); return TRUE; } else { 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, xmlNode *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_xml = expand_idref(rule_xml, data_set->input); 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(location_rule->role_filter == RSC_ROLE_SLAVE) { /* Fold slave back into Started for simplicity * At the point Slave location constraints are evaluated, * all resources are still either stopped or started */ location_rule->role_filter = RSC_ROLE_STARTED; } } 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); ); } slist_iter( node, node_t, data_set->nodes, lpc, accept = test_rule( rule_xml, node->details->attrs, RSC_ROLE_UNKNOWN, data_set->now); crm_debug_2("Rule %s %s on %s", ID(rule_xml), accept?"passed":"failed", node->details->uname); 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; } static gint sort_cons_priority_lh(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; } CRM_ASSERT(rsc_constraint1->rsc_lh != NULL); CRM_ASSERT(rsc_constraint1->rsc_rh != NULL); if(rsc_constraint1->rsc_lh->priority > rsc_constraint2->rsc_lh->priority) { return -1; } if(rsc_constraint1->rsc_lh->priority < rsc_constraint2->rsc_lh->priority) { return 1; } return strcmp(rsc_constraint1->rsc_lh->id, rsc_constraint2->rsc_lh->id); } static gint sort_cons_priority_rh(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; } CRM_ASSERT(rsc_constraint1->rsc_lh != NULL); CRM_ASSERT(rsc_constraint1->rsc_rh != NULL); if(rsc_constraint1->rsc_rh->priority > rsc_constraint2->rsc_rh->priority) { return -1; } if(rsc_constraint1->rsc_rh->priority < rsc_constraint2->rsc_rh->priority) { return 1; } return strcmp(rsc_constraint1->rsc_rh->id, rsc_constraint2->rsc_rh->id); } gboolean rsc_colocation_new(const char *id, const char *node_attr, int score, resource_t *rsc_lh, resource_t *rsc_rh, const char *state_lh, const char *state_rh, pe_working_set_t *data_set) { 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; if(node_attr == NULL) { node_attr = "#"XML_ATTR_UNAME; } crm_debug_3("%s ==> %s (%s %d)", rsc_lh->id, rsc_rh->id, node_attr, score); rsc_lh->rsc_cons = g_list_insert_sorted( rsc_lh->rsc_cons, new_con, sort_cons_priority_rh); rsc_rh->rsc_cons_lhs = g_list_insert_sorted( rsc_rh->rsc_cons_lhs, new_con, sort_cons_priority_lh); data_set->colocation_constraints = g_list_append( data_set->colocation_constraints, new_con); return TRUE; } /* LHS before RHS */ int new_rsc_order(resource_t *lh_rsc, const char *lh_task, resource_t *rh_rsc, const char *rh_task, enum pe_ordering type, pe_working_set_t *data_set) { char *lh_key = NULL; char *rh_key = NULL; CRM_CHECK(lh_rsc != NULL, return -1); CRM_CHECK(lh_task != NULL, return -1); CRM_CHECK(rh_rsc != NULL, return -1); CRM_CHECK(rh_task != NULL, return -1); lh_key = generate_op_key(lh_rsc->id, lh_task, 0); rh_key = generate_op_key(rh_rsc->id, rh_task, 0); return custom_action_order(lh_rsc, lh_key, NULL, rh_rsc, rh_key, NULL, type, data_set); } /* 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; } static enum pe_ordering get_flags( - const char *id, int score, const char *action_1, const char *action_2) { + const char *id, enum pe_order_kind kind, const char *action_1, const char *action_2, gboolean invert) { enum pe_ordering flags = pe_order_optional; - if(score < 0) { + if(invert && kind == pe_order_kind_mandatory) { crm_debug_2("Upgrade %s: implies left", id); flags |= pe_order_implies_left; if(safe_str_eq(action_2, RSC_DEMOTE)) { crm_debug_2("Upgrade %s: demote", id); flags |= pe_order_demote; } - } else if(score > 0) { + } else if(invert && kind == pe_order_kind_mandatory) { crm_debug_2("Upgrade %s: implies right", id); flags |= pe_order_implies_right; if(safe_str_eq(action_1, RSC_START) || safe_str_eq(action_1, RSC_PROMOTE)) { crm_debug_2("Upgrade %s: runnable", id); flags |= pe_order_runnable_left; } + + } else if(kind == pe_order_kind_serialize) { + flags |= pe_order_serialize_only; } + return flags; } static gboolean -unpack_order_set(xmlNode *set, int score, - action_t **begin, action_t **end, - action_t **inv_begin, action_t **inv_end, const char *symmetrical, pe_working_set_t *data_set) +unpack_order_set(xmlNode *set, enum pe_order_kind kind, + action_t **begin, action_t **end, action_t **inv_begin, action_t **inv_end, + const char *symmetrical, pe_working_set_t *data_set) { + GListPtr set_iter = NULL; + GListPtr resources = NULL; + resource_t *last = NULL; resource_t *resource = NULL; - int local_score = score; + int local_kind = kind; gboolean sequential = FALSE; enum pe_ordering flags = pe_order_optional; char *key = NULL; const char *id = ID(set); const char *action = crm_element_value(set, "action"); const char *sequential_s = crm_element_value(set, "sequential"); - const char *score_s = crm_element_value(set, XML_RULE_ATTR_SCORE); + const char *kind_s = crm_element_value(set, XML_ORDER_ATTR_KIND); char *pseudo_id = NULL; char *end_id = NULL; char *begin_id = NULL; if(action == NULL) { action = RSC_START; } pseudo_id = crm_concat(id, action, '-'); end_id = crm_concat(pseudo_id, "end", '-'); begin_id = crm_concat(pseudo_id, "begin", '-'); *end = get_pseudo_op(end_id, data_set); *begin = get_pseudo_op(begin_id, data_set); - if(score_s) { - local_score = char2score(score_s); + if(kind_s) { + local_kind = get_ordering_type(set); } sequential = crm_is_true(sequential_s); - flags = get_flags(id, local_score, action, action); - + flags = get_flags(id, local_kind, action, action, FALSE); + xml_child_iter_filter( set, xml_rsc, XML_TAG_RESOURCE_REF, - + resource = pe_find_resource(data_set->resources, ID(xml_rsc)); + resources = g_list_append(resources, resource); + ); - key = generate_op_key(resource->id, action, 0); - custom_action_order(NULL, NULL, *begin, resource, key, NULL, - flags|pe_order_implies_left_printed, data_set); + set_iter = resources; + while(set_iter != NULL) { + resource = (resource_t *) set_iter->data; + set_iter = set_iter->next; key = generate_op_key(resource->id, action, 0); - custom_action_order(resource, key, NULL, NULL, NULL, *end, + + custom_action_order(NULL, NULL, *begin, resource, crm_strdup(key), NULL, + flags|pe_order_implies_left_printed, data_set); + + custom_action_order(resource, crm_strdup(key), NULL, NULL, NULL, *end, flags|pe_order_implies_right_printed, data_set); - if(sequential) { + if(local_kind == pe_order_kind_serialize) { + /* Serialize before everything that comes after */ + slist_iter( + then_rsc, resource_t, set_iter, lpc, + + char *then_key = generate_op_key(then_rsc->id, action, 0); + custom_action_order(resource, crm_strdup(key), NULL, then_rsc, then_key, NULL, + flags, data_set); + ); + + } else if(sequential) { if(last != NULL) { new_rsc_order(last, action, resource, action, flags, data_set); } last = resource; } + } + + if(crm_is_true(symmetrical) == FALSE) { + goto done; - ); + } else if(symmetrical && local_kind == pe_order_kind_serialize) { + crm_config_warn("Cannot invert serialized constraint set %s", id); + goto done; - if(crm_is_true(symmetrical) == FALSE) { + } else if(local_kind == pe_order_kind_serialize) { goto done; } + last = NULL; - local_score *= -1; action = invert_action(action); pseudo_id = crm_concat(id, action, '-'); end_id = crm_concat(pseudo_id, "end", '-'); begin_id = crm_concat(pseudo_id, "begin", '-'); *inv_end = get_pseudo_op(end_id, data_set); *inv_begin = get_pseudo_op(begin_id, data_set); - flags = get_flags(id, local_score, action, action); - - xml_child_iter_filter( - set, xml_rsc, XML_TAG_RESOURCE_REF, + flags = get_flags(id, local_kind, action, action, TRUE); - resource = pe_find_resource(data_set->resources, ID(xml_rsc)); + set_iter = resources; + while(set_iter != NULL) { + resource = (resource_t *) set_iter->data; + set_iter = set_iter->next; key = generate_op_key(resource->id, action, 0); - custom_action_order(NULL, NULL, *inv_begin, resource, key, NULL, + + custom_action_order(NULL, NULL, *inv_begin, resource, crm_strdup(key), NULL, flags|pe_order_implies_left_printed, data_set); - key = generate_op_key(resource->id, action, 0); - custom_action_order(resource, key, NULL, NULL, NULL, *inv_end, + custom_action_order(resource, crm_strdup(key), NULL, NULL, NULL, *inv_end, flags|pe_order_implies_right_printed, data_set); if(sequential) { if(last != NULL) { new_rsc_order(resource, action, last, action, flags, data_set); } last = resource; } - - ); + } done: + g_list_free(resources); crm_free(pseudo_id); return TRUE; } static gboolean order_rsc_sets( - const char *id, xmlNode *set1, xmlNode *set2, int score, pe_working_set_t *data_set) { + const char *id, xmlNode *set1, xmlNode *set2, enum pe_order_kind kind, pe_working_set_t *data_set) { resource_t *rsc_1 = NULL; resource_t *rsc_2 = NULL; const char *action_1 = crm_element_value(set1, "action"); const char *action_2 = crm_element_value(set2, "action"); const char *sequential_1 = crm_element_value(set1, "sequential"); const char *sequential_2 = crm_element_value(set2, "sequential"); - enum pe_ordering flags = get_flags(id, score, action_1, action_2); + enum pe_ordering flags = get_flags(id, kind, action_1, action_2, FALSE); if(crm_is_true(sequential_1)) { /* get the first one */ xml_child_iter_filter( set1, xml_rsc, XML_TAG_RESOURCE_REF, rsc_1 = pe_find_resource(data_set->resources, ID(xml_rsc)); break; ); } if(crm_is_true(sequential_2)) { /* get the last one */ const char *rid = NULL; xml_child_iter_filter( set2, xml_rsc, XML_TAG_RESOURCE_REF, rid = ID(xml_rsc); ); rsc_2 = pe_find_resource(data_set->resources, rid); } if(rsc_1 != NULL && rsc_2 != NULL) { new_rsc_order(rsc_1, action_1, rsc_2, action_2, flags, data_set); } else if(rsc_1 != NULL) { xml_child_iter_filter( set2, xml_rsc, XML_TAG_RESOURCE_REF, rsc_2 = pe_find_resource(data_set->resources, ID(xml_rsc)); new_rsc_order(rsc_1, action_1, rsc_2, action_2, flags, data_set); ); } else if(rsc_2 != NULL) { xml_child_iter_filter( set1, xml_rsc, XML_TAG_RESOURCE_REF, rsc_1 = pe_find_resource(data_set->resources, ID(xml_rsc)); new_rsc_order(rsc_1, action_1, rsc_2, action_2, flags, data_set); ); } else { xml_child_iter_filter( set1, xml_rsc, XML_TAG_RESOURCE_REF, rsc_1 = pe_find_resource(data_set->resources, ID(xml_rsc)); xml_child_iter_filter( set2, xml_rsc_2, XML_TAG_RESOURCE_REF, rsc_2 = pe_find_resource(data_set->resources, ID(xml_rsc_2)); new_rsc_order(rsc_1, action_1, rsc_2, action_2, flags, data_set); ); ); } return TRUE; } gboolean unpack_rsc_order(xmlNode *xml_obj, pe_working_set_t *data_set) { - int score_i = 0; gboolean any_sets = FALSE; action_t *set_end = NULL; action_t *set_begin = NULL; action_t *set_inv_end = NULL; action_t *set_inv_begin = NULL; xmlNode *last = NULL; action_t *last_end = NULL; action_t *last_begin = NULL; action_t *last_inv_end = NULL; action_t *last_inv_begin = NULL; const char *id = crm_element_value(xml_obj, XML_ATTR_ID); - const char *score = crm_element_value(xml_obj, XML_RULE_ATTR_SCORE); const char *invert = crm_element_value(xml_obj, XML_CONS_ATTR_SYMMETRICAL); + enum pe_order_kind kind = get_ordering_type(xml_obj); if(invert == NULL) { invert = "true"; } - if(score == NULL) { - score = "INFINITY"; - } - - score_i = char2score(score); - xml_child_iter_filter( xml_obj, set, "resource_set", any_sets = TRUE; - if(unpack_order_set(set, score_i, &set_begin, &set_end, + if(unpack_order_set(set, kind, &set_begin, &set_end, &set_inv_begin, &set_inv_end, invert, data_set) == FALSE) { return FALSE; } else if(last) { const char *set_action = crm_element_value(set, "action"); const char *last_action = crm_element_value(last, "action"); - enum pe_ordering flags = get_flags(id, score_i, last_action, set_action); + enum pe_ordering flags = get_flags(id, kind, last_action, set_action, FALSE); order_actions(last_end, set_begin, flags); if(crm_is_true(invert)) { set_action = invert_action(set_action?set_action:RSC_START); last_action = invert_action(last_action?last_action:RSC_START); - score_i *= -1; - flags = get_flags(id, score_i, last_action, set_action); + flags = get_flags(id, kind, last_action, set_action, TRUE); order_actions(last_inv_begin, set_inv_end, flags); } - } else if(/* never called */last && order_rsc_sets(id, last, set, score_i, data_set) == FALSE) { + } else if(/* never called */last && order_rsc_sets(id, last, set, kind, data_set) == FALSE) { return FALSE; } last = set; last_end = set_end; last_begin = set_begin; last_inv_end = set_inv_end; last_inv_begin = set_inv_begin; ); if(any_sets == FALSE) { return unpack_simple_rsc_order(xml_obj, data_set); } return TRUE; } static gboolean unpack_colocation_set(xmlNode *set, int score, pe_working_set_t *data_set) { resource_t *with = NULL; resource_t *resource = NULL; const char *set_id = ID(set); const char *role = crm_element_value(set, "role"); const char *sequential = crm_element_value(set, "sequential"); int local_score = score; const char *score_s = crm_element_value(set, XML_RULE_ATTR_SCORE); if(score_s) { local_score = char2score(score_s); } if(crm_is_true(sequential)) { xml_child_iter_filter( set, xml_rsc, XML_TAG_RESOURCE_REF, resource = pe_find_resource(data_set->resources, ID(xml_rsc)); if(with != NULL) { crm_debug_2("Colocating %s with %s", resource->id, with->id); rsc_colocation_new(set_id, NULL, local_score, resource, with, role, role, data_set); } with = resource; ); } return TRUE; } static gboolean colocate_rsc_sets( const char *id, xmlNode *set1, xmlNode *set2, int score, pe_working_set_t *data_set) { resource_t *rsc_1 = NULL; resource_t *rsc_2 = NULL; const char *role_1 = crm_element_value(set1, "role"); const char *role_2 = crm_element_value(set2, "role"); const char *sequential_1 = crm_element_value(set1, "sequential"); const char *sequential_2 = crm_element_value(set2, "sequential"); if(crm_is_true(sequential_1)) { /* get the first one */ xml_child_iter_filter( set1, xml_rsc, XML_TAG_RESOURCE_REF, rsc_1 = pe_find_resource(data_set->resources, ID(xml_rsc)); break; ); } if(crm_is_true(sequential_2)) { /* get the last one */ const char *rid = NULL; xml_child_iter_filter( set2, xml_rsc, XML_TAG_RESOURCE_REF, rid = ID(xml_rsc); ); rsc_2 = pe_find_resource(data_set->resources, rid); } if(rsc_1 != NULL && rsc_2 != NULL) { rsc_colocation_new(id, NULL, score, rsc_1, rsc_2, role_1, role_2, data_set); } else if(rsc_1 != NULL) { xml_child_iter_filter( set2, xml_rsc, XML_TAG_RESOURCE_REF, rsc_2 = pe_find_resource(data_set->resources, ID(xml_rsc)); rsc_colocation_new(id, NULL, score, rsc_1, rsc_2, role_1, role_2, data_set); ); } else if(rsc_2 != NULL) { xml_child_iter_filter( set1, xml_rsc, XML_TAG_RESOURCE_REF, rsc_1 = pe_find_resource(data_set->resources, ID(xml_rsc)); rsc_colocation_new(id, NULL, score, rsc_1, rsc_2, role_1, role_2, data_set); ); } else { xml_child_iter_filter( set1, xml_rsc, XML_TAG_RESOURCE_REF, rsc_1 = pe_find_resource(data_set->resources, ID(xml_rsc)); xml_child_iter_filter( set2, xml_rsc_2, XML_TAG_RESOURCE_REF, rsc_2 = pe_find_resource(data_set->resources, ID(xml_rsc_2)); rsc_colocation_new(id, NULL, score, rsc_1, rsc_2, role_1, role_2, data_set); ); ); } return TRUE; } static gboolean unpack_simple_colocation(xmlNode *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 *score = crm_element_value(xml_obj, XML_RULE_ATTR_SCORE); const char *id_lh = crm_element_value(xml_obj, XML_COLOC_ATTR_SOURCE); const char *id_rh = crm_element_value(xml_obj, XML_COLOC_ATTR_TARGET); const char *state_lh = crm_element_value(xml_obj, XML_COLOC_ATTR_SOURCE_ROLE); const char *state_rh = crm_element_value(xml_obj, XML_COLOC_ATTR_TARGET_ROLE); const char *attr = crm_element_value(xml_obj, XML_COLOC_ATTR_NODE_ATTR); 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(crm_is_true(symmetrical)) { crm_config_warn("The %s colocation constraint attribute has been removed." " It didn't do what you think it did anyway.", XML_CONS_ATTR_SYMMETRICAL); } if(score) { score_i = char2score(score); } rsc_colocation_new(id, attr, score_i, rsc_lh, rsc_rh, state_lh, state_rh, data_set); return TRUE; } gboolean unpack_rsc_colocation(xmlNode *xml_obj, pe_working_set_t *data_set) { int score_i = 0; xmlNode *last = NULL; gboolean any_sets = FALSE; const char *id = crm_element_value(xml_obj, XML_ATTR_ID); const char *score = crm_element_value(xml_obj, XML_RULE_ATTR_SCORE); if(score) { score_i = char2score(score); } xml_child_iter_filter( xml_obj, set, "resource_set", any_sets = TRUE; if(unpack_colocation_set(set, score_i, data_set) == FALSE) { return FALSE; } else if(last && colocate_rsc_sets(id, last, set, score_i, data_set) == FALSE) { return FALSE; } last = set; ); if(any_sets == FALSE) { return unpack_simple_colocation(xml_obj, data_set); } return TRUE; } gboolean is_active(rsc_to_node_t *cons) { return TRUE; } diff --git a/pengine/regression.sh b/pengine/regression.sh index 08ea53bbf5..f0eb84cdd9 100755 --- a/pengine/regression.sh +++ b/pengine/regression.sh @@ -1,341 +1,342 @@ #!/bin/bash # 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 # if [ -x /usr/bin/valgrind ]; then export G_SLICE=always-malloc VALGRIND_CMD="valgrind -q --show-reachable=no --leak-check=full --trace-children=no --time-stamp=yes --num-callers=20 --suppressions=./ptest.supp" fi . regression.core.sh create_mode="true" echo Generating test outputs for these tests... # do_test file description echo Done. echo "" echo Performing the following tests... create_mode="false" echo "" do_test simple1 "Offline " do_test simple2 "Start " do_test simple3 "Start 2 " do_test simple4 "Start Failed" do_test simple6 "Stop Start " do_test simple7 "Shutdown " #do_test simple8 "Stonith " #do_test simple9 "Lower version" #do_test simple10 "Higher version" do_test simple11 "Priority (ne)" do_test simple12 "Priority (eq)" do_test simple8 "Stickiness" echo "" do_test params-0 "Params: No change" do_test params-1 "Params: Changed" do_test params-2 "Params: Resource definition" do_test params-4 "Params: Reload" do_test novell-251689 "Resource definition change + target_role=stopped" do_test bug-lf-2106 "Restart all anonymous clone instances after config change" echo "" do_test orphan-0 "Orphan ignore" do_test orphan-1 "Orphan stop" echo "" do_test target-0 "Target Role : baseline" do_test target-1 "Target Role : test" echo "" do_test date-1 "Dates" -d "2005-020" do_test date-2 "Date Spec - Pass" -d "2005-020T12:30" do_test date-3 "Date Spec - Fail" -d "2005-020T11:30" do_test probe-0 "Probe (anon clone)" do_test probe-1 "Pending Probe" do_test probe-2 "Correctly re-probe cloned groups" do_test standby "Standby" do_test comments "Comments" echo "" do_test rsc_dep1 "Must not " do_test rsc_dep3 "Must " do_test rsc_dep5 "Must not 3 " do_test rsc_dep7 "Must 3 " do_test rsc_dep10 "Must (but cant)" do_test rsc_dep2 "Must (running) " do_test rsc_dep8 "Must (running : alt) " do_test rsc_dep4 "Must (running + move)" do_test asymmetric "Asymmetric - require explicit location constraints" echo "" do_test order1 "Order start 1 " do_test order2 "Order start 2 " do_test order3 "Order stop " do_test order4 "Order (multiple) " do_test order5 "Order (move) " do_test order6 "Order (move w/ restart) " do_test order7 "Order (manditory) " do_test order-optional "Order (score=0) " do_test order-required "Order (score=INFINITY) " do_test bug-lf-2171 "Prevent group start when clone is stopped" do_test order-clone "Clone ordering should be able to prevent startup of dependant clones" do_test order-sets "Ordering for resource sets" do_test order-serialize "Serialize resources without inhibiting migration" +do_test order-serialize-set "Serialize a set of resources without inhibiting migration" echo "" do_test coloc-loop "Colocation - loop" do_test coloc-many-one "Colocation - many-to-one" do_test coloc-list "Colocation - many-to-one with list" do_test coloc-group "Colocation - groups" do_test coloc-slave-anti "Anti-colocation with slave shouldn't prevent master colocation" do_test coloc-attr "Colocation based on node attributes" do_test coloc-negative-group "Negative colocation with a group" #echo "" #do_test agent1 "version: lt (empty)" #do_test agent2 "version: eq " #do_test agent3 "version: gt " echo "" do_test attrs1 "string: eq (and) " do_test attrs2 "string: lt / gt (and)" do_test attrs3 "string: ne (or) " do_test attrs4 "string: exists " do_test attrs5 "string: not_exists " do_test attrs6 "is_dc: true " do_test attrs7 "is_dc: false " do_test attrs8 "score_attribute " echo "" do_test mon-rsc-1 "Schedule Monitor - start" do_test mon-rsc-2 "Schedule Monitor - move " do_test mon-rsc-3 "Schedule Monitor - pending start " do_test mon-rsc-4 "Schedule Monitor - move/pending start" echo "" do_test rec-rsc-0 "Resource Recover - no start " do_test rec-rsc-1 "Resource Recover - start " do_test rec-rsc-2 "Resource Recover - monitor " do_test rec-rsc-3 "Resource Recover - stop - ignore" do_test rec-rsc-4 "Resource Recover - stop - block " do_test rec-rsc-5 "Resource Recover - stop - fence " do_test rec-rsc-6 "Resource Recover - multiple - restart" do_test rec-rsc-7 "Resource Recover - multiple - stop " do_test rec-rsc-8 "Resource Recover - multiple - block " do_test rec-rsc-9 "Resource Recover - group/group" echo "" do_test quorum-1 "No quorum - ignore" do_test quorum-2 "No quorum - freeze" do_test quorum-3 "No quorum - stop " do_test quorum-4 "No quorum - start anyway" do_test quorum-5 "No quorum - start anyway (group)" do_test quorum-6 "No quorum - start anyway (clone)" echo "" do_test rec-node-1 "Node Recover - Startup - no fence" do_test rec-node-2 "Node Recover - Startup - fence " do_test rec-node-3 "Node Recover - HA down - no fence" do_test rec-node-4 "Node Recover - HA down - fence " do_test rec-node-5 "Node Recover - CRM down - no fence" do_test rec-node-6 "Node Recover - CRM down - fence " do_test rec-node-7 "Node Recover - no quorum - ignore " do_test rec-node-8 "Node Recover - no quorum - freeze " do_test rec-node-9 "Node Recover - no quorum - stop " do_test rec-node-10 "Node Recover - no quorum - stop w/fence" do_test rec-node-11 "Node Recover - CRM down w/ group - fence " do_test rec-node-12 "Node Recover - nothing active - fence " do_test rec-node-13 "Node Recover - failed resource + shutdown - fence " do_test rec-node-15 "Node Recover - unknown lrm section" do_test rec-node-14 "Serialize all stonith's" echo "" do_test multi1 "Multiple Active (stop/start)" echo "" do_test migrate-stop "Migration in a stopping stack" do_test migrate-start "Migration in a starting stack" do_test migrate-stop_start "Migration in a restarting stack" do_test migrate-stop-complex "Migration in a complex stopping stack" do_test migrate-start-complex "Migration in a complex starting stack" do_test migrate-1 "Migrate (migrate)" do_test migrate-2 "Migrate (stable)" do_test migrate-3 "Migrate (failed migrate_to)" do_test migrate-4 "Migrate (failed migrate_from)" do_test novell-252693 "Migration in a stopping stack" do_test novell-252693-2 "Migration in a starting stack" do_test novell-252693-3 "Non-Migration in a starting and stopping stack" do_test bug-1820 "Migration in a group" do_test bug-1820-1 "Non-migration in a group" do_test migrate-5 "Primitive migration with a clone" #echo "" #do_test complex1 "Complex " echo "" do_test group1 "Group " do_test group2 "Group + Native " do_test group3 "Group + Group " do_test group4 "Group + Native (nothing)" do_test group5 "Group + Native (move) " do_test group6 "Group + Group (move) " do_test group7 "Group colocation" do_test group13 "Group colocation (cant run)" do_test group8 "Group anti-colocation" do_test group9 "Group recovery" do_test group10 "Group partial recovery" do_test group11 "Group target_role" do_test group14 "Group stop (graph terminated)" do_test group15 "-ve group colocation" do_test bug-1573 "Partial stop of a group with two children" do_test bug-1718 "Mandatory group ordering - Stop group_FUN" echo "" do_test clone-anon-probe-1 "Probe the correct (anonymous) clone instance for each node" do_test clone-anon-probe-2 "Avoid needless re-probing of anonymous clones" do_test inc0 "Incarnation start" do_test inc1 "Incarnation start order" do_test inc2 "Incarnation silent restart, stop, move" do_test inc3 "Inter-incarnation ordering, silent restart, stop, move" do_test inc4 "Inter-incarnation ordering, silent restart, stop, move (ordered)" do_test inc5 "Inter-incarnation ordering, silent restart, stop, move (restart 1)" do_test inc6 "Inter-incarnation ordering, silent restart, stop, move (restart 2)" do_test inc7 "Clone colocation" do_test inc8 "Clone anti-colocation" do_test inc9 "Non-unique clone" do_test inc10 "Non-unique clone (stop)" do_test inc11 "Primitive colocation with clones" do_test inc12 "Clone shutdown" do_test cloned-group "Make sure only the correct number of cloned groups are started" do_test clone-no-shuffle "Dont prioritize allocation of instances that must be moved" do_test clone-max-zero "Orphan processing with clone-max=0" do_test clone-anon-dup "Bug LF#2087 - Correctly parse the state of anonymous clones that are active more than once per node" do_test bug-lf-2160 "Dont shuffle clones due to colocation" do_test bug-lf-2213 "clone-node-max enforcement for cloned groups" do_test bug-lf-2153 "Clone ordering constraints" echo "" do_test master-0 "Stopped -> Slave" do_test master-1 "Stopped -> Promote" do_test master-2 "Stopped -> Promote : notify" do_test master-3 "Stopped -> Promote : master location" do_test master-4 "Started -> Promote : master location" do_test master-5 "Promoted -> Promoted" do_test master-6 "Promoted -> Promoted (2)" do_test master-7 "Promoted -> Fenced" do_test master-8 "Promoted -> Fenced -> Moved" do_test master-9 "Stopped + Promotable + No quorum" do_test master-10 "Stopped -> Promotable : notify with monitor" do_test master-11 "Stopped -> Promote : colocation" do_test novell-239082 "Demote/Promote ordering" do_test novell-239087 "Stable master placement" do_test master-12 "Promotion based solely on rsc_location constraints" do_test master-13 "Include preferences of colocated resources when placing master" do_test master-demote "Ordering when actions depends on demoting a slave resource" do_test master-ordering "Prevent resources from starting that need a master" do_test bug-1765 "Master-Master Colocation (dont stop the slaves)" do_test master-group "Promotion of cloned groups" do_test bug-lf-1852 "Don't shuffle master/slave instances unnecessarily" do_test master-failed-demote "Dont retry failed demote actions" do_test master-failed-demote-2 "Dont retry failed demote actions (notify=false)" do_test master-depend "Ensure resources that depend on the master don't get allocated until the master does" do_test master-reattach "Re-attach to a running master" do_test master-allow-start "Don't include master score if it would prevent allocation" do_test master-colocation "Allow master instances placemaker to be influenced by colocation constraints" do_test master-pseudo "Make sure promote/demote pseudo actions are created correctly" do_test master-role "Prevent target-role from promoting more than master-max instances" echo "" do_test managed-0 "Managed (reference)" do_test managed-1 "Not managed - down " do_test managed-2 "Not managed - up " echo "" do_test interleave-0 "Interleave (reference)" do_test interleave-1 "coloc - not interleaved" do_test interleave-2 "coloc - interleaved " do_test interleave-3 "coloc - interleaved (2)" do_test interleave-pseudo-stop "Interleaved clone during stonith" do_test interleave-stop "Interleaved clone during stop" do_test interleave-restart "Interleaved clone during dependancy restart" echo "" do_test notify-0 "Notify reference" do_test notify-1 "Notify simple" do_test notify-2 "Notify simple, confirm" do_test notify-3 "Notify move, confirm" do_test novell-239079 "Notification priority" #do_test notify-2 "Notify - 764" echo "" do_test 594 "OSDL #594" do_test 662 "OSDL #662" do_test 696 "OSDL #696" do_test 726 "OSDL #726" do_test 735 "OSDL #735" do_test 764 "OSDL #764" do_test 797 "OSDL #797" do_test 829 "OSDL #829" do_test 994 "OSDL #994" do_test 994-2 "OSDL #994 - with a dependant resource" do_test 1360 "OSDL #1360 - Clone stickiness" do_test 1484 "OSDL #1484 - on_fail=stop" do_test 1494 "OSDL #1494 - Clone stability" do_test unrunnable-1 "Unrunnable" do_test stonith-0 "Stonith loop - 1" do_test stonith-1 "Stonith loop - 2" do_test stonith-2 "Stonith loop - 3" do_test stonith-3 "Stonith startup" do_test bug-1572-1 "Recovery of groups depending on master/slave" do_test bug-1572-2 "Recovery of groups depending on master/slave when the master is never re-promoted" do_test bug-1685 "Depends-on-master ordering" do_test bug-1822 "Dont promote partially active groups" do_test bug-pm-11 "New resource added to a m/s group" do_test bug-pm-12 "Recover only the failed portion of a cloned group" do_test bug-n-387749 "Don't shuffle clone instances" do_test bug-n-385265 "Don't ignore the failure stickiness of group children - resource_idvscommon should stay stopped" do_test bug-n-385265-2 "Ensure groups are migrated instead of remaining partially active on the current node" do_test bug-lf-1920 "Correctly handle probes that find active resources" do_test bnc-515172 "Location constraint with multiple expressions" echo "" do_test systemhealth1 "System Health () #1" do_test systemhealth2 "System Health () #2" do_test systemhealth3 "System Health () #3" do_test systemhealthn1 "System Health (None) #1" do_test systemhealthn2 "System Health (None) #2" do_test systemhealthn3 "System Health (None) #3" do_test systemhealthm1 "System Health (Migrate On Red) #1" do_test systemhealthm2 "System Health (Migrate On Red) #2" do_test systemhealthm3 "System Health (Migrate On Red) #3" do_test systemhealtho1 "System Health (Only Green) #1" do_test systemhealtho2 "System Health (Only Green) #2" do_test systemhealtho3 "System Health (Only Green) #3" do_test systemhealthp1 "System Health (Progessive) #1" do_test systemhealthp2 "System Health (Progessive) #2" do_test systemhealthp3 "System Health (Progessive) #3" echo "" do_test utilization "Placement Strategy - utilization" do_test minimal "Placement Strategy - minimal" do_test balanced "Placement Strategy - balanced" echo "" test_results diff --git a/pengine/test10/order-serialize-set.dot b/pengine/test10/order-serialize-set.dot new file mode 100644 index 0000000000..175dc8e3d0 --- /dev/null +++ b/pengine/test10/order-serialize-set.dot @@ -0,0 +1,82 @@ +digraph "g" { +"all_stopped" -> "xen-b-fencing_stop_0 xen-a" [ style = bold] +"all_stopped" [ style=bold color="green" fontcolor="orange" ] +"base_migrate_from_0 xen-b" -> "all_stopped" [ style = bold] +"base_migrate_from_0 xen-b" -> "base_monitor_10000 xen-b" [ style = bold] +"base_migrate_from_0 xen-b" -> "xen-set-start-end" [ style = bold] +"base_migrate_from_0 xen-b" [ style=bold color="green" fontcolor="black" ] +"base_migrate_to_0 xen-a" -> "all_stopped" [ style = bold] +"base_migrate_to_0 xen-a" -> "base_migrate_from_0 xen-b" [ style = bold] +"base_migrate_to_0 xen-a" [ style=bold color="green" fontcolor="black" ] +"base_monitor_10000 xen-b" [ style=bold color="green" fontcolor="black" ] +"core-101_migrate_from_0 xen-b" -> "all_stopped" [ style = bold] +"core-101_migrate_from_0 xen-b" -> "base_migrate_from_0 xen-b" [ style = bold] +"core-101_migrate_from_0 xen-b" -> "base_migrate_to_0 xen-a" [ style = bold] +"core-101_migrate_from_0 xen-b" -> "core-101_monitor_10000 xen-b" [ style = bold] +"core-101_migrate_from_0 xen-b" -> "core-200_migrate_from_0 xen-b" [ style = bold] +"core-101_migrate_from_0 xen-b" -> "core-200_migrate_to_0 xen-a" [ style = bold] +"core-101_migrate_from_0 xen-b" -> "edge_migrate_from_0 xen-b" [ style = bold] +"core-101_migrate_from_0 xen-b" -> "edge_migrate_to_0 xen-a" [ style = bold] +"core-101_migrate_from_0 xen-b" -> "xen-set-start-end" [ style = bold] +"core-101_migrate_from_0 xen-b" [ style=bold color="green" fontcolor="black" ] +"core-101_migrate_to_0 xen-a" -> "all_stopped" [ style = bold] +"core-101_migrate_to_0 xen-a" -> "core-101_migrate_from_0 xen-b" [ style = bold] +"core-101_migrate_to_0 xen-a" [ style=bold color="green" fontcolor="black" ] +"core-101_monitor_10000 xen-b" [ style=bold color="green" fontcolor="black" ] +"core-200_migrate_from_0 xen-b" -> "all_stopped" [ style = bold] +"core-200_migrate_from_0 xen-b" -> "base_migrate_from_0 xen-b" [ style = bold] +"core-200_migrate_from_0 xen-b" -> "base_migrate_to_0 xen-a" [ style = bold] +"core-200_migrate_from_0 xen-b" -> "core-200_monitor_10000 xen-b" [ style = bold] +"core-200_migrate_from_0 xen-b" -> "edge_migrate_from_0 xen-b" [ style = bold] +"core-200_migrate_from_0 xen-b" -> "edge_migrate_to_0 xen-a" [ style = bold] +"core-200_migrate_from_0 xen-b" -> "xen-set-start-end" [ style = bold] +"core-200_migrate_from_0 xen-b" [ style=bold color="green" fontcolor="black" ] +"core-200_migrate_to_0 xen-a" -> "all_stopped" [ style = bold] +"core-200_migrate_to_0 xen-a" -> "core-200_migrate_from_0 xen-b" [ style = bold] +"core-200_migrate_to_0 xen-a" [ style=bold color="green" fontcolor="black" ] +"core-200_monitor_10000 xen-b" [ style=bold color="green" fontcolor="black" ] +"db_migrate_from_0 xen-b" -> "all_stopped" [ style = bold] +"db_migrate_from_0 xen-b" -> "base_migrate_from_0 xen-b" [ style = bold] +"db_migrate_from_0 xen-b" -> "base_migrate_to_0 xen-a" [ style = bold] +"db_migrate_from_0 xen-b" -> "core-101_migrate_from_0 xen-b" [ style = bold] +"db_migrate_from_0 xen-b" -> "core-101_migrate_to_0 xen-a" [ style = bold] +"db_migrate_from_0 xen-b" -> "core-200_migrate_from_0 xen-b" [ style = bold] +"db_migrate_from_0 xen-b" -> "core-200_migrate_to_0 xen-a" [ style = bold] +"db_migrate_from_0 xen-b" -> "db_monitor_10000 xen-b" [ style = bold] +"db_migrate_from_0 xen-b" -> "edge_migrate_from_0 xen-b" [ style = bold] +"db_migrate_from_0 xen-b" -> "edge_migrate_to_0 xen-a" [ style = bold] +"db_migrate_from_0 xen-b" -> "xen-set-start-end" [ style = bold] +"db_migrate_from_0 xen-b" [ style=bold color="green" fontcolor="black" ] +"db_migrate_to_0 xen-a" -> "all_stopped" [ style = bold] +"db_migrate_to_0 xen-a" -> "db_migrate_from_0 xen-b" [ style = bold] +"db_migrate_to_0 xen-a" [ style=bold color="green" fontcolor="black" ] +"db_monitor_10000 xen-b" [ style=bold color="green" fontcolor="black" ] +"edge_migrate_from_0 xen-b" -> "all_stopped" [ style = bold] +"edge_migrate_from_0 xen-b" -> "base_migrate_from_0 xen-b" [ style = bold] +"edge_migrate_from_0 xen-b" -> "base_migrate_to_0 xen-a" [ style = bold] +"edge_migrate_from_0 xen-b" -> "edge_monitor_10000 xen-b" [ style = bold] +"edge_migrate_from_0 xen-b" -> "xen-set-start-end" [ style = bold] +"edge_migrate_from_0 xen-b" [ style=bold color="green" fontcolor="black" ] +"edge_migrate_to_0 xen-a" -> "all_stopped" [ style = bold] +"edge_migrate_to_0 xen-a" -> "edge_migrate_from_0 xen-b" [ style = bold] +"edge_migrate_to_0 xen-a" [ style=bold color="green" fontcolor="black" ] +"edge_monitor_10000 xen-b" [ style=bold color="green" fontcolor="black" ] +"xen-a-fencing_monitor_60000 xen-b" [ style=bold color="green" fontcolor="black" ] +"xen-a-fencing_start_0 xen-b" -> "xen-a-fencing_monitor_60000 xen-b" [ style = bold] +"xen-a-fencing_start_0 xen-b" [ style=bold color="green" fontcolor="black" ] +"xen-a-fencing_stop_0 xen-b" -> "xen-a-fencing_start_0 xen-b" [ style = bold] +"xen-a-fencing_stop_0 xen-b" [ style=bold color="green" fontcolor="black" ] +"xen-b-fencing_stop_0 xen-a" [ style=bold color="green" fontcolor="black" ] +"xen-set-start-begin" -> "base_migrate_from_0 xen-b" [ style = bold] +"xen-set-start-begin" -> "base_migrate_to_0 xen-a" [ style = bold] +"xen-set-start-begin" -> "core-101_migrate_from_0 xen-b" [ style = bold] +"xen-set-start-begin" -> "core-101_migrate_to_0 xen-a" [ style = bold] +"xen-set-start-begin" -> "core-200_migrate_from_0 xen-b" [ style = bold] +"xen-set-start-begin" -> "core-200_migrate_to_0 xen-a" [ style = bold] +"xen-set-start-begin" -> "db_migrate_from_0 xen-b" [ style = bold] +"xen-set-start-begin" -> "db_migrate_to_0 xen-a" [ style = bold] +"xen-set-start-begin" -> "edge_migrate_from_0 xen-b" [ style = bold] +"xen-set-start-begin" -> "edge_migrate_to_0 xen-a" [ style = bold] +"xen-set-start-begin" [ style=bold color="green" fontcolor="orange" ] +"xen-set-start-end" [ style=bold color="green" fontcolor="orange" ] +} diff --git a/pengine/test10/order-serialize-set.exp b/pengine/test10/order-serialize-set.exp new file mode 100644 index 0000000000..88396521fc --- /dev/null +++ b/pengine/test10/order-serialize-set.exp @@ -0,0 +1,392 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pengine/test10/order-serialize-set.scores b/pengine/test10/order-serialize-set.scores new file mode 100644 index 0000000000..3ab363b0a7 --- /dev/null +++ b/pengine/test10/order-serialize-set.scores @@ -0,0 +1,21 @@ +Allocation scores: +native_color: xen-a-fencing allocation score on xen-b: 1000 +native_color: xen-a-fencing allocation score on xen-a: -1000000 +native_color: xen-b-fencing allocation score on xen-b: -1000000 +native_color: xen-b-fencing allocation score on xen-a: 1000 +native_color: db allocation score on xen-b: 0 +native_color: db allocation score on xen-a: 6000 +native_color: dbreplica allocation score on xen-b: 6000 +native_color: dbreplica allocation score on xen-a: 0 +native_color: core-101 allocation score on xen-b: 0 +native_color: core-101 allocation score on xen-a: 6000 +native_color: core-200 allocation score on xen-b: 0 +native_color: core-200 allocation score on xen-a: 6000 +native_color: sysadmin allocation score on xen-b: 6000 +native_color: sysadmin allocation score on xen-a: 0 +native_color: edge allocation score on xen-b: 0 +native_color: edge allocation score on xen-a: 6000 +native_color: base allocation score on xen-b: 0 +native_color: base allocation score on xen-a: 6000 +native_color: Email_Alerting allocation score on xen-b: 1000 +native_color: Email_Alerting allocation score on xen-a: 0 diff --git a/pengine/test10/order-serialize-set.xml b/pengine/test10/order-serialize-set.xml new file mode 100644 index 0000000000..eb5f7bf32e --- /dev/null +++ b/pengine/test10/order-serialize-set.xml @@ -0,0 +1,336 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +