84 const GList *iter = NULL;
88 for (iter = rsc->
children; iter != NULL; iter = iter->next) {
95 for (iter = rsc->
actions; iter != NULL; iter = iter->next) {
98 if (*promoting && *demoting) {
129 const GList *location_constraints,
132 for (
const GList *iter = location_constraints; iter; iter = iter->next) {
140 if (constraint_node != NULL) {
145 "Applying location %s to %s promotion priority on %s: " 147 location->
id, child->
id,
148 pe__node_name(constraint_node),
173 for (GList *iter = rsc->
children; iter != NULL; iter = iter->next) {
176 if (node_to_be_promoted_on(child) == NULL) {
178 "%s can't be promoted because member %s can't",
186 pe_rsc_trace(rsc,
"%s can't be promoted because it won't be active",
192 crm_notice(
"Unmanaged instance %s will be left promoted on %s",
193 rsc->
id, pe__node_name(node));
195 pe_rsc_trace(rsc,
"%s can't be promoted because it is unmanaged",
202 "%s can't be promoted because its promotion priority %d " 208 pe_rsc_trace(rsc,
"%s can't be promoted because %s can't run resources",
209 rsc->
id, pe__node_name(node));
214 local_node = g_hash_table_lookup(
parent->allowed_nodes, node->
details->
id);
216 if (local_node == NULL) {
222 crm_warn(
"%s can't be promoted because %s is not allowed on %s " 224 rsc->
id,
parent->id, pe__node_name(node));
231 "%s can't be promoted because %s has " 232 "maximum promoted instances already",
233 rsc->
id, pe__node_name(node));
252 cmp_promotable_instance(gconstpointer a, gconstpointer b)
265 "%s has higher promotion priority than %s " 266 "(sort index %d > %d)",
271 "%s has lower promotion priority than %s " 272 "(sort index %d < %d)",
282 "%s has higher promotion priority than %s " 283 "(higher current role)",
286 }
else if (role1 < role2) {
288 "%s has lower promotion priority than %s " 289 "(lower current role)",
310 add_sort_index_to_node_score(gpointer
data, gpointer user_data)
319 pe_rsc_trace(clone,
"Not adding sort index of %s: negative", child->
id);
324 if (chosen == NULL) {
325 pe_rsc_trace(clone,
"Not adding sort index of %s: inactive", child->
id);
334 "Added cumulative priority of %s (%s) to score on %s (now %s)",
347 apply_coloc_to_dependent(gpointer
data, gpointer user_data)
361 pe_rsc_trace(clone,
"Applying colocation %s (promoted %s with %s) @%s",
378 apply_coloc_to_primary(gpointer
data, gpointer user_data)
388 || !pcmk__colocation_has_influence(colocation, NULL)) {
392 pe_rsc_trace(clone,
"Applying colocation %s (%s with promoted %s) @%s",
398 colocation, factor,
flags);
409 set_sort_index_to_node_score(gpointer
data, gpointer user_data)
420 "Final sort index for %s is INFINITY (unmanaged promoted)",
423 }
else if ((chosen == NULL) || (child->
sort_index < 0)) {
425 "Final sort index for %s is %d (ignoring node score)",
435 "Adding scores for %s: final sort index for %s is %d",
449 GList *colocations = NULL;
457 for (GList *iter = clone->
children; iter != NULL; iter = iter->next) {
461 "Adding scores for %s: initial sort index for %s is %d",
467 g_list_foreach(clone->
children, add_sort_index_to_node_score, clone);
470 g_list_foreach(colocations, apply_coloc_to_dependent, clone);
471 g_list_free(colocations);
474 g_list_foreach(colocations, apply_coloc_to_primary, clone);
475 g_list_free(colocations);
484 g_list_foreach(clone->
children, set_sort_index_to_node_score, clone);
502 find_active_anon_instance(
const pcmk_resource_t *clone,
const char *
id,
505 for (GList *iter = clone->
children; iter; iter = iter->next) {
513 if (active != NULL) {
534 for (GList *iter = clone->
children; iter; iter = iter->next) {
567 return (allowed != NULL) && (allowed->
weight >= 0);
585 const char *reason =
"allowed";
591 active = find_active_anon_instance(
parent,
id, node);
600 if ((active == NULL) && anonymous_known_on(
parent,
id, node)) {
611 reason =
"none probed";
623 "Ignoring %s promotion score (for %s) on %s: not probed",
624 rsc->
id,
id, pe__node_name(node));
630 if (is_allowed(rsc, node)) {
631 pe_rsc_trace(rsc,
"Counting %s promotion score (for %s) on %s: %s",
632 rsc->
id,
id, pe__node_name(node), reason);
637 pe_rsc_trace(rsc,
"Ignoring %s promotion score (for %s) on %s: not allowed",
638 rsc->
id,
id, pe__node_name(node));
657 char *attr_name = NULL;
658 const char *attr_value = NULL;
687 const char *attr_value = NULL;
689 if (is_default != NULL) {
693 CRM_CHECK((rsc != NULL) && (node != NULL),
return 0);
701 for (
const GList *iter = rsc->
children;
702 iter != NULL; iter = iter->next) {
705 bool child_default =
false;
706 int child_score = promotion_score(child, node, &child_default);
708 if (!child_default && (is_default != NULL)) {
711 score += child_score;
716 if (!promotion_score_applies(rsc, node)) {
726 attr_value = promotion_attr_value(rsc, node,
name);
727 if (attr_value != NULL) {
729 name, pe__node_name(node), pcmk__s(attr_value,
"(unset)"));
736 if (strcmp(rsc->
id,
name) != 0) {
737 attr_value = promotion_attr_value(rsc, node,
name);
738 pe_rsc_trace(rsc,
"Promotion score for %s on %s (for %s) = %s",
739 name, pe__node_name(node), rsc->
id,
740 pcmk__s(attr_value,
"(unset)"));
745 if (attr_value == NULL) {
749 if (is_default != NULL) {
769 for (GList *iter = rsc->
children; iter != NULL; iter = iter->next) {
774 int score, new_score;
777 while (g_hash_table_iter_next(&iter, NULL, (
void **) &node)) {
785 score = promotion_score(child_rsc, node, NULL);
788 if (new_score != node->weight) {
789 node->weight = new_score;
791 "Added %s promotion priority (%s) to score " 801 "Updating %s priority to promotion score (%d->%d)",
817 set_current_role_unpromoted(
void *
data,
void *user_data)
825 g_list_foreach(rsc->
children, set_current_role_unpromoted, NULL);
836 set_next_role_unpromoted(
void *
data,
void *user_data)
839 GList *assigned = NULL;
842 if (assigned == NULL) {
846 g_list_free(assigned);
848 g_list_foreach(rsc->
children, set_next_role_unpromoted, NULL);
859 set_next_role_promoted(
void *
data, gpointer user_data)
866 g_list_foreach(rsc->
children, set_next_role_promoted, NULL);
885 out->
message(out,
"promotion-score", instance, chosen,
889 "%s promotion score on %s: sort=%s priority=%s",
891 ((chosen == NULL)?
"none" : pe__node_name(chosen)),
905 set_instance_priority(gpointer
data, gpointer user_data)
913 pe_rsc_trace(clone,
"Assigning priority for %s: %s", instance->
id,
917 set_current_role_unpromoted(instance, NULL);
921 chosen = instance->
fns->
location(instance, &list, FALSE);
922 if (pcmk__list_of_multiple(list)) {
927 if (chosen == NULL) {
931 next_role = instance->
fns->
state(instance, FALSE);
937 bool is_default =
false;
939 instance->
priority = promotion_score(instance, chosen,
966 next_role, instance->
id));
970 apply_promoted_locations(instance, instance->
rsc_location, chosen);
971 apply_promoted_locations(instance, clone->
rsc_location, chosen);
975 for (GList *iter = list; iter != NULL; iter = iter->next) {
998 set_instance_role(gpointer
data, gpointer user_data)
1001 int *count = (
int *) user_data;
1006 show_promotion_score(instance);
1009 pe_rsc_trace(clone,
"Not supposed to promote instance %s",
1014 chosen = node_to_be_promoted_on(instance);
1017 if (chosen == NULL) {
1018 set_next_role_unpromoted(instance, NULL);
1025 crm_notice(
"Clone instance %s cannot be promoted without quorum",
1027 set_next_role_unpromoted(instance, NULL);
1032 pe_rsc_info(clone,
"Choosing %s (%s) on %s for promotion",
1034 pe__node_name(chosen));
1035 set_next_role_promoted(instance, NULL);
1049 GHashTableIter iter;
1054 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node)) {
1059 g_list_foreach(rsc->
children, set_instance_priority, rsc);
1060 sort_promotable_instances(rsc);
1063 g_list_foreach(rsc->
children, set_instance_role, &promoted);
1064 pe_rsc_info(rsc,
"%s: Promoted %d instances of a possible %d",
1079 bool *any_promoting,
bool *any_demoting)
1081 for (GList *iter = clone->
children; iter != NULL; iter = iter->next) {
1085 check_for_role_change(instance, any_demoting, any_promoting);
1102 for (GList *iter = clone->
children; iter != NULL; iter = iter->next) {
1118 bool any_promoting =
false;
1119 bool any_demoting =
false;
1122 create_promotable_instance_actions(clone, &any_promoting, &any_demoting);
1128 reset_instance_priorities(clone);
1144 for (GList *iter = clone->
children; iter != NULL; iter = iter->next) {
1152 order_instance_promotion(clone, instance, previous);
1153 order_instance_demotion(clone, instance, previous);
1154 previous = instance;
1173 GHashTableIter iter;
1175 const char *primary_value = NULL;
1182 primary_value = pcmk__colocation_node_attr(primary_node, attr, primary);
1185 "Applying %s (%s with %s on %s by %s @%d) to %s",
1187 colocation->
primary->
id, pe__node_name(primary_node), attr,
1188 colocation->
score, dependent->
id);
1191 while (g_hash_table_iter_next(&iter, NULL, (
void **) &node)) {
1192 const char *dependent_value = pcmk__colocation_node_attr(node, attr,
1198 "Added %s score (%s) to %s (now %s)",
1200 pe__node_name(node),
1218 GList *affected_nodes = NULL;
1224 for (GList *iter = primary->
children; iter != NULL; iter = iter->next) {
1232 update_dependent_allowed_nodes(dependent, primary, node,
1234 affected_nodes = g_list_prepend(affected_nodes, node);
1250 "Applying %s (mandatory %s with %s) to %s",
1254 affected_nodes,
true);
1256 g_list_free(affected_nodes);
1279 if (primary_instance != NULL) {
1285 "Applying %s (%s with %s) to %s priority (%s + %s = %s)",
1291 dependent->
priority = new_priority;
1296 "Applying %s (%s with %s) to %s: can't be promoted",
pcmk_assignment_methods_t * cmds
Resource assignment methods.
const pcmk_resource_t * pe__const_top_resource(const pcmk_resource_t *rsc, bool include_bundle)
#define CRM_CHECK(expr, failure_action)
enum rsc_role_e role_filter
enum pe_quorum_policy no_quorum_policy
Response to loss of quorum.
#define crm_notice(fmt, args...)
GHashTable * known_on
Nodes where resource has been probed (key is node ID, not name)
pcmk_scheduler_t * cluster
Cluster that resource is part of.
#define pe_rsc_debug(rsc, fmt, args...)
node_type
Possible node types.
Whether action should not be executed.
pcmk_node_t *(* location)(const pcmk_resource_t *rsc, GList **list, int current)
List nodes where a resource (or any of its children) is.
void(* create_actions)(pcmk_resource_t *rsc)
const char * pcmk_readable_score(int score)
Return a displayable static string for a score value.
int(* message)(pcmk__output_t *out, const char *message_id,...)
enum rsc_role_e role
Resource's current role.
G_GNUC_INTERNAL void pcmk__require_promotion_tickets(pcmk_resource_t *rsc)
Whether partition has quorum (via have-quorum property)
GList * children
Resource's child resources, if any.
int count
Counter reused by assignment and promotion code.
Match only clones and their instances, by either clone or instance ID.
enum rsc_role_e(* state)(const pcmk_resource_t *rsc, gboolean current)
Get resource's current or assigned role.
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...)
Whether node scores should be output instead of logged.
G_GNUC_INTERNAL pcmk_resource_t * pcmk__find_compatible_instance(const pcmk_resource_t *match_rsc, const pcmk_resource_t *rsc, enum rsc_role_e role, bool current)
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)
char * pcmk_promotion_score_name(const char *rsc_id)
Return the name of the node attribute used as a promotion score.
#define CRM_LOG_ASSERT(expr)
Where resource is assigned.
int pe__set_clone_flag(pcmk_resource_t *clone, enum pcmk__clone_flags flag)
G_GNUC_INTERNAL bool pcmk__node_available(const pcmk_node_t *node, bool consider_score, bool consider_guest)
#define pe__set_resource_flags(resource, flags_to_set)
pcmk_resource_t *(* find_rsc)(pcmk_resource_t *rsc, const char *search, const pcmk_node_t *node, int flags)
Search for a resource ID in a resource and its children.
const char * role2text(enum rsc_role_e role)
#define PCMK_ACTION_DEMOTE
int weight
Node score for a given resource.
#define crm_warn(fmt, args...)
void pe__set_next_role(pcmk_resource_t *rsc, enum rsc_role_e role, const char *why)
Implementation of pcmk_resource_t.
Actions are ordered (optionally, if no other flags are set)
pcmk_node_t * pe_find_node_id(const GList *node_list, const char *id)
Find a node by ID in a list of nodes.
char * clone_strip(const char *last_rsc_id)
int priority
Configured priority.
const char * pe__node_attribute_calculated(const pcmk_node_t *node, const char *name, const pcmk_resource_t *rsc, enum pcmk__rsc_node node_type, bool force_host)
void * priv
For Pacemaker use only.
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
struct pe_node_shared_s * details
Basic node information.
void pe__create_promotable_pseudo_ops(pcmk_resource_t *clone, bool any_promoting, bool any_demoting)
G_GNUC_INTERNAL gint pcmk__cmp_instance(gconstpointer a, gconstpointer b)
unsigned long long flags
Group of enum pcmk_rsc_flags.
char * clone_name
Resource instance ID in history.
Implementation of pcmk_node_t.
int pe__clone_promoted_node_max(const pcmk_resource_t *clone)
int pe__clone_promoted_max(const pcmk_resource_t *clone)
const char * id
Node ID at the cluster layer.
#define pcmk__order_resource_actions(first_rsc, first_task, then_rsc, then_task, flags)
void(* apply_coloc_score)(pcmk_resource_t *dependent, const pcmk_resource_t *primary, const pcmk__colocation_t *colocation, bool for_dependent)
pcmk_resource_t * primary
Whether resource has not yet been assigned to a node.
Whether resource is in the process of modifying allowed node scores.
If 'then' is required, 'first' must be added to the transition graph.
G_GNUC_INTERNAL GList * pcmk__with_this_colocations(const pcmk_resource_t *rsc)
pcmk_rsc_methods_t * fns
Resource object methods.
int sort_index
Promotion score on assigned node.
#define crm_err(fmt, args...)
If matching by node, compare current node instead of assigned node.
If 'first' is required and runnable, 'then' must be in graph.
G_GNUC_INTERNAL GList * pcmk__this_with_colocations(const pcmk_resource_t *rsc)
This structure contains everything that makes up a single output formatter.
G_GNUC_INTERNAL void pcmk__promotable_restart_ordering(pcmk_resource_t *rsc)
#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)
GList * running_on
Nodes where resource may be active.
const char * node_attribute
int pcmk__add_scores(int score1, int score2)
#define PCMK_ACTION_PROMOTED
Resource role is unknown.
#define pe_rsc_trace(rsc, fmt, args...)
bool pe__clone_is_ordered(const pcmk_resource_t *clone)
unsigned long long flags
Group of enum pcmk_scheduler_flags.
#define PCMK_ACTION_DEMOTED
Whether resource is managed.
G_GNUC_INTERNAL 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)
Whether resource is not an anonymous clone instance.
#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)
Where resource is running.