27 #define INFINITY_HACK (PCMK_SCORE_INFINITY * -100) 50 if (pcmk__is_bundle_node(node) && pcmk__is_bundled(rsc)
54 }
else if (rsc != NULL) {
92 if (colocation1 == NULL) {
95 if (colocation2 == NULL) {
129 if (pcmk__is_clone(rsc1)) {
140 return strcmp(rsc1->
id, rsc2->
id);
164 cmp_dependent_priority(gconstpointer a, gconstpointer b)
166 return cmp_colocation_priority(a, b,
true);
190 cmp_primary_priority(gconstpointer a, gconstpointer b)
192 return cmp_colocation_priority(a, b,
false);
210 pcmk__assert((list != NULL) && (colocation != NULL) && (rsc != NULL));
213 "Adding colocation %s (%s with %s using %s @%s) to " 214 "'this with' list for %s",
218 *list = g_list_insert_sorted(*list, (gpointer) colocation,
219 cmp_primary_priority);
244 *list = g_list_copy(addition);
250 for (
const GList *iter = addition; iter != NULL; iter = iter->next) {
270 pcmk__assert((list != NULL) && (colocation != NULL) && (rsc != NULL));
273 "Adding colocation %s (%s with %s using %s @%s) to " 274 "'with this' list for %s",
278 *list = g_list_insert_sorted(*list, (gpointer) colocation,
279 cmp_dependent_priority);
304 *list = g_list_copy(addition);
310 for (
const GList *iter = addition; iter != NULL; iter = iter->next) {
328 const char *first_tasks[] = { NULL, NULL };
329 const char *then_tasks[] = { NULL, NULL };
355 for (
int first_lpc = 0;
356 (first_lpc <= 1) && (first_tasks[first_lpc] != NULL); first_lpc++) {
358 for (
int then_lpc = 0;
359 (then_lpc <= 1) && (then_tasks[then_lpc] != NULL); then_lpc++) {
362 then_rsc, then_tasks[then_lpc],
386 const char *dependent_role_spec,
387 const char *primary_role_spec, uint32_t
flags)
395 if ((dependent == NULL) || (primary == NULL)) {
397 "does not exist",
id);
410 "Ignoring colocation '%s' (%s with %s) because score is 0",
411 id, dependent->
id, primary->
id);
419 new_con->
score = score;
436 anti_colocation_order(dependent, new_con->
dependent_role, primary,
438 anti_colocation_order(primary, new_con->
primary_role, dependent,
457 const char *influence_s)
459 if (influence_s != NULL) {
477 unpack_colocation_set(xmlNode *
set,
int score,
const char *coloc_id,
480 xmlNode *xml_rsc = NULL;
483 const char *set_id = pcmk__xe_id(
set);
485 bool with_previous =
false;
486 int local_score = score;
487 bool sequential =
false;
489 const char *xml_rsc_id = NULL;
492 if (score_s != NULL) {
497 "because '%s' is not a valid score",
498 coloc_id, set_id, score_s);
502 if (local_score == 0) {
503 crm_trace(
"Ignoring colocation '%s' for set '%s' because score is 0",
515 with_previous =
true;
520 " (such as %s) is deprecated and will be removed in a" 531 if (local_score > 0) {
537 xml_rsc_id = pcmk__xe_id(xml_rsc);
541 if (resource == NULL) {
544 "No such resource", xml_rsc_id, set_id);
549 | unpack_influence(coloc_id, resource, influence_s);
552 resource->
id, other->
id, set_id);
554 other, role, role,
flags);
557 other->
id, resource->
id, set_id);
559 resource, role, role,
flags);
576 xmlNode *xml_rsc_with = NULL;
578 xml_rsc_id = pcmk__xe_id(xml_rsc);
582 if (resource == NULL) {
585 "No such resource", xml_rsc_id, set_id);
589 | unpack_influence(coloc_id, resource, influence_s);
592 xml_rsc_with != NULL;
596 xml_rsc_id = pcmk__xe_id(xml_rsc_with);
605 resource, other, role, role,
flags);
624 colocate_rsc_sets(
const char *
id,
const xmlNode *set1,
const xmlNode *set2,
625 int score,
const char *influence_s,
628 xmlNode *xml_rsc = NULL;
632 const char *xml_rsc_id = NULL;
637 bool sequential =
false;
641 crm_trace(
"Ignoring colocation '%s' between sets %s and %s " 642 "because score is 0",
643 id, pcmk__xe_id(set1), pcmk__xe_id(set2));
651 if (xml_rsc != NULL) {
652 xml_rsc_id = pcmk__xe_id(xml_rsc);
658 "because first resource %s not found",
659 pcmk__xe_id(set1), pcmk__xe_id(set2),
674 xml_rsc_id = pcmk__xe_id(xml_rsc);
681 "because last resource %s not found",
682 pcmk__xe_id(set1), pcmk__xe_id(set2), xml_rsc_id);
687 if ((rsc_1 != NULL) && (rsc_2 != NULL)) {
692 }
else if (rsc_1 != NULL) {
699 xml_rsc_id = pcmk__xe_id(xml_rsc);
705 "in set %s: No such resource",
706 pcmk__xe_id(set1), xml_rsc_id,
714 }
else if (rsc_2 != NULL) {
720 xml_rsc_id = pcmk__xe_id(xml_rsc);
726 "with set %s: No such resource",
727 pcmk__xe_id(set1), xml_rsc_id,
732 | unpack_influence(
id, rsc_1, influence_s);
743 xmlNode *xml_rsc_2 = NULL;
745 xml_rsc_id = pcmk__xe_id(xml_rsc);
751 "with set %s: No such resource",
752 pcmk__xe_id(set1), xml_rsc_id,
758 | unpack_influence(
id, rsc_1, influence_s);
764 xml_rsc_id = pcmk__xe_id(xml_rsc_2);
771 "%s with set %s resource %s: No such " 773 pcmk__xe_id(set1), pcmk__xe_id(xml_rsc),
774 pcmk__xe_id(set2), xml_rsc_id);
778 role_1, role_2,
flags);
795 unpack_simple_colocation(
const xmlNode *xml_obj,
const char *
id,
int score,
815 if (dependent == NULL) {
817 "does not exist",
id, dependent_id);
820 }
else if (primary == NULL) {
822 "does not exist",
id, primary_id);
834 dependent_role, primary_role,
flags);
839 unpack_colocation_tags(xmlNode *xml_obj, xmlNode **expanded_xml,
842 const char *
id = NULL;
843 const char *dependent_id = NULL;
844 const char *primary_id = NULL;
845 const char *dependent_role = NULL;
846 const char *primary_role = NULL;
854 xmlNode *dependent_set = NULL;
855 xmlNode *primary_set = NULL;
856 bool any_sets =
false;
858 *expanded_xml = NULL;
860 CRM_CHECK(xml_obj != NULL,
return EINVAL);
862 id = pcmk__xe_id(xml_obj);
871 if (*expanded_xml != NULL) {
878 if ((dependent_id == NULL) || (primary_id == NULL)) {
885 "valid resource or tag",
id, dependent_id);
892 "valid resource or tag",
id, primary_id);
896 if ((dependent != NULL) && (primary != NULL)) {
901 if ((dependent_tag != NULL) && (primary_tag != NULL)) {
904 "tags cannot be colocated",
id);
919 *expanded_xml = NULL;
923 if (dependent_set != NULL) {
924 if (dependent_role != NULL) {
940 *expanded_xml = NULL;
944 if (primary_set != NULL) {
945 if (primary_role != NULL) {
959 *expanded_xml = NULL;
977 xmlNode *last = NULL;
979 xmlNode *orig_xml = NULL;
980 xmlNode *expanded_xml = NULL;
983 const char *score = NULL;
984 const char *influence_s = NULL;
986 if (pcmk__str_empty(
id)) {
992 if (unpack_colocation_tags(xml_obj, &expanded_xml,
996 if (expanded_xml != NULL) {
998 xml_obj = expanded_xml;
1002 if (score != NULL) {
1007 "is not a valid score",
id, score);
1018 if (expanded_xml != NULL) {
1024 if (pcmk__str_empty(pcmk__xe_id(
set))) {
1029 unpack_colocation_set(
set, score_i,
id, influence_s,
scheduler);
1032 colocate_rsc_sets(
id, last,
set, score_i, influence_s,
scheduler);
1043 unpack_simple_colocation(xml_obj,
id, score_i, influence_s,
scheduler);
1108 for (iter = rsc->
priv->
actions; iter != NULL; iter = iter->next) {
1122 for (iter = rsc->
priv->
children; iter != NULL; iter = iter->next) {
1142 GList *colocations = NULL;
1144 bool is_start =
false;
1168 for (iter = rsc->
priv->
children; iter != NULL; iter = iter->next) {
1174 if ((child_action == NULL)
1176 crm_trace(
"Not blocking %s colocation dependents because " 1177 "at least %s has runnable %s",
1183 crm_trace(
"Blocking %s colocation dependents due to unrunnable %s %s",
1188 for (iter = colocations; iter != NULL; iter = iter->next) {
1214 g_list_free(colocations);
1241 if (child != NULL) {
1275 && (colocation != NULL));
1282 dependent_role_rsc = get_resource_for_role(dependent);
1284 primary_role_rsc = get_resource_for_role(primary);
1287 && (dependent_role_rsc->
priv->
parent != NULL)
1308 crm_trace(
"Skipping %scolocation '%s': dependent limited to %s role " 1310 "but %s next role is %s",
1311 ((colocation->
score < 0)?
"anti-" :
""),
1313 dependent_role_rsc->
id,
1320 crm_trace(
"Skipping %scolocation '%s': primary limited to %s role " 1321 "but %s next role is %s",
1322 ((colocation->
score < 0)?
"anti-" :
""),
1324 primary_role_rsc->
id,
1349 const char *value = NULL;
1350 GHashTable *work = NULL;
1351 GHashTableIter iter;
1358 }
else if (colocation->
score < 0) {
1365 g_hash_table_iter_init(&iter, work);
1366 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node)) {
1369 node->assign->score);
1371 "Applied %s to %s score on %s (now %s after " 1372 "subtracting %s because primary %s inactive)",
1373 colocation->
id, dependent->
id,
1374 pcmk__node_name(node),
1391 node->assign->score);
1393 "Applied %s to %s score on %s (now %s after " 1395 colocation->
id, dependent->
id,
1396 pcmk__node_name(node),
1411 "Banned %s from %s because colocation %s attribute %s " 1413 dependent->
id, pcmk__node_name(node),
1414 colocation->
id, attr);
1428 "%s: Rolling back scores from %s (no available nodes)",
1429 dependent->
id, primary->
id);
1433 g_hash_table_destroy(work);
1455 const char *dependent_value = NULL;
1456 const char *primary_value = NULL;
1458 int score_multiplier = 1;
1459 int priority_delta = 0;
1464 && (colocation != NULL));
1469 if (dependent_node == NULL) {
1473 if ((primary_node != NULL)
1501 score_multiplier = -1;
1512 score_multiplier = -1;
1515 priority_delta = score_multiplier * colocation->
score;
1519 "Applied %s to %s promotion priority (now %s after %s %d)",
1520 colocation->
id, dependent->
id,
1522 ((score_multiplier == 1)?
"adding" :
"subtracting"),
1525 return priority_delta;
1542 GHashTable *allowed_nodes_orig = NULL;
1543 GHashTableIter iter;
1546 const char *best_node = NULL;
1548 if ((colocation != NULL) && (rsc == colocation->
dependent)
1566 loc_iter != NULL; loc_iter = loc_iter->next) {
1578 while (g_hash_table_iter_next(&iter, NULL, (
void **) &node)) {
1580 if ((node->assign->score > best_score)
1585 best_score = node->assign->score;
1586 best_node = node->priv->name;
1591 if (best_node == NULL) {
1592 crm_info(
"No allowed node for %s matches node attribute %s=%s",
1593 rsc->
id, attr, value);
1595 crm_info(
"Allowed node %s for %s had best score (%d) " 1596 "of those matching node attribute %s=%s",
1597 best_node, rsc->
id, best_score, attr, value);
1601 if (allowed_nodes_orig != NULL) {
1619 GHashTableIter iter;
1621 int allowed_nodes = 0;
1624 while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &allowed_node)) {
1625 if ((allowed_node->assign->score >= 0) && (++allowed_nodes > 1)) {
1631 ((allowed_nodes == 1)?
"on a single node" :
"nowhere"));
1632 return (allowed_nodes == 1);
1654 add_node_scores_matching_attr(GHashTable *nodes,
1658 float factor,
bool only_positive)
1660 GHashTableIter iter;
1665 g_hash_table_iter_init(&iter, nodes);
1666 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node)) {
1673 score = best_node_score_matching_attr(colocation, source_rsc, attr, value);
1675 if ((factor < 0) && (score < 0)) {
1711 || !allowed_on_one(colocation->
dependent)) {
1713 "(double negative disallowed)",
1714 pcmk__node_name(node), node->assign->score, factor,
1721 crm_trace(
"%s: Filtering %d + %f * %d (node was marked unusable)",
1722 pcmk__node_name(node), node->assign->score, factor,
1727 delta_f = factor * score;
1730 delta = (int) ((delta_f < 0)? (delta_f - 0.5) : (delta_f + 0.5));
1736 if ((delta == 0) && (score != 0)) {
1739 }
else if (factor < 0.0) {
1746 if (only_positive && (new_score < 0) && (node->assign->score > 0)) {
1747 crm_trace(
"%s: Filtering %d + %f * %d = %d " 1748 "(negative disallowed, marking node unusable)",
1749 pcmk__node_name(node), node->assign->score, factor, score,
1755 if (only_positive && (new_score < 0) && (node->assign->score == 0)) {
1756 crm_trace(
"%s: Filtering %d + %f * %d = %d (negative disallowed)",
1757 pcmk__node_name(node), node->assign->score, factor, score,
1762 crm_trace(
"%s: %d + %f * %d = %d", pcmk__node_name(node),
1763 node->assign->score, factor, score, new_score);
1764 node->assign->score = new_score;
1804 float factor, uint32_t
flags)
1806 GHashTable *work = NULL;
1809 && ((colocation != NULL)
1810 || ((target_rsc == NULL) && (*nodes == NULL))));
1812 if (log_id == NULL) {
1813 log_id = source_rsc->
id;
1819 log_id, source_rsc->
id);
1824 if (*nodes == NULL) {
1826 target_rsc = source_rsc;
1830 pcmk__rsc_trace(source_rsc,
"%s: Merging %s scores from %s (at %.6f)",
1831 log_id, (pos?
"positive" :
"all"), source_rsc->
id, factor);
1833 add_node_scores_matching_attr(work, source_rsc, target_rsc, colocation,
1843 GList *colocations = NULL;
1848 "Checking additional %d optional '%s with' " 1850 g_list_length(colocations), source_rsc->
id);
1854 "Checking additional %d optional 'with %s' " 1856 g_list_length(colocations), source_rsc->
id);
1860 for (GList *iter = colocations; iter != NULL; iter = iter->next) {
1864 float other_factor = factor * constraint->
score 1876 "Optionally merging score of '%s' constraint " 1883 other_factor,
flags);
1887 g_list_free(colocations);
1890 pcmk__rsc_info(source_rsc,
"%s: Rolling back optional scores from %s",
1891 log_id, source_rsc->
id);
1892 g_hash_table_destroy(work);
1900 GHashTableIter iter;
1902 g_hash_table_iter_init(&iter, work);
1903 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node)) {
1905 node->assign->score = 1;
1910 if (*nodes != NULL) {
1911 g_hash_table_destroy(*nodes);
1938 if (pcmk__is_clone(primary)) {
1942 "%s: Incorporating attenuated %s assignment scores due " 1944 primary->
id, dependent->
id, colocation->
id);
1948 colocation, factor,
flags);
1972 const GList *primary_nodes,
bool merge_scores)
1974 GHashTableIter iter;
1978 && (colocation != NULL));
1981 while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &dependent_node)) {
1985 dependent_node->priv->id);
1986 if (primary_node == NULL) {
1989 "Banning %s from %s (no primary instance) for %s",
1990 dependent->
id, pcmk__node_name(dependent_node),
1993 }
else if (merge_scores) {
1994 dependent_node->assign->score =
1998 "Added %s's score %s to %s's score for %s (now %d) " 1999 "for colocation %s",
2002 dependent->
id, pcmk__node_name(dependent_node),
2003 dependent_node->assign->score, colocation->
id);
const pcmk_resource_t * pe__const_top_resource(const pcmk_resource_t *rsc, bool include_bundle)
bool pcmk__colocation_has_influence(const pcmk__colocation_t *colocation, const pcmk_resource_t *rsc)
#define CRM_CHECK(expr, failure_action)
xmlNode * pcmk__xe_resolve_idref(xmlNode *xml, xmlNode *search)
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)
xmlNode * pcmk__xml_copy(xmlNode *parent, xmlNode *src)
xmlNode * pcmk__xe_first_child(const xmlNode *parent, const char *node_name, const char *attr_n, const char *attr_v)
const char * pcmk_role_text(enum rsc_role_e role)
Get readable description of a resource role.
#define pcmk__if_tracing(if_action, else_action)
pcmk_resource_t * uber_parent(pcmk_resource_t *rsc)
const char * pcmk_readable_score(int score)
Return a displayable static string for a score value.
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...)
#define pcmk__rsc_trace(rsc, fmt, args...)
#define PCMK_META_CONTAINER_ATTRIBUTE_TARGET
#define PCMK_XE_RSC_COLOCATION
#define PCMK_XE_RESOURCE_REF
#define pcmk__rsc_info(rsc, fmt, args...)
#define PCMK_XA_WITH_RSC_ROLE
#define pcmk__set_rsc_flags(resource, flags_to_set)
#define pcmk__config_err(fmt...)
GList * location_constraints
pcmk__scheduler_private_t * priv
void pe_action_set_reason(pcmk_action_t *action, const char *reason, bool overwrite)
void(* with_this_colocations)(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList **list)
enum pcmk__coloc_affects pcmk__colocation_affects(const pcmk_resource_t *dependent, const pcmk_resource_t *primary, const pcmk__colocation_t *colocation, bool preview)
G_GNUC_INTERNAL void pcmk__update_action_for_orderings(pcmk_action_t *action, pcmk_scheduler_t *scheduler)
#define PCMK__XA_ORDERING
void pcmk__xe_remove_attr(xmlNode *element, const char *name)
bool pcmk__xe_attr_is_true(const xmlNode *node, const char *name)
void(* this_with_colocations)(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList **list)
void pcmk__add_this_with(GList **list, const pcmk__colocation_t *colocation, const pcmk_resource_t *rsc)
#define PCMK__VALUE_GROUP
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)
void pcmk__block_colocation_dependents(pcmk_action_t *action)
void pcmk__xml_free(xmlNode *xml)
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
int pcmk__xe_get_bool_attr(const xmlNode *node, const char *name, bool *value)
#define PCMK_ACTION_DEMOTE
pcmk_scheduler_t * scheduler
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)
#define pcmk__clear_action_flags(action, flags_to_clear)
pcmk_node_t * pe_find_node_id(const GList *node_list, const char *id)
Find a node by ID in a list of nodes.
GList * colocation_constraints
enum pcmk__rsc_variant variant
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
#define crm_trace(fmt, args...)
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)
pcmk_node_t * assigned_node
GList * with_this_colocations
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
void(* apply_location)(pcmk_resource_t *rsc, pcmk__location_t *location)
#define PCMK_ACTION_START
pcmk__resource_private_t * priv
int pcmk__apply_coloc_to_priority(pcmk_resource_t *dependent, const pcmk_resource_t *primary, const pcmk__colocation_t *colocation)
Wrappers for and extensions to libxml2.
enum rsc_role_e next_role
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_spec, const char *primary_role_spec, uint32_t 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 PCMK_XA_INFLUENCE
#define pcmk__clear_rsc_flags(resource, flags_to_clear)
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)
G_GNUC_INTERNAL int pcmk__parse_constraint_role(const char *id, const char *role_spec, enum rsc_role_e *role)
int pcmk__add_scores(int score1, int score2)
#define pcmk__warn_once(wo_flag, fmt...)
#define pcmk__order_resource_actions(first_rsc, first_task, then_rsc, then_task, flags)
GHashTable * allowed_nodes
xmlNode * pcmk__xe_next(const xmlNode *node, const char *element_name)
pcmk_resource_t * primary
#define pcmk__assert(expr)
#define PCMK_XA_NODE_ATTRIBUTE
Cluster status and scheduling.
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)
pcmk_scheduler_t * scheduler
G_GNUC_INTERNAL bool pcmk__valid_resource_or_tag(const pcmk_scheduler_t *scheduler, const char *id, pcmk_resource_t **rsc, pcmk__idref_t **tag)
GList * pcmk__this_with_colocations(const pcmk_resource_t *rsc)
#define PCMK_XE_RESOURCE_SET
const char * pcmk__node_attr(const pcmk_node_t *node, const char *name, const char *target, enum pcmk__rsc_node node_type)
GList * this_with_colocations
#define PCMK_ACTION_PROMOTE
int pcmk_parse_score(const char *score_s, int *score, int default_score)
Parse an integer score from a string.
pcmk_resource_t * dependent
#define pe__show_node_scores(level, rsc, text, nodes, scheduler)
const char * node_attribute
int crm_str_to_boolean(const char *s, int *ret)
#define PCMK_XA_SYMMETRICAL
#define crm_log_xml_trace(xml, text)
pcmk_resource_t * pe__bundled_resource(const pcmk_resource_t *rsc)
void pcmk__add_with_this_list(GList **list, GList *addition, const pcmk_resource_t *rsc)
Resource role is unknown.
void pcmk__add_dependent_scores(gpointer data, gpointer user_data)
Location constraint object.
#define pcmk__assert_alloc(nmemb, size)
#define PCMK_XA_SEQUENTIAL
G_GNUC_INTERNAL xmlNode * pcmk__expand_tags_in_sets(xmlNode *xml_obj, const pcmk_scheduler_t *scheduler)
#define crm_info(fmt, args...)
const char * pcmk__colocation_node_attr(const pcmk_node_t *node, const char *attr, const pcmk_resource_t *rsc)
const pcmk__assignment_methods_t * cmds
GList * pcmk__with_this_colocations(const pcmk_resource_t *rsc)
#define PCMK_SCORE_INFINITY
Integer score to use to represent "infinity".
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
struct pcmk__node_assignment * assign