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;
291 "%s: Assigning colocation %s primary %s first" 292 "(score=%d role=%s)",
293 rsc->
id, colocation->
id, other->
id,
299 if ((archive != NULL)
302 "%s: Reverting scores from colocation with %s " 303 "because no nodes allowed",
309 if (archive != NULL) {
310 g_hash_table_destroy(archive);
322 apply_with_this(
void *
data,
void *user_data)
330 if (!pcmk__colocation_has_influence(colocation, NULL)) {
334 "%s: Incorporating attenuated %s assignment scores due " 335 "to colocation %s", rsc->
id, other->
id, colocation->
id);
358 crm_trace(
"Pacemaker Remote node %s will be online",
367 crm_trace(
"Pacemaker Remote node %s will be shut down " 368 "(%sassigned connection's next role is %s)",
404 pe_rsc_debug(rsc,
"Breaking assignment loop involving %s", rsc->
id);
412 g_list_foreach(rsc->
rsc_cons, apply_this_with, rsc);
416 g_list_foreach(rsc->
rsc_cons_lhs, apply_with_this, rsc);
420 "Banning %s from all nodes because it will be stopped",
428 crm_notice(
"Resource %s cannot be elevated from %s to %s due to " 429 "no-quorum-policy=freeze",
445 const char *reason = NULL;
449 assign_to = pe__current_node(rsc);
450 if (assign_to == NULL) {
459 pe_rsc_info(rsc,
"Unmanaged resource %s assigned to %s: %s", rsc->
id,
460 (assign_to? assign_to->
details->
uname :
"no node"), reason);
464 pe_rsc_debug(rsc,
"Forcing %s to stop: stop-all-resources", rsc->
id);
468 && assign_best_node(rsc, prefer)) {
473 pe_rsc_info(rsc,
"Resource %s cannot run anywhere", rsc->
id);
486 remote_connection_assigned(rsc);
505 bool need_stop,
bool need_promote)
516 pe_rsc_trace(rsc,
"Creating %s action to take %s down from %s to %s",
517 (need_stop?
"required" :
"optional"), rsc->
id,
519 fn = rsc_action_matrix[role][next_role];
523 fn(rsc, current, !need_stop);
530 bool required = need_stop;
532 next_role = rsc_state_matrix[role][rsc->
role];
536 pe_rsc_trace(rsc,
"Creating %s action to take %s up from %s to %s",
537 (required?
"required" :
"optional"), rsc->
id,
539 fn = rsc_action_matrix[role][next_role];
585 "Creating action for %s to represent already pending start",
607 "Creating action to take %s from %s to %s (ending at %s)",
610 fn = rsc_action_matrix[role][next_role];
628 bool need_stop =
false;
629 bool need_promote =
false;
630 bool is_moving =
false;
631 bool allow_migrate =
false;
632 bool multiply_active =
false;
635 unsigned int num_all_active = 0;
636 unsigned int num_clean_active = 0;
637 const char *next_role_source = NULL;
641 next_role_source = set_default_next_role(rsc);
643 "Creating all actions for %s transition from %s to %s " 658 rsc->
id, pe__node_name(current),
670 && allow_migrate && (num_all_active == 2)
676 pe_rsc_trace(rsc,
"Partial migration of %s from %s to %s will continue",
684 if (num_all_active > 2) {
686 crm_notice(
"Forcing recovery of %s because it is migrating " 687 "from %s to %s and possibly active elsewhere",
692 crm_notice(
"Forcing recovery of %s because it can no longer " 693 "migrate from %s to %s",
699 allow_migrate =
false;
702 multiply_active = (num_all_active > 1);
711 multiply_active = (num_clean_active > 1);
714 if (multiply_active) {
718 pe_proc_err(
"%s resource %s might be active on %u nodes (%s)",
719 pcmk__s(
class,
"Untyped"), rsc->id, num_all_active,
720 recovery2text(rsc->recovery_type));
721 crm_notice(
"See https://wiki.clusterlabs.org/wiki/FAQ" 722 "#Resource_is_Too_Active for more information");
724 switch (rsc->recovery_type) {
741 create_pending_start(rsc);
766 pe_rsc_trace(rsc,
"Creating start action for promoted resource %s",
771 pe_rsc_trace(rsc,
"%s restart is required for recovery", rsc->
id);
777 schedule_restart_actions(rsc, current, need_stop, need_promote);
780 schedule_role_transition_actions(rsc);
802 while (g_hash_table_iter_next(&iter, NULL, (
void **) &node)) {
803 if (node->details->remote_rsc != NULL) {
825 GList *allowed_nodes = NULL;
835 return allowed_nodes;
848 GList *allowed_nodes = NULL;
849 bool check_unfencing =
false;
850 bool check_utilization =
false;
856 "Skipping implicit constraints for unmanaged resource %s",
869 check_utilization = (g_hash_table_size(rsc->
utilization) > 0)
899 if (check_unfencing || check_utilization || (rsc->
container != NULL)) {
900 allowed_nodes = allowed_nodes_as_list(rsc);
903 if (check_unfencing) {
907 if (check_utilization) {
947 if (remote_rsc != NULL) {
951 for (GList *item = allowed_nodes; item; item = item->next) {
966 crm_trace(
"Order and colocate %s relative to its container %s",
996 rsc_avoids_remote_nodes(rsc);
998 g_list_free(allowed_nodes);
1022 CRM_CHECK((colocation != NULL) && (dependent != NULL) && (primary != NULL),
1025 if (for_dependent) {
1033 pe_rsc_trace(dependent,
"%s %s with %s (%s, score=%d, filter=%d)",
1034 ((colocation->
score > 0)?
"Colocating" :
"Anti-colocating"),
1035 dependent->
id, primary->
id, colocation->
id, colocation->
score,
1038 switch (filter_results) {
1082 return pcmk_all_flags_set(rsc->
flags,
1099 for (GList *iter = rsc->
running_on; iter != NULL; iter = iter->next) {
1103 if (is_expected_node(rsc, current)) {
1109 "Skipping stop of multiply active resource %s " 1110 "on expected node %s",
1111 rsc->
id, pe__node_name(current));
1120 "Skipping stop of %s on %s " 1121 "because partial migration there will continue",
1122 rsc->
id, pe__node_name(current));
1126 "Forcing stop of %s on %s " 1127 "because migration target changed",
1128 rsc->
id, pe__node_name(current));
1134 rsc->
id, pe__node_name(current));
1162 pe_proc_err(
"Stopping %s until %s can be unfenced",
1163 rsc->
id, pe__node_name(current));
1184 pe_rsc_trace(rsc,
"Scheduling %s start of %s on %s (score %d)",
1185 (optional?
"optional" :
"required"), rsc->
id,
1186 pe__node_name(node), node->
weight);
1195 if (is_expected_node(rsc, node)) {
1200 "Start of multiply active resouce %s " 1201 "on expected node %s will be a pseudo-action",
1202 rsc->
id, pe__node_name(node));
1219 GList *action_list = NULL;
1220 bool runnable =
true;
1226 for (iter = action_list; iter != NULL; iter = iter->next) {
1233 g_list_free(action_list);
1238 pe_rsc_trace(rsc,
"Scheduling %s promotion of %s on %s",
1239 (optional?
"optional" :
"required"), rsc->
id,
1240 pe__node_name(node));
1242 if (is_expected_node(rsc, node)) {
1247 "Promotion of multiply active resouce %s " 1248 "on expected node %s will be a pseudo-action",
1249 rsc->
id, pe__node_name(node));
1253 pe_rsc_trace(rsc,
"Not promoting %s on %s: start unrunnable",
1254 rsc->
id, pe__node_name(node));
1256 for (iter = action_list; iter != NULL; iter = iter->next) {
1261 g_list_free(action_list);
1281 for (GList *iter = rsc->
running_on; iter != NULL; iter = iter->next) {
1284 if (is_expected_node(rsc, current)) {
1286 "Skipping demote of multiply active resource %s " 1287 "on expected node %s",
1288 rsc->
id, pe__node_name(current));
1290 pe_rsc_trace(rsc,
"Scheduling %s demotion of %s on %s",
1291 (optional?
"optional" :
"required"), rsc->
id,
1292 pe__node_name(current));
1322 CRM_CHECK((rsc != NULL) && (node != NULL),
return);
1325 pe_rsc_trace(rsc,
"Skipping clean-up of %s on %s: resource failed",
1326 rsc->
id, pe__node_name(node));
1331 pe_rsc_trace(rsc,
"Skipping clean-up of %s on %s: node unavailable",
1332 rsc->
id, pe__node_name(node));
1336 crm_notice(
"Scheduling clean-up of %s on %s", rsc->
id, pe__node_name(node));
1365 if (value != NULL) {
1373 if (value != NULL) {
1384 if (
parent->container != NULL) {
1394 value = g_hash_table_lookup(rsc->
meta,
"external-ip");
1395 if (value != NULL) {
1404 GHashTable *utilization)
1410 pe_rsc_trace(orig_rsc,
"%s: Adding primitive %s as colocated utilization",
1411 orig_rsc->
id, rsc->
id);
1430 if (shutdown != NULL) {
1431 long long result_ll;
1434 result = (time_t) result_ll;
1448 ban_if_not_locked(gpointer
data, gpointer user_data)
1471 if (rsc->lock_node != NULL) {
1474 if (rsc->running_on != NULL) {
1480 "Cancelling shutdown lock because %s is already active",
1483 rsc->lock_node = NULL;
1488 }
else if (pcmk__list_of_1(rsc->running_on)) {
1489 pe_node_t *node = rsc->running_on->data;
1493 pe_rsc_debug(rsc,
"Not locking %s to unclean %s for shutdown",
1494 rsc->id, pe__node_name(node));
1496 rsc->lock_node = node;
1497 rsc->lock_time = shutdown_time(node);
1502 if (rsc->lock_node == NULL) {
1507 if (rsc->cluster->shutdown_lock > 0) {
1508 time_t lock_expiration = rsc->lock_time + rsc->cluster->shutdown_lock;
1510 pe_rsc_info(rsc,
"Locking %s to %s due to shutdown (expires @%lld)",
1511 rsc->id, pe__node_name(rsc->lock_node),
1512 (
long long) lock_expiration);
1515 pe_rsc_info(rsc,
"Locking %s to %s due to shutdown",
1516 rsc->id, pe__node_name(rsc->lock_node));
1520 g_list_foreach(rsc->cluster->nodes, ban_if_not_locked, rsc);
#define CRM_CHECK(expr, failure_action)
pe_node_t * pe_find_node(GList *node_list, const char *uname)
enum pe_quorum_policy no_quorum_policy
#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)
G_GNUC_INTERNAL bool pcmk__node_unfenced(pe_node_t *node)
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_node_t * pe__find_active_on(const pe_resource_t *rsc, unsigned int *count_all, unsigned int *count_clean)
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)
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)
#define pe_rsc_restarting
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
pe_resource_t * dependent
G_GNUC_INTERNAL GList * pcmk__sort_nodes(GList *nodes, pe_node_t *active_node)
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)
void resource_location(pe_resource_t *rsc, pe_node_t *node, int score, const char *tag, pe_working_set_t *data_set)
G_GNUC_INTERNAL void pcmk__order_vs_unfence(pe_resource_t *rsc, pe_node_t *node, pe_action_t *action, enum pe_ordering order)
pe_node_t * partial_migration_target
void pcmk__primitive_internal_constraints(pe_resource_t *rsc)
#define pe_rsc_stop_unexpected
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)
void pcmk__primitive_add_graph_meta(pe_resource_t *rsc, xmlNode *xml)
#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)
G_GNUC_INTERNAL void pcmk__create_utilization_constraints(pe_resource_t *rsc, GList *allowed_nodes)
#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)
pe_resource_t * uber_parent(pe_resource_t *rsc)
#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
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)
#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
#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
#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
#define pe_rsc_allocating
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)
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)
pcmk__action_result_t result
#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)
rsc_role_e
Possible roles that a resource can be in.
enum pe_action_flags flags
pe_working_set_t * cluster
const char * node_attribute
bool pe__resource_is_remote_conn(const pe_resource_t *rsc, const pe_working_set_t *data_set)
#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.
pe_action_t * pe__clear_resource_history(pe_resource_t *rsc, pe_node_t *node, pe_working_set_t *data_set)
#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