100 const xmlNode *rsc_entry,
bool active_on_node)
102 bool changed =
false;
103 const char *attr_list[] = {
117 if (active_on_node) {
119 "because %s changed from '%s' to '%s'",
120 rsc->
id, pe__node_name(node), attr_list[i],
121 pcmk__s(old_value,
""), pcmk__s(value,
""));
125 if (changed && active_on_node) {
147 if ((strcmp(rsc->
id,
id) == 0)
151 for (GList *iter = rsc->
children; iter != NULL; iter = iter->next) {
190 set_allocation_methods_for_rsc(
pe_resource_t *rsc,
void *ignored)
193 g_list_foreach(rsc->
children, (GFunc) set_allocation_methods_for_rsc, NULL);
212 GList *colocated_rscs)
216 if (orig_rsc == NULL) {
220 if ((rsc == NULL) || (g_list_find(colocated_rscs, rsc) != NULL)) {
221 return colocated_rscs;
224 pe_rsc_trace(orig_rsc,
"%s is in colocation chain with %s",
225 rsc->
id, orig_rsc->
id);
226 colocated_rscs = g_list_append(colocated_rscs, rsc);
229 for (gIter = rsc->
rsc_cons; gIter != NULL; gIter = gIter->next) {
233 if (primary == orig_rsc) {
248 for (gIter = rsc->
rsc_cons_lhs; gIter != NULL; gIter = gIter->next) {
252 if (dependent == orig_rsc) {
256 if (pe_rsc_is_clone(rsc) && !pe_rsc_is_clone(dependent)) {
270 return colocated_rscs;
288 for (GList *iter = rsc->
children; iter != NULL; iter = iter->next) {
298 current = pe__current_node(rsc);
312 out->
message(out,
"rsc-action", rsc, current, next);
343 if (!force && (chosen != NULL)) {
349 crm_debug(
"All nodes for resource %s are unavailable, unclean or " 350 "shutting down (%s can%s run resources, with weight %d)",
351 rsc->
id, pe__node_name(chosen),
362 if (chosen == NULL) {
363 crm_debug(
"Could not allocate a node for %s", rsc->
id);
366 for (GList *iter = rsc->
actions; iter != NULL; iter = iter->next) {
380 const char *interval_ms_s = NULL;
381 const char *target_rc_s = NULL;
384 interval_ms_s = g_hash_table_lookup(op->
meta,
386 target_rc_s = g_hash_table_lookup(op->
meta,
388 if ((interval_ms_s != NULL)
399 crm_debug(
"Assigning %s to %s", rsc->
id, pe__node_name(chosen));
409 out->
message(out,
"resource-util", rsc, chosen, __func__);
437 bool changed =
false;
446 for (GList *iter = rsc->
children; iter != NULL; iter = iter->next) {
474 crm_info(
"Unassigning %s from %s", rsc->
id, pe__node_name(old));
503 int fail_count, remaining_tries;
520 if (fail_count <= 0) {
532 if (remaining_tries <= 0) {
533 crm_warn(
"%s cannot run on %s due to reaching migration threshold " 534 "(clean up resource to allow again)" 535 CRM_XS " failures=%d migration-threshold=%d",
536 rsc_to_ban->
id, pe__node_name(node), fail_count,
538 if (failed != NULL) {
539 *failed = rsc_to_ban;
544 crm_info(
"%s can fail %d more time%s on " 545 "%s before reaching migration threshold (%d)",
552 convert_const_pointer(
const void *ptr)
568 get_node_weight(
pe_node_t *node, GHashTable *nodes)
572 if ((node != NULL) && (nodes != NULL)) {
573 weighted_node = g_hash_table_lookup(nodes, node->
details->
id);
575 return (weighted_node == NULL)? -
INFINITY : weighted_node->
weight;
590 cmp_resources(gconstpointer a, gconstpointer b, gpointer
data)
594 GList *nodes = (GList *)
data;
601 GHashTable *r1_nodes = NULL;
602 GHashTable *r2_nodes = NULL;
603 const char *reason = NULL;
609 if (r1_weight > r2_weight) {
613 if (r1_weight < r2_weight) {
619 reason =
"no node list";
626 resource1->
id, &r1_nodes, NULL, 1,
629 resource2->
id, &r2_nodes, NULL, 1,
637 reason =
"current location";
639 r1_node = pe__current_node(resource1);
642 r2_node = pe__current_node(resource2);
644 r1_weight = get_node_weight(r1_node, r1_nodes);
645 r2_weight = get_node_weight(r2_node, r2_nodes);
646 if (r1_weight > r2_weight) {
650 if (r1_weight < r2_weight) {
657 for (GList *iter = nodes; iter != NULL; iter = iter->next) {
660 r1_weight = get_node_weight(node, r1_nodes);
661 r2_weight = get_node_weight(node, r2_nodes);
662 if (r1_weight > r2_weight) {
666 if (r1_weight < r2_weight) {
673 crm_trace(
"%s (%d)%s%s %c %s (%d)%s%s: %s",
674 resource1->
id, r1_weight,
675 ((r1_node == NULL)?
"" :
" on "),
676 ((r1_node == NULL)?
"" : r1_node->
details->
id),
677 ((rc < 0)?
'>' : ((rc > 0)?
'<' :
'=')),
678 resource2->
id, r2_weight,
679 ((r2_node == NULL)?
"" :
" on "),
680 ((r2_node == NULL)?
"" : r2_node->
details->
id),
682 if (r1_nodes != NULL) {
683 g_hash_table_destroy(r1_nodes);
685 if (r2_nodes != NULL) {
686 g_hash_table_destroy(r2_nodes);
704 cmp_resources, nodes);
724 g_hash_table_insert(table, (gpointer) node->
details->
id, node);
736 apply_parent_colocations(
const pe_resource_t *rsc, GHashTable **nodes)
741 for (iter = rsc->
parent->
rsc_cons; iter != NULL; iter = iter->next) {
750 if (!pcmk__colocation_has_influence(colocation, rsc)) {
782 pe_node_t *current_node1 = pe__current_node(instance1);
783 pe_node_t *current_node2 = pe__current_node(instance2);
784 GHashTable *colocated_scores1 = NULL;
785 GHashTable *colocated_scores2 = NULL;
788 && (instance2 != NULL) && (instance2->
parent != NULL)
789 && (current_node1 != NULL) && (current_node2 != NULL));
792 colocated_scores1 = new_node_table(current_node1);
793 colocated_scores2 = new_node_table(current_node2);
796 apply_parent_colocations(instance1, &colocated_scores1);
797 apply_parent_colocations(instance2, &colocated_scores2);
800 node1 = g_hash_table_lookup(colocated_scores1, current_node1->
details->
id);
801 node2 = g_hash_table_lookup(colocated_scores2, current_node2->
details->
id);
805 crm_trace(
"Assign %s (%d on %s) after %s (%d on %s)",
811 crm_trace(
"Assign %s (%d on %s) before %s (%d on %s)",
817 g_hash_table_destroy(colocated_scores1);
818 g_hash_table_destroy(colocated_scores2);
836 for (GList *iter = rsc->
children; iter != NULL; iter = iter->next) {
858 (*node)->details->id);
859 if ((allowed == NULL) || (allowed->
weight < 0)) {
860 pe_rsc_trace(rsc,
"%s: current location (%s) is unavailable",
861 rsc->
id, pe__node_name(*node));
888 CRM_ASSERT((instance1 != NULL) && (instance2 != NULL));
891 div1 = strrchr(instance1->
id,
':');
893 div1 = strrchr(instance1->
id,
'-');
895 div2 = strrchr(instance2->
id,
':');
897 div2 = strrchr(instance2->
id,
'-');
901 return (gint) (strtol(div1 + 1, NULL, 10) - strtol(div2 + 1, NULL, 10));
935 unsigned int nnodes1 = 0;
936 unsigned int nnodes2 = 0;
944 CRM_ASSERT((instance1 != NULL) && (instance2 != NULL));
952 if ((nnodes1 > 0) && (nnodes2 > 0)) {
953 if (nnodes1 < nnodes2) {
954 crm_trace(
"Assign %s (active on %d) before %s (active on %d): " 955 "less multiply active",
956 instance1->
id, nnodes1, instance2->
id, nnodes2);
959 }
else if (nnodes1 > nnodes2) {
960 crm_trace(
"Assign %s (active on %d) after %s (active on %d): " 961 "more multiply active",
962 instance1->
id, nnodes1, instance2->
id, nnodes2);
970 can1 = node_is_allowed(instance1, &
node1);
971 can2 = node_is_allowed(instance2, &
node2);
973 crm_trace(
"Assign %s before %s: not active on a disallowed node",
974 instance1->
id, instance2->
id);
977 }
else if (!can1 && can2) {
978 crm_trace(
"Assign %s after %s: active on a disallowed node",
979 instance1->
id, instance2->
id);
985 crm_trace(
"Assign %s before %s: priority (%d > %d)",
986 instance1->
id, instance2->
id,
991 crm_trace(
"Assign %s after %s: priority (%d < %d)",
992 instance1->
id, instance2->
id,
999 crm_trace(
"No assignment preference for %s vs. %s: inactive",
1000 instance1->
id, instance2->
id);
1003 }
else if (
node1 == NULL) {
1004 crm_trace(
"Assign %s after %s: active", instance1->
id, instance2->
id);
1007 }
else if (
node2 == NULL) {
1008 crm_trace(
"Assign %s before %s: active", instance1->
id, instance2->
id);
1015 if (can1 && !can2) {
1016 crm_trace(
"Assign %s before %s: current node can run resources",
1017 instance1->
id, instance2->
id);
1020 }
else if (!can1 && can2) {
1021 crm_trace(
"Assign %s after %s: current node can't run resources",
1022 instance1->
id, instance2->
id);
1030 crm_trace(
"No assignment preference for %s vs. %s: " 1031 "parent not allowed on either instance's current node",
1032 instance1->
id, instance2->
id);
1035 }
else if (
node1 == NULL) {
1036 crm_trace(
"Assign %s after %s: parent not allowed on current node",
1037 instance1->
id, instance2->
id);
1040 }
else if (
node2 == NULL) {
1041 crm_trace(
"Assign %s before %s: parent allowed on current node",
1042 instance1->
id, instance2->
id);
1048 crm_trace(
"Assign %s before %s: fewer active instances on current node",
1049 instance1->
id, instance2->
id);
1053 crm_trace(
"Assign %s after %s: more active instances on current node",
1054 instance1->
id, instance2->
id);
1059 can1 = did_fail(instance1);
1060 can2 = did_fail(instance2);
1061 if (!can1 && can2) {
1062 crm_trace(
"Assign %s before %s: failed", instance1->
id, instance2->
id);
1064 }
else if (can1 && !can2) {
1065 crm_trace(
"Assign %s after %s: not failed",
1066 instance1->
id, instance2->
id);
1071 rc = cmp_instance_by_colocation(instance1, instance2);
1079 crm_trace(
"Assign %s before %s: instance number",
1080 instance1->
id, instance2->
id);
1081 }
else if (rc > 0) {
1082 crm_trace(
"Assign %s after %s: instance number",
1083 instance1->
id, instance2->
id);
1085 crm_trace(
"No assignment preference for %s vs. %s",
1086 instance1->
id, instance2->
id);
void pcmk__set_allocation_methods(pe_working_set_t *data_set)
#define CRM_CHECK(expr, failure_action)
G_GNUC_INTERNAL void pcmk__primitive_add_graph_meta(pe_resource_t *rsc, xmlNode *xml)
G_GNUC_INTERNAL pe_node_t * pcmk__primitive_assign(pe_resource_t *rsc, const pe_node_t *prefer)
void clone_append_meta(pe_resource_t *rsc, xmlNode *xml)
#define crm_notice(fmt, args...)
G_GNUC_INTERNAL void pcmk__release_node_capacity(GHashTable *current_utilization, const pe_resource_t *rsc)
G_GNUC_INTERNAL void pcmk__add_rsc_actions_to_graph(pe_resource_t *rsc)
G_GNUC_INTERNAL uint32_t pcmk__update_ordered_actions(pe_action_t *first, pe_action_t *then, const pe_node_t *node, uint32_t flags, uint32_t filter, uint32_t type, pe_working_set_t *data_set)
G_GNUC_INTERNAL void pcmk__primitive_apply_coloc_score(pe_resource_t *dependent, const pe_resource_t *primary, const pcmk__colocation_t *colocation, bool for_dependent)
GList * pcmk__colocated_resources(pe_resource_t *rsc, pe_resource_t *orig_rsc, GList *colocated_rscs)
#define pe__show_node_weights(level, rsc, text, nodes, data_set)
pe_node_t * pe__find_active_on(const pe_resource_t *rsc, unsigned int *count_all, unsigned int *count_clean)
int(* message)(pcmk__output_t *out, const char *message_id,...)
void clone_create_actions(pe_resource_t *rsc)
bool clone_create_probe(pe_resource_t *rsc, pe_node_t *node)
resource_alloc_functions_t * cmds
gint pcmk__cmp_instance_number(gconstpointer a, gconstpointer b)
pe_node_t * pe__copy_node(const pe_node_t *this_node)
void clone_expand(pe_resource_t *rsc)
G_GNUC_INTERNAL enum pe_action_flags pcmk__group_action_flags(pe_action_t *action, const pe_node_t *node)
void pcmk__output_resource_actions(pe_resource_t *rsc)
pe_resource_t * dependent
pe_node_t * pcmk__clone_allocate(pe_resource_t *rsc, const pe_node_t *prefer)
G_GNUC_INTERNAL GList * pcmk__sort_nodes(GList *nodes, pe_node_t *active_node)
bool pcmk__rsc_agent_changed(pe_resource_t *rsc, pe_node_t *node, const xmlNode *rsc_entry, bool active_on_node)
G_GNUC_INTERNAL void pcmk__group_apply_coloc_score(pe_resource_t *dependent, const pe_resource_t *primary, const pcmk__colocation_t *colocation, bool for_dependent)
void pcmk__bundle_expand(pe_resource_t *rsc)
G_GNUC_INTERNAL uint32_t pcmk__group_update_ordered_actions(pe_action_t *first, pe_action_t *then, const pe_node_t *node, uint32_t flags, uint32_t filter, uint32_t type, pe_working_set_t *data_set)
bool pcmk__bundle_create_probe(pe_resource_t *rsc, pe_node_t *node)
void pcmk__bundle_internal_constraints(pe_resource_t *rsc)
G_GNUC_INTERNAL void pcmk__add_colocated_node_scores(pe_resource_t *rsc, const char *log_id, GHashTable **nodes, const char *attr, float factor, uint32_t flags)
gint pcmk__cmp_instance(gconstpointer a, gconstpointer b)
void pcmk__noop_add_graph_meta(pe_resource_t *rsc, xmlNode *xml)
#define pe__set_resource_flags(resource, flags_to_set)
void trigger_unfencing(pe_resource_t *rsc, pe_node_t *node, const char *reason, pe_action_t *dependency, pe_working_set_t *data_set)
#define pe_rsc_provisional
#define crm_warn(fmt, args...)
void pcmk__bundle_add_utilization(const pe_resource_t *rsc, const pe_resource_t *orig_rsc, GList *all_rscs, GHashTable *utilization)
#define crm_debug(fmt, args...)
G_GNUC_INTERNAL bool pcmk__node_available(const pe_node_t *node, bool consider_score, bool consider_guest)
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.
bool pe__is_guest_node(const pe_node_t *node)
void clone_internal_constraints(pe_resource_t *rsc)
#define pe_rsc_start_pending
#define pe__clear_action_flags(action, flags_to_clear)
#define crm_trace(fmt, args...)
G_GNUC_INTERNAL GList * pcmk__group_colocated_resources(pe_resource_t *rsc, pe_resource_t *orig_rsc, GList *colocated_rscs)
pe_node_t * pcmk__bundle_allocate(pe_resource_t *rsc, const pe_node_t *prefer)
GList *(* colocated_resources)(pe_resource_t *rsc, pe_resource_t *orig_rsc, GList *colocated_rscs)
G_GNUC_INTERNAL pe_node_t * pcmk__group_assign(pe_resource_t *rsc, const pe_node_t *prefer)
uint32_t pcmk__multi_update_actions(pe_action_t *first, pe_action_t *then, const pe_node_t *node, uint32_t flags, uint32_t filter, uint32_t type, pe_working_set_t *data_set)
void pcmk__bundle_shutdown_lock(pe_resource_t *rsc)
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
struct pe_node_shared_s * details
#define XML_AGENT_ATTR_PROVIDER
pe_working_set_t * data_set
void(* output_actions)(pe_resource_t *rsc)
bool pcmk__finalize_assignment(pe_resource_t *rsc, pe_node_t *chosen, bool force)
enum pe_action_flags clone_action_flags(pe_action_t *action, const pe_node_t *node)
G_GNUC_INTERNAL bool pcmk__probe_rsc_on_node(pe_resource_t *rsc, pe_node_t *node)
bool pcmk__threshold_reached(pe_resource_t *rsc, pe_node_t *node, pe_resource_t **failed)
enum pe_obj_types variant
G_GNUC_INTERNAL void pcmk__output_bundle_actions(pe_resource_t *rsc)
G_GNUC_INTERNAL void pcmk__primitive_internal_constraints(pe_resource_t *rsc)
G_GNUC_INTERNAL void pcmk__clone_apply_coloc_score(pe_resource_t *dependent, const pe_resource_t *primary, const pcmk__colocation_t *colocation, bool for_dependent)
G_GNUC_INTERNAL void pcmk__apply_location(pe_resource_t *rsc, pe__location_t *constraint)
G_GNUC_INTERNAL void pcmk__group_shutdown_lock(pe_resource_t *rsc)
void pcmk__bundle_create_actions(pe_resource_t *rsc)
GHashTable * pcmk__strkey_table(GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
pcmk__action_result_t result
#define pe_flag_show_utilization
void pcmk__bundle_rsc_location(pe_resource_t *rsc, pe__location_t *constraint)
void clone_rsc_location(pe_resource_t *rsc, pe__location_t *constraint)
G_GNUC_INTERNAL void pcmk__group_internal_constraints(pe_resource_t *rsc)
G_GNUC_INTERNAL void pcmk__group_create_actions(pe_resource_t *rsc)
G_GNUC_INTERNAL pe_node_t * pcmk__top_allowed_node(const pe_resource_t *rsc, const pe_node_t *node)
enum pe_action_flags pcmk__bundle_action_flags(pe_action_t *action, const pe_node_t *node)
G_GNUC_INTERNAL void pcmk__primitive_shutdown_lock(pe_resource_t *rsc)
void pe__set_next_role(pe_resource_t *rsc, enum rsc_role_e role, const char *why)
G_GNUC_INTERNAL void pcmk__consume_node_capacity(GHashTable *current_utilization, pe_resource_t *rsc)
This structure contains everything that makes up a single output formatter.
#define XML_LRM_ATTR_INTERVAL_MS
G_GNUC_INTERNAL void pcmk__primitive_add_utilization(const pe_resource_t *rsc, const pe_resource_t *orig_rsc, GList *all_rscs, GHashTable *utilization)
void pcmk__sort_resources(pe_working_set_t *data_set)
#define pe__clear_resource_flags(resource, flags_to_clear)
#define pcmk__plural_s(i)
G_GNUC_INTERNAL void pcmk__bundle_apply_coloc_score(pe_resource_t *dependent, const pe_resource_t *primary, const pcmk__colocation_t *colocation, bool for_dependent)
G_GNUC_INTERNAL void pcmk__group_add_utilization(const pe_resource_t *rsc, const pe_resource_t *orig_rsc, GList *all_rscs, GHashTable *utilization)
#define pe_rsc_failure_ignored
pe_working_set_t * cluster
const char * node_attribute
G_GNUC_INTERNAL void pcmk__group_apply_location(pe_resource_t *rsc, pe__location_t *location)
void pcmk__unassign_resource(pe_resource_t *rsc)
bool pcmk__assign_resource(pe_resource_t *rsc, pe_node_t *node, bool force)
void pcmk__clone_add_utilization(const pe_resource_t *rsc, const pe_resource_t *orig_rsc, GList *all_rscs, GHashTable *utilization)
#define pe_rsc_trace(rsc, fmt, args...)
G_GNUC_INTERNAL void pcmk__primitive_create_actions(pe_resource_t *rsc)
pe_action_t * custom_action(pe_resource_t *rsc, char *key, const char *task, const pe_node_t *on_node, gboolean optional, gboolean foo, pe_working_set_t *data_set)
Create or update an action object.
GList * pcmk__rscs_matching_id(const char *id, pe_working_set_t *data_set)
G_GNUC_INTERNAL enum pcmk__coloc_affects pcmk__colocation_affects(const pe_resource_t *dependent, const pe_resource_t *primary, const pcmk__colocation_t *colocation, bool preview)
#define crm_info(fmt, args...)
#define XML_ATTR_TE_TARGET_RC
int pe_get_failcount(pe_node_t *node, pe_resource_t *rsc, time_t *last_failure, uint32_t flags, xmlNode *xml_op, pe_working_set_t *data_set)
G_GNUC_INTERNAL enum pe_action_flags pcmk__primitive_action_flags(pe_action_t *action, const pe_node_t *node)
void pcmk__clone_shutdown_lock(pe_resource_t *rsc)
#define XML_AGENT_ATTR_CLASS
GHashTable * allowed_nodes