158 if (prefer == NULL) {
159 prefer = most_free_node;
168 nodes = sorted_allowed_nodes(rsc);
173 if ((prefer != NULL) && (nodes != NULL)) {
177 if (chosen == NULL) {
178 pe_rsc_trace(rsc,
"Preferred node %s for %s was unknown",
179 pe__node_name(prefer), rsc->
id);
188 pe_rsc_trace(rsc,
"Preferred node %s for %s was unsuitable",
189 pe__node_name(chosen), rsc->
id);
193 pe_rsc_trace(rsc,
"Preferred node %s for %s was unavailable",
194 pe__node_name(chosen), rsc->
id);
199 "Chose preferred node %s for %s (ignoring %d candidates)",
200 pe__node_name(chosen), rsc->
id, g_list_length(nodes));
204 if ((chosen == NULL) && (best != NULL)) {
211 if (!pe_rsc_is_unique_clone(rsc->
parent)
223 pe_node_t *running = pe__current_node(rsc);
225 if (running == NULL) {
229 pe_rsc_trace(rsc,
"Current node for %s (%s) can't run resources",
230 rsc->
id, pe__node_name(running));
233 int nodes_with_best_score = 1;
235 for (GList *iter = nodes->next; iter; iter = iter->next) {
242 if (pe__same_node(allowed, running)) {
246 nodes_with_best_score++;
249 if (nodes_with_best_score > 1) {
251 "Chose %s for %s from %d nodes with score %s",
252 pe__node_name(chosen), rsc->
id,
253 nodes_with_best_score,
260 pe__node_name(chosen), rsc->
id, g_list_length(nodes));
276 apply_this_with(gpointer
data, gpointer user_data)
281 GHashTable *archive = NULL;
292 "%s: Assigning colocation %s primary %s first" 293 "(score=%d role=%s)",
294 rsc->
id, colocation->
id, other->
id,
301 if ((archive != NULL)
304 "%s: Reverting scores from colocation with %s " 305 "because no nodes allowed",
311 if (archive != NULL) {
312 g_hash_table_destroy(archive);
333 crm_trace(
"Pacemaker Remote node %s will be online",
342 crm_trace(
"Pacemaker Remote node %s will be shut down " 343 "(%sassigned connection's next role is %s)",
363 GList *this_with_colocations = NULL;
364 GList *with_this_colocations = NULL;
384 pe_rsc_debug(rsc,
"Breaking assignment loop involving %s", rsc->
id);
396 for (iter = this_with_colocations; iter != NULL; iter = iter->next) {
397 colocation = iter->data;
400 apply_this_with(iter->data, rsc);
403 for (iter = with_this_colocations; iter != NULL; iter = iter->next) {
404 colocation = iter->data;
415 for (iter = this_with_colocations; iter != NULL; iter = iter->next) {
416 colocation = iter->data;
420 apply_this_with(iter->data, rsc);
423 for (iter = with_this_colocations; iter != NULL; iter = iter->next) {
424 colocation = iter->data;
432 g_list_free(this_with_colocations);
433 g_list_free(with_this_colocations);
437 "Banning %s from all nodes because it will be stopped",
445 crm_notice(
"Resource %s cannot be elevated from %s to %s due to " 446 "no-quorum-policy=freeze",
462 const char *reason = NULL;
466 assign_to = pe__current_node(rsc);
467 if (assign_to == NULL) {
476 pe_rsc_info(rsc,
"Unmanaged resource %s assigned to %s: %s", rsc->
id,
477 (assign_to? assign_to->
details->
uname :
"no node"), reason);
481 pe_rsc_debug(rsc,
"Forcing %s to stop: stop-all-resources", rsc->
id);
485 && assign_best_node(rsc, prefer)) {
490 pe_rsc_info(rsc,
"Resource %s cannot run anywhere", rsc->
id);
503 remote_connection_assigned(rsc);
522 bool need_stop,
bool need_promote)
533 pe_rsc_trace(rsc,
"Creating %s action to take %s down from %s to %s",
534 (need_stop?
"required" :
"optional"), rsc->
id,
536 fn = rsc_action_matrix[role][next_role];
540 fn(rsc, current, !need_stop);
547 bool required = need_stop;
549 next_role = rsc_state_matrix[role][rsc->
role];
553 pe_rsc_trace(rsc,
"Creating %s action to take %s up from %s to %s",
554 (required?
"required" :
"optional"), rsc->
id,
556 fn = rsc_action_matrix[role][next_role];
602 "Creating action for %s to represent already pending start",
624 "Creating action to take %s from %s to %s (ending at %s)",
627 fn = rsc_action_matrix[role][next_role];
645 bool need_stop =
false;
646 bool need_promote =
false;
647 bool is_moving =
false;
648 bool allow_migrate =
false;
649 bool multiply_active =
false;
652 unsigned int num_all_active = 0;
653 unsigned int num_clean_active = 0;
654 const char *next_role_source = NULL;
658 next_role_source = set_default_next_role(rsc);
660 "Creating all actions for %s transition from %s to %s " 665 current = rsc->
fns->
active_node(rsc, &num_all_active, &num_clean_active);
675 rsc->
id, pe__node_name(current),
687 && allow_migrate && (num_all_active == 2)
693 pe_rsc_trace(rsc,
"Partial migration of %s from %s to %s will continue",
701 if (num_all_active > 2) {
703 crm_notice(
"Forcing recovery of %s because it is migrating " 704 "from %s to %s and possibly active elsewhere",
709 crm_notice(
"Forcing recovery of %s because it can no longer " 710 "migrate from %s to %s",
716 allow_migrate =
false;
719 multiply_active = (num_all_active > 1);
728 multiply_active = (num_clean_active > 1);
731 if (multiply_active) {
735 pe_proc_err(
"%s resource %s might be active on %u nodes (%s)",
736 pcmk__s(
class,
"Untyped"), rsc->id, num_all_active,
737 recovery2text(rsc->recovery_type));
738 crm_notice(
"See https://wiki.clusterlabs.org/wiki/FAQ" 739 "#Resource_is_Too_Active for more information");
741 switch (rsc->recovery_type) {
758 create_pending_start(rsc);
783 pe_rsc_trace(rsc,
"Creating start action for promoted resource %s",
788 pe_rsc_trace(rsc,
"%s restart is required for recovery", rsc->
id);
794 schedule_restart_actions(rsc, current, need_stop, need_promote);
797 schedule_role_transition_actions(rsc);
819 while (g_hash_table_iter_next(&iter, NULL, (
void **) &node)) {
820 if (node->details->remote_rsc != NULL) {
842 GList *allowed_nodes = NULL;
852 return allowed_nodes;
864 GList *allowed_nodes = NULL;
865 bool check_unfencing =
false;
866 bool check_utilization =
false;
872 "Skipping implicit constraints for unmanaged resource %s",
883 check_utilization = (g_hash_table_size(rsc->
utilization) > 0)
914 if (check_unfencing || check_utilization || (rsc->
container != NULL)) {
915 allowed_nodes = allowed_nodes_as_list(rsc);
918 if (check_unfencing) {
922 if (check_utilization) {
962 if (remote_rsc != NULL) {
966 for (GList *item = allowed_nodes; item; item = item->next) {
981 crm_trace(
"Order and colocate %s relative to its container %s",
1011 rsc_avoids_remote_nodes(rsc);
1013 g_list_free(allowed_nodes);
1037 CRM_CHECK((colocation != NULL) && (dependent != NULL) && (primary != NULL),
1040 if (for_dependent) {
1048 pe_rsc_trace(dependent,
"%s %s with %s (%s, score=%d, filter=%d)",
1049 ((colocation->
score > 0)?
"Colocating" :
"Anti-colocating"),
1050 dependent->
id, primary->
id, colocation->
id, colocation->
score,
1053 switch (filter_results) {
1074 && (rsc == orig_rsc) && (list != NULL),
1079 if (rsc->
parent != NULL) {
1093 && (rsc == orig_rsc) && (list != NULL),
1098 if (rsc->
parent != NULL) {
1135 return pcmk_all_flags_set(rsc->
flags,
1152 for (GList *iter = rsc->
running_on; iter != NULL; iter = iter->next) {
1156 if (is_expected_node(rsc, current)) {
1162 "Skipping stop of multiply active resource %s " 1163 "on expected node %s",
1164 rsc->
id, pe__node_name(current));
1173 "Skipping stop of %s on %s " 1174 "because partial migration there will continue",
1175 rsc->
id, pe__node_name(current));
1179 "Forcing stop of %s on %s " 1180 "because migration target changed",
1181 rsc->
id, pe__node_name(current));
1187 rsc->
id, pe__node_name(current));
1215 pe_proc_err(
"Stopping %s until %s can be unfenced",
1216 rsc->
id, pe__node_name(current));
1237 pe_rsc_trace(rsc,
"Scheduling %s start of %s on %s (score %d)",
1238 (optional?
"optional" :
"required"), rsc->
id,
1239 pe__node_name(node), node->
weight);
1248 if (is_expected_node(rsc, node)) {
1253 "Start of multiply active resouce %s " 1254 "on expected node %s will be a pseudo-action",
1255 rsc->
id, pe__node_name(node));
1272 GList *action_list = NULL;
1273 bool runnable =
true;
1279 for (iter = action_list; iter != NULL; iter = iter->next) {
1286 g_list_free(action_list);
1291 pe_rsc_trace(rsc,
"Scheduling %s promotion of %s on %s",
1292 (optional?
"optional" :
"required"), rsc->
id,
1293 pe__node_name(node));
1295 if (is_expected_node(rsc, node)) {
1300 "Promotion of multiply active resouce %s " 1301 "on expected node %s will be a pseudo-action",
1302 rsc->
id, pe__node_name(node));
1306 pe_rsc_trace(rsc,
"Not promoting %s on %s: start unrunnable",
1307 rsc->
id, pe__node_name(node));
1309 for (iter = action_list; iter != NULL; iter = iter->next) {
1314 g_list_free(action_list);
1334 for (GList *iter = rsc->
running_on; iter != NULL; iter = iter->next) {
1337 if (is_expected_node(rsc, current)) {
1339 "Skipping demote of multiply active resource %s " 1340 "on expected node %s",
1341 rsc->
id, pe__node_name(current));
1343 pe_rsc_trace(rsc,
"Scheduling %s demotion of %s on %s",
1344 (optional?
"optional" :
"required"), rsc->
id,
1345 pe__node_name(current));
1375 CRM_CHECK((rsc != NULL) && (node != NULL),
return);
1378 pe_rsc_trace(rsc,
"Skipping clean-up of %s on %s: resource failed",
1379 rsc->
id, pe__node_name(node));
1384 pe_rsc_trace(rsc,
"Skipping clean-up of %s on %s: node unavailable",
1385 rsc->
id, pe__node_name(node));
1389 crm_notice(
"Scheduling clean-up of %s on %s", rsc->
id, pe__node_name(node));
1418 if (value != NULL) {
1426 if (value != NULL) {
1437 if (
parent->container != NULL) {
1447 value = g_hash_table_lookup(rsc->
meta,
"external-ip");
1448 if (value != NULL) {
1457 GHashTable *utilization)
1463 pe_rsc_trace(orig_rsc,
"%s: Adding primitive %s as colocated utilization",
1464 orig_rsc->
id, rsc->
id);
1482 if (shutdown != NULL) {
1483 long long result_ll;
1486 result = (time_t) result_ll;
1500 ban_if_not_locked(gpointer
data, gpointer user_data)
1523 if (rsc->lock_node != NULL) {
1526 if (rsc->running_on != NULL) {
1532 "Cancelling shutdown lock because %s is already active",
1535 rsc->lock_node = NULL;
1540 }
else if (pcmk__list_of_1(rsc->running_on)) {
1541 pe_node_t *node = rsc->running_on->data;
1545 pe_rsc_debug(rsc,
"Not locking %s to unclean %s for shutdown",
1546 rsc->id, pe__node_name(node));
1548 rsc->lock_node = node;
1549 rsc->lock_time = shutdown_time(node);
1554 if (rsc->lock_node == NULL) {
1559 if (rsc->cluster->shutdown_lock > 0) {
1560 time_t lock_expiration = rsc->lock_time + rsc->cluster->shutdown_lock;
1562 pe_rsc_info(rsc,
"Locking %s to %s due to shutdown (expires @%lld)",
1563 rsc->id, pe__node_name(rsc->lock_node),
1564 (
long long) lock_expiration);
1567 pe_rsc_info(rsc,
"Locking %s to %s due to shutdown",
1568 rsc->id, pe__node_name(rsc->lock_node));
1572 g_list_foreach(rsc->cluster->nodes, ban_if_not_locked, rsc);
#define CRM_CHECK(expr, failure_action)
enum pe_quorum_policy no_quorum_policy
G_GNUC_INTERNAL void pcmk__add_this_with_list(GList **list, GList *addition)
#define crm_notice(fmt, args...)
G_GNUC_INTERNAL void pcmk__release_node_capacity(GHashTable *current_utilization, const pe_resource_t *rsc)
#define pe_rsc_debug(rsc, fmt, args...)
#define XML_CONFIG_ATTR_SHUTDOWN_LOCK
#define pe__set_action_flags(action, flags_to_set)
#define pe__show_node_weights(level, rsc, text, nodes, data_set)
enum pe_action_flags pcmk__primitive_action_flags(pe_action_t *action, const pe_node_t *node)
#define promote_action(rsc, node, optional)
const char * pcmk_readable_score(int score)
Return a displayable static string for a score value.
#define stop_action(rsc, node, optional)
pe_node_t * pcmk__primitive_assign(pe_resource_t *rsc, const pe_node_t *prefer)
pe_resource_t * container
void pcmk__schedule_cleanup(pe_resource_t *rsc, const pe_node_t *node, bool optional)
pe_node_t * partial_migration_source
void pe__update_recheck_time(time_t recheck, pe_working_set_t *data_set)
G_GNUC_INTERNAL bool pcmk__any_node_available(GHashTable *nodes)
gint pe__cmp_node_name(gconstpointer a, gconstpointer b)
void pcmk__primitive_with_colocations(const pe_resource_t *rsc, const pe_resource_t *orig_rsc, GList **list)
resource_alloc_functions_t * cmds
#define delete_action(rsc, node, optional)
#define pe_flag_remove_after_stop
#define XML_RSC_ATTR_INCARNATION
enum rsc_role_e next_role
pe_resource_t * remote_rsc
void pcmk__primitive_apply_coloc_score(pe_resource_t *dependent, const pe_resource_t *primary, const pcmk__colocation_t *colocation, bool for_dependent)
void(* with_this_colocations)(const pe_resource_t *rsc, const pe_resource_t *orig_rsc, GList **list)
#define pe_rsc_restarting
resource_object_functions_t * fns
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
G_GNUC_INTERNAL GList * pcmk__sort_nodes(GList *nodes, pe_node_t *active_node)
const pe_resource_t * pe__const_top_resource(const pe_resource_t *rsc, bool include_bundle)
bool pcmk__rsc_can_migrate(const pe_resource_t *rsc, const pe_node_t *current)
time_t get_effective_time(pe_working_set_t *data_set)
pe_node_t * partial_migration_target
void resource_location(pe_resource_t *rsc, const pe_node_t *node, int score, const char *tag, pe_working_set_t *data_set)
void pcmk__primitive_internal_constraints(pe_resource_t *rsc)
#define pe_rsc_stop_unexpected
#define pe_rsc_allow_remote_remotes
#define pe_flag_have_quorum
#define CRM_SCORE_INFINITY
#define pe_proc_err(fmt...)
pe_working_set_t * data_set
Cluster that this node is part of.
G_GNUC_INTERNAL void pcmk__apply_coloc_to_priority(pe_resource_t *dependent, const pe_resource_t *primary, const pcmk__colocation_t *colocation)
char * crm_meta_name(const char *field)
G_GNUC_INTERNAL 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)
#define pe__set_resource_flags(resource, flags_to_set)
pe_node_t *(* assign)(pe_resource_t *rsc, const pe_node_t *prefer)
pe_node_t *(* active_node)(const pe_resource_t *rsc, unsigned int *count_all, unsigned int *count_clean)
#define pe_flag_stop_everything
#define demote_action(rsc, node, optional)
#define pe_rsc_provisional
const char * role2text(enum rsc_role_e role)
int pcmk__scan_ll(const char *text, long long *result, long long default_value)
GList * dangling_migrations
void pe_action_set_reason(pe_action_t *action, const char *reason, bool overwrite)
G_GNUC_INTERNAL const pe_node_t * pcmk__ban_insufficient_capacity(pe_resource_t *rsc)
G_GNUC_INTERNAL bool pcmk__node_available(const pe_node_t *node, bool consider_score, bool consider_guest)
#define XML_CIB_ATTR_SHUTDOWN
pe_resource_t * pe__resource_contains_guest_node(const pe_working_set_t *data_set, const pe_resource_t *rsc)
#define XML_RSC_ATTR_CONTAINER
GList * pcmk__with_this_colocations(const pe_resource_t *rsc)
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
const char * pe_node_attribute_raw(const pe_node_t *node, const char *name)
void pcmk__with_primitive_colocations(const pe_resource_t *rsc, const pe_resource_t *orig_rsc, GList **list)
#define pe_rsc_start_pending
#define pe__clear_action_flags(action, flags_to_clear)
#define crm_trace(fmt, args...)
#define do_crm_log(level, fmt, args...)
Log a message.
#define PCMK_RESOURCE_CLASS_STONITH
GList * pcmk__this_with_colocations(const 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
G_GNUC_INTERNAL bool pcmk__finalize_assignment(pe_resource_t *rsc, pe_node_t *chosen, bool force)
#define pe_rsc_needs_fencing
gboolean order_actions(pe_action_t *lh_action, pe_action_t *rh_action, enum pe_ordering order)
#define pe_rsc_promotable
G_GNUC_INTERNAL bool pcmk__node_unfenced(const pe_node_t *node)
#define pe_flag_stonith_enabled
G_GNUC_INTERNAL void pcmk__new_ordering(pe_resource_t *first_rsc, char *first_task, pe_action_t *first_action, pe_resource_t *then_rsc, char *then_task, pe_action_t *then_action, uint32_t flags, pe_working_set_t *data_set)
#define XML_RSC_ATTR_TARGET_ROLE
#define XML_RSC_ATTR_REMOTE_NODE
G_GNUC_INTERNAL void pcmk__add_with_this_list(GList **list, GList *addition)
#define pe_rsc_allocating
enum pe_obj_types variant
void(* this_with_colocations)(const pe_resource_t *rsc, const pe_resource_t *orig_rsc, GList **list)
const char * placement_strategy
void pcmk__primitive_create_actions(pe_resource_t *rsc)
G_GNUC_INTERNAL void pcmk__order_restart_vs_unfence(gpointer data, gpointer user_data)
void pcmk__create_migration_actions(pe_resource_t *rsc, const pe_node_t *current)
void pcmk__primitive_add_graph_meta(const pe_resource_t *rsc, xmlNode *xml)
char * pcmk__op_key(const char *rsc_id, const char *op_type, guint interval_ms)
Generate an operation key (RESOURCE_ACTION_INTERVAL)
#define pcmk__order_resource_actions(first_rsc, first_task, then_rsc, then_task, flags)
void(* apply_coloc_score)(pe_resource_t *dependent, const pe_resource_t *primary, const pcmk__colocation_t *colocation, bool for_dependent)
#define pe_rsc_fence_device
void pcmk__primitive_shutdown_lock(pe_resource_t *rsc)
G_GNUC_INTERNAL void pcmk__create_utilization_constraints(pe_resource_t *rsc, const GList *allowed_nodes)
pe_action_t * pe__clear_resource_history(pe_resource_t *rsc, const pe_node_t *node, pe_working_set_t *data_set)
pcmk__action_result_t result
G_GNUC_INTERNAL void pcmk__add_dependent_scores(gpointer data, gpointer user_data)
#define start_action(rsc, node, optional)
G_GNUC_INTERNAL GHashTable * pcmk__copy_node_table(GHashTable *nodes)
G_GNUC_INTERNAL void pcmk__create_recurring_actions(pe_resource_t *rsc)
void pe__set_next_role(pe_resource_t *rsc, enum rsc_role_e role, const char *why)
void pcmk__primitive_add_utilization(const pe_resource_t *rsc, const pe_resource_t *orig_rsc, GList *all_rscs, GHashTable *utilization)
#define pe_rsc_needs_unfencing
#define pe__clear_resource_flags(resource, flags_to_clear)
pe_node_t * pe_find_node(const GList *node_list, const char *node_name)
Find a node by name in a list of nodes.
rsc_role_e
Possible roles that a resource can be in.
enum pe_action_flags flags
pe_working_set_t * cluster
bool pe__resource_is_remote_conn(const pe_resource_t *rsc, const pe_working_set_t *data_set)
G_GNUC_INTERNAL void pcmk__order_vs_unfence(const pe_resource_t *rsc, pe_node_t *node, pe_action_t *action, enum pe_ordering order)
#define pe_flag_have_stonith_resource
#define pe_flag_enable_unfencing
void(* rsc_transition_fn)(pe_resource_t *rsc, pe_node_t *node, bool optional)
#define pe_rsc_trace(rsc, fmt, args...)
GList * pe__resource_actions(const pe_resource_t *rsc, const pe_node_t *node, const char *task, bool require_node)
Find all actions of given type for a resource.
#define CRM_OP_LRM_DELETE
#define pe_flag_show_scores
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)
G_GNUC_INTERNAL void pcmk__apply_coloc_to_weights(pe_resource_t *dependent, const pe_resource_t *primary, const pcmk__colocation_t *colocation)
void pcmk__abort_dangling_migration(void *data, void *user_data)
pe_action_t * pe_fence_op(pe_node_t *node, const char *op, bool optional, const char *reason, bool priority_delay, pe_working_set_t *data_set)
#define pe_rsc_info(rsc, fmt, args...)
#define XML_AGENT_ATTR_CLASS
GHashTable * allowed_nodes