20 #define INFINITY_HACK (INFINITY * -100)
22 #define VARIANT_NATIVE 1
76 node_t *chosen = NULL;
80 gboolean result = FALSE;
97 best = g_list_nth_data(nodes, 0);
100 if (prefer && nodes) {
103 if (chosen == NULL) {
104 pe_rsc_trace(rsc,
"Preferred node %s for %s was unknown",
114 pe_rsc_trace(rsc,
"Preferred node %s for %s was unsuitable",
119 pe_rsc_trace(rsc,
"Preferred node %s for %s was unavailable",
125 "Chose preferred node %s for %s (ignoring %d candidates)",
130 if ((chosen == NULL) && nodes) {
136 pe_rsc_trace(rsc,
"Chose node %s for %s from %d candidates",
139 if (!pe_rsc_is_unique_clone(rsc->
parent)
150 node_t *running = pe__current_node(rsc);
153 pe_rsc_trace(rsc,
"Current node for %s (%s) can't run resources",
155 }
else if (running) {
156 for (GList *iter = nodes->next; iter; iter = iter->next) {
157 node_t *tmp = (node_t *) iter->data;
174 static char score[33];
175 int log_level = (chosen->
weight >=
INFINITY)? LOG_WARNING : LOG_INFO;
179 "Chose node %s for %s from %d nodes with score %s",
189 node_list_attr_score(GHashTable * list,
const char *attr,
const char *value)
194 const char *best_node = NULL;
200 g_hash_table_iter_init(&iter, list);
201 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node)) {
202 int weight = node->
weight;
207 if (weight > best_score || best_node == NULL) {
218 crm_info(
"Best score for %s=%s was %s with %d",
219 attr, value, best_node ? best_node :
"<none>", best_score);
226 node_hash_update(GHashTable * list1, GHashTable * list2,
const char *attr,
float factor,
227 gboolean only_positive)
238 g_hash_table_iter_init(&iter, list1);
239 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node)) {
244 if(node == NULL) {
continue; };
248 weight_f = factor * score;
251 weight = (int)(weight_f < 0 ? weight_f - 0.5 : weight_f + 0.5);
255 if (factor < 0 && score < 0) {
262 crm_trace(
"%s: Filtering %d + %f*%d (factor * score)",
266 crm_trace(
"%s: Filtering %d + %f*%d (node < 0)",
269 }
else if (only_positive && new_score < 0 && node->weight > 0) {
271 crm_trace(
"%s: Filtering %d + %f*%d (score > 0)",
274 }
else if (only_positive && new_score < 0 && node->weight == 0) {
275 crm_trace(
"%s: Filtering %d + %f*%d (score == 0)",
289 GListPtr list = g_hash_table_get_values(hash);
307 GHashTable *work = NULL;
315 pe_rsc_info(rsc,
"%s: Breaking dependency loop at %s", rhs, rsc->
id);
325 while (last->next != NULL) {
340 pe_rsc_trace(rsc,
"%s: Combining scores from %d children of %s", rhs, g_list_length(iter), rsc->
id);
342 for(iter = rsc->
children; iter->next != NULL; iter = iter->next) {
354 pe_rsc_info(rsc,
"%s: Rolling back scores from %s", rhs, rsc->
id);
355 g_hash_table_destroy(work);
365 crm_trace(
"Checking %d additional colocation constraints", g_list_length(gIter));
370 while (last->next != NULL) {
374 gIter = ((
resource_t*)last->data)->rsc_cons_lhs;
375 crm_trace(
"Checking %d additional optional group colocation constraints from %s",
376 g_list_length(gIter), ((
resource_t*)last->data)->id);
380 crm_trace(
"Checking %d additional optional colocation constraints %s", g_list_length(gIter), rsc->
id);
383 for (; gIter != NULL; gIter = gIter->next) {
388 other = constraint->
rsc_rh;
390 other = constraint->
rsc_lh;
405 g_hash_table_iter_init(&iter, work);
406 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node)) {
414 g_hash_table_destroy(nodes);
422 node_has_been_unfenced(node_t *node)
426 return unfenced && strcmp(
"0", unfenced);
444 pe_rsc_debug(rsc,
"Escalating allocation of %s to its parent: %s", rsc->
id,
454 pe_rsc_debug(rsc,
"Dependency loop detected involving %s", rsc->
id);
462 for (gIter = rsc->
rsc_cons; gIter != NULL; gIter = gIter->next) {
465 GHashTable *archive = NULL;
469 rsc->
id, constraint->
id, rsc_rh->id,
475 rsc_rh->cmds->allocate(rsc_rh, NULL, data_set);
478 pe_rsc_info(rsc,
"%s: Rolling back scores from %s", rsc->
id, rsc_rh->id);
484 g_hash_table_destroy(archive);
490 for (gIter = rsc->
rsc_cons_lhs; gIter != NULL; gIter = gIter->next) {
502 pe_rsc_trace(rsc,
"Making sure %s doesn't get allocated", rsc->
id);
509 crm_notice(
"Resource %s cannot be elevated from %s to %s: no-quorum-policy=freeze",
522 const char *reason = NULL;
523 node_t *assign_to = NULL;
526 assign_to = pe__current_node(rsc);
527 if (assign_to == NULL) {
536 pe_rsc_info(rsc,
"Unmanaged resource %s allocated to %s: %s", rsc->
id,
537 (assign_to? assign_to->
details->
uname :
"no node"), reason);
545 && native_choose_node(rsc, prefer, data_set)) {
551 pe_rsc_info(rsc,
"Resource %s cannot run anywhere", rsc->
id);
569 crm_trace(
"Setting Pacemaker Remote node %s to ONLINE",
579 crm_trace(
"Setting Pacemaker Remote node %s to SHUTDOWN (next role %s, %sallocated)",
590 is_op_dup(
resource_t *rsc,
const char *name, guint interval_ms)
592 gboolean dup = FALSE;
593 const char *
id = NULL;
594 const char *value = NULL;
595 xmlNode *operation = NULL;
596 guint interval2_ms = 0;
599 for (operation = __xml_first_child(rsc->
ops_xml); operation != NULL;
600 operation = __xml_next_element(operation)) {
601 if (
crm_str_eq((
const char *)operation->name,
"op", TRUE)) {
609 if (interval_ms != interval2_ms) {
619 (
"Do not use the same (name, interval) combination more than once per resource");
629 op_cannot_recur(
const char *name)
642 const char *name = NULL;
643 const char *role = NULL;
644 const char *interval_spec = NULL;
645 const char *node_uname = node? node->
details->
uname :
"n/a";
647 guint interval_ms = 0;
649 gboolean is_optional = TRUE;
662 if (interval_ms == 0) {
667 if (is_op_dup(rsc, name, interval_ms)) {
668 crm_trace(
"Not creating duplicate recurring action %s for %dms %s",
669 ID(operation), interval_ms, name);
673 if (op_cannot_recur(name)) {
674 crm_config_err(
"Ignoring %s because action '%s' cannot be recurring",
675 ID(operation), name);
681 crm_trace(
"Not creating recurring action %s for disabled resource %s",
682 ID(operation), rsc->
id);
687 pe_rsc_trace(rsc,
"Creating recurring action %s for %s in role %s on %s",
702 if (possible_matches == NULL) {
704 pe_rsc_trace(rsc,
"Marking %s mandatory: not active", key);
709 for (gIter = possible_matches; gIter != NULL; gIter = gIter->next) {
717 g_list_free(possible_matches);
723 const char *result =
"Ignoring";
726 char *after_key = NULL;
730 log_level = LOG_INFO;
731 result =
"Cancelling";
732 cancel_op =
pe_cancel_op(rsc, name, interval_ms, node, data_set);
758 do_crm_log(log_level,
"%s action %s (%s vs. %s)",
766 mon =
custom_action(rsc, key, name, node, is_optional, TRUE, data_set);
773 pe_rsc_debug(rsc,
"%s\t %s (cancelled : start un-runnable)",
774 node_uname, mon->
uuid);
778 pe_rsc_debug(rsc,
"%s\t %s (cancelled : no node available)",
779 node_uname, mon->
uuid);
783 pe_rsc_info(rsc,
" Start recurring %s (%us) for %s on %s",
784 mon->
task, interval_ms / 1000, rsc->
id, node_uname);
791 free(running_master);
796 NULL, strdup(key), mon,
800 NULL, strdup(key), mon,
821 xmlNode *operation = NULL;
823 for (operation = __xml_first_child(rsc->
ops_xml); operation != NULL;
824 operation = __xml_next_element(operation)) {
825 if (
crm_str_eq((
const char *)operation->name,
"op", TRUE)) {
826 RecurringOp(rsc, start, node, operation, data_set);
837 const char *name = NULL;
838 const char *role = NULL;
839 const char *interval_spec = NULL;
840 const char *node_uname = node? node->
details->
uname :
"n/a";
842 guint interval_ms = 0;
854 if (interval_ms == 0) {
859 if (is_op_dup(rsc, name, interval_ms)) {
860 crm_trace(
"Not creating duplicate recurring action %s for %dms %s",
861 ID(operation), interval_ms, name);
865 if (op_cannot_recur(name)) {
866 crm_config_err(
"Invalid recurring action %s wth name: '%s'",
ID(operation), name);
872 crm_trace(
"Not creating recurring action %s for disabled resource %s",
873 ID(operation), rsc->
id);
880 crm_notice(
"Ignoring %s (recurring monitors for role=Stopped are not supported for anonyous clones)",
886 "Creating recurring action %s for %s in role %s on nodes where it should not be running",
892 if (possible_matches) {
895 g_list_free(possible_matches);
897 cancel_op =
pe_cancel_op(rsc, name, interval_ms, node, data_set);
906 pe_rsc_info(rsc,
"Cancel action %s (%s vs. %s) on %s",
911 for (gIter = data_set->
nodes; gIter != NULL; gIter = gIter->next) {
912 node_t *stop_node = (node_t *) gIter->data;
913 const char *stop_node_uname = stop_node->
details->
uname;
914 gboolean is_optional = TRUE;
915 gboolean probe_is_optional = TRUE;
916 gboolean stop_is_optional = TRUE;
918 char *rc_inactive = NULL;
923 if (node &&
safe_str_eq(stop_node_uname, node_uname)) {
927 pe_rsc_trace(rsc,
"Creating recurring action %s for %s on %s",
932 if (possible_matches == NULL) {
933 pe_rsc_trace(rsc,
"Marking %s mandatory on %s: not active", key,
937 pe_rsc_trace(rsc,
"Marking %s optional on %s: already active", key,
940 g_list_free(possible_matches);
943 stopped_mon =
custom_action(rsc, strdup(key), name, stop_node, is_optional, TRUE, data_set);
954 for (pIter = probes; pIter != NULL; pIter = pIter->next) {
964 if (probe_complete_ops) {
965 g_list_free(probe_complete_ops);
970 for (local_gIter = stop_ops; local_gIter != NULL; local_gIter = local_gIter->next) {
974 stop_is_optional = FALSE;
978 crm_debug(
"%s\t %s (cancelled : stop un-runnable)",
979 crm_str(stop_node_uname), stopped_mon->uuid);
985 NULL, strdup(key), stopped_mon,
992 g_list_free(stop_ops);
995 if (is_optional == FALSE && probe_is_optional && stop_is_optional
997 pe_rsc_trace(rsc,
"Marking %s optional on %s due to unmanaged",
998 key,
crm_str(stop_node_uname));
1007 pe_rsc_debug(rsc,
"%s\t %s (cancelled : no node available)",
1008 crm_str(stop_node_uname), stopped_mon->uuid);
1014 crm_notice(
" Start recurring %s (%us) for %s on %s", stopped_mon->task,
1015 interval_ms / 1000, rsc->
id,
crm_str(stop_node_uname));
1027 xmlNode *operation = NULL;
1029 for (operation = __xml_first_child(rsc->
ops_xml); operation != NULL;
1030 operation = __xml_next_element(operation)) {
1031 if (
crm_str_eq((
const char *)operation->name,
"op", TRUE)) {
1032 RecurringOp_Stopped(rsc, start, node, operation, data_set);
1047 pe_rsc_trace(rsc,
"Processing migration actions %s moving from %s to %s . partial migration = %s",
1052 if (partial == FALSE) {
1058 if ((migrate_to && migrate_from) || (migrate_from && partial)) {
1119 node_t *chosen = NULL;
1120 node_t *current = NULL;
1121 gboolean need_stop = FALSE;
1122 gboolean is_moving = FALSE;
1126 unsigned int num_all_active = 0;
1127 unsigned int num_clean_active = 0;
1128 bool multiply_active = FALSE;
1143 pe_rsc_trace(rsc,
"Processing state transition for %s %p: %s->%s", rsc->
id, rsc,
1149 node_t *dangling_source = (node_t *) gIter->data;
1158 DeleteRsc(rsc, dangling_source, FALSE, data_set);
1162 if ((num_all_active == 2) && (num_clean_active == 2) && chosen
1172 "Will attempt to continue with a partial migration to target %s from %s",
1184 multiply_active = (num_clean_active > 1);
1186 multiply_active = (num_all_active > 1);
1189 if (multiply_active) {
1192 crm_notice(
"Resource %s can no longer migrate to %s. Stopping on %s too",
1198 pe_proc_err(
"Resource %s is active on %u nodes (%s)",
1199 rsc->
id, num_all_active,
1201 crm_notice(
"See https://wiki.clusterlabs.org/wiki/FAQ#Resource_is_Too_Active for more information");
1212 allow_migrate = FALSE;
1252 rsc->
id, need_stop ?
" required" :
"");
1253 if (
rsc_action_matrix[role][next_role] (rsc, current, !need_stop, data_set) == FALSE) {
1263 rsc->
id, need_stop ?
" required" :
"");
1264 if (
rsc_action_matrix[role][next_role] (rsc, chosen, !need_stop, data_set) == FALSE) {
1275 if (
rsc_action_matrix[role][next_role] (rsc, chosen, FALSE, data_set) == FALSE) {
1282 pe_rsc_trace(rsc,
"No monitor additional ops for blocked resource");
1287 Recurring(rsc, start, chosen, data_set);
1288 Recurring_Stopped(rsc, start, chosen, data_set);
1290 pe_rsc_trace(rsc,
"Monitor ops for inactive resource");
1291 Recurring_Stopped(rsc, NULL, NULL, data_set);
1298 pe_rsc_trace(rsc,
"Not allowing partial migration to continue. %s", rsc->
id);
1299 allow_migrate = FALSE;
1301 }
else if (is_moving == FALSE ||
1308 allow_migrate = FALSE;
1311 if (allow_migrate) {
1312 handle_migration_actions(rsc, current, chosen, data_set);
1319 GHashTableIter iter;
1320 node_t *node = NULL;
1322 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node)) {
1346 GList *allowed_nodes = NULL;
1349 allowed_nodes = g_hash_table_get_values(rsc->
allowed_nodes);
1355 return allowed_nodes;
1364 GList *allowed_nodes = NULL;
1365 bool check_unfencing = FALSE;
1370 "Skipping native constraints for unmanaged resource: %s",
1383 check_utilization = (g_hash_table_size(rsc->
utilization) > 0)
1404 if (check_unfencing || check_utilization || rsc->
container) {
1405 allowed_nodes = allowed_nodes_as_list(rsc, data_set);
1408 if (check_unfencing) {
1411 for (GList *item = allowed_nodes; item; item = item->next) {
1415 crm_debug(
"Ordering any stops of %s before %s, and any starts after",
1434 NULL, strdup(unfence->
uuid), unfence,
1444 if (check_utilization) {
1447 pe_rsc_trace(rsc,
"Creating utilization constraints for %s - strategy: %s",
1450 for (gIter = rsc->
running_on; gIter != NULL; gIter = gIter->next) {
1451 node_t *current = (node_t *) gIter->data;
1456 if (load_stopped->
node == NULL) {
1462 NULL, load_stopped_task, load_stopped,
pe_order_load, data_set);
1465 for (GList *item = allowed_nodes; item; item = item->next) {
1470 if (load_stopped->
node == NULL) {
1482 free(load_stopped_task);
1497 rsc_avoids_remote_nodes(rsc->
container);
1527 for (GList *item = allowed_nodes; item; item = item->next) {
1542 crm_trace(
"Order and colocate %s relative to its container %s",
1566 rsc_avoids_remote_nodes(rsc);
1568 g_list_free(allowed_nodes);
1576 if (rsc_lh == NULL) {
1577 pe_err(
"rsc_lh was NULL for %s", constraint->
id);
1580 }
else if (constraint->
rsc_rh == NULL) {
1581 pe_err(
"rsc_rh was NULL for %s", constraint->
id);
1585 pe_rsc_trace(rsc_lh,
"Processing colocation constraint between %s and %s", rsc_lh->
id,
1595 if (constraint->
score == 0) {
1625 if ((rh_node == NULL)
1627 crm_err(
"%s must be colocated with %s but is not (%s vs. %s)",
1628 rsc_lh->
id, rsc_rh->
id,
1636 if ((rh_node != NULL)
1638 crm_err(
"%s and %s must be anti-colocated but are allocated "
1639 "to the same node (%s)",
1646 if (constraint->
score > 0
1648 crm_trace(
"LH: Skipping constraint: \"%s\" state filter nextrole is %s",
1653 if (constraint->
score > 0
1659 if (constraint->
score < 0
1661 crm_trace(
"LH: Skipping negative constraint: \"%s\" state filter",
1666 if (constraint->
score < 0
1668 crm_trace(
"RH: Skipping negative constraint: \"%s\" state filter",
1679 const char *rh_value = NULL;
1680 const char *lh_value = NULL;
1682 int score_multiplier = 1;
1707 score_multiplier = -1;
1716 const char *tmp = NULL;
1717 const char *value = NULL;
1720 GHashTable *work = NULL;
1721 gboolean do_check = FALSE;
1723 GHashTableIter iter;
1724 node_t *node = NULL;
1734 }
else if (constraint->
score < 0) {
1743 g_hash_table_iter_init(&iter, work);
1744 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node)) {
1753 }
else if (do_check == FALSE || constraint->
score >=
INFINITY) {
1756 do_check ?
"failed" :
"unallocated");
1768 static char score[33];
1772 pe_rsc_info(rsc_lh,
"%s: Rolling back scores from %s (%d, %s)",
1773 rsc_lh->
id, rsc_rh->
id, do_check, score);
1777 g_hash_table_destroy(work);
1791 pe_rsc_trace(rsc_lh,
"%sColocating %s with %s (%s, weight=%d, filter=%d)",
1792 constraint->
score >= 0 ?
"" :
"Anti-",
1793 rsc_lh->
id, rsc_rh->
id, constraint->
id, constraint->
score, filter_results);
1795 switch (filter_results) {
1797 influence_priority(rsc_lh, rsc_rh, constraint);
1800 pe_rsc_trace(rsc_lh,
"%sColocating %s with %s (%s, weight=%d)",
1801 constraint->
score >= 0 ?
"" :
"Anti-",
1802 rsc_lh->
id, rsc_rh->
id, constraint->
id, constraint->
score);
1803 colocation_match(rsc_lh, rsc_rh, constraint);
1815 pe_rsc_trace(rsc_lh,
"LH: Skipping constraint: \"%s\" state filter",
1826 if (rsc_ticket == NULL) {
1827 pe_err(
"rsc_ticket was NULL");
1831 if (rsc_lh == NULL) {
1832 pe_err(
"rsc_lh was NULL for %s", rsc_ticket->
id);
1843 pe_rsc_trace(rsc_lh,
"Processing ticket dependencies from %s", rsc_lh->
id);
1845 for (; gIter != NULL; gIter = gIter->next) {
1853 pe_rsc_trace(rsc_lh,
"%s: Processing ticket dependency on %s (%s, %s)",
1875 if (filter_rsc_ticket(rsc_lh, rsc_ticket) == FALSE) {
1881 for (gIter = rsc_lh->
running_on; gIter != NULL; gIter = gIter->next) {
1882 node_t *node = (node_t *) gIter->data;
1889 if (filter_rsc_ticket(rsc_lh, rsc_ticket) == FALSE) {
1916 return action->
flags;
1940 const char *reason = NULL;
1963 if (reason == NULL) {
2002 crm_trace(
"Testing %s on %s (0x%.6x) with %s 0x%.6x",
2049 pe_rsc_trace(first->
rsc,
"Unset migrate runnable on %s because of %s",
2057 ((then->
flags & pe_action_optional) == FALSE) &&
2077 pe_rsc_trace(then->
rsc,
"Unset runnable on %s because %s is neither runnable or migratable", first->
uuid, then->
uuid);
2120 handle_restart_ordering(first, then, filter);
2123 if (then_flags != then->
flags) {
2126 "Then: Flags for %s on %s are now 0x%.6x (was 0x%.6x) because of %s 0x%.6x",
2136 if (first_flags != first->
flags) {
2139 "First: Flags for %s on %s are now 0x%.6x (was 0x%.6x) because of %s 0x%.6x",
2151 GHashTableIter iter;
2152 node_t *node = NULL;
2154 if (constraint == NULL) {
2155 pe_err(
"Constraint is NULL");
2158 }
else if (rsc == NULL) {
2159 pe_err(
"LHS of rsc_to_node (%s) is NULL", constraint->
id);
2168 pe_rsc_debug(rsc,
"Constraint (%s) is not active (role : %s vs. %s)",
2172 }
else if (
is_active(constraint) == FALSE) {
2173 pe_rsc_trace(rsc,
"Constraint (%s) is not active", constraint->
id);
2178 pe_rsc_trace(rsc,
"RHS of constraint %s is NULL", constraint->
id);
2182 for (gIter = constraint->
node_list_rh; gIter != NULL; gIter = gIter->next) {
2183 node_t *node = (node_t *) gIter->data;
2184 node_t *other_node = NULL;
2188 if (other_node != NULL) {
2191 other_node->details->uname, node->
weight, other_node->weight);
2198 g_hash_table_insert(rsc->
allowed_nodes, (gpointer) other_node->details->id, other_node);
2201 if (other_node->rsc_discover_mode < constraint->
discover_mode) {
2211 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node)) {
2224 for (gIter = rsc->
actions; gIter != NULL; gIter = gIter->next) {
2227 crm_trace(
"processing action %d for rsc=%s", action->
id, rsc->
id);
2231 for (gIter = rsc->
children; gIter != NULL; gIter = gIter->next) {
2234 child_rsc->
cmds->
expand(child_rsc, data_set);
2238 #define log_change(a, fmt, args...) do { \
2239 if(a && a->reason && terminal) { \
2240 printf(" * "fmt" \tdue to %s\n", ##args, a->reason); \
2241 } else if(a && a->reason) { \
2242 crm_notice(fmt" \tdue to %s", ##args, a->reason); \
2243 } else if(terminal) { \
2244 printf(" * "fmt"\n", ##args); \
2246 crm_notice(fmt, ##args); \
2250 #define STOP_SANITY_ASSERT(lineno) do { \
2251 if(current && current->details->unclean) { \
2253 } else if(stop == NULL) { \
2254 crm_err("%s:%d: No stop action exists for %s", __FUNCTION__, lineno, rsc->id); \
2255 CRM_ASSERT(stop != NULL); \
2256 } else if(is_set(stop->flags, pe_action_optional)) { \
2257 crm_err("%s:%d: Action %s is still optional", __FUNCTION__, lineno, stop->uuid); \
2258 CRM_ASSERT(is_not_set(stop->flags, pe_action_optional)); \
2262 static int rsc_width = 5;
2263 static int detail_width = 5;
2268 char *reason = NULL;
2269 char *details = NULL;
2270 bool same_host = FALSE;
2271 bool same_role = FALSE;
2272 bool need_role = FALSE;
2275 CRM_ASSERT(destination != NULL || origin != NULL);
2277 if(source == NULL) {
2281 len = strlen(rsc->
id);
2282 if(len > rsc_width) {
2283 rsc_width = len + 2;
2290 if(origin != NULL && destination != NULL && origin->
details == destination->
details) {
2298 if(need_role && origin == NULL) {
2302 }
else if(need_role && destination == NULL) {
2306 }
else if(origin == NULL || destination == NULL) {
2310 }
else if(need_role && same_role && same_host) {
2314 }
else if(same_role && same_host) {
2318 }
else if(same_role && need_role) {
2322 }
else if(same_role) {
2326 }
else if(same_host) {
2335 len = strlen(details);
2336 if(len > detail_width) {
2343 }
else if(source->
reason) {
2347 reason = strdup(
" blocked");
2350 reason = strdup(
"");
2354 printf(
" * %-8s %-*s ( %*s ) %s\n", change, rsc_width, rsc->
id, detail_width, details, reason);
2356 crm_notice(
" * %-8s %-*s ( %*s ) %s", change, rsc_width, rsc->
id, detail_width, details, reason);
2367 node_t *next = NULL;
2368 node_t *current = NULL;
2377 gboolean moving = FALSE;
2388 for (gIter = rsc->
children; gIter != NULL; gIter = gIter->next) {
2398 current = pe__current_node(rsc);
2414 || (current == NULL && next == NULL)) {
2426 if (possible_matches) {
2427 start = possible_matches->data;
2428 g_list_free(possible_matches);
2434 start_node = current;
2437 if (possible_matches) {
2438 stop = possible_matches->data;
2439 g_list_free(possible_matches);
2443 if (possible_matches) {
2444 promote = possible_matches->data;
2445 g_list_free(possible_matches);
2449 if (possible_matches) {
2450 demote = possible_matches->data;
2451 g_list_free(possible_matches);
2458 if (possible_matches) {
2459 migrate_op = possible_matches->data;
2465 LogAction(
"Migrate", rsc, current, next, start, NULL, terminal);
2468 LogAction(
"Reload", rsc, current, next, start, NULL, terminal);
2475 LogAction(
"Stop", rsc, current, NULL, stop,
2476 (stop && stop->
reason)? stop : start, terminal);
2479 }
else if (moving && current) {
2481 rsc, current, next, stop, NULL, terminal);
2484 LogAction(
"Recover", rsc, current, NULL, stop, NULL, terminal);
2488 LogAction(
"Restart", rsc, current, next, start, NULL, terminal);
2492 g_list_free(possible_matches);
2503 for (gIter = rsc->
running_on; gIter != NULL; gIter = gIter->next) {
2504 node_t *node = (node_t *) gIter->data;
2508 if (possible_matches) {
2509 stop_op = possible_matches->data;
2510 g_list_free(possible_matches);
2517 LogAction(
"Stop", rsc, node, NULL, stop_op,
2518 (stop_op && stop_op->reason)? stop_op : start, terminal);
2525 LogAction(
"Recover", rsc, current, next, stop, start, terminal);
2528 }
else if (moving) {
2529 LogAction(
"Move", rsc, current, next, stop, NULL, terminal);
2533 LogAction(
"Reload", rsc, current, next, start, NULL, terminal);
2536 LogAction(
"Restart", rsc, current, next, start, NULL, terminal);
2541 LogAction(
"Demote", rsc, current, next, demote, NULL, terminal);
2545 LogAction(
"Promote", rsc, current, next, promote, NULL, terminal);
2548 LogAction(
"Start", rsc, current, next, start, NULL, terminal);
2560 for (gIter = rsc->
running_on; gIter != NULL; gIter = gIter->next) {
2561 node_t *current = (node_t *) gIter->data;
2587 DeleteRsc(rsc, current, optional, data_set);
2594 if (!node_has_been_unfenced(current)) {
2614 if (is_unfence_device(rsc, data_set)
2625 if (!node_has_been_unfenced(node)) {
2659 gboolean runnable = TRUE;
2668 for (gIter = action_list; gIter != NULL; gIter = gIter->next) {
2675 g_list_free(action_list);
2686 for (gIter = action_list; gIter != NULL; gIter = gIter->next) {
2692 g_list_free(action_list);
2705 for (gIter = rsc->
running_on; gIter != NULL; gIter = gIter->next) {
2706 node_t *current = (node_t *) gIter->data;
2738 }
else if (node == NULL) {
2739 pe_rsc_trace(rsc,
"Resource %s not deleted: NULL node", rsc->
id);
2743 pe_rsc_trace(rsc,
"Resource %s not deleted from %s: unrunnable", rsc->
id,
2768 node_t *running = NULL;
2769 node_t *allowed = NULL;
2772 static const char *rc_master = NULL;
2773 static const char *rc_inactive = NULL;
2775 if (rc_inactive == NULL) {
2782 pe_rsc_trace(rsc,
"Skipping active resource detection for %s", rsc->
id);
2791 "Skipping probe for %s on %s because Pacemaker Remote nodes cannot run stonith agents",
2797 "Skipping probe for %s on %s because guest nodes cannot run resources containing guest nodes",
2800 }
else if (rsc->is_remote_node) {
2802 "Skipping probe for %s on %s because Pacemaker Remote nodes cannot host remote connections",
2810 gboolean any_created = FALSE;
2812 for (gIter = rsc->
children; gIter != NULL; gIter = gIter->next) {
2815 any_created = child_rsc->
cmds->
create_probe(child_rsc, node, complete, force, data_set)
2840 if (allowed == NULL) {
2899 pe_rsc_trace(rsc,
"Skipping probe for %s on node %s, %s is stopped",
2920 pe_rsc_trace(rsc,
"Skipping probe for %s on node %s, %s is stopping, restarting or moving",
2940 if (running == NULL) {
2950 if (is_unfence_device(rsc, data_set) || !pe_rsc_is_clone(top)) {
2974 if (!is_unfence_device(rsc, data_set)) {
3003 && pe_rsc_is_anon_clone(rsc->
parent)
3029 target = stonith_op->
node;
3031 for (gIter = rsc->
actions; gIter != NULL; gIter = gIter->next) {
3034 switch (action->
needs) {
3046 && !rsc_is_known_on(rsc, target)) {
3072 bool order_implicit = FALSE;
3078 target = stonith_op->
node;
3085 order_implicit = TRUE;
3093 order_implicit = TRUE;
3096 for (gIter = action_list; gIter != NULL; gIter = gIter->next) {
3103 if (order_implicit) {
3108 crm_notice(
"Stop of failed resource %s is implicit after %s is fenced",
3111 crm_info(
"%s is implicit after %s is fenced",
3115 __FUNCTION__, __LINE__);
3125 if (pe_rsc_is_bundled(rsc) == FALSE) {
3131 crm_notice(
"Stop of failed resource %s is implicit because %s will be fenced",
3134 crm_info(
"%s is implicit because %s will be fenced",
3195 g_list_free(action_list);
3200 for (gIter = action_list; gIter != NULL; gIter = gIter->next) {
3208 "Demote of failed resource %s is implicit after %s is fenced",
3211 pe_rsc_info(rsc,
"%s is implicit after %s is fenced",
3221 if (pe_rsc_is_bundled(rsc)) {
3224 }
else if (order_implicit) {
3230 g_list_free(action_list);
3239 for (gIter = rsc->
children; gIter != NULL; gIter = gIter->next) {
3246 pe_rsc_trace(rsc,
"Skipping fencing constraints for unmanaged resource: %s", rsc->
id);
3249 native_start_constraints(rsc, stonith_op, data_set);
3250 native_stop_constraints(rsc, stonith_op, data_set);
3261 for (gIter = rsc->
children; gIter != NULL; gIter = gIter->next) {
3281 }
else if (node == NULL) {
3324 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)
enum rsc_role_e role_filter
enum rsc_start_requirement needs
enum pe_quorum_policy no_quorum_policy
enum pe_action_flags(* action_flags)(action_t *, node_t *)
#define crm_notice(fmt, args...)
void native_expand(resource_t *rsc, pe_working_set_t *data_set)
#define pe_rsc_debug(rsc, fmt, args...)
gboolean safe_str_neq(const char *a, const char *b)
gboolean PromoteRsc(resource_t *rsc, node_t *next, gboolean optional, pe_working_set_t *data_set)
void native_internal_constraints(resource_t *rsc, pe_working_set_t *data_set)
gboolean NullOp(resource_t *rsc, node_t *next, gboolean optional, pe_working_set_t *data_set)
gboolean is_active(pe__location_t *cons)
GListPtr dangling_migrations
#define promote_action(rsc, node, optional)
enum rsc_role_e(* state)(const pe_resource_t *, gboolean)
GList * sort_nodes_by_weight(GList *nodes, pe_node_t *active_node, pe_working_set_t *data_set)
node_t * node_copy(const node_t *this_node)
#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
pe_node_t * partial_migration_source
void(* expand)(resource_t *, pe_working_set_t *)
gboolean StopRsc(resource_t *rsc, node_t *next, gboolean optional, pe_working_set_t *data_set)
resource_alloc_functions_t * cmds
#define crm_config_err(fmt...)
#define pe_action_implies(action, reason, flag)
#define delete_action(rsc, node, optional)
#define pe_flag_remove_after_stop
#define XML_RSC_ATTR_INCARNATION
enum rsc_role_e next_role
action_t * pe_fence_op(node_t *node, const char *op, bool optional, const char *reason, pe_working_set_t *data_set)
gboolean exclusive_discover
pe_resource_t * remote_rsc
GListPtr find_actions(GListPtr input, const char *key, const node_t *on_node)
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)
void(* rsc_colocation_lh)(pe_resource_t *, pe_resource_t *, rsc_colocation_t *, pe_working_set_t *)
resource_object_functions_t * fns
#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.
gboolean pe__is_guest_or_remote_node(pe_node_t *node)
void native_create_actions(resource_t *rsc, pe_working_set_t *data_set)
#define CRM_LOG_ASSERT(expr)
pe_node_t * pe_find_node(GListPtr node_list, const char *uname)
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 clear_bit(word, bit)
guint crm_parse_interval_spec(const char *input)
void rsc_ticket_constraint(resource_t *lh_rsc, rsc_ticket_t *rsc_ticket, pe_working_set_t *data_set)
void native_rsc_location(pe_resource_t *rsc, pe__location_t *constraint)
pe_node_t * partial_migration_target
action_t * get_pseudo_op(const char *name, pe_working_set_t *data_set)
#define pe_rsc_allow_remote_remotes
#define pe_flag_have_quorum
#define pe_proc_err(fmt...)
gboolean remote_requires_reset
gboolean native_assign_node(resource_t *rsc, GListPtr candidates, node_t *chosen, gboolean force)
pe_node_t * pe_find_node_id(GListPtr node_list, const char *id)
void create_secondary_notification(pe_action_t *action, resource_t *rsc, pe_action_t *stonith_op, pe_working_set_t *data_set)
char * crm_meta_name(const char *field)
void(* rsc_colocation_rh)(pe_resource_t *, pe_resource_t *, rsc_colocation_t *, pe_working_set_t *)
#define pe_flag_stop_everything
#define demote_action(rsc, node, optional)
void native_rsc_colocation_lh(pe_resource_t *lh_rsc, pe_resource_t *rh_rsc, rsc_colocation_t *constraint, pe_working_set_t *data_set)
void native_append_meta(resource_t *rsc, xmlNode *xml)
#define pe_rsc_provisional
const char * role2text(enum rsc_role_e role)
#define CRM_ATTR_UNFENCED
gboolean rsc_colocation_new(const char *id, const char *node_attr, int score, resource_t *rsc_lh, resource_t *rsc_rh, const char *state_lh, const char *state_rh, pe_working_set_t *data_set)
void native_rsc_colocation_rh_must(resource_t *rsc_lh, gboolean update_lh, resource_t *rsc_rh, gboolean update_rh)
void process_utilization(resource_t *rsc, node_t **prefer, pe_working_set_t *data_set)
enum pe_discover_e discover_mode
void pe_action_set_reason(pe_action_t *action, const char *reason, bool overwrite)
#define set_bit(word, bit)
#define pe_rsc_allow_migrate
gboolean pe__is_guest_node(pe_node_t *node)
#define crm_debug(fmt, args...)
pe_resource_t * uber_parent(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 * node_attribute
#define pe_rsc_start_pending
gboolean update_action(pe_action_t *action, pe_working_set_t *data_set)
#define crm_trace(fmt, args...)
#define do_crm_log(level, fmt, args...)
Log a message.
action_t * find_first_action(GListPtr input, const char *uuid, const char *task, node_t *on_node)
pe_resource_t * pe__resource_contains_guest_node(const pe_working_set_t *data_set, const pe_resource_t *rsc)
struct pe_node_shared_s * details
enum rsc_recovery_type recovery_type
GHashTable * rsc_merge_weights(resource_t *rsc, const char *rhs, GHashTable *nodes, const char *attr, float factor, enum pe_weights flags)
enum loss_ticket_policy_e loss_policy
#define pe_rsc_needs_fencing
gboolean DemoteRsc(resource_t *rsc, node_t *next, gboolean optional, pe_working_set_t *data_set)
#define pe_rsc_promotable
void LogActions(resource_t *rsc, pe_working_set_t *data_set, gboolean terminal)
void pe_fence_node(pe_working_set_t *data_set, node_t *node, const char *reason)
Schedule a fence action for a node.
gboolean StartRsc(resource_t *rsc, node_t *next, gboolean optional, pe_working_set_t *data_set)
gboolean RoleError(resource_t *rsc, node_t *next, gboolean optional, pe_working_set_t *data_set)
action_t * custom_action(resource_t *rsc, char *key, const char *task, node_t *on_node, gboolean optional, gboolean foo, pe_working_set_t *data_set)
#define pe_flag_stonith_enabled
const char * pe_node_attribute_raw(pe_node_t *node, const char *name)
enum filter_colocation_res filter_colocation_constraint(resource_t *rsc_lh, resource_t *rsc_rh, rsc_colocation_t *constraint, gboolean preview)
xmlNode * find_rsc_op_entry(resource_t *rsc, const char *key)
#define XML_RSC_ATTR_TARGET_ROLE
#define XML_LRM_ATTR_MIGRATE_TARGET
#define XML_RSC_ATTR_REMOTE_NODE
GHashTable * node_hash_dup(GHashTable *hash)
gboolean native_create_probe(resource_t *rsc, node_t *node, action_t *complete, gboolean force, pe_working_set_t *data_set)
#define pe_rsc_allocating
enum rsc_role_e text2role(const char *role)
enum pe_obj_types variant
void ReloadRsc(resource_t *rsc, node_t *node, pe_working_set_t *data_set)
gboolean crm_str_eq(const char *a, const char *b, gboolean use_case)
const char * placement_strategy
gboolean can_run_resources(const node_t *node)
void graph_element_from_action(action_t *action, pe_working_set_t *data_set)
gboolean can_run_any(GHashTable *nodes)
#define CRMD_ACTION_RELOAD
#define pe_rsc_fence_device
#define PCMK_RESOURCE_CLASS_STONITH
GHashTable * node_hash_from_list(GListPtr list)
node_t * native_color(resource_t *rsc, node_t *preferred, pe_working_set_t *data_set)
#define STOP_SANITY_ASSERT(lineno)
void add_hash_param(GHashTable *hash, const char *name, const char *value)
gboolean update_action_flags(action_t *action, enum pe_action_flags flags, const char *source, int line)
#define start_action(rsc, node, optional)
#define crm_err(fmt, args...)
void resource_location(resource_t *rsc, node_t *node, int score, const char *tag, pe_working_set_t *data_set)
gboolean check_utilization(const char *value)
#define pe_clear_action_bit(action, bit)
gboolean DeleteRsc(resource_t *rsc, node_t *node, gboolean optional, pe_working_set_t *data_set)
GHashTable * native_merge_weights(resource_t *rsc, const char *rhs, GHashTable *nodes, const char *attr, float factor, enum pe_weights flags)
int merge_weights(int w1, int w2)
#define pe_rsc_needs_unfencing
gboolean(* rsc_action_matrix[RSC_ROLE_MAX][RSC_ROLE_MAX])(resource_t *, node_t *, gboolean, pe_working_set_t *)
gboolean(* create_probe)(resource_t *, node_t *, action_t *, gboolean, pe_working_set_t *)
enum pe_action_flags flags
#define pe_rsc_maintenance
#define XML_OP_ATTR_PENDING
int custom_action_order(resource_t *lh_rsc, char *lh_task, action_t *lh_action, resource_t *rh_rsc, char *rh_task, action_t *rh_action, enum pe_ordering type, pe_working_set_t *data_set)
#define pe_flag_have_stonith_resource
enum rsc_role_e rsc_state_matrix[RSC_ROLE_MAX][RSC_ROLE_MAX]
void rsc_stonith_ordering(resource_t *rsc, action_t *stonith_op, pe_working_set_t *data_set)
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 dump_node_scores(level, rsc, text, nodes)
void print_resource(int log_level, const char *pre_text, resource_t *rsc, gboolean details)
#define safe_str_eq(a, b)
node_t *(* allocate)(resource_t *, node_t *, pe_working_set_t *)
void native_rsc_colocation_rh_mustnot(resource_t *rsc_lh, gboolean update_lh, resource_t *rsc_rh, gboolean update_rh)
gboolean order_actions(action_t *lh_action, action_t *rh_action, enum pe_ordering order)
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
gint sort_node_uname(gconstpointer a, gconstpointer b)
char * crm_strdup_printf(char const *format,...) __attribute__((__format__(__printf__
#define crm_info(fmt, args...)
char * generate_op_key(const char *rsc_id, const char *op_type, guint interval_ms)
Generate an operation key.
GHashTable *(* merge_weights)(resource_t *, const char *, GHashTable *, const char *, float, enum pe_weights)
void trigger_unfencing(resource_t *rsc, node_t *node, const char *reason, action_t *dependency, pe_working_set_t *data_set)
#define XML_ATTR_TE_TARGET_RC
enum pe_action_flags native_action_flags(action_t *action, node_t *node)
enum crm_ais_msg_types type
#define pe_rsc_info(rsc, fmt, args...)
void native_rsc_colocation_rh(pe_resource_t *lh_rsc, pe_resource_t *rh_rsc, rsc_colocation_t *constraint, pe_working_set_t *data_set)
GHashTable * allowed_nodes
#define pe_flag_startup_probes
int new_rsc_order(resource_t *lh_rsc, const char *lh_task, resource_t *rh_rsc, const char *rh_task, enum pe_ordering type, pe_working_set_t *data_set)