21 #define EXPAND_CONSTRAINT_IDREF(__set, __rsc, __name) do { \ 22 __rsc = pcmk__find_constraint_resource(data_set->resources, __name); \ 23 if (__rsc == NULL) { \ 24 pcmk__config_err("%s: No resource found for %s", __set, __name); \ 30 cmp_dependent_priority(gconstpointer a, gconstpointer b)
80 cmp_primary_priority(gconstpointer a, gconstpointer b)
132 anti_colocation_order(
pe_resource_t *first_rsc,
int first_role,
136 const char *first_tasks[] = { NULL, NULL };
137 const char *then_tasks[] = { NULL, NULL };
163 for (
int first_lpc = 0;
164 (first_lpc <= 1) && (first_tasks[first_lpc] != NULL); first_lpc++) {
166 for (
int then_lpc = 0;
167 (then_lpc <= 1) && (then_tasks[then_lpc] != NULL); then_lpc++) {
170 then_rsc, then_tasks[then_lpc],
193 const char *dependent_role,
const char *primary_role,
199 crm_trace(
"Ignoring colocation '%s' because score is 0",
id);
202 if ((dependent == NULL) || (primary == NULL)) {
204 "does not exist",
id);
209 if (new_con == NULL) {
226 new_con->
score = score;
232 if (node_attr == NULL) {
237 dependent->
id, primary->
id, node_attr, score);
240 cmp_primary_priority);
243 cmp_dependent_priority);
249 anti_colocation_order(dependent, new_con->
dependent_role, primary,
251 anti_colocation_order(primary, new_con->
primary_role, dependent,
268 unpack_influence(
const char *coloc_id,
const pe_resource_t *rsc,
269 const char *influence_s)
271 if (influence_s != NULL) {
279 return (influence_i != 0);
286 unpack_colocation_set(xmlNode *
set,
int score,
const char *coloc_id,
289 xmlNode *xml_rsc = NULL;
292 const char *set_id =
ID(
set);
296 int local_score = score;
303 if (local_score == 0) {
304 crm_trace(
"Ignoring colocation '%s' for set '%s' because score is 0",
309 if (ordering == NULL) {
313 if ((sequential != NULL) && !
crm_is_true(sequential)) {
316 }
else if ((local_score > 0)
326 unpack_influence(coloc_id, resource,
327 influence_s), data_set);
332 }
else if (local_score > 0) {
341 last->
id, resource->
id);
343 resource, role, role,
344 unpack_influence(coloc_id, last,
345 influence_s), data_set);
360 xmlNode *xml_rsc_with = NULL;
361 bool influence =
true;
364 influence = unpack_influence(coloc_id, resource, influence_s);
367 xml_rsc_with != NULL;
370 if (pcmk__str_eq(resource->
id,
ID(xml_rsc_with),
375 pe_rsc_trace(resource,
"Anti-Colocating %s with %s", resource->
id,
378 resource, with, role, role,
379 influence, data_set);
386 colocate_rsc_sets(
const char *
id, xmlNode *set1, xmlNode *set2,
int score,
389 xmlNode *xml_rsc = NULL;
400 crm_trace(
"Ignoring colocation '%s' between sets because score is 0",
404 if ((sequential_1 == NULL) ||
crm_is_true(sequential_1)) {
407 if (xml_rsc != NULL) {
412 if ((sequential_2 == NULL) ||
crm_is_true(sequential_2)) {
414 const char *rid = NULL;
424 if ((rsc_1 != NULL) && (rsc_2 != NULL)) {
426 unpack_influence(
id, rsc_1, influence_s),
429 }
else if (rsc_1 != NULL) {
430 bool influence = unpack_influence(
id, rsc_1, influence_s);
437 role_2, influence, data_set);
440 }
else if (rsc_2 != NULL) {
447 unpack_influence(
id, rsc_1, influence_s),
455 xmlNode *xml_rsc_2 = NULL;
456 bool influence =
true;
459 influence = unpack_influence(
id, rsc_1, influence_s);
467 role_1, role_2, influence,
475 unpack_simple_colocation(xmlNode *xml_obj,
const char *
id,
502 if (dependent == NULL) {
504 "does not exist",
id, dependent_id);
507 }
else if (primary == NULL) {
509 "does not exist",
id, primary_id);
512 }
else if ((dependent_instance != NULL) && !pe_rsc_is_clone(dependent)) {
514 "is not a clone but instance '%s' was requested",
515 id, dependent_id, dependent_instance);
518 }
else if ((primary_instance != NULL) && !pe_rsc_is_clone(primary)) {
520 "is not a clone but instance '%s' was requested",
521 id, primary_id, primary_instance);
525 if (dependent_instance != NULL) {
527 if (dependent == NULL) {
529 "does not have an instance '%s'",
530 id, dependent_id, dependent_instance);
535 if (primary_instance != NULL) {
537 if (primary == NULL) {
539 "does not have an instance '%s'",
540 "'%s'",
id, primary_id, primary_instance);
548 "' attribute has been removed");
556 dependent_role, primary_role,
557 unpack_influence(
id, dependent, influence_s), data_set);
562 unpack_colocation_tags(xmlNode *xml_obj, xmlNode **expanded_xml,
565 const char *
id = NULL;
566 const char *dependent_id = NULL;
567 const char *primary_id = NULL;
568 const char *dependent_role = NULL;
569 const char *primary_role = NULL;
577 xmlNode *dependent_set = NULL;
578 xmlNode *primary_set = NULL;
579 bool any_sets =
false;
581 *expanded_xml = NULL;
588 crm_element_name(xml_obj));
594 if (*expanded_xml != NULL) {
601 if ((dependent_id == NULL) || (primary_id == NULL)) {
608 "valid resource or tag",
id, dependent_id);
615 "valid resource or tag",
id, primary_id);
619 if ((dependent != NULL) && (primary != NULL)) {
624 if ((dependent_tag != NULL) && (primary_tag != NULL)) {
627 "tags cannot be colocated",
id);
640 *expanded_xml = NULL;
644 if (dependent_set != NULL) {
645 if (dependent_role != NULL) {
647 crm_xml_add(dependent_set,
"role", dependent_role);
657 *expanded_xml = NULL;
661 if (primary_set != NULL) {
662 if (primary_role != NULL) {
674 *expanded_xml = NULL;
692 xmlNode *last = NULL;
694 xmlNode *orig_xml = NULL;
695 xmlNode *expanded_xml = NULL;
706 if (unpack_colocation_tags(xml_obj, &expanded_xml,
712 xml_obj = expanded_xml;
720 if (expanded_xml != NULL) {
726 unpack_colocation_set(
set, score_i,
id, influence_s, data_set);
729 colocate_rsc_sets(
id, last,
set, score_i, influence_s, data_set);
740 unpack_simple_colocation(xml_obj,
id, influence_s, data_set);
750 for (GList *gIter = rsc->
actions; gIter != NULL; gIter = gIter->next) {
797 for (gIter = rsc->
children; gIter != NULL; gIter = gIter->next) {
806 for (gIter = rsc->
rsc_cons_lhs; gIter != NULL; gIter = gIter->next) {
843 && (dependent->
parent != NULL)
863 crm_trace(
"Skipping colocation '%s': %s will not run anywhere",
864 constraint->
id, dependent->
id);
869 if ((primary_node == NULL) ||
871 crm_err(
"%s must be colocated with %s but is not (%s vs. %s)",
872 dependent->
id, primary->
id,
874 (primary_node == NULL)?
"unallocated" : primary_node->
details->
uname);
880 if ((primary_node != NULL) &&
882 crm_err(
"%s and %s must be anti-colocated but are allocated " 883 "to the same node (%s)",
890 if ((constraint->
score > 0)
894 crm_trace(
"Skipping colocation '%s': dependent limited to %s role " 895 "but %s next role is %s",
901 if ((constraint->
score > 0)
905 crm_trace(
"Skipping colocation '%s': primary limited to %s role " 906 "but %s next role is %s",
912 if ((constraint->
score < 0)
915 crm_trace(
"Skipping anti-colocation '%s': dependent role %s matches",
920 if ((constraint->
score < 0)
923 crm_trace(
"Skipping anti-colocation '%s': primary role %s matches",
947 const char *value = NULL;
948 GHashTable *work = NULL;
959 }
else if (constraint->
score < 0) {
966 g_hash_table_iter_init(&iter, work);
967 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node)) {
969 pe_rsc_trace(dependent,
"%s: %s@%s -= %d (%s inactive)",
970 constraint->
id, dependent->
id, node->details->uname,
971 constraint->
score, primary->
id);
978 constraint->
id, dependent->
id,
979 node->details->uname, constraint->
score);
984 pe_rsc_trace(dependent,
"%s: %s@%s -= %d (%s mismatch)",
985 constraint->
id, dependent->
id, node->details->uname,
986 constraint->
score, attribute);
1000 "%s: Rolling back scores from %s (no available nodes)",
1001 dependent->
id, primary->
id);
1005 g_hash_table_destroy(work);
1024 const char *dependent_value = NULL;
1025 const char *primary_value = NULL;
1027 int score_multiplier = 1;
1054 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
#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)
#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)
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.
gboolean update_action(pe_action_t *action, pe_working_set_t *data_set)
#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
#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)
gboolean can_run_any(GHashTable *nodes)
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
GHashTable * pcmk__copy_node_table(GHashTable *nodes)
#define XML_COLOC_ATTR_NODE_ATTR
int crm_str_to_boolean(const char *s, int *ret)
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)
int pe__add_scores(int score1, int score2)
#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
#define RSC_ROLE_UNKNOWN_S
#define crm_log_xml_trace(xml, text)
gboolean crm_is_true(const char *s)
#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.