24 #define EXPAND_CONSTRAINT_IDREF(__set, __rsc, __name) do { \ 25 __rsc = pcmk__find_constraint_resource(data_set->resources, __name); \ 26 if (__rsc == NULL) { \ 27 pcmk__config_err("%s: No resource found for %s", __set, __name); \ 33 cmp_dependent_priority(gconstpointer a, gconstpointer b)
83 cmp_primary_priority(gconstpointer a, gconstpointer b)
135 anti_colocation_order(
pe_resource_t *first_rsc,
int first_role,
139 const char *first_tasks[] = { NULL, NULL };
140 const char *then_tasks[] = { NULL, NULL };
166 for (
int first_lpc = 0;
167 (first_lpc <= 1) && (first_tasks[first_lpc] != NULL); first_lpc++) {
169 for (
int then_lpc = 0;
170 (then_lpc <= 1) && (then_tasks[then_lpc] != NULL); then_lpc++) {
173 then_rsc, then_tasks[then_lpc],
196 const char *dependent_role,
const char *primary_role,
202 crm_trace(
"Ignoring colocation '%s' because score is 0",
id);
205 if ((dependent == NULL) || (primary == NULL)) {
207 "does not exist",
id);
212 if (new_con == NULL) {
229 new_con->
score = score;
235 if (node_attr == NULL) {
240 dependent->
id, primary->
id, node_attr, score);
243 cmp_primary_priority);
246 cmp_dependent_priority);
252 anti_colocation_order(dependent, new_con->
dependent_role, primary,
254 anti_colocation_order(primary, new_con->
primary_role, dependent,
271 unpack_influence(
const char *coloc_id,
const pe_resource_t *rsc,
272 const char *influence_s)
274 if (influence_s != NULL) {
282 return (influence_i != 0);
289 unpack_colocation_set(xmlNode *
set,
int score,
const char *coloc_id,
292 xmlNode *xml_rsc = NULL;
295 const char *set_id =
ID(
set);
298 int local_score = score;
299 bool sequential =
false;
306 if (local_score == 0) {
307 crm_trace(
"Ignoring colocation '%s' for set '%s' because score is 0",
312 if (ordering == NULL) {
319 }
else if ((local_score > 0)
329 unpack_influence(coloc_id, resource,
335 }
else if (local_score > 0) {
344 last->
id, resource->
id);
346 resource, role, role,
347 unpack_influence(coloc_id, last,
363 xmlNode *xml_rsc_with = NULL;
364 bool influence =
true;
367 influence = unpack_influence(coloc_id, resource, influence_s);
370 xml_rsc_with != NULL;
373 if (pcmk__str_eq(resource->
id,
ID(xml_rsc_with),
378 pe_rsc_trace(resource,
"Anti-Colocating %s with %s", resource->
id,
381 resource, with, role, role,
389 colocate_rsc_sets(
const char *
id, xmlNode *set1, xmlNode *set2,
int score,
392 xmlNode *xml_rsc = NULL;
400 bool sequential =
false;
403 crm_trace(
"Ignoring colocation '%s' between sets because score is 0",
412 if (xml_rsc != NULL) {
420 const char *rid = NULL;
430 if ((rsc_1 != NULL) && (rsc_2 != NULL)) {
432 unpack_influence(
id, rsc_1, influence_s),
435 }
else if (rsc_1 != NULL) {
436 bool influence = unpack_influence(
id, rsc_1, influence_s);
446 }
else if (rsc_2 != NULL) {
453 unpack_influence(
id, rsc_1, influence_s),
461 xmlNode *xml_rsc_2 = NULL;
462 bool influence =
true;
465 influence = unpack_influence(
id, rsc_1, influence_s);
473 role_1, role_2, influence,
481 unpack_simple_colocation(xmlNode *xml_obj,
const char *
id,
507 if (dependent == NULL) {
509 "does not exist",
id, dependent_id);
512 }
else if (primary == NULL) {
514 "does not exist",
id, primary_id);
517 }
else if ((dependent_instance != NULL) && !pe_rsc_is_clone(dependent)) {
519 "is not a clone but instance '%s' was requested",
520 id, dependent_id, dependent_instance);
523 }
else if ((primary_instance != NULL) && !pe_rsc_is_clone(primary)) {
525 "is not a clone but instance '%s' was requested",
526 id, primary_id, primary_instance);
530 if (dependent_instance != NULL) {
532 if (dependent == NULL) {
534 "does not have an instance '%s'",
535 id, dependent_id, dependent_instance);
540 if (primary_instance != NULL) {
542 if (primary == NULL) {
544 "does not have an instance '%s'",
545 "'%s'",
id, primary_id, primary_instance);
553 "' attribute has been removed");
561 dependent_role, primary_role,
562 unpack_influence(
id, dependent, influence_s),
data_set);
567 unpack_colocation_tags(xmlNode *xml_obj, xmlNode **expanded_xml,
570 const char *
id = NULL;
571 const char *dependent_id = NULL;
572 const char *primary_id = NULL;
573 const char *dependent_role = NULL;
574 const char *primary_role = NULL;
582 xmlNode *dependent_set = NULL;
583 xmlNode *primary_set = NULL;
584 bool any_sets =
false;
586 *expanded_xml = NULL;
593 crm_element_name(xml_obj));
599 if (*expanded_xml != NULL) {
606 if ((dependent_id == NULL) || (primary_id == NULL)) {
613 "valid resource or tag",
id, dependent_id);
620 "valid resource or tag",
id, primary_id);
624 if ((dependent != NULL) && (primary != NULL)) {
629 if ((dependent_tag != NULL) && (primary_tag != NULL)) {
632 "tags cannot be colocated",
id);
645 *expanded_xml = NULL;
649 if (dependent_set != NULL) {
650 if (dependent_role != NULL) {
652 crm_xml_add(dependent_set,
"role", dependent_role);
662 *expanded_xml = NULL;
666 if (primary_set != NULL) {
667 if (primary_role != NULL) {
679 *expanded_xml = NULL;
697 xmlNode *last = NULL;
699 xmlNode *orig_xml = NULL;
700 xmlNode *expanded_xml = NULL;
711 if (unpack_colocation_tags(xml_obj, &expanded_xml,
717 xml_obj = expanded_xml;
725 if (expanded_xml != NULL) {
731 unpack_colocation_set(
set, score_i,
id, influence_s,
data_set);
734 colocate_rsc_sets(
id, last,
set, score_i, influence_s,
data_set);
745 unpack_simple_colocation(xml_obj,
id, influence_s,
data_set);
755 for (GList *gIter = rsc->
actions; gIter != NULL; gIter = gIter->next) {
802 for (gIter = rsc->
children; gIter != NULL; gIter = gIter->next) {
811 for (gIter = rsc->
rsc_cons_lhs; gIter != NULL; gIter = gIter->next) {
848 && (dependent->
parent != NULL)
868 crm_trace(
"Skipping colocation '%s': %s will not run anywhere",
869 constraint->
id, dependent->
id);
874 if ((primary_node == NULL) ||
876 crm_err(
"%s must be colocated with %s but is not (%s vs. %s)",
877 dependent->
id, primary->
id,
879 (primary_node == NULL)?
"unallocated" : primary_node->
details->
uname);
885 if ((primary_node != NULL) &&
887 crm_err(
"%s and %s must be anti-colocated but are allocated " 888 "to the same node (%s)",
895 if ((constraint->
score > 0)
899 crm_trace(
"Skipping colocation '%s': dependent limited to %s role " 900 "but %s next role is %s",
906 if ((constraint->
score > 0)
910 crm_trace(
"Skipping colocation '%s': primary limited to %s role " 911 "but %s next role is %s",
917 if ((constraint->
score < 0)
920 crm_trace(
"Skipping anti-colocation '%s': dependent role %s matches",
925 if ((constraint->
score < 0)
928 crm_trace(
"Skipping anti-colocation '%s': primary role %s matches",
952 const char *value = NULL;
953 GHashTable *work = NULL;
964 }
else if (constraint->
score < 0) {
971 g_hash_table_iter_init(&iter, work);
972 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node)) {
974 pe_rsc_trace(dependent,
"%s: %s@%s -= %d (%s inactive)",
975 constraint->
id, dependent->
id, node->details->uname,
976 constraint->
score, primary->
id);
983 constraint->
id, dependent->
id,
984 node->details->uname, constraint->
score);
990 pe_rsc_trace(dependent,
"%s: %s@%s -= %d (%s mismatch)",
991 constraint->
id, dependent->
id, node->details->uname,
992 constraint->
score, attribute);
1006 "%s: Rolling back scores from %s (no available nodes)",
1007 dependent->
id, primary->
id);
1011 g_hash_table_destroy(work);
1030 const char *dependent_value = NULL;
1031 const char *primary_value = NULL;
1033 int score_multiplier = 1;
1060 score_multiplier = -1;
#define CRM_CHECK(expr, failure_action)
void pcmk__unpack_colocation(xmlNode *xml_obj, pe_working_set_t *data_set)
#define XML_COLOC_ATTR_TARGET_INSTANCE
G_GNUC_INTERNAL bool pcmk__any_node_available(GHashTable *nodes)
#define pcmk__config_warn(fmt...)
#define RSC_ROLE_STARTED_S
#define XML_RULE_ATTR_SCORE
xmlNode * first_named_child(const xmlNode *parent, const char *name)
enum rsc_role_e next_role
int char2score(const char *score)
Get the integer value of a score string.
#define pcmk__config_err(fmt...)
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
#define CRMD_ACTION_PROMOTE
pe_resource_t * dependent
#define XML_COLOC_ATTR_TARGET_ROLE
#define CRM_SCORE_INFINITY
#define XML_CONS_TAG_RSC_SET
void pcmk__block_colocated_starts(pe_action_t *action, pe_working_set_t *data_set)
#define CRMD_ACTION_START
G_GNUC_INTERNAL xmlNode * pcmk__expand_tags_in_sets(xmlNode *xml_obj, pe_working_set_t *data_set)
xmlNode * copy_xml(xmlNode *src_node)
#define pe_rsc_provisional
const char * role2text(enum rsc_role_e role)
#define CRMD_ACTION_DEMOTE
#define XML_COLOC_ATTR_TARGET
void pe_action_set_reason(pe_action_t *action, const char *reason, bool overwrite)
int pcmk__xe_get_bool_attr(xmlNodePtr node, const char *name, bool *value)
pe_resource_t * uber_parent(pe_resource_t *rsc)
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
#define pe__clear_action_flags(action, flags_to_clear)
#define crm_trace(fmt, args...)
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
struct pe_node_shared_s * details
xmlNode * expand_idref(xmlNode *input, xmlNode *top)
pe_resource_t * find_clone_instance(pe_resource_t *rsc, const char *sub_id, pe_working_set_t *data_set)
#define pe_rsc_promotable
pe_working_set_t * data_set
#define pcmk__order_resource_actions(lh_rsc, lh_task, rh_rsc, rh_task, flags, data_set)
void pcmk__new_colocation(const char *id, const char *node_attr, int score, pe_resource_t *dependent, pe_resource_t *primary, const char *dependent_role, const char *primary_role, bool influence, pe_working_set_t *data_set)
const char * pe_node_attribute_raw(pe_node_t *node, const char *name)
#define XML_COLOC_ATTR_SOURCE_INSTANCE
#define XML_TAG_RESOURCE_REF
void free_xml(xmlNode *child)
enum rsc_role_e text2role(const char *role)
enum pe_obj_types variant
G_GNUC_INTERNAL pe_resource_t * pcmk__find_constraint_resource(GList *rsc_list, const char *id)
enum pcmk__coloc_affects pcmk__colocation_affects(pe_resource_t *dependent, pe_resource_t *primary, pcmk__colocation_t *constraint, bool preview)
#define XML_COLOC_ATTR_SOURCE_ROLE
#define XML_COLOC_ATTR_NODE_ATTR
int crm_str_to_boolean(const char *s, int *ret)
G_GNUC_INTERNAL void pcmk__update_action_for_orderings(pe_action_t *action, pe_working_set_t *data_set)
Cluster status and scheduling.
#define XML_COLOC_ATTR_INFLUENCE
void pcmk__apply_coloc_to_priority(pe_resource_t *dependent, pe_resource_t *primary, pcmk__colocation_t *constraint)
G_GNUC_INTERNAL GHashTable * pcmk__copy_node_table(GHashTable *nodes)
#define crm_err(fmt, args...)
#define EXPAND_CONSTRAINT_IDREF(__set, __rsc, __name)
GList * colocation_constraints
void xml_remove_prop(xmlNode *obj, const char *name)
void pcmk__apply_coloc_to_weights(pe_resource_t *dependent, pe_resource_t *primary, pcmk__colocation_t *constraint)
const char * node_attribute
int pcmk__add_scores(int score1, int score2)
#define RSC_ROLE_UNKNOWN_S
#define crm_log_xml_trace(xml, text)
bool pcmk__xe_attr_is_true(xmlNodePtr node, const char *name)
#define pe_rsc_trace(rsc, fmt, args...)
#define XML_CONS_ATTR_SYMMETRICAL
pe_action_t * find_first_action(GList *input, const char *uuid, const char *task, pe_node_t *on_node)
#define XML_COLOC_ATTR_SOURCE
G_GNUC_INTERNAL bool pcmk__valid_resource_or_tag(pe_working_set_t *data_set, const char *id, pe_resource_t **rsc, pe_tag_t **tag)
#define pe_rsc_info(rsc, fmt, args...)
G_GNUC_INTERNAL bool pcmk__tag_to_set(xmlNode *xml_obj, xmlNode **rsc_set, const char *attr, bool convert_rsc, pe_working_set_t *data_set)
GHashTable * allowed_nodes
xmlNode * crm_next_same_xml(const xmlNode *sibling)
Get next instance of same XML tag.