26 #define INFINITY_HACK (INFINITY * -100) 58 if (colocation1 == NULL) {
61 if (colocation2 == NULL) {
130 cmp_dependent_priority(gconstpointer a, gconstpointer b)
132 return cmp_colocation_priority(a, b,
true);
156 cmp_primary_priority(gconstpointer a, gconstpointer b)
158 return cmp_colocation_priority(a, b,
false);
176 CRM_ASSERT((list != NULL) && (colocation != NULL) && (rsc != NULL));
179 "Adding colocation %s (%s with %s using %s @%s) to " 180 "'this with' list for %s",
184 *list = g_list_insert_sorted(*list, (gpointer) colocation,
185 cmp_primary_priority);
210 *list = g_list_copy(addition);
216 for (
const GList *iter = addition; iter != NULL; iter = iter->next) {
236 CRM_ASSERT((list != NULL) && (colocation != NULL) && (rsc != NULL));
239 "Adding colocation %s (%s with %s using %s @%s) to " 240 "'with this' list for %s",
244 *list = g_list_insert_sorted(*list, (gpointer) colocation,
245 cmp_dependent_priority);
270 *list = g_list_copy(addition);
276 for (
const GList *iter = addition; iter != NULL; iter = iter->next) {
294 const char *first_tasks[] = { NULL, NULL };
295 const char *then_tasks[] = { NULL, NULL };
321 for (
int first_lpc = 0;
322 (first_lpc <= 1) && (first_tasks[first_lpc] != NULL); first_lpc++) {
324 for (
int then_lpc = 0;
325 (then_lpc <= 1) && (then_tasks[then_lpc] != NULL); then_lpc++) {
328 then_rsc, then_tasks[then_lpc],
350 const char *dependent_role,
const char *primary_role,
357 if ((dependent == NULL) || (primary == NULL)) {
359 "does not exist",
id);
365 "Ignoring colocation '%s' (%s with %s) because score is 0",
366 id, dependent->
id, primary->
id);
386 new_con->
score = score;
399 anti_colocation_order(dependent, new_con->
dependent_role, primary,
401 anti_colocation_order(primary, new_con->
primary_role, dependent,
420 const char *influence_s)
422 if (influence_s != NULL) {
440 unpack_colocation_set(xmlNode *
set,
int score,
const char *coloc_id,
443 xmlNode *xml_rsc = NULL;
446 const char *set_id =
ID(
set);
448 bool with_previous =
false;
449 int local_score = score;
450 bool sequential =
false;
452 const char *xml_rsc_id = NULL;
458 if (local_score == 0) {
459 crm_trace(
"Ignoring colocation '%s' for set '%s' because score is 0",
469 with_previous =
true;
472 "Support for 'ordering' other than 'group' in " 474 "will be removed in a future release", set_id);
482 if (local_score > 0) {
486 xml_rsc_id =
ID(xml_rsc);
489 if (resource == NULL) {
492 "No such resource", xml_rsc_id, set_id);
497 | unpack_influence(coloc_id, resource, influence_s);
499 pe_rsc_trace(resource,
"Colocating %s with %s in set %s",
500 resource->
id, other->
id, set_id);
502 other, role, role,
flags);
504 pe_rsc_trace(resource,
"Colocating %s with %s in set %s",
505 other->
id, resource->
id, set_id);
507 resource, role, role,
flags);
522 xmlNode *xml_rsc_with = NULL;
524 xml_rsc_id =
ID(xml_rsc);
527 if (resource == NULL) {
530 "No such resource", xml_rsc_id, set_id);
534 | unpack_influence(coloc_id, resource, influence_s);
536 xml_rsc_with != NULL;
539 xml_rsc_id =
ID(xml_rsc_with);
547 resource, other, role, role,
flags);
565 colocate_rsc_sets(
const char *
id,
const xmlNode *set1,
const xmlNode *set2,
566 int score,
const char *influence_s,
569 xmlNode *xml_rsc = NULL;
573 const char *xml_rsc_id = NULL;
578 bool sequential =
false;
582 crm_trace(
"Ignoring colocation '%s' between sets %s and %s " 583 "because score is 0",
id,
ID(set1),
ID(set2));
591 if (xml_rsc != NULL) {
592 xml_rsc_id =
ID(xml_rsc);
598 "because first resource %s not found",
599 ID(set1),
ID(set2), xml_rsc_id);
611 xml_rsc_id =
ID(xml_rsc);
618 "because last resource %s not found",
619 ID(set1),
ID(set2), xml_rsc_id);
624 if ((rsc_1 != NULL) && (rsc_2 != NULL)) {
629 }
else if (rsc_1 != NULL) {
634 xml_rsc_id =
ID(xml_rsc);
640 "in set %s: No such resource",
641 ID(set1), xml_rsc_id,
ID(set2));
648 }
else if (rsc_2 != NULL) {
652 xml_rsc_id =
ID(xml_rsc);
658 "with set %s: No such resource",
659 ID(set1), xml_rsc_id,
ID(set2));
663 | unpack_influence(
id, rsc_1, influence_s);
672 xmlNode *xml_rsc_2 = NULL;
674 xml_rsc_id =
ID(xml_rsc);
680 "with set %s: No such resource",
681 ID(set1), xml_rsc_id,
ID(set2));
686 | unpack_influence(
id, rsc_1, influence_s);
691 xml_rsc_id =
ID(xml_rsc_2);
697 "%s with set %s resource %s: No such " 698 "resource",
ID(set1),
ID(xml_rsc),
699 ID(set2), xml_rsc_id);
703 role_1, role_2,
flags);
710 unpack_simple_colocation(xmlNode *xml_obj,
const char *
id,
726 const char *primary_instance = NULL;
727 const char *dependent_instance = NULL;
740 if (dependent_instance != NULL) {
743 "deprecated and will be removed in a future release.");
745 if (primary_instance != NULL) {
748 "deprecated and will be removed in a future release.");
751 if (dependent == NULL) {
753 "does not exist",
id, dependent_id);
756 }
else if (primary == NULL) {
758 "does not exist",
id, primary_id);
761 }
else if ((dependent_instance != NULL) && !pe_rsc_is_clone(dependent)) {
763 "is not a clone but instance '%s' was requested",
764 id, dependent_id, dependent_instance);
767 }
else if ((primary_instance != NULL) && !pe_rsc_is_clone(primary)) {
769 "is not a clone but instance '%s' was requested",
770 id, primary_id, primary_instance);
774 if (dependent_instance != NULL) {
776 if (dependent == NULL) {
778 "does not have an instance '%s'",
779 id, dependent_id, dependent_instance);
784 if (primary_instance != NULL) {
786 if (primary == NULL) {
788 "does not have an instance '%s'",
789 "'%s'",
id, primary_id, primary_instance);
797 "' attribute has been removed");
806 dependent_role, primary_role,
flags);
811 unpack_colocation_tags(xmlNode *xml_obj, xmlNode **expanded_xml,
814 const char *
id = NULL;
815 const char *dependent_id = NULL;
816 const char *primary_id = NULL;
817 const char *dependent_role = NULL;
818 const char *primary_role = NULL;
826 xmlNode *dependent_set = NULL;
827 xmlNode *primary_set = NULL;
828 bool any_sets =
false;
830 *expanded_xml = NULL;
832 CRM_CHECK(xml_obj != NULL,
return EINVAL);
843 if (*expanded_xml != NULL) {
850 if ((dependent_id == NULL) || (primary_id == NULL)) {
857 "valid resource or tag",
id, dependent_id);
864 "valid resource or tag",
id, primary_id);
868 if ((dependent != NULL) && (primary != NULL)) {
873 if ((dependent_tag != NULL) && (primary_tag != NULL)) {
876 "tags cannot be colocated",
id);
889 *expanded_xml = NULL;
893 if (dependent_set != NULL) {
894 if (dependent_role != NULL) {
896 crm_xml_add(dependent_set,
"role", dependent_role);
906 *expanded_xml = NULL;
910 if (primary_set != NULL) {
911 if (primary_role != NULL) {
923 *expanded_xml = NULL;
941 xmlNode *last = NULL;
943 xmlNode *orig_xml = NULL;
944 xmlNode *expanded_xml = NULL;
947 const char *score = NULL;
948 const char *influence_s = NULL;
950 if (pcmk__str_empty(
id)) {
956 if (unpack_colocation_tags(xml_obj, &expanded_xml,
960 if (expanded_xml != NULL) {
962 xml_obj = expanded_xml;
976 if (expanded_xml != NULL) {
982 if (pcmk__str_empty(
ID(
set))) {
987 unpack_colocation_set(
set, score_i,
id, influence_s,
scheduler);
990 colocate_rsc_sets(
id, last,
set, score_i, influence_s,
scheduler);
1001 unpack_simple_colocation(xml_obj,
id, influence_s,
scheduler);
1020 for (iter = rsc->
actions; iter != NULL; iter = iter->next) {
1034 for (iter = rsc->
children; iter != NULL; iter = iter->next) {
1054 GList *colocations = NULL;
1056 bool is_start =
false;
1075 if (rsc->
parent != NULL) {
1080 for (iter = rsc->
children; iter != NULL; iter = iter->next) {
1085 if ((child_action == NULL)
1087 crm_trace(
"Not blocking %s colocation dependents because " 1088 "at least %s has runnable %s",
1094 crm_trace(
"Blocking %s colocation dependents due to unrunnable %s %s",
1099 for (iter = colocations; iter != NULL; iter = iter->next) {
1125 g_list_free(colocations);
1152 if (child != NULL) {
1185 CRM_ASSERT((dependent != NULL) && (primary != NULL)
1186 && (colocation != NULL));
1193 dependent_role_rsc = get_resource_for_role(dependent);
1194 primary_role_rsc = get_resource_for_role(primary);
1197 && (dependent_role_rsc->
parent != NULL)
1217 crm_trace(
"Skipping colocation '%s': %s will not run anywhere",
1218 colocation->
id, dependent->
id);
1223 if (!pe__same_node(primary_node, dependent->
allocated_to)) {
1224 crm_err(
"%s must be colocated with %s but is not (%s vs. %s)",
1225 dependent->
id, primary->
id,
1227 pe__node_name(primary_node));
1233 if (pe__same_node(dependent->
allocated_to, primary_node)) {
1234 crm_err(
"%s and %s must be anti-colocated but are assigned " 1235 "to the same node (%s)",
1236 dependent->
id, primary->
id,
1237 pe__node_name(primary_node));
1245 crm_trace(
"Skipping %scolocation '%s': dependent limited to %s role " 1247 "but %s next role is %s",
1248 ((colocation->
score < 0)?
"anti-" :
""),
1250 dependent_role_rsc->
id,
1257 crm_trace(
"Skipping %scolocation '%s': primary limited to %s role " 1258 "but %s next role is %s",
1259 ((colocation->
score < 0)?
"anti-" :
""),
1285 const char *value = NULL;
1286 GHashTable *work = NULL;
1287 GHashTableIter iter;
1291 value = pcmk__colocation_node_attr(primary->
allocated_to, attr,
1294 }
else if (colocation->
score < 0) {
1301 g_hash_table_iter_init(&iter, work);
1302 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node)) {
1306 "Applied %s to %s score on %s (now %s after " 1307 "subtracting %s because primary %s inactive)",
1308 colocation->
id, dependent->
id, pe__node_name(node),
1314 if (pcmk__str_eq(pcmk__colocation_node_attr(node, attr, dependent),
1327 "Applied %s to %s score on %s (now %s after " 1329 colocation->
id, dependent->
id, pe__node_name(node),
1344 "Banned %s from %s because colocation %s attribute %s " 1346 dependent->
id, pe__node_name(node), colocation->
id,
1360 "%s: Rolling back scores from %s (no available nodes)",
1361 dependent->
id, primary->
id);
1365 g_hash_table_destroy(work);
1385 const char *dependent_value = NULL;
1386 const char *primary_value = NULL;
1388 int score_multiplier = 1;
1392 CRM_ASSERT((dependent != NULL) && (primary != NULL) &&
1393 (colocation != NULL));
1399 dependent_value = pcmk__colocation_node_attr(dependent->
allocated_to, attr,
1401 primary_value = pcmk__colocation_node_attr(primary->
allocated_to, attr,
1404 primary_role_rsc = get_resource_for_role(primary);
1420 score_multiplier = -1;
1426 "Applied %s to %s promotion priority (now %s after %s %s)",
1427 colocation->
id, dependent->
id,
1429 ((score_multiplier == 1)?
"adding" :
"subtracting"),
1442 best_node_score_matching_attr(
const pcmk_resource_t *rsc,
const char *attr,
1445 GHashTableIter iter;
1448 const char *best_node = NULL;
1452 while (g_hash_table_iter_next(&iter, NULL, (
void **) &node)) {
1454 if ((node->weight > best_score)
1456 && pcmk__str_eq(value, pcmk__colocation_node_attr(node, attr, rsc),
1459 best_score = node->weight;
1460 best_node = node->details->uname;
1465 if (best_node == NULL) {
1466 crm_info(
"No allowed node for %s matches node attribute %s=%s",
1467 rsc->
id, attr, value);
1469 crm_info(
"Allowed node %s for %s had best score (%d) " 1470 "of those matching node attribute %s=%s",
1471 best_node, rsc->
id, best_score, attr, value);
1488 GHashTableIter iter;
1490 int allowed_nodes = 0;
1493 while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &allowed_node)) {
1494 if ((allowed_node->weight >= 0) && (++allowed_nodes > 1)) {
1500 ((allowed_nodes == 1)?
"on a single node" :
"nowhere"));
1501 return (allowed_nodes == 1);
1523 add_node_scores_matching_attr(GHashTable *nodes,
1527 float factor,
bool only_positive)
1529 GHashTableIter iter;
1534 g_hash_table_iter_init(&iter, nodes);
1535 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node)) {
1540 const char *value = pcmk__colocation_node_attr(node, attr, target_rsc);
1542 score = best_node_score_matching_attr(source_rsc, attr, value);
1544 if ((factor < 0) && (score < 0)) {
1579 || !pcmk__colocation_has_influence(colocation, NULL)
1580 || !allowed_on_one(colocation->
dependent)) {
1582 "(double negative disallowed)",
1583 pe__node_name(node), node->weight, factor, score);
1589 crm_trace(
"%s: Filtering %d + %f * %d (node was marked unusable)",
1590 pe__node_name(node), node->weight, factor, score);
1594 delta_f = factor * score;
1597 delta = (int) ((delta_f < 0)? (delta_f - 0.5) : (delta_f + 0.5));
1603 if ((delta == 0) && (score != 0)) {
1606 }
else if (factor < 0.0) {
1613 if (only_positive && (new_score < 0) && (node->weight > 0)) {
1614 crm_trace(
"%s: Filtering %d + %f * %d = %d " 1615 "(negative disallowed, marking node unusable)",
1616 pe__node_name(node), node->weight, factor, score,
1622 if (only_positive && (new_score < 0) && (node->weight == 0)) {
1623 crm_trace(
"%s: Filtering %d + %f * %d = %d (negative disallowed)",
1624 pe__node_name(node), node->weight, factor, score,
1629 crm_trace(
"%s: %d + %f * %d = %d", pe__node_name(node),
1630 node->weight, factor, score, new_score);
1631 node->weight = new_score;
1671 float factor, uint32_t
flags)
1673 GHashTable *work = NULL;
1675 CRM_ASSERT((source_rsc != NULL) && (nodes != NULL)
1676 && ((colocation != NULL)
1677 || ((target_rsc == NULL) && (*nodes == NULL))));
1679 if (log_id == NULL) {
1680 log_id = source_rsc->
id;
1685 pe_rsc_info(source_rsc,
"%s: Breaking dependency loop at %s",
1686 log_id, source_rsc->
id);
1691 if (*nodes == NULL) {
1693 target_rsc = source_rsc;
1697 pe_rsc_trace(source_rsc,
"%s: Merging %s scores from %s (at %.6f)",
1698 log_id, (pos?
"positive" :
"all"), source_rsc->
id, factor);
1700 add_node_scores_matching_attr(work, source_rsc, target_rsc, colocation,
1710 GList *colocations = NULL;
1715 "Checking additional %d optional '%s with' " 1717 g_list_length(colocations), source_rsc->
id);
1721 "Checking additional %d optional 'with %s' " 1723 g_list_length(colocations), source_rsc->
id);
1727 for (GList *iter = colocations; iter != NULL; iter = iter->next) {
1731 float other_factor = factor * constraint->
score / (float)
INFINITY;
1735 }
else if (!pcmk__colocation_has_influence(constraint, NULL)) {
1742 "Optionally merging score of '%s' constraint " 1748 other_factor,
flags);
1751 g_list_free(colocations);
1754 pe_rsc_info(source_rsc,
"%s: Rolling back optional scores from %s",
1755 log_id, source_rsc->
id);
1756 g_hash_table_destroy(work);
1764 GHashTableIter iter;
1766 g_hash_table_iter_init(&iter, work);
1767 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node)) {
1774 if (*nodes != NULL) {
1775 g_hash_table_destroy(*nodes);
1799 if (!pcmk__colocation_has_influence(colocation, NULL)) {
1806 "%s: Incorporating attenuated %s assignment scores due " 1808 target_rsc->
id, source_rsc->
id, colocation->
id);
1812 colocation, factor,
flags);
1836 const GList *primary_nodes,
bool merge_scores)
1838 GHashTableIter iter;
1841 CRM_ASSERT((dependent != NULL) && (primary != NULL)
1842 && (colocation != NULL));
1845 while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &dependent_node)) {
1849 dependent_node->details->id);
1850 if (primary_node == NULL) {
1851 dependent_node->weight = -
INFINITY;
1853 "Banning %s from %s (no primary instance) for %s",
1854 dependent->
id, pe__node_name(dependent_node),
1857 }
else if (merge_scores) {
1861 "Added %s's score %s to %s's score for %s (now %s) " 1862 "for colocation %s",
1864 dependent->
id, pe__node_name(dependent_node),
pcmk_assignment_methods_t * cmds
Resource assignment methods.
#define CRM_CHECK(expr, failure_action)
void pcmk__add_colocated_node_scores(pcmk_resource_t *source_rsc, const pcmk_resource_t *target_rsc, const char *log_id, GHashTable **nodes, const pcmk__colocation_t *colocation, float factor, uint32_t flags)
void pcmk__add_with_this(GList **list, const pcmk__colocation_t *colocation, const pcmk_resource_t *rsc)
void pcmk__apply_coloc_to_priority(pcmk_resource_t *dependent, const pcmk_resource_t *primary, const pcmk__colocation_t *colocation)
pcmk_scheduler_t * cluster
Cluster that resource is part of.
#define pcmk__if_tracing(if_action, else_action)
const char * pcmk_readable_score(int score)
Return a displayable static string for a score value.
#define PCMK__ROLE_STARTED
pcmk_resource_t * uber_parent(pcmk_resource_t *rsc)
Whether resource is an implicit container resource for a bundle replica.
#define XML_COLOC_ATTR_TARGET_INSTANCE
G_GNUC_INTERNAL bool pcmk__tag_to_set(xmlNode *xml_obj, xmlNode **rsc_set, const char *attr, bool convert_rsc, const pcmk_scheduler_t *scheduler)
G_GNUC_INTERNAL bool pcmk__any_node_available(GHashTable *nodes)
#define pcmk__config_warn(fmt...)
GList * children
Resource's child resources, if any.
#define XML_RULE_ATTR_SCORE
xmlNode * first_named_child(const xmlNode *parent, const char *name)
enum rsc_role_e next_role
Resource's scheduled next role.
Implementation of pcmk_action_t.
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.
void pe_action_set_reason(pcmk_action_t *action, const char *reason, bool overwrite)
void(* add_colocated_node_scores)(pcmk_resource_t *source_rsc, const pcmk_resource_t *target_rsc, const char *log_id, GHashTable **nodes, const pcmk__colocation_t *colocation, float factor, uint32_t flags)
#define XML_CONS_TAG_RSC_DEPEND
enum pcmk__coloc_affects pcmk__colocation_affects(const pcmk_resource_t *dependent, const pcmk_resource_t *primary, const pcmk__colocation_t *colocation, bool preview)
bool pcmk__xe_attr_is_true(const xmlNode *node, const char *name)
G_GNUC_INTERNAL void pcmk__update_action_for_orderings(pcmk_action_t *action, pcmk_scheduler_t *scheduler)
#define XML_COLOC_ATTR_TARGET_ROLE
void pcmk__add_this_with(GList **list, const pcmk__colocation_t *colocation, const pcmk_resource_t *rsc)
Implementation of pcmk_scheduler_t.
#define CRM_SCORE_INFINITY
#define XML_CONS_TAG_RSC_SET
void pcmk__unpack_colocation(xmlNode *xml_obj, pcmk_scheduler_t *scheduler)
G_GNUC_INTERNAL bool pcmk__node_available(const pcmk_node_t *node, bool consider_score, bool consider_guest)
void pcmk__apply_coloc_to_scores(pcmk_resource_t *dependent, const pcmk_resource_t *primary, const pcmk__colocation_t *colocation)
#define pe__set_resource_flags(resource, flags_to_set)
GList * resources
Resources in cluster.
void pcmk__block_colocation_dependents(pcmk_action_t *action)
void(* with_this_colocations)(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList **list)
xmlNode * copy_xml(xmlNode *src_node)
const char * role2text(enum rsc_role_e role)
#define PCMK_ACTION_DEMOTE
int weight
Node score for a given resource.
pcmk_resource_t * parent
Resource's parent resource, if any.
#define XML_COLOC_ATTR_TARGET
Implementation of pcmk_resource_t.
G_GNUC_INTERNAL pcmk_resource_t * pcmk__find_constraint_resource(GList *rsc_list, const char *id)
const pcmk_resource_t * pe__get_rsc_in_container(const pcmk_resource_t *instance)
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
pcmk_node_t * pe_find_node_id(const GList *node_list, const char *id)
Find a node by ID in a list of nodes.
int priority
Configured priority.
#define pe_warn_once(pe_wo_bit, fmt...)
void(* this_with_colocations)(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList **list)
#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.
xmlNode * expand_idref(xmlNode *input, xmlNode *top)
#define PCMK_ACTION_START
int pcmk__xe_get_bool_attr(const xmlNode *node, const char *name, bool *value)
unsigned long long flags
Group of enum pcmk_rsc_flags.
void pcmk__add_this_with_list(GList **list, GList *addition, const pcmk_resource_t *rsc)
Ordering applies only if 'first' is required and on same node as 'then'.
#define XML_COLOC_ATTR_SOURCE_INSTANCE
void pcmk__colocation_intersect_nodes(pcmk_resource_t *dependent, const pcmk_resource_t *primary, const pcmk__colocation_t *colocation, const GList *primary_nodes, bool merge_scores)
#define XML_TAG_RESOURCE_REF
G_GNUC_INTERNAL bool pcmk__valid_resource_or_tag(const pcmk_scheduler_t *scheduler, const char *id, pcmk_resource_t **rsc, pcmk_tag_t **tag)
void free_xml(xmlNode *child)
Implementation of pcmk_node_t.
enum rsc_role_e text2role(const char *role)
enum pe_obj_types variant
Resource variant.
#define pcmk__order_resource_actions(first_rsc, first_task, then_rsc, then_task, flags)
#define XML_COLOC_ATTR_SOURCE_ROLE
pcmk_resource_t * primary
Whether resource has "critical" meta-attribute enabled.
Whether resource has not yet been assigned to a node.
#define XML_COLOC_ATTR_NODE_ATTR
int crm_str_to_boolean(const char *s, int *ret)
Cluster status and scheduling.
Whether resource is in the process of modifying allowed node scores.
#define XML_COLOC_ATTR_INFLUENCE
#define PCMK__ROLE_UNKNOWN
Whether action is runnable.
G_GNUC_INTERNAL GHashTable * pcmk__copy_node_table(GHashTable *nodes)
pcmk_action_t * find_first_action(const GList *input, const char *uuid, const char *task, const pcmk_node_t *on_node)
#define crm_err(fmt, args...)
pcmk_scheduler_t * scheduler
GList * pcmk__this_with_colocations(const pcmk_resource_t *rsc)
GList * colocation_constraints
Colocation constraints.
void xml_remove_prop(xmlNode *obj, const char *name)
void pcmk__new_colocation(const char *id, const char *node_attr, int score, pcmk_resource_t *dependent, pcmk_resource_t *primary, const char *dependent_role, const char *primary_role, uint32_t flags)
Configuration tag object.
pcmk_node_t * allocated_to
Node resource is assigned to.
#define pe__clear_resource_flags(resource, flags_to_clear)
#define PCMK_ACTION_PROMOTE
pcmk_resource_t * dependent
#define pe__show_node_scores(level, rsc, text, nodes, scheduler)
enum pe_action_flags flags
Group of enum pe_action_flags.
const char * node_attribute
int pcmk__add_scores(int score1, int score2)
#define crm_log_xml_trace(xml, text)
void pcmk__add_with_this_list(GList **list, GList *addition, const pcmk_resource_t *rsc)
Whether resource can be promoted and demoted.
Resource role is unknown.
void pcmk__add_dependent_scores(gpointer data, gpointer user_data)
#define pe_rsc_trace(rsc, fmt, args...)
int stickiness
Extra preference for current node.
pcmk_resource_t * find_clone_instance(const pcmk_resource_t *rsc, const char *sub_id)
#define XML_CONS_ATTR_SYMMETRICAL
G_GNUC_INTERNAL xmlNode * pcmk__expand_tags_in_sets(xmlNode *xml_obj, const pcmk_scheduler_t *scheduler)
#define crm_info(fmt, args...)
#define XML_COLOC_ATTR_SOURCE
GList * pcmk__with_this_colocations(const pcmk_resource_t *rsc)
#define pe_rsc_info(rsc, fmt, args...)
char * id
Resource ID in configuration.
GHashTable * allowed_nodes
Nodes where resource may run (key is node ID, not name)
xmlNode * crm_next_same_xml(const xmlNode *sibling)
Get next instance of same XML tag.