21 #define INFINITY_HACK (INFINITY * -100) 23 #define VARIANT_NATIVE 1 76 #define clear_node_weights_flags(nw_flags, nw_rsc, flags_to_clear) do { \ 77 flags = pcmk__clear_flags_as(__func__, __LINE__, LOG_TRACE, \ 78 "Node weight", (nw_rsc)->id, (flags), \ 79 (flags_to_clear), #flags_to_clear); \ 90 gboolean result = FALSE;
107 best = g_list_nth_data(nodes, 0);
110 if (prefer && nodes) {
113 if (chosen == NULL) {
114 pe_rsc_trace(rsc,
"Preferred node %s for %s was unknown",
124 pe_rsc_trace(rsc,
"Preferred node %s for %s was unsuitable",
129 pe_rsc_trace(rsc,
"Preferred node %s for %s was unavailable",
135 "Chose preferred node %s for %s (ignoring %d candidates)",
140 if ((chosen == NULL) && nodes) {
146 pe_rsc_trace(rsc,
"Chose node %s for %s from %d candidates",
149 if (!pe_rsc_is_unique_clone(rsc->
parent)
160 pe_node_t *running = pe__current_node(rsc);
163 pe_rsc_trace(rsc,
"Current node for %s (%s) can't run resources",
165 }
else if (running) {
166 for (GList *iter = nodes->next; iter; iter = iter->next) {
184 static char score[33];
185 int log_level = (chosen->
weight >=
INFINITY)? LOG_WARNING : LOG_INFO;
189 "Chose node %s for %s from %d nodes with score %s",
207 best_node_score_matching_attr(
const pe_resource_t *rsc,
const char *attr,
213 const char *best_node = NULL;
217 while (g_hash_table_iter_next(&iter, NULL, (
void **) &node)) {
222 best_score = node->weight;
223 best_node = node->details->uname;
228 if (best_node == NULL) {
229 crm_info(
"No allowed node for %s matches node attribute %s=%s",
230 rsc->
id, attr, value);
232 crm_info(
"Allowed node %s for %s had best score (%d) " 233 "of those matching node attribute %s=%s",
234 best_node, rsc->
id, best_score, attr, value);
255 add_node_scores_matching_attr(GHashTable *nodes,
const pe_resource_t *rsc,
256 const char *attr,
float factor,
267 g_hash_table_iter_init(&iter, nodes);
268 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node)) {
274 score = best_node_score_matching_attr(rsc, attr,
277 if ((factor < 0) && (score < 0)) {
283 crm_trace(
"%s: Filtering %d + %f * %d (double negative disallowed)",
284 node->details->uname, node->weight, factor, score);
289 crm_trace(
"%s: Filtering %d + %f * %d (node was marked unusable)",
290 node->details->uname, node->weight, factor, score);
294 weight_f = factor * score;
297 weight = (int) ((weight_f < 0)? (weight_f - 0.5) : (weight_f + 0.5));
303 if ((weight == 0) && (score != 0)) {
306 }
else if (factor < 0.0) {
313 if (only_positive && (new_score < 0) && (node->weight > 0)) {
314 crm_trace(
"%s: Filtering %d + %f * %d = %d " 315 "(negative disallowed, marking node unusable)",
316 node->details->uname, node->weight, factor, score,
322 if (only_positive && (new_score < 0) && (node->weight == 0)) {
323 crm_trace(
"%s: Filtering %d + %f * %d = %d (negative disallowed)",
324 node->details->uname, node->weight, factor, score,
329 crm_trace(
"%s: %d + %f * %d = %d", node->details->uname,
330 node->weight, factor, score, new_score);
331 node->weight = new_score;
358 GHashTable *nodes,
const char *attr,
float factor,
361 GHashTable *work = NULL;
365 pe_rsc_info(rsc,
"%s: Breaking dependency loop at %s", rhs, rsc->
id);
371 if (is_nonempty_group(rsc)) {
372 GList *last = g_list_last(rsc->
children);
376 "using last member %s (at %.6f)",
377 rhs, rsc->
id, last_rsc->
id, factor);
385 }
else if (is_nonempty_group(rsc)) {
396 pe_rsc_trace(rsc,
"%s: Merging scores from first member of group %s " 397 "(at %.6f)", rhs, rsc->
id, factor);
403 pe_rsc_trace(rsc,
"%s: Merging scores from %s (at %.6f)",
404 rhs, rsc->
id, factor);
406 add_node_scores_matching_attr(work, rsc, attr, factor,
412 int multiplier = (factor < 0)? -1 : 1;
417 "Checking additional %d optional '%s with' constraints",
418 g_list_length(gIter), rsc->
id);
420 }
else if (is_nonempty_group(rsc)) {
424 pe_rsc_trace(rsc,
"Checking additional %d optional 'with group %s' " 425 "constraints using last member %s",
426 g_list_length(gIter), rsc->
id, last_rsc->
id);
431 "Checking additional %d optional 'with %s' constraints",
432 g_list_length(gIter), rsc->
id);
435 for (; gIter != NULL; gIter = gIter->next) {
439 if (constraint->
score == 0) {
444 other = constraint->
rsc_rh;
446 other = constraint->
rsc_lh;
449 pe_rsc_trace(rsc,
"Optionally merging score of '%s' constraint (%s with %s)",
460 pe_rsc_info(rsc,
"%s: Rolling back optional scores from %s",
462 g_hash_table_destroy(work);
472 g_hash_table_iter_init(&iter, work);
473 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node)) {
481 g_hash_table_destroy(nodes);
511 pe_rsc_debug(rsc,
"Escalating allocation of %s to its parent: %s", rsc->
id,
521 pe_rsc_debug(rsc,
"Dependency loop detected involving %s", rsc->
id);
528 for (gIter = rsc->
rsc_cons; gIter != NULL; gIter = gIter->next) {
531 GHashTable *archive = NULL;
534 if (constraint->
score == 0) {
544 "%s: Allocating %s first (constraint=%s score=%d role=%s)",
545 rsc->
id, rsc_rh->id, constraint->
id,
547 rsc_rh->cmds->allocate(rsc_rh, NULL, data_set);
550 pe_rsc_info(rsc,
"%s: Rolling back scores from %s", rsc->
id, rsc_rh->id);
556 g_hash_table_destroy(archive);
562 for (gIter = rsc->
rsc_cons_lhs; gIter != NULL; gIter = gIter->next) {
565 if (constraint->
score == 0) {
568 pe_rsc_trace(rsc,
"Merging score of '%s' constraint (%s with %s)",
579 pe_rsc_trace(rsc,
"Making sure %s doesn't get allocated", rsc->
id);
586 crm_notice(
"Resource %s cannot be elevated from %s to %s: no-quorum-policy=freeze",
598 const char *reason = NULL;
602 assign_to = pe__current_node(rsc);
603 if (assign_to == NULL) {
612 pe_rsc_info(rsc,
"Unmanaged resource %s allocated to %s: %s", rsc->
id,
613 (assign_to? assign_to->
details->
uname :
"no node"), reason);
621 && native_choose_node(rsc, prefer, data_set)) {
627 pe_rsc_info(rsc,
"Resource %s cannot run anywhere", rsc->
id);
644 crm_trace(
"Setting Pacemaker Remote node %s to ONLINE",
654 crm_trace(
"Setting Pacemaker Remote node %s to SHUTDOWN (next role %s, %sallocated)",
667 gboolean dup = FALSE;
668 const char *
id = NULL;
669 const char *value = NULL;
670 xmlNode *operation = NULL;
671 guint interval2_ms = 0;
674 for (operation = pcmk__xe_first_child(rsc->
ops_xml); operation != NULL;
675 operation = pcmk__xe_next(operation)) {
677 if (pcmk__str_eq((
const char *)operation->name,
"op",
pcmk__str_none)) {
685 if (interval_ms != interval2_ms) {
694 "same name and interval combination more " 695 "than once per resource)",
ID(operation),
id);
705 op_cannot_recur(
const char *
name)
715 const char *
name = NULL;
716 const char *role = NULL;
717 const char *interval_spec = NULL;
718 const char *node_uname = node? node->
details->
uname :
"n/a";
720 guint interval_ms = 0;
722 gboolean is_optional = TRUE;
735 if (interval_ms == 0) {
740 if (is_op_dup(rsc,
name, interval_ms)) {
741 crm_trace(
"Not creating duplicate recurring action %s for %dms %s",
742 ID(operation), interval_ms,
name);
746 if (op_cannot_recur(
name)) {
754 crm_trace(
"Not creating recurring action %s for disabled resource %s",
755 ID(operation), rsc->
id);
760 pe_rsc_trace(rsc,
"Creating recurring action %s for %s in role %s on %s",
775 if (possible_matches == NULL) {
777 pe_rsc_trace(rsc,
"Marking %s mandatory: not active", key);
782 for (gIter = possible_matches; gIter != NULL; gIter = gIter->next) {
790 g_list_free(possible_matches);
796 const char *result =
"Ignoring";
799 char *after_key = NULL;
803 log_level = LOG_INFO;
804 result =
"Cancelling";
831 do_crm_log(log_level,
"%s action %s (%s vs. %s)",
846 pe_rsc_debug(rsc,
"%s\t %s (cancelled : start un-runnable)",
847 node_uname, mon->
uuid);
852 pe_rsc_debug(rsc,
"%s\t %s (cancelled : no node available)",
853 node_uname, mon->
uuid);
858 pe_rsc_info(rsc,
" Start recurring %s (%us) for %s on %s",
859 mon->
task, interval_ms / 1000, rsc->
id, node_uname);
866 free(running_master);
871 NULL, strdup(key), mon,
875 NULL, strdup(key), mon,
896 xmlNode *operation = NULL;
898 for (operation = pcmk__xe_first_child(rsc->
ops_xml);
900 operation = pcmk__xe_next(operation)) {
902 if (pcmk__str_eq((
const char *)operation->name,
"op",
pcmk__str_none)) {
903 RecurringOp(rsc, start, node, operation, data_set);
914 const char *
name = NULL;
915 const char *role = NULL;
916 const char *interval_spec = NULL;
917 const char *node_uname = node? node->
details->
uname :
"n/a";
919 guint interval_ms = 0;
931 if (interval_ms == 0) {
936 if (is_op_dup(rsc,
name, interval_ms)) {
937 crm_trace(
"Not creating duplicate recurring action %s for %dms %s",
938 ID(operation), interval_ms,
name);
942 if (op_cannot_recur(
name)) {
950 crm_trace(
"Not creating recurring action %s for disabled resource %s",
951 ID(operation), rsc->
id);
958 crm_notice(
"Ignoring %s (recurring monitors for Stopped role are " 959 "not supported for anonymous clones)",
965 "Creating recurring action %s for %s in role %s on nodes where it should not be running",
971 if (possible_matches) {
974 g_list_free(possible_matches);
985 pe_rsc_info(rsc,
"Cancel action %s (%s vs. %s) on %s",
990 for (gIter = data_set->
nodes; gIter != NULL; gIter = gIter->next) {
992 const char *stop_node_uname = stop_node->
details->
uname;
993 gboolean is_optional = TRUE;
994 gboolean probe_is_optional = TRUE;
995 gboolean stop_is_optional = TRUE;
997 char *rc_inactive = NULL;
1002 if (node && pcmk__str_eq(stop_node_uname, node_uname,
pcmk__str_casei)) {
1006 pe_rsc_trace(rsc,
"Creating recurring action %s for %s on %s",
1007 ID(operation), rsc->
id,
crm_str(stop_node_uname));
1011 if (possible_matches == NULL) {
1012 pe_rsc_trace(rsc,
"Marking %s mandatory on %s: not active", key,
1014 is_optional = FALSE;
1016 pe_rsc_trace(rsc,
"Marking %s optional on %s: already active", key,
1019 g_list_free(possible_matches);
1022 stopped_mon =
custom_action(rsc, strdup(key),
name, stop_node, is_optional, TRUE, data_set);
1033 for (pIter = probes; pIter != NULL; pIter = pIter->next) {
1040 g_list_free(probes);
1043 if (probe_complete_ops) {
1044 g_list_free(probe_complete_ops);
1049 for (local_gIter = stop_ops; local_gIter != NULL; local_gIter = local_gIter->next) {
1053 stop_is_optional = FALSE;
1057 crm_debug(
"%s\t %s (cancelled : stop un-runnable)",
1058 crm_str(stop_node_uname), stopped_mon->uuid);
1060 __func__, __LINE__);
1065 NULL, strdup(key), stopped_mon,
1072 g_list_free(stop_ops);
1075 if (is_optional == FALSE && probe_is_optional && stop_is_optional
1077 pe_rsc_trace(rsc,
"Marking %s optional on %s due to unmanaged",
1078 key,
crm_str(stop_node_uname));
1088 pe_rsc_debug(rsc,
"%s\t %s (cancelled : no node available)",
1089 crm_str(stop_node_uname), stopped_mon->uuid);
1091 __func__, __LINE__);
1096 crm_notice(
" Start recurring %s (%us) for %s on %s", stopped_mon->task,
1097 interval_ms / 1000, rsc->
id,
crm_str(stop_node_uname));
1109 xmlNode *operation = NULL;
1111 for (operation = pcmk__xe_first_child(rsc->
ops_xml);
1113 operation = pcmk__xe_next(operation)) {
1115 if (pcmk__str_eq((
const char *)operation->name,
"op",
pcmk__str_none)) {
1116 RecurringOp_Stopped(rsc, start, node, operation, data_set);
1131 pe_rsc_trace(rsc,
"Processing migration actions %s moving from %s to %s . partial migration = %s",
1136 if (partial == FALSE) {
1144 if ((migrate_to && migrate_from) || (migrate_from && partial)) {
1217 gboolean need_stop = FALSE;
1218 bool need_promote = FALSE;
1219 gboolean is_moving = FALSE;
1223 unsigned int num_all_active = 0;
1224 unsigned int num_clean_active = 0;
1225 bool multiply_active = FALSE;
1235 pe_rsc_trace(rsc,
"Creating all actions for %s transition from %s to %s (%s) on %s",
1238 ((chosen == NULL)?
"no node" : chosen->
details->
uname));
1247 pe_rsc_trace(rsc,
"Creating stop action %s cleanup for %s on %s due to dangling migration",
1253 DeleteRsc(rsc, dangling_source, FALSE, data_set);
1257 if ((num_all_active == 2) && (num_clean_active == 2) && chosen
1266 pe_rsc_trace(rsc,
"Will attempt to continue with partial migration " 1267 "to target %s from %s",
1279 multiply_active = (num_clean_active > 1);
1281 multiply_active = (num_all_active > 1);
1284 if (multiply_active) {
1287 crm_notice(
"Resource %s can no longer migrate from %s to %s " 1288 "(will stop on both nodes)",
1294 pe_proc_err(
"Resource %s is active on %u nodes (%s)",
1295 rsc->
id, num_all_active,
1297 crm_notice(
"See https://wiki.clusterlabs.org/wiki/FAQ#Resource_is_Too_Active for more information");
1308 allow_migrate = FALSE;
1312 pe_rsc_trace(rsc,
"Creating start action for %s to represent already pending start",
1332 need_promote = TRUE;
1341 pe_rsc_trace(rsc,
"Creating start action for promoted resource %s",
1346 pe_rsc_trace(rsc,
"%s restart is required for recovery", rsc->
id);
1357 pe_rsc_trace(rsc,
"Creating %s action to take %s down from %s to %s",
1358 (need_stop?
"required" :
"optional"), rsc->
id,
1360 if (rsc_action_matrix[role][next_role] (rsc, current, !need_stop, data_set) == FALSE) {
1369 bool required = need_stop;
1371 next_role = rsc_state_matrix[role][rsc->
role];
1375 pe_rsc_trace(rsc,
"Creating %s action to take %s up from %s to %s",
1376 (required?
"required" :
"optional"), rsc->
id,
1378 if (rsc_action_matrix[role][next_role](rsc, chosen, !required,
1379 data_set) == FALSE) {
1388 next_role = rsc_state_matrix[role][rsc->
next_role];
1389 pe_rsc_trace(rsc,
"Creating action to take %s from %s to %s (ending at %s)",
1392 if (rsc_action_matrix[role][next_role] (rsc, chosen, FALSE, data_set) == FALSE) {
1399 pe_rsc_trace(rsc,
"Not creating recurring monitors for blocked resource %s",
1404 pe_rsc_trace(rsc,
"Creating recurring monitors for %s resource %s",
1408 Recurring(rsc, start, chosen, data_set);
1409 Recurring_Stopped(rsc, start, chosen, data_set);
1412 pe_rsc_trace(rsc,
"Creating recurring monitors for inactive resource %s",
1414 Recurring_Stopped(rsc, NULL, NULL, data_set);
1421 pe_rsc_trace(rsc,
"Not allowing partial migration of %s to continue",
1423 allow_migrate = FALSE;
1426 || pcmk_any_flags_set(rsc->
flags,
1431 allow_migrate = FALSE;
1434 if (allow_migrate) {
1435 handle_migration_actions(rsc, current, chosen, data_set);
1442 GHashTableIter iter;
1445 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node)) {
1446 if (node->details->remote_rsc) {
1469 GList *allowed_nodes = NULL;
1472 allowed_nodes = g_hash_table_get_values(rsc->
allowed_nodes);
1478 return allowed_nodes;
1487 GList *allowed_nodes = NULL;
1488 bool check_unfencing = FALSE;
1489 bool check_utilization = FALSE;
1493 "Skipping native constraints for unmanaged resource: %s",
1506 check_utilization = (g_hash_table_size(rsc->
utilization) > 0)
1536 if (check_unfencing || check_utilization || rsc->
container) {
1537 allowed_nodes = allowed_nodes_as_list(rsc, data_set);
1540 if (check_unfencing) {
1543 for (GList *item = allowed_nodes; item; item = item->next) {
1547 crm_debug(
"Ordering any stops of %s before %s, and any starts after",
1566 NULL, strdup(unfence->
uuid), unfence,
1576 if (check_utilization) {
1579 pe_rsc_trace(rsc,
"Creating utilization constraints for %s - strategy: %s",
1582 for (gIter = rsc->
running_on; gIter != NULL; gIter = gIter->next) {
1589 if (load_stopped->
node == NULL) {
1592 __func__, __LINE__);
1596 NULL, load_stopped_task, load_stopped,
pe_order_load, data_set);
1599 for (GList *item = allowed_nodes; item; item = item->next) {
1605 if (load_stopped->
node == NULL) {
1608 __func__, __LINE__);
1618 free(load_stopped_task);
1633 rsc_avoids_remote_nodes(rsc->
container);
1663 for (GList *item = allowed_nodes; item; item = item->next) {
1678 crm_trace(
"Order and colocate %s relative to its container %s",
1706 rsc_avoids_remote_nodes(rsc);
1708 g_list_free(allowed_nodes);
1716 if (rsc_lh == NULL) {
1717 pe_err(
"rsc_lh was NULL for %s", constraint->
id);
1720 }
else if (constraint->
rsc_rh == NULL) {
1721 pe_err(
"rsc_rh was NULL for %s", constraint->
id);
1725 if (constraint->
score == 0) {
1728 pe_rsc_trace(rsc_lh,
"Processing colocation constraint between %s and %s", rsc_lh->
id,
1738 if (constraint->
score == 0) {
1768 if ((rh_node == NULL)
1770 crm_err(
"%s must be colocated with %s but is not (%s vs. %s)",
1771 rsc_lh->
id, rsc_rh->
id,
1779 if ((rh_node != NULL)
1781 crm_err(
"%s and %s must be anti-colocated but are allocated " 1782 "to the same node (%s)",
1789 if (constraint->
score > 0
1791 crm_trace(
"LH: Skipping constraint: \"%s\" state filter nextrole is %s",
1796 if (constraint->
score > 0
1802 if (constraint->
score < 0
1804 crm_trace(
"LH: Skipping negative constraint: \"%s\" state filter",
1809 if (constraint->
score < 0
1811 crm_trace(
"RH: Skipping negative constraint: \"%s\" state filter",
1822 const char *rh_value = NULL;
1823 const char *lh_value = NULL;
1825 int score_multiplier = 1;
1827 if (constraint->
score == 0) {
1853 score_multiplier = -1;
1864 const char *value = NULL;
1865 GHashTable *work = NULL;
1866 GHashTableIter iter;
1869 if (constraint->
score == 0) {
1879 }
else if (constraint->
score < 0) {
1886 g_hash_table_iter_init(&iter, work);
1887 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node)) {
1890 constraint->
id, rsc_lh->
id, node->details->uname,
1891 constraint->
score, rsc_rh->
id);
1897 constraint->
id, rsc_lh->
id,
1898 node->details->uname, constraint->
score);
1904 constraint->
id, rsc_lh->
id, node->details->uname,
1905 constraint->
score, attribute);
1918 "%s: Rolling back scores from %s (no available nodes)",
1919 rsc_lh->
id, rsc_rh->
id);
1923 g_hash_table_destroy(work);
1937 pe_rsc_trace(rsc_lh,
"%s %s with %s (%s, score=%d, filter=%d)",
1938 ((constraint->
score >= 0)?
"Colocating" :
"Anti-colocating"),
1939 rsc_lh->
id, rsc_rh->
id, constraint->
id, constraint->
score, filter_results);
1941 switch (filter_results) {
1943 influence_priority(rsc_lh, rsc_rh, constraint);
1946 colocation_match(rsc_lh, rsc_rh, constraint);
1958 pe_rsc_trace(rsc_lh,
"LH: Skipping constraint: \"%s\" state filter",
1969 if (rsc_ticket == NULL) {
1970 pe_err(
"rsc_ticket was NULL");
1974 if (rsc_lh == NULL) {
1975 pe_err(
"rsc_lh was NULL for %s", rsc_ticket->
id);
1986 pe_rsc_trace(rsc_lh,
"Processing ticket dependencies from %s", rsc_lh->
id);
1988 for (; gIter != NULL; gIter = gIter->next) {
1996 pe_rsc_trace(rsc_lh,
"%s: Processing ticket dependency on %s (%s, %s)",
2018 if (filter_rsc_ticket(rsc_lh, rsc_ticket) == FALSE) {
2024 for (gIter = rsc_lh->
running_on; gIter != NULL; gIter = gIter->next) {
2027 pe_fence_node(data_set, node,
"deadman ticket was lost", FALSE);
2032 if (filter_rsc_ticket(rsc_lh, rsc_ticket) == FALSE) {
2083 const char *reason = NULL;
2106 if (reason == NULL) {
2145 crm_trace(
"Testing %s on %s (0x%.6x) with %s 0x%.6x",
2193 pe_rsc_trace(first->
rsc,
"Unset migrate runnable on %s because of %s",
2221 pe_rsc_trace(then->
rsc,
"Unset runnable on %s because %s is neither runnable or migratable", first->
uuid, then->
uuid);
2264 handle_restart_ordering(first, then, filter);
2267 if (then_flags != then->
flags) {
2270 "Then: Flags for %s on %s are now 0x%.6x (was 0x%.6x) because of %s 0x%.6x",
2280 if (first_flags != first->
flags) {
2283 "First: Flags for %s on %s are now 0x%.6x (was 0x%.6x) because of %s 0x%.6x",
2295 bool need_role =
false;
2297 CRM_CHECK((constraint != NULL) && (rsc != NULL),
return);
2303 "Not applying %s to %s because role will be %s not %s",
2310 pe_rsc_trace(rsc,
"Not applying %s to %s because no nodes match",
2311 constraint->
id, rsc->
id);
2316 (need_role?
" for role " :
""),
2319 for (gIter = constraint->
node_list_rh; gIter != NULL; gIter = gIter->next) {
2325 if (other_node != NULL) {
2335 g_hash_table_insert(rsc->
allowed_nodes, (gpointer) other_node->details->id, other_node);
2338 if (other_node->rsc_discover_mode < constraint->
discover_mode) {
2356 for (gIter = rsc->
actions; gIter != NULL; gIter = gIter->next) {
2363 for (gIter = rsc->
children; gIter != NULL; gIter = gIter->next) {
2366 child_rsc->
cmds->
expand(child_rsc, data_set);
2370 #define log_change(a, fmt, args...) do { \ 2371 if(a && a->reason && terminal) { \ 2372 printf(" * "fmt" \tdue to %s\n", ##args, a->reason); \ 2373 } else if(a && a->reason) { \ 2374 crm_notice(fmt" \tdue to %s", ##args, a->reason); \ 2375 } else if(terminal) { \ 2376 printf(" * "fmt"\n", ##args); \ 2378 crm_notice(fmt, ##args); \ 2382 #define STOP_SANITY_ASSERT(lineno) do { \ 2383 if(current && current->details->unclean) { \ 2385 } else if(stop == NULL) { \ 2386 crm_err("%s:%d: No stop action exists for %s", \ 2387 __func__, lineno, rsc->id); \ 2388 CRM_ASSERT(stop != NULL); \ 2389 } else if (pcmk_is_set(stop->flags, pe_action_optional)) { \ 2390 crm_err("%s:%d: Action %s is still optional", \ 2391 __func__, lineno, stop->uuid); \ 2392 CRM_ASSERT(!pcmk_is_set(stop->flags, pe_action_optional)); \ 2400 char *reason = NULL;
2401 char *details = NULL;
2402 bool same_host = FALSE;
2403 bool same_role = FALSE;
2404 bool need_role = FALSE;
2406 static int rsc_width = 5;
2407 static int detail_width = 5;
2410 CRM_ASSERT(destination != NULL || origin != NULL);
2412 if(source == NULL) {
2416 len = strlen(rsc->
id);
2417 if(len > rsc_width) {
2418 rsc_width = len + 2;
2425 if(origin != NULL && destination != NULL && origin->
details == destination->
details) {
2433 if (need_role && (origin == NULL)) {
2437 }
else if (origin == NULL) {
2441 }
else if (need_role && (destination == NULL)) {
2445 }
else if (destination == NULL) {
2449 }
else if (need_role && same_role && same_host) {
2453 }
else if (same_role && same_host) {
2457 }
else if (need_role && same_role) {
2461 }
else if (same_role) {
2465 }
else if (same_host) {
2474 len = strlen(details);
2475 if(len > detail_width) {
2482 }
else if(source->
reason) {
2486 reason = strdup(
" blocked");
2489 reason = strdup(
"");
2493 printf(
" * %-8s %-*s ( %*s ) %s\n", change, rsc_width, rsc->
id, detail_width, details, reason);
2495 crm_notice(
" * %-8s %-*s ( %*s ) %s", change, rsc_width, rsc->
id, detail_width, details, reason);
2516 gboolean moving = FALSE;
2527 for (gIter = rsc->
children; gIter != NULL; gIter = gIter->next) {
2537 current = pe__current_node(rsc);
2553 || (current == NULL && next == NULL)) {
2565 if (possible_matches) {
2566 start = possible_matches->data;
2567 g_list_free(possible_matches);
2573 start_node = current;
2576 if (possible_matches) {
2577 stop = possible_matches->data;
2578 g_list_free(possible_matches);
2582 if (possible_matches) {
2583 promote = possible_matches->data;
2584 g_list_free(possible_matches);
2588 if (possible_matches) {
2589 demote = possible_matches->data;
2590 g_list_free(possible_matches);
2597 if (possible_matches) {
2598 migrate_op = possible_matches->data;
2603 }
else if ((migrate_op != NULL) && (current != NULL)
2605 LogAction(
"Migrate", rsc, current, next, start, NULL, terminal);
2608 LogAction(
"Reload", rsc, current, next, start, NULL, terminal);
2612 if ((demote != NULL) && (promote != NULL)
2615 LogAction(
"Re-promote", rsc, current, next, promote, demote,
2623 LogAction(
"Stop", rsc, current, NULL, stop,
2624 (stop && stop->
reason)? stop : start, terminal);
2627 }
else if (moving && current) {
2629 rsc, current, next, stop, NULL, terminal);
2632 LogAction(
"Recover", rsc, current, NULL, stop, NULL, terminal);
2636 LogAction(
"Restart", rsc, current, next, start, NULL, terminal);
2640 g_list_free(possible_matches);
2651 for (gIter = rsc->
running_on; gIter != NULL; gIter = gIter->next) {
2656 if (possible_matches) {
2657 stop_op = possible_matches->data;
2658 g_list_free(possible_matches);
2665 LogAction(
"Stop", rsc, node, NULL, stop_op,
2666 (stop_op && stop_op->reason)? stop_op : start, terminal);
2671 }
else if ((stop != NULL)
2674 LogAction(
"Recover", rsc, current, next, stop, start, terminal);
2677 }
else if (moving) {
2678 LogAction(
"Move", rsc, current, next, stop, NULL, terminal);
2682 LogAction(
"Reload", rsc, current, next, start, NULL, terminal);
2685 LogAction(
"Restart", rsc, current, next, start, NULL, terminal);
2690 LogAction(
"Demote", rsc, current, next, demote, NULL, terminal);
2694 LogAction(
"Promote", rsc, current, next, promote, NULL, terminal);
2697 LogAction(
"Start", rsc, current, next, start, NULL, terminal);
2709 for (gIter = rsc->
running_on; gIter != NULL; gIter = gIter->next) {
2733 __func__, __LINE__);
2737 DeleteRsc(rsc, current, optional, data_set);
2744 if (!node_has_been_unfenced(current)) {
2764 if (is_unfence_device(rsc, data_set)
2775 if (!node_has_been_unfenced(node)) {
2799 __func__, __LINE__);
2810 gboolean runnable = TRUE;
2819 for (gIter = action_list; gIter != NULL; gIter = gIter->next) {
2826 g_list_free(action_list);
2837 for (gIter = action_list; gIter != NULL; gIter = gIter->next) {
2841 __func__, __LINE__);
2844 g_list_free(action_list);
2857 for (gIter = rsc->
running_on; gIter != NULL; gIter = gIter->next) {
2890 }
else if (node == NULL) {
2891 pe_rsc_trace(rsc,
"Resource %s not deleted: NULL node", rsc->
id);
2895 pe_rsc_trace(rsc,
"Resource %s not deleted from %s: unrunnable", rsc->
id,
2924 static const char *rc_master = NULL;
2925 static const char *rc_inactive = NULL;
2927 if (rc_inactive == NULL) {
2934 pe_rsc_trace(rsc,
"Skipping active resource detection for %s", rsc->
id);
2943 "Skipping probe for %s on %s because Pacemaker Remote nodes cannot run stonith agents",
2949 "Skipping probe for %s on %s because guest nodes cannot run resources containing guest nodes",
2952 }
else if (rsc->is_remote_node) {
2954 "Skipping probe for %s on %s because Pacemaker Remote nodes cannot host remote connections",
2962 gboolean any_created = FALSE;
2964 for (gIter = rsc->
children; gIter != NULL; gIter = gIter->next) {
2967 any_created = child_rsc->
cmds->
create_probe(child_rsc, node, complete, force, data_set)
2992 if (allowed == NULL) {
3053 pe_rsc_trace(rsc,
"Skipping probe for %s on node %s, %s is stopped",
3074 pe_rsc_trace(rsc,
"Skipping probe for %s on node %s, %s is stopping, restarting or moving",
3095 if (running == NULL) {
3105 if (is_unfence_device(rsc, data_set) || !pe_rsc_is_clone(top)) {
3130 if (!is_unfence_device(rsc, data_set)) {
3159 && pe_rsc_is_anon_clone(rsc->
parent)
3187 for (gIter = rsc->
actions; gIter != NULL; gIter = gIter->next) {
3202 && !rsc_is_known_on(rsc,
target)) {
3228 bool order_implicit =
false;
3249 order_implicit =
true;
3252 if (action_list && order_implicit) {
3256 for (gIter = action_list; gIter != NULL; gIter = gIter->next) {
3261 __func__, __LINE__);
3263 if (order_implicit) {
3265 __func__, __LINE__);
3279 if (!pe_rsc_is_bundled(rsc)) {
3286 crm_notice(
"Stop of failed resource %s is implicit %s %s is fenced",
3287 rsc->
id, (order_implicit?
"after" :
"because"),
3290 crm_info(
"%s is implicit %s %s is fenced",
3291 action->uuid, (order_implicit?
"after" :
"because"),
3351 g_list_free(action_list);
3356 for (gIter = action_list; gIter != NULL; gIter = gIter->next) {
3359 if (
action->node->details->online == FALSE ||
action->node->details->unclean == TRUE
3364 "Demote of failed resource %s is implicit after %s is fenced",
3367 pe_rsc_info(rsc,
"%s is implicit after %s is fenced",
3375 __func__, __LINE__);
3377 if (pe_rsc_is_bundled(rsc)) {
3380 }
else if (order_implicit) {
3386 g_list_free(action_list);
3395 for (gIter = rsc->
children; gIter != NULL; gIter = gIter->next) {
3402 pe_rsc_trace(rsc,
"Skipping fencing constraints for unmanaged resource: %s", rsc->
id);
3405 native_start_constraints(rsc, stonith_op, data_set);
3406 native_stop_constraints(rsc, stonith_op, data_set);
3417 for (gIter = rsc->
children; gIter != NULL; gIter = gIter->next) {
3436 pe_rsc_trace(rsc,
"%s: preventing reload because failed", rsc->
id);
3443 pe_rsc_trace(rsc,
"%s: preventing reload because start pending", rsc->
id);
3447 }
else if (node == NULL) {
3490 for (parent = rsc; parent != NULL; parent = parent->
parent) {
pe_action_t * pe_cancel_op(pe_resource_t *rsc, const char *name, guint interval_ms, pe_node_t *node, pe_working_set_t *data_set)
#define CRM_CHECK(expr, failure_action)
gboolean rsc_colocation_new(const char *id, const char *node_attr, int score, pe_resource_t *rsc_lh, pe_resource_t *rsc_rh, const char *state_lh, const char *state_rh, pe_working_set_t *data_set)
enum rsc_role_e role_filter
enum rsc_start_requirement needs
enum pe_quorum_policy no_quorum_policy
#define crm_notice(fmt, args...)
bool pe__is_guest_or_remote_node(const pe_node_t *node)
#define pe_rsc_debug(rsc, fmt, args...)
#define pe__set_action_flags(action, flags_to_set)
GListPtr dangling_migrations
#define promote_action(rsc, node, optional)
GList * sort_nodes_by_weight(GList *nodes, pe_node_t *active_node, pe_working_set_t *data_set)
#define stop_action(rsc, node, optional)
pe_node_t * pe__find_active_on(const pe_resource_t *rsc, unsigned int *count_all, unsigned int *count_clean)
pe_resource_t * container
bool pcmk__strcase_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
pe_node_t * partial_migration_source
gboolean PromoteRsc(pe_resource_t *rsc, pe_node_t *next, gboolean optional, pe_working_set_t *data_set)
resource_alloc_functions_t * cmds
#define pe_action_implies(action, reason, flag)
#define pcmk__config_err(fmt...)
#define delete_action(rsc, node, optional)
enum filter_colocation_res filter_colocation_constraint(pe_resource_t *rsc_lh, pe_resource_t *rsc_rh, rsc_colocation_t *constraint, gboolean preview)
#define pe_flag_remove_after_stop
#define XML_RSC_ATTR_INCARNATION
enum rsc_role_e next_role
#define pe__show_node_weights(level, rsc, text, nodes)
gboolean exclusive_discover
gboolean StartRsc(pe_resource_t *rsc, pe_node_t *next, gboolean optional, pe_working_set_t *data_set)
pe_resource_t * remote_rsc
void pcmk__bundle_log_actions(pe_resource_t *rsc, pe_working_set_t *data_set, gboolean terminal)
char * score2char_stack(int score, char *buf, size_t len)
resource_object_functions_t * fns
#define clear_node_weights_flags(nw_flags, nw_rsc, flags_to_clear)
#define XML_LRM_ATTR_INTERVAL
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
pe_node_t * pe__copy_node(const pe_node_t *this_node)
enum pe_graph_flags native_update_actions(pe_action_t *first, pe_action_t *then, pe_node_t *node, enum pe_action_flags flags, enum pe_action_flags filter, enum pe_ordering type, pe_working_set_t *data_set)
#define CRM_LOG_ASSERT(expr)
pe_node_t * pe_find_node(GListPtr node_list, const char *uname)
void resource_location(pe_resource_t *rsc, pe_node_t *node, int score, const char *tag, pe_working_set_t *data_set)
guint crm_parse_interval_spec(const char *input)
Parse milliseconds from a Pacemaker interval specification.
pe_node_t * partial_migration_target
pe_node_t *(* allocate)(pe_resource_t *, pe_node_t *, pe_working_set_t *)
gboolean RoleError(pe_resource_t *rsc, pe_node_t *next, gboolean optional, pe_working_set_t *data_set)
#define pe_rsc_allow_remote_remotes
gboolean can_run_resources(const pe_node_t *node)
#define pe_flag_have_quorum
#define CRM_SCORE_INFINITY
#define pe_proc_err(fmt...)
gboolean remote_requires_reset
gboolean native_assign_node(pe_resource_t *rsc, GListPtr candidates, pe_node_t *chosen, gboolean force)
pe_node_t * pe_find_node_id(GListPtr node_list, const char *id)
char * crm_meta_name(const char *field)
void native_rsc_colocation_lh(pe_resource_t *rsc_lh, pe_resource_t *rsc_rh, rsc_colocation_t *constraint, pe_working_set_t *data_set)
#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_flag_stop_everything
#define demote_action(rsc, node, optional)
#define pe_rsc_provisional
const char * role2text(enum rsc_role_e role)
#define CRM_ATTR_UNFENCED
enum pe_discover_e discover_mode
void pe_action_set_reason(pe_action_t *action, const char *reason, bool overwrite)
gboolean(* create_probe)(pe_resource_t *, pe_node_t *, pe_action_t *, gboolean, pe_working_set_t *)
gboolean DemoteRsc(pe_resource_t *rsc, pe_node_t *next, gboolean optional, pe_working_set_t *data_set)
#define pe_rsc_allow_migrate
pe_action_t * get_pseudo_op(const char *name, pe_working_set_t *data_set)
#define crm_debug(fmt, args...)
void native_expand(pe_resource_t *rsc, pe_working_set_t *data_set)
gboolean(* rsc_transition_fn)(pe_resource_t *rsc, pe_node_t *next, gboolean optional, pe_working_set_t *data_set)
pe_resource_t * uber_parent(pe_resource_t *rsc)
void(* rsc_colocation_rh)(pe_resource_t *, pe_resource_t *, rsc_colocation_t *, pe_working_set_t *)
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
void native_internal_constraints(pe_resource_t *rsc, pe_working_set_t *data_set)
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)
const char * node_attribute
void native_append_meta(pe_resource_t *rsc, xmlNode *xml)
#define pe_rsc_start_pending
gboolean update_action(pe_action_t *action, pe_working_set_t *data_set)
#define pe__clear_action_flags(action, flags_to_clear)
int custom_action_order(pe_resource_t *lh_rsc, char *lh_task, pe_action_t *lh_action, pe_resource_t *rh_rsc, char *rh_task, pe_action_t *rh_action, enum pe_ordering type, pe_working_set_t *data_set)
#define crm_trace(fmt, args...)
#define do_crm_log(level, fmt, args...)
Log a message.
void pe_fence_node(pe_working_set_t *data_set, pe_node_t *node, const char *reason, bool priority_delay)
Schedule a fence action for a node.
void process_utilization(pe_resource_t *rsc, pe_node_t **prefer, pe_working_set_t *data_set)
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
GListPtr find_actions(GListPtr input, const char *key, const pe_node_t *on_node)
struct pe_node_shared_s * details
enum rsc_recovery_type recovery_type
enum loss_ticket_policy_e loss_policy
#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
void(* expand)(pe_resource_t *, pe_working_set_t *)
xmlNode * find_rsc_op_entry(pe_resource_t *rsc, const char *key)
#define pe_flag_stonith_enabled
const char * pe_node_attribute_raw(pe_node_t *node, const char *name)
#define pe__set_graph_flags(graph_flags, gr_action, flags_to_set)
#define XML_RSC_ATTR_TARGET_ROLE
#define XML_LRM_ATTR_MIGRATE_TARGET
#define XML_RSC_ATTR_REMOTE_NODE
gboolean update_action_flags(pe_action_t *action, enum pe_action_flags flags, const char *source, int line)
enum pe_action_flags(* action_flags)(pe_action_t *, pe_node_t *)
#define pe_rsc_allocating
enum rsc_role_e text2role(const char *role)
enum pe_obj_types variant
int new_rsc_order(pe_resource_t *lh_rsc, const char *lh_task, pe_resource_t *rh_rsc, const char *rh_task, enum pe_ordering type, pe_working_set_t *data_set)
void native_rsc_location(pe_resource_t *rsc, pe__location_t *constraint)
const char * placement_strategy
gboolean can_run_any(GHashTable *nodes)
char * pcmk__op_key(const char *rsc_id, const char *op_type, guint interval_ms)
Generate an operation key (RESOURCE_ACTION_INTERVAL)
#define CRMD_ACTION_RELOAD
#define pe_rsc_fence_device
void native_rsc_colocation_rh(pe_resource_t *rsc_lh, pe_resource_t *rsc_rh, rsc_colocation_t *constraint, pe_working_set_t *data_set)
GHashTable * pcmk__copy_node_table(GHashTable *nodes)
#define PCMK_RESOURCE_CLASS_STONITH
enum pe_action_flags native_action_flags(pe_action_t *action, pe_node_t *node)
enum rsc_role_e(* state)(const pe_resource_t *, gboolean)
void(* rsc_colocation_lh)(pe_resource_t *, pe_resource_t *, rsc_colocation_t *, pe_working_set_t *)
void ReloadRsc(pe_resource_t *rsc, pe_node_t *node, pe_working_set_t *data_set)
#define STOP_SANITY_ASSERT(lineno)
void add_hash_param(GHashTable *hash, const char *name, const char *value)
#define start_action(rsc, node, optional)
int pe__add_scores(int score1, int score2)
#define crm_err(fmt, args...)
gboolean StopRsc(pe_resource_t *rsc, pe_node_t *next, gboolean optional, pe_working_set_t *data_set)
pe_node_t * pcmk__native_allocate(pe_resource_t *rsc, pe_node_t *prefer, pe_working_set_t *data_set)
void rsc_stonith_ordering(pe_resource_t *rsc, pe_action_t *stonith_op, pe_working_set_t *data_set)
#define pe_rsc_needs_unfencing
void native_create_actions(pe_resource_t *rsc, pe_working_set_t *data_set)
#define pe__clear_resource_flags(resource, flags_to_clear)
void LogActions(pe_resource_t *rsc, pe_working_set_t *data_set, gboolean terminal)
GHashTable * pcmk__native_merge_weights(pe_resource_t *rsc, const char *rhs, GHashTable *nodes, const char *attr, float factor, uint32_t flags)
enum pe_action_flags flags
#define pe_rsc_maintenance
#define XML_OP_ATTR_PENDING
gboolean DeleteRsc(pe_resource_t *rsc, pe_node_t *node, gboolean optional, pe_working_set_t *data_set)
#define pe_flag_have_stonith_resource
GList * find_actions_exact(GList *input, const char *key, const pe_node_t *on_node)
#define pe_flag_enable_unfencing
#define pe_rsc_trace(rsc, fmt, args...)
#define pe__set_order_flags(order_flags, flags_to_set)
void rsc_ticket_constraint(pe_resource_t *rsc_lh, rsc_ticket_t *rsc_ticket, pe_working_set_t *data_set)
pe_action_t * find_first_action(GListPtr input, const char *uuid, const char *task, pe_node_t *on_node)
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 XML_LRM_ATTR_MIGRATE_SOURCE
gboolean native_create_probe(pe_resource_t *rsc, pe_node_t *node, pe_action_t *complete, gboolean force, pe_working_set_t *data_set)
#define CRM_OP_LRM_DELETE
gint sort_node_uname(gconstpointer a, gconstpointer b)
char * crm_strdup_printf(char const *format,...) __attribute__((__format__(__printf__
void graph_element_from_action(pe_action_t *action, pe_working_set_t *data_set)
#define crm_info(fmt, args...)
#define XML_ATTR_TE_TARGET_RC
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)
GHashTable *(* merge_weights)(pe_resource_t *, const char *, GHashTable *, const char *, float, enum pe_weights)
enum crm_ais_msg_types type
#define pe_rsc_info(rsc, fmt, args...)
gboolean NullOp(pe_resource_t *rsc, pe_node_t *next, gboolean optional, pe_working_set_t *data_set)
void create_secondary_notification(pe_action_t *action, pe_resource_t *rsc, pe_action_t *stonith_op, pe_working_set_t *data_set)
#define XML_AGENT_ATTR_CLASS
pe_action_t * custom_action(pe_resource_t *rsc, char *key, const char *task, pe_node_t *on_node, gboolean optional, gboolean foo, pe_working_set_t *data_set)
GHashTable * allowed_nodes
#define pe_flag_startup_probes