12 #include <sys/param.h>
13 #include <sys/types.h>
28 #include <../lib/pengine/unpack.h>
36 #define EXPAND_CONSTRAINT_IDREF(__set, __rsc, __name) do { \
37 __rsc = pe_find_constraint_resource(data_set->resources, __name); \
39 crm_config_err("%s: No resource found for %s", __set, __name); \
45 const char *action_first,
const char *action_then, gboolean invert);
49 const char *discovery,
73 xmlNode *xml_obj = NULL;
74 xmlNode *lifetime = NULL;
76 for (xml_obj = __xml_first_child_element(xml_constraints); xml_obj != NULL;
77 xml_obj = __xml_next_element(xml_obj)) {
79 const char *tag = crm_element_name(xml_obj);
86 crm_trace(
"Processing constraint %s %s", tag,
id);
90 crm_config_warn(
"Support for the lifetime tag, used by %s, is deprecated."
91 " The rules it contains should instead be direct descendents of the constraint object",
95 if (lifetime && !evaluate_lifetime(lifetime, data_set)) {
96 crm_info(
"Constraint %s %s is not active", tag,
id);
111 pe_err(
"Unsupported constraint type: %s", tag);
119 invert_action(
const char *action)
150 get_ordering_type(xmlNode * xml_obj)
168 "Support for 'score' in rsc_order is deprecated "
169 "and will be removed in a future release (use 'kind' instead)");
190 pe_find_constraint_resource(
GListPtr rsc_list,
const char *
id)
194 for (rIter = rsc_list;
id && rIter; rIter = rIter->next) {
219 NULL, (gpointer*) tag);
222 rc = g_hash_table_lookup_extended(data_set->
tags,
id,
223 NULL, (gpointer*) tag);
229 }
else if (*tag == NULL) {
234 }
else if (*tag == NULL) {
250 *rsc = pe_find_constraint_resource(data_set->
resources,
id);
258 rc = pe_find_constraint_tag(data_set,
id, tag);
265 order_is_symmetrical(xmlNode * xml_obj,
266 enum pe_order_kind parent_kind,
const char * parent_symmetrical_s)
274 if (kind_s || score_s) {
275 kind = get_ordering_type(xml_obj);
278 if (symmetrical_s == NULL) {
279 symmetrical_s = parent_symmetrical_s;
287 " Ignoring symmetrical=\"%s\"",
310 gboolean invert_bool = TRUE;
311 int min_required_before = 0;
315 const char *id_first = NULL;
316 const char *id_then = NULL;
317 const char *action_then = NULL;
318 const char *action_first = NULL;
319 const char *instance_then = NULL;
320 const char *instance_first = NULL;
322 const char *
id = NULL;
324 if (xml_obj == NULL) {
331 crm_config_err(
"%s constraint must have an id", crm_element_name(xml_obj));
335 invert_bool = order_is_symmetrical(xml_obj, kind, NULL);
346 if (action_first == NULL) {
349 if (action_then == NULL) {
350 action_then = action_first;
353 if (id_then == NULL || id_first == NULL) {
359 rsc_then = pe_find_constraint_resource(data_set->
resources, id_then);
360 rsc_first = pe_find_constraint_resource(data_set->
resources, id_first);
362 if (rsc_then == NULL) {
363 crm_config_err(
"Constraint %s: no resource found for name '%s'",
id, id_then);
366 }
else if (rsc_first == NULL) {
367 crm_config_err(
"Constraint %s: no resource found for name '%s'",
id, id_first);
370 }
else if (instance_then && pe_rsc_is_clone(rsc_then) == FALSE) {
372 " Resource '%s' is not a clone but instance %s was requested",
373 id, id_then, instance_then);
376 }
else if (instance_first && pe_rsc_is_clone(rsc_first) == FALSE) {
378 " Resource '%s' is not a clone but instance %s was requested",
379 id, id_first, instance_first);
385 if (rsc_then == NULL) {
386 crm_config_warn(
"Invalid constraint '%s': No instance '%s' of '%s'",
id, instance_then,
392 if (instance_first) {
394 if (rsc_first == NULL) {
395 crm_config_warn(
"Invalid constraint '%s': No instance '%s' of '%s'",
id, instance_first,
402 kind = get_ordering_type(xml_obj);
405 crm_trace(
"Upgrade : recovery - implies right");
409 if (invert_bool == FALSE) {
412 cons_weight |=
get_flags(
id, kind, action_first, action_then, FALSE);
415 if (pe_rsc_is_clone(rsc_first)) {
419 const char *min_clones_s = g_hash_table_lookup(rsc_first->
meta,
428 }
else if (require_all_s) {
430 "Support for require-all in ordering constraints "
431 "is deprecated and will be removed in a future release"
432 " (use clone-min clone meta-attribute instead)");
435 min_required_before = 1;
443 if (min_required_before) {
455 for (rIter = rsc_first->
children;
id && rIter; rIter = rIter->next) {
459 NULL, NULL, unordered_action,
469 order_id =
new_rsc_order(rsc_first, action_first, rsc_then, action_then, cons_weight, data_set);
472 pe_rsc_trace(rsc_first,
"order-%d (%s): %s_%s before %s_%s flags=0x%.6x",
473 order_id,
id, rsc_first->
id, action_first, rsc_then->
id, action_then, cons_weight);
475 if (invert_bool == FALSE) {
479 action_then = invert_action(action_then);
480 action_first = invert_action(action_first);
481 if (action_then == NULL || action_first == NULL) {
483 " Please specify the inverse manually.",
id);
489 crm_trace(
"Upgrade : recovery - implies left");
493 cons_weight |=
get_flags(
id, kind, action_first, action_then, TRUE);
495 order_id =
new_rsc_order(rsc_then, action_then, rsc_first, action_first, cons_weight, data_set);
497 pe_rsc_trace(rsc_then,
"order-%d (%s): %s_%s before %s_%s flags=0x%.6x",
498 order_id,
id, rsc_then->
id, action_then, rsc_first->
id, action_first, cons_weight);
504 expand_tags_in_sets(xmlNode * xml_obj, xmlNode ** expanded_xml,
pe_working_set_t * data_set)
506 xmlNode *new_xml = NULL;
508 gboolean any_refs = FALSE;
509 const char *cons_id = NULL;
511 *expanded_xml = NULL;
513 if (xml_obj == NULL) {
519 cons_id =
ID(new_xml);
521 for (set = __xml_first_child_element(new_xml); set != NULL;
522 set = __xml_next_element(set)) {
524 xmlNode *xml_rsc = NULL;
532 for (xml_rsc = __xml_first_child_element(set); xml_rsc != NULL;
533 xml_rsc = __xml_next_element(xml_rsc)) {
537 const char *
id =
ID(xml_rsc);
543 if (valid_resource_or_tag(data_set,
id, &rsc, &tag) == FALSE) {
544 crm_config_err(
"Constraint '%s': Invalid reference to '%s'", cons_id,
id);
553 xmlNode *last_ref = xml_rsc;
577 for (gIter = tag->
refs; gIter != NULL; gIter = gIter->next) {
578 const char *obj_ref = (
const char *) gIter->data;
579 xmlNode *new_rsc_ref = NULL;
581 new_rsc_ref = xmlNewDocRawNode(
getDocPtr(set), NULL,
584 xmlAddNextSibling(last_ref, new_rsc_ref);
586 last_ref = new_rsc_ref;
595 tag_refs = g_list_append(tag_refs, xml_rsc);
609 for (gIter = tag_refs; gIter != NULL; gIter = gIter->next) {
610 xmlNode *tag_ref = gIter->data;
614 g_list_free(tag_refs);
618 *expanded_xml = new_xml;
627 tag_to_set(xmlNode * xml_obj, xmlNode ** rsc_set,
const char * attr,
630 const char *cons_id = NULL;
631 const char *
id = NULL;
638 if (xml_obj == NULL) {
649 if (cons_id == NULL) {
650 crm_config_err(
"%s constraint must have an id", crm_element_name(xml_obj));
659 if (valid_resource_or_tag(data_set,
id, &rsc, &tag) == FALSE) {
660 crm_config_err(
"Constraint '%s': Invalid reference to '%s'", cons_id,
id);
672 for (gIter = tag->
refs; gIter != NULL; gIter = gIter->next) {
673 const char *obj_ref = (
const char *) gIter->data;
674 xmlNode *rsc_ref = NULL;
683 }
else if (rsc && convert_rsc) {
686 xmlNode *rsc_ref = NULL;
706 static gboolean unpack_rsc_location(xmlNode * xml_obj,
resource_t * rsc_lh,
const char * role,
718 return unpack_rsc_location(xml_obj, rsc_lh, NULL, NULL, data_set, NULL);
723 regex_t *r_patt = calloc(1,
sizeof(regex_t));
727 if(value[0] ==
'!') {
732 if (regcomp(r_patt, value, REG_EXTENDED)) {
739 for (rIter = data_set->
resources; rIter; rIter = rIter->next) {
742 regmatch_t *pmatch = NULL;
745 if(r_patt->re_nsub > 0) {
746 nregs = r_patt->re_nsub + 1;
750 pmatch = calloc(nregs,
sizeof(regmatch_t));
752 status = regexec(r_patt, r->
id, nregs, pmatch, 0);
754 if(invert == FALSE && status == 0) {
761 .
re = &re_match_data,
765 crm_debug(
"'%s' matched '%s' for %s", r->
id, value,
id);
766 unpack_rsc_location(xml_obj, r, NULL, NULL, data_set, &match_data);
768 }
else if (invert && (status != 0)) {
769 crm_debug(
"'%s' is an inverted match of '%s' for %s", r->
id, value,
id);
770 unpack_rsc_location(xml_obj, r, NULL, NULL, data_set, NULL);
773 crm_trace(
"'%s' does not match '%s' for %s", r->
id, value,
id);
787 unpack_rsc_location(xmlNode * xml_obj,
resource_t * rsc_lh,
const char * role,
796 if (rsc_lh == NULL) {
806 if (node != NULL && score != NULL) {
813 location =
rsc2node_new(
id, rsc_lh, score_i, discovery, match, data_set);
827 generate_location_rule(rsc_lh, rule_xml, discovery, next_change,
828 data_set, match_data);
833 " rsc_location must contain at least one rule",
id);
852 if (location && role) {
854 pe_err(
"Invalid constraint %s: Bad role %s",
id, role);
877 unpack_location_tags(xmlNode * xml_obj, xmlNode ** expanded_xml,
pe_working_set_t * data_set)
879 const char *
id = NULL;
880 const char *id_lh = NULL;
881 const char *state_lh = NULL;
885 tag_t *tag_lh = NULL;
887 xmlNode *new_xml = NULL;
888 xmlNode *rsc_set_lh = NULL;
890 *expanded_xml = NULL;
892 if (xml_obj == NULL) {
899 crm_config_err(
"%s constraint must have an id", crm_element_name(xml_obj));
904 expand_tags_in_sets(xml_obj, &new_xml, data_set);
908 *expanded_xml = new_xml;
917 if (valid_resource_or_tag(data_set, id_lh, &rsc_lh, &tag_lh) == FALSE) {
918 crm_config_err(
"Constraint '%s': Invalid reference to '%s'",
id, id_lh);
944 *expanded_xml = new_xml;
955 unpack_location_set(xmlNode * location, xmlNode * set,
pe_working_set_t * data_set)
957 xmlNode *xml_rsc = NULL;
961 const char *local_score;
969 if (set_id == NULL) {
977 for (xml_rsc = __xml_first_child_element(set); xml_rsc != NULL;
978 xml_rsc = __xml_next_element(xml_rsc)) {
982 unpack_rsc_location(location, resource, role, local_score, data_set, NULL);
993 gboolean any_sets = FALSE;
995 xmlNode *orig_xml = NULL;
996 xmlNode *expanded_xml = NULL;
998 if (unpack_location_tags(xml_obj, &expanded_xml, data_set) == FALSE) {
1004 xml_obj = expanded_xml;
1007 for (set = __xml_first_child_element(xml_obj); set != NULL;
1008 set = __xml_next_element(set)) {
1013 if (unpack_location_set(xml_obj, set, data_set) == FALSE) {
1027 if (any_sets == FALSE) {
1028 return unpack_simple_location(xml_obj, data_set);
1035 get_node_score(
const char *rule,
const char *score, gboolean raw,
node_t * node,
resource_t *rsc)
1039 if (score == NULL) {
1040 pe_err(
"Rule %s: no score specified. Assuming 0.", rule);
1048 if (attr_score == NULL) {
1049 crm_debug(
"Rule %s: node %s did not have a value for %s",
1054 crm_debug(
"Rule %s: node %s had value %s for %s",
1063 generate_location_rule(
pe_resource_t *rsc, xmlNode *rule_xml,
1064 const char *discovery,
crm_time_t *next_change,
1067 const char *rule_id = NULL;
1068 const char *score = NULL;
1069 const char *
boolean = NULL;
1070 const char *role = NULL;
1075 gboolean do_and = TRUE;
1076 gboolean accept = TRUE;
1077 gboolean raw_score = TRUE;
1078 gboolean score_allocated = FALSE;
1087 crm_trace(
"Processing rule: %s", rule_id);
1090 pe_err(
"Bad role specified for %s: %s", rule_id, role);
1095 if (score == NULL) {
1097 if (score != NULL) {
1105 location_rule =
rsc2node_new(rule_id, rsc, 0, discovery, NULL, data_set);
1107 if (location_rule == NULL) {
1111 if (match_data && match_data->
re && match_data->
re->
nregs > 0 && match_data->
re->
pmatch[0].rm_so != -1) {
1112 if (raw_score == FALSE) {
1116 score = (
const char *) result;
1117 score_allocated = TRUE;
1123 crm_trace(
"Setting role filter: %s", role);
1136 for (gIter = match_L; gIter != NULL; gIter = gIter->next) {
1139 node->
weight = get_node_score(rule_id, score, raw_score, node, rsc);
1143 for (gIter = data_set->
nodes; gIter != NULL; gIter = gIter->next) {
1148 data_set->
now, next_change, match_data);
1150 crm_trace(
"Rule %s %s on %s",
ID(rule_xml), accept ?
"passed" :
"failed",
1153 score_f = get_node_score(rule_id, score, raw_score, node, rsc);
1161 if (
local == NULL && do_and) {
1164 }
else if (
local == NULL) {
1166 match_L = g_list_append(match_L,
local);
1169 if (do_and == FALSE) {
1174 }
else if (do_and && !accept) {
1178 if (
delete != NULL) {
1179 match_L = g_list_remove(match_L,
delete);
1186 if (score_allocated == TRUE) {
1187 free((
char *)score);
1192 crm_trace(
"No matching nodes for rule %s", rule_id);
1197 return location_rule;
1201 sort_cons_priority_lh(gconstpointer a, gconstpointer b)
1249 sort_cons_priority_rh(gconstpointer a, gconstpointer b)
1297 anti_colocation_order(
resource_t * first_rsc,
int first_role,
1301 const char *first_tasks[] = { NULL, NULL };
1302 const char *then_tasks[] = { NULL, NULL };
1330 for (first_lpc = 0; first_lpc <= 1 && first_tasks[first_lpc] != NULL; first_lpc++) {
1331 for (then_lpc = 0; then_lpc <= 1 && then_tasks[then_lpc] != NULL; then_lpc++) {
1332 new_rsc_order(first_rsc, first_tasks[first_lpc], then_rsc, then_tasks[then_lpc],
1345 if (rsc_lh == NULL) {
1349 }
else if (rsc_rh == NULL) {
1355 if (new_con == NULL) {
1368 new_con->
rsc_lh = rsc_lh;
1369 new_con->
rsc_rh = rsc_rh;
1370 new_con->
score = score;
1375 if (node_attr == NULL) {
1379 pe_rsc_trace(rsc_lh,
"%s ==> %s (%s %d)", rsc_lh->
id, rsc_rh->
id, node_attr, score);
1381 rsc_lh->
rsc_cons = g_list_insert_sorted(rsc_lh->
rsc_cons, new_con, sort_cons_priority_rh);
1384 g_list_insert_sorted(rsc_rh->
rsc_cons_lhs, new_con, sort_cons_priority_lh);
1389 anti_colocation_order(rsc_lh, new_con->
role_lh, rsc_rh, new_con->
role_rh, data_set);
1390 anti_colocation_order(rsc_rh, new_con->
role_rh, rsc_lh, new_con->
role_lh, data_set);
1402 char *lh_key = NULL;
1403 char *rh_key = NULL;
1414 if (validate_order_resources(lh_rsc, lh_task, rh_rsc, rh_task)) {
1426 task_from_action_or_key(
action_t *action,
const char *key)
1431 res = strdup(action->
task);
1445 char *lh_task = NULL;
1446 char *rh_task = NULL;
1447 gboolean rh_migratable;
1448 gboolean lh_migratable;
1467 if (lh_migratable == FALSE && rh_migratable == FALSE) {
1477 if (lh_task == NULL || rh_task == NULL) {
1484 if (lh_migratable && rh_migratable) {
1492 if (rh_migratable) {
1493 if (lh_migratable) {
1507 if (lh_migratable) {
1529 if (rh_migratable) {
1540 if (rh_migratable) {
1570 if (lh_rsc == NULL && lh_action) {
1571 lh_rsc = lh_action->
rsc;
1573 if (rh_rsc == NULL && rh_action) {
1574 rh_rsc = rh_action->
rsc;
1577 if ((lh_action == NULL && lh_rsc == NULL)
1578 || (rh_action == NULL && rh_rsc == NULL)) {
1579 crm_config_err(
"Invalid inputs %p.%p %p.%p", lh_rsc, lh_action, rh_rsc, rh_action);
1580 free(lh_action_task);
1581 free(rh_action_task);
1588 lh_rsc?lh_rsc->
id:
"NA", lh_action_task, lh_action?lh_action->
uuid:
"NA",
1589 rh_rsc?rh_rsc->
id:
"NA", rh_action_task, rh_action?rh_action->
uuid:
"NA");
1610 if (order->
lh_rsc == NULL && lh_action) {
1614 if (order->
rh_rsc == NULL && rh_action) {
1619 handle_migration_ordering(order, data_set);
1639 const char *action_first,
const char *action_then, gboolean invert)
1644 crm_trace(
"Upgrade %s: implies left",
id);
1648 crm_trace(
"Upgrade %s: implies right",
id);
1668 xmlNode *xml_rsc = NULL;
1675 int local_kind = parent_kind;
1676 gboolean sequential = FALSE;
1678 gboolean symmetrical = TRUE;
1681 const char *
id =
ID(set);
1692 if (action == NULL) {
1697 local_kind = get_ordering_type(set);
1699 if (sequential_s == NULL) {
1705 symmetrical = order_is_symmetrical(set, parent_kind, parent_symmetrical_s);
1712 for (xml_rsc = __xml_first_child_element(set); xml_rsc != NULL;
1713 xml_rsc = __xml_next_element(xml_rsc)) {
1717 resources = g_list_append(resources, resource);
1721 if (g_list_length(resources) == 1) {
1747 set_iter = resources;
1748 while (set_iter != NULL) {
1750 set_iter = set_iter->next;
1767 for (gIter = set_iter; gIter != NULL; gIter = gIter->next) {
1775 }
else if (sequential) {
1784 if (symmetrical == FALSE) {
1789 action = invert_action(action);
1806 set_iter = resources;
1807 while (set_iter != NULL) {
1809 set_iter = set_iter->next;
1830 g_list_free(resources);
1835 order_rsc_sets(
const char *
id, xmlNode * set1, xmlNode * set2,
enum pe_order_kind kind,
1839 xmlNode *xml_rsc = NULL;
1840 xmlNode *xml_rsc_2 = NULL;
1852 gboolean require_all = require_all_s ?
crm_is_true(require_all_s) : TRUE;
1856 if (action_1 == NULL) {
1860 if (action_2 == NULL) {
1865 action_1 = invert_action(action_1);
1866 action_2 = invert_action(action_2);
1877 if (symmetrical == FALSE) {
1891 for (xml_rsc = __xml_first_child_element(set1); xml_rsc != NULL;
1892 xml_rsc = __xml_next_element(xml_rsc)) {
1903 NULL, NULL, unordered_action,
1906 for (xml_rsc_2 = __xml_first_child_element(set2); xml_rsc_2 != NULL;
1907 xml_rsc_2 = __xml_next_element(xml_rsc_2)) {
1926 if (invert == FALSE) {
1928 const char *rid = NULL;
1930 for (xml_rsc = __xml_first_child_element(set1); xml_rsc != NULL;
1931 xml_rsc = __xml_next_element(xml_rsc)) {
1941 for (xml_rsc = __xml_first_child_element(set1); xml_rsc != NULL;
1942 xml_rsc = __xml_next_element(xml_rsc)) {
1953 if (invert == FALSE) {
1955 for (xml_rsc = __xml_first_child_element(set2); xml_rsc != NULL;
1956 xml_rsc = __xml_next_element(xml_rsc)) {
1966 const char *rid = NULL;
1968 for (xml_rsc = __xml_first_child_element(set2); xml_rsc != NULL;
1969 xml_rsc = __xml_next_element(xml_rsc)) {
1979 if (rsc_1 != NULL && rsc_2 != NULL) {
1982 }
else if (rsc_1 != NULL) {
1983 for (xml_rsc = __xml_first_child_element(set2); xml_rsc != NULL;
1984 xml_rsc = __xml_next_element(xml_rsc)) {
1992 }
else if (rsc_2 != NULL) {
1993 xmlNode *xml_rsc = NULL;
1995 for (xml_rsc = __xml_first_child_element(set1); xml_rsc != NULL;
1996 xml_rsc = __xml_next_element(xml_rsc)) {
2005 for (xml_rsc = __xml_first_child_element(set1); xml_rsc != NULL;
2006 xml_rsc = __xml_next_element(xml_rsc)) {
2009 xmlNode *xml_rsc_2 = NULL;
2013 for (xml_rsc_2 = __xml_first_child_element(set2);
2015 xml_rsc_2 = __xml_next_element(xml_rsc_2)) {
2030 unpack_order_tags(xmlNode * xml_obj, xmlNode ** expanded_xml,
pe_working_set_t * data_set)
2032 const char *
id = NULL;
2033 const char *id_first = NULL;
2034 const char *id_then = NULL;
2035 const char *action_first = NULL;
2036 const char *action_then = NULL;
2040 tag_t *tag_first = NULL;
2041 tag_t *tag_then = NULL;
2043 xmlNode *new_xml = NULL;
2044 xmlNode *rsc_set_first = NULL;
2045 xmlNode *rsc_set_then = NULL;
2046 gboolean any_sets = FALSE;
2048 *expanded_xml = NULL;
2050 if (xml_obj == NULL) {
2057 crm_config_err(
"%s constraint must have an id", crm_element_name(xml_obj));
2062 expand_tags_in_sets(xml_obj, &new_xml, data_set);
2066 *expanded_xml = new_xml;
2072 if (id_first == NULL || id_then == NULL) {
2076 if (valid_resource_or_tag(data_set, id_first, &rsc_first, &tag_first) == FALSE) {
2077 crm_config_err(
"Constraint '%s': Invalid reference to '%s'",
id, id_first);
2081 if (valid_resource_or_tag(data_set, id_then, &rsc_then, &tag_then) == FALSE) {
2082 crm_config_err(
"Constraint '%s': Invalid reference to '%s'",
id, id_then);
2086 if (rsc_first && rsc_then) {
2102 if (rsc_set_first) {
2106 crm_xml_add(rsc_set_first,
"action", action_first);
2130 *expanded_xml = new_xml;
2141 gboolean any_sets = FALSE;
2155 xmlNode *set = NULL;
2156 xmlNode *last = NULL;
2158 xmlNode *orig_xml = NULL;
2159 xmlNode *expanded_xml = NULL;
2172 gboolean invert_bool = order_is_symmetrical(xml_obj, kind, NULL);
2175 rc = unpack_order_tags(xml_obj, &expanded_xml, data_set);
2178 xml_obj = expanded_xml;
2180 }
else if (rc == FALSE) {
2184 for (set = __xml_first_child_element(xml_obj); set != NULL;
2185 set = __xml_next_element(set)) {
2190 if (unpack_order_set(set, kind, &rsc, &set_begin, &set_end,
2191 &set_inv_begin, &set_inv_end, invert, data_set) == FALSE) {
2232 if (order_rsc_sets(
id, last, set, kind, data_set, FALSE, invert_bool) == FALSE) {
2237 && order_rsc_sets(
id, set, last, kind, data_set, TRUE, invert_bool) == FALSE) {
2258 if (any_sets == FALSE) {
2259 return unpack_simple_rsc_order(xml_obj, data_set);
2266 unpack_colocation_set(xmlNode * set,
int score,
pe_working_set_t * data_set)
2268 xmlNode *xml_rsc = NULL;
2271 const char *set_id =
ID(set);
2275 int local_score = score;
2283 if(ordering == NULL) {
2287 if (sequential != NULL &&
crm_is_true(sequential) == FALSE) {
2290 }
else if (local_score >= 0 &&
safe_str_eq(ordering,
"group")) {
2291 for (xml_rsc = __xml_first_child_element(set); xml_rsc != NULL;
2292 xml_rsc = __xml_next_element(xml_rsc)) {
2305 }
else if (local_score >= 0) {
2307 for (xml_rsc = __xml_first_child_element(set); xml_rsc != NULL;
2308 xml_rsc = __xml_next_element(xml_rsc)) {
2328 for (xml_rsc = __xml_first_child_element(set); xml_rsc != NULL;
2329 xml_rsc = __xml_next_element(xml_rsc)) {
2332 xmlNode *xml_rsc_with = NULL;
2336 for (xml_rsc_with = __xml_first_child_element(set);
2337 xml_rsc_with != NULL;
2338 xml_rsc_with = __xml_next_element(xml_rsc_with)) {
2345 pe_rsc_trace(resource,
"Anti-Colocating %s with %s", resource->
id,
2359 colocate_rsc_sets(
const char *
id, xmlNode * set1, xmlNode * set2,
int score,
2362 xmlNode *xml_rsc = NULL;
2372 if (sequential_1 == NULL ||
crm_is_true(sequential_1)) {
2374 for (xml_rsc = __xml_first_child_element(set1); xml_rsc != NULL;
2375 xml_rsc = __xml_next_element(xml_rsc)) {
2384 if (sequential_2 == NULL ||
crm_is_true(sequential_2)) {
2386 const char *rid = NULL;
2388 for (xml_rsc = __xml_first_child_element(set2); xml_rsc != NULL;
2389 xml_rsc = __xml_next_element(xml_rsc)) {
2398 if (rsc_1 != NULL && rsc_2 != NULL) {
2401 }
else if (rsc_1 != NULL) {
2402 for (xml_rsc = __xml_first_child_element(set2); xml_rsc != NULL;
2403 xml_rsc = __xml_next_element(xml_rsc)) {
2411 }
else if (rsc_2 != NULL) {
2412 for (xml_rsc = __xml_first_child_element(set1); xml_rsc != NULL;
2413 xml_rsc = __xml_next_element(xml_rsc)) {
2422 for (xml_rsc = __xml_first_child_element(set1); xml_rsc != NULL;
2423 xml_rsc = __xml_next_element(xml_rsc)) {
2426 xmlNode *xml_rsc_2 = NULL;
2430 for (xml_rsc_2 = __xml_first_child_element(set2);
2432 xml_rsc_2 = __xml_next_element(xml_rsc_2)) {
2468 if (rsc_lh == NULL) {
2469 crm_config_err(
"Invalid constraint '%s': No resource named '%s'",
id, id_lh);
2472 }
else if (rsc_rh == NULL) {
2473 crm_config_err(
"Invalid constraint '%s': No resource named '%s'",
id, id_rh);
2476 }
else if (instance_lh && pe_rsc_is_clone(rsc_lh) == FALSE) {
2478 (
"Invalid constraint '%s': Resource '%s' is not a clone but instance %s was requested",
2479 id, id_lh, instance_lh);
2482 }
else if (instance_rh && pe_rsc_is_clone(rsc_rh) == FALSE) {
2484 (
"Invalid constraint '%s': Resource '%s' is not a clone but instance %s was requested",
2485 id, id_rh, instance_rh);
2491 if (rsc_lh == NULL) {
2492 crm_config_warn(
"Invalid constraint '%s': No instance '%s' of '%s'",
id, instance_lh,
2500 if (rsc_rh == NULL) {
2501 crm_config_warn(
"Invalid constraint '%s': No instance '%s' of '%s'",
id, instance_rh,
2508 crm_config_warn(
"The %s colocation constraint attribute has been removed."
2521 unpack_colocation_tags(xmlNode * xml_obj, xmlNode ** expanded_xml,
pe_working_set_t * data_set)
2523 const char *
id = NULL;
2524 const char *id_lh = NULL;
2525 const char *id_rh = NULL;
2526 const char *state_lh = NULL;
2527 const char *state_rh = NULL;
2532 tag_t *tag_lh = NULL;
2533 tag_t *tag_rh = NULL;
2535 xmlNode *new_xml = NULL;
2536 xmlNode *rsc_set_lh = NULL;
2537 xmlNode *rsc_set_rh = NULL;
2538 gboolean any_sets = FALSE;
2540 *expanded_xml = NULL;
2542 if (xml_obj == NULL) {
2549 crm_config_err(
"%s constraint must have an id", crm_element_name(xml_obj));
2554 expand_tags_in_sets(xml_obj, &new_xml, data_set);
2558 *expanded_xml = new_xml;
2564 if (id_lh == NULL || id_rh == NULL) {
2568 if (valid_resource_or_tag(data_set, id_lh, &rsc_lh, &tag_lh) == FALSE) {
2569 crm_config_err(
"Constraint '%s': Invalid reference to '%s'",
id, id_lh);
2573 if (valid_resource_or_tag(data_set, id_rh, &rsc_rh, &tag_rh) == FALSE) {
2574 crm_config_err(
"Constraint '%s': Invalid reference to '%s'",
id, id_rh);
2578 if (rsc_lh && rsc_rh) {
2583 if (tag_lh && tag_rh) {
2585 crm_config_err(
"Either LHS or RHS of %s should be a normal resource instead of a template/tag",
2629 *expanded_xml = new_xml;
2641 xmlNode *set = NULL;
2642 xmlNode *last = NULL;
2643 gboolean any_sets = FALSE;
2645 xmlNode *orig_xml = NULL;
2646 xmlNode *expanded_xml = NULL;
2657 rc = unpack_colocation_tags(xml_obj, &expanded_xml, data_set);
2660 xml_obj = expanded_xml;
2662 }
else if (rc == FALSE) {
2666 for (set = __xml_first_child_element(xml_obj); set != NULL;
2667 set = __xml_next_element(set)) {
2672 if (unpack_colocation_set(set, score_i, data_set) == FALSE) {
2675 }
else if (last && colocate_rsc_sets(
id, last, set, score_i, data_set) == FALSE) {
2687 if (any_sets == FALSE) {
2688 return unpack_simple_colocation(xml_obj, data_set);
2696 const char *state_lh,
const char *loss_policy,
pe_working_set_t * data_set)
2700 if (rsc_lh == NULL) {
2706 if (new_rsc_ticket == NULL) {
2714 new_rsc_ticket->
id =
id;
2715 new_rsc_ticket->
ticket = ticket;
2716 new_rsc_ticket->
rsc_lh = rsc_lh;
2723 crm_config_err(
"Resetting %s loss-policy to 'stop': fencing is not configured",
2725 loss_policy =
"stop";
2730 crm_debug(
"On loss of ticket '%s': Fence the nodes running %s (%s)",
2735 crm_debug(
"On loss of ticket '%s': Freeze %s (%s)",
2741 crm_debug(
"On loss of ticket '%s': Demote %s (%s)",
2747 crm_debug(
"On loss of ticket '%s': Stop %s (%s)",
2754 crm_debug(
"On loss of ticket '%s': Default to demote %s (%s)",
2760 crm_debug(
"On loss of ticket '%s': Default to stop %s (%s)",
2782 unpack_rsc_ticket_set(xmlNode * set,
ticket_t * ticket,
const char *loss_policy,
2785 xmlNode *xml_rsc = NULL;
2787 const char *set_id = NULL;
2788 const char *role = NULL;
2791 CRM_CHECK(ticket != NULL,
return FALSE);
2794 if (set_id == NULL) {
2805 pe_rsc_trace(resource,
"Resource '%s' depends on ticket '%s'",
2806 resource->
id, ticket->
id);
2807 rsc_ticket_new(set_id, resource, ticket, role, loss_policy, data_set);
2830 if (xml_obj == NULL) {
2836 crm_config_err(
"%s constraint must have an id", crm_element_name(xml_obj));
2840 if (ticket_str == NULL) {
2841 crm_config_err(
"Invalid constraint '%s': No ticket specified",
id);
2844 ticket = g_hash_table_lookup(data_set->
tickets, ticket_str);
2847 if (ticket == NULL) {
2848 crm_config_err(
"Invalid constraint '%s': No ticket named '%s'",
id, ticket_str);
2852 if (id_lh == NULL) {
2853 crm_config_err(
"Invalid constraint '%s': No resource specified",
id);
2856 rsc_lh = pe_find_constraint_resource(data_set->
resources, id_lh);
2859 if (rsc_lh == NULL) {
2860 crm_config_err(
"Invalid constraint '%s': No resource named '%s'",
id, id_lh);
2863 }
else if (instance_lh && pe_rsc_is_clone(rsc_lh) == FALSE) {
2865 (
"Invalid constraint '%s': Resource '%s' is not a clone but instance %s was requested",
2866 id, id_lh, instance_lh);
2872 if (rsc_lh == NULL) {
2873 crm_config_warn(
"Invalid constraint '%s': No instance '%s' of '%s'",
id, instance_lh,
2879 rsc_ticket_new(
id, rsc_lh, ticket, state_lh, loss_policy, data_set);
2884 unpack_rsc_ticket_tags(xmlNode * xml_obj, xmlNode ** expanded_xml,
pe_working_set_t * data_set)
2886 const char *
id = NULL;
2887 const char *id_lh = NULL;
2888 const char *state_lh = NULL;
2891 tag_t *tag_lh = NULL;
2893 xmlNode *new_xml = NULL;
2894 xmlNode *rsc_set_lh = NULL;
2895 gboolean any_sets = FALSE;
2897 *expanded_xml = NULL;
2899 if (xml_obj == NULL) {
2906 crm_config_err(
"%s constraint must have an id", crm_element_name(xml_obj));
2911 expand_tags_in_sets(xml_obj, &new_xml, data_set);
2915 *expanded_xml = new_xml;
2920 if (id_lh == NULL) {
2924 if (valid_resource_or_tag(data_set, id_lh, &rsc_lh, &tag_lh) == FALSE) {
2925 crm_config_err(
"Constraint '%s': Invalid reference to '%s'",
id, id_lh);
2928 }
else if (rsc_lh) {
2955 *expanded_xml = new_xml;
2966 xmlNode *set = NULL;
2967 gboolean any_sets = FALSE;
2975 xmlNode *orig_xml = NULL;
2976 xmlNode *expanded_xml = NULL;
2980 if (xml_obj == NULL) {
2986 crm_config_err(
"%s constraint must have an id", crm_element_name(xml_obj));
2990 if (data_set->
tickets == NULL) {
2995 if (ticket_str == NULL) {
2996 crm_config_err(
"Invalid constraint '%s': No ticket specified",
id);
2999 ticket = g_hash_table_lookup(data_set->
tickets, ticket_str);
3002 if (ticket == NULL) {
3004 if (ticket == NULL) {
3009 rc = unpack_rsc_ticket_tags(xml_obj, &expanded_xml, data_set);
3012 xml_obj = expanded_xml;
3014 }
else if (rc == FALSE) {
3018 for (set = __xml_first_child_element(xml_obj); set != NULL;
3019 set = __xml_next_element(set)) {
3024 if (unpack_rsc_ticket_set(set, ticket, loss_policy, data_set) == FALSE) {
3035 if (any_sets == FALSE) {
3036 return unpack_simple_rsc_ticket(xml_obj, data_set);