12 #include <sys/param.h> 126 gboolean force_restart = FALSE;
127 gboolean delete_resource = FALSE;
128 gboolean changed = FALSE;
130 const char *value = NULL;
131 const char *old_value = NULL;
133 const char *attr_list[] = {
139 for (; attr_lpc <
PCMK__NELEM(attr_list); attr_lpc++) {
142 if (value == old_value
150 force_restart = TRUE;
151 crm_notice(
"Forcing restart of %s on %s, %s changed: %s -> %s",
160 delete_resource = TRUE;
162 }
else if (changed) {
163 delete_resource = TRUE;
165 return delete_resource;
172 guint interval_ms = 0;
175 const char *task = NULL;
176 const char *call_id = NULL;
186 rsc->
id, task, interval_ms,
187 active_node->
details->
uname, (reason? reason :
"unknown"));
189 cancel =
pe_cancel_op(rsc, task, interval_ms, active_node, data_set);
199 guint interval_ms = 0;
201 gboolean did_change = FALSE;
204 const char *digest_secure = NULL;
206 CRM_CHECK(active_node != NULL,
return FALSE);
209 if (interval_ms > 0) {
210 xmlNode *op_match = NULL;
218 if ((op_match == NULL)
220 CancelXmlOp(rsc, xml_op, active_node,
"orphan", data_set);
224 }
else if (op_match == NULL) {
259 out->
info(out,
"Only 'private' parameters to " 272 required =
custom_action(rsc, key, task, NULL, TRUE, TRUE, data_set);
276 trigger_unfencing(rsc, active_node,
"Device parameters changed", NULL, data_set);
283 trigger_unfencing(rsc, active_node,
"Device parameters changed (reload)", NULL, data_set);
287 if (interval_ms > 0) {
295 op =
custom_action(rsc, key, task, active_node, TRUE, TRUE, data_set);
299 }
else if (digest_restart) {
300 pe_rsc_trace(rsc,
"Reloading '%s' action for resource %s", task, rsc->
id);
308 pe_rsc_trace(rsc,
"Resource %s doesn't support agent reloads",
314 required =
custom_action(rsc, key, task, NULL, TRUE, TRUE, data_set);
333 const char *reason = NULL;
338 if (check_action_definition(rsc, node, rsc_op, data_set)
342 reason =
"action definition changed";
348 switch (digest_data->
rc) {
350 crm_trace(
"Resource %s history entry %s on %s has no digest to compare",
356 reason =
"resource parameters have changed";
375 const char *task = NULL;
377 xmlNode *rsc_op = NULL;
378 GList *op_list = NULL;
379 GList *sorted_op_list = NULL;
386 || pe_rsc_is_clone(parent) == FALSE
388 pe_rsc_trace(rsc,
"Skipping param check for %s and deleting: orphan", rsc->
id);
391 pe_rsc_trace(rsc,
"Skipping param check for %s (orphan clone)", rsc->
id);
396 if (check_rsc_parameters(rsc, node, rsc_entry, FALSE, data_set)) {
399 pe_rsc_trace(rsc,
"Skipping param check for %s: no longer active on %s",
406 if (check_rsc_parameters(rsc, node, rsc_entry, TRUE, data_set)) {
410 for (rsc_op = pcmk__xe_first_child(rsc_entry); rsc_op != NULL;
411 rsc_op = pcmk__xe_next(rsc_op)) {
414 op_list = g_list_prepend(op_list, rsc_op);
421 for (gIter = sorted_op_list; gIter != NULL; gIter = gIter->next) {
422 xmlNode *rsc_op = (xmlNode *) gIter->data;
423 guint interval_ms = 0;
427 if (start_index < stop_index) {
430 }
else if (offset < start_index) {
438 if ((interval_ms > 0) &&
441 CancelXmlOp(rsc, rsc_op, node,
"maintenance mode", data_set);
460 }
else if (check_action_definition(rsc, node, rsc_op, data_set)
468 g_list_free(sorted_op_list);
472 find_rsc_list(GList *result,
pe_resource_t * rsc,
const char *
id, gboolean renamed_clones,
476 gboolean match = FALSE;
483 if (data_set == NULL) {
486 for (gIter = data_set->
resources; gIter != NULL; gIter = gIter->next) {
489 result = find_rsc_list(result, child,
id, renamed_clones, partial,
496 if (strstr(rsc->
id,
id)) {
504 if (strcmp(rsc->
id,
id) == 0) {
513 result = g_list_prepend(result, rsc);
518 for (; gIter != NULL; gIter = gIter->next) {
521 result = find_rsc_list(result, child,
id, renamed_clones, partial, NULL);
531 const char *
id = NULL;
533 xmlNode *lrm_rscs = NULL;
536 xmlNode *node_state = NULL;
538 for (node_state = pcmk__xe_first_child(status); node_state != NULL;
539 node_state = pcmk__xe_next(node_state)) {
554 crm_trace(
"Skipping param check for %s: can't run resources",
562 xmlNode *rsc_entry = NULL;
564 for (rsc_entry = pcmk__xe_first_child(lrm_rscs);
566 rsc_entry = pcmk__xe_next(rsc_entry)) {
572 GList *result = NULL;
573 const char *rsc_id =
ID(rsc_entry);
577 result = find_rsc_list(NULL, NULL, rsc_id, TRUE, FALSE, data_set);
578 for (gIter = result; gIter != NULL; gIter = gIter->next) {
584 check_actions_for(rsc_entry, rsc, node, data_set);
599 gIter != NULL; gIter = gIter->next) {
631 int fail_count, countdown;
648 if (fail_count <= 0) {
661 if (countdown == 0) {
663 crm_warn(
"Forcing %s away from %s after %d failures (max=%d)",
667 crm_info(
"%s can fail %d more times on %s before being forced off",
678 for (; gIter != NULL; gIter = gIter->next) {
681 common_apply_stickiness(child_rsc, node, data_set);
691 if (current == NULL) {
693 }
else if ((match != NULL)
698 pe_rsc_debug(sticky_rsc,
"Resource %s: preferring current location" 699 " (node=%s, weight=%d)", sticky_rsc->
id,
705 pe_rsc_debug(rsc,
"Ignoring stickiness for %s: the cluster is asymmetric" 706 " and node %s is not explicitly allowed", rsc->
id, node->
details->
uname);
708 while (g_hash_table_iter_next(&iter, NULL, (
void **)&nIter)) {
709 crm_err(
"%s[%s] = %d", rsc->
id, nIter->details->uname, nIter->weight);
725 if (failcount_clear_action_exists(node, rsc) == FALSE) {
726 check_migration_threshold(rsc, node, data_set);
737 for (; gIter != NULL; gIter = gIter->next) {
750 for (; gIter != NULL; gIter = gIter->next) {
758 calculate_system_health(gpointer gKey, gpointer gValue, gpointer user_data)
760 const char *key = (
const char *)gKey;
761 const char *value = (
const char *)gValue;
762 int *system_health = (
int *)user_data;
764 if (!gKey || !gValue || !user_data) {
793 }
else if (pcmk__str_eq(health_strategy,
"migrate-on-red",
pcmk__str_casei)) {
802 }
else if (pcmk__str_eq(health_strategy,
"only-green",
pcmk__str_casei)) {
811 }
else if (pcmk__str_eq(health_strategy,
"progressive",
pcmk__str_casei)) {
817 "node-health-base"));
828 crm_err(
"Unknown node health strategy: %s", health_strategy);
832 crm_info(
"Applying automated node health strategy: %s", health_strategy);
834 for (gIter = data_set->
nodes; gIter != NULL; gIter = gIter->next) {
835 int system_health = base_health;
839 g_hash_table_foreach(node->
details->
attrs, calculate_system_health, &system_health);
841 crm_info(
" Node %s has an combined system health of %d",
847 if (system_health != 0) {
851 for (; gIter2 != NULL; gIter2 = gIter2->next) {
854 rsc2node_new(health_strategy, rsc, system_health, NULL, node, data_set);
867 if (data_set->
input == NULL) {
877 apply_system_health(data_set);
891 for (GList *gIter = data_set->
nodes; gIter != NULL; gIter = gIter->next) {
900 pe_fence_node(data_set, node,
"the connection is unrecoverable", FALSE);
912 if (probed != NULL &&
crm_is_true(probed) == FALSE) {
920 for (GList *gIter2 = data_set->
resources; gIter2 != NULL; gIter2 = gIter2->next) {
940 for (; gIter != NULL; gIter = gIter->next) {
942 rsc_discover_filter(child_rsc, node);
961 result = (time_t) result_ll;
974 for (GList *item = rsc->
children; item != NULL;
998 "Cancelling shutdown lock because %s is already active",
1006 }
else if (pcmk__list_of_1(rsc->
running_on)) {
1011 pe_rsc_debug(rsc,
"Not locking %s to unclean %s for shutdown",
1015 rsc->
lock_time = shutdown_time(node, data_set);
1028 pe_rsc_info(rsc,
"Locking %s to %s due to shutdown (expires @%lld)",
1030 (
long long) lock_expiration);
1033 pe_rsc_info(rsc,
"Locking %s to %s due to shutdown",
1038 for (GList *item = data_set->
nodes; item != NULL; item = item->next) {
1058 GList *gIter = NULL;
1061 for (gIter = data_set->
resources; gIter != NULL; gIter = gIter->next) {
1062 apply_shutdown_lock((
pe_resource_t *) gIter->data, data_set);
1068 for (gIter = data_set->
nodes; gIter != NULL; gIter = gIter->next) {
1078 apply_placement_constraints(data_set);
1080 gIter = data_set->
nodes;
1081 for (; gIter != NULL; gIter = gIter->next) {
1082 GList *gIter2 = NULL;
1086 for (; gIter2 != NULL; gIter2 = gIter2->next) {
1089 common_apply_stickiness(rsc, node, data_set);
1090 rsc_discover_filter(rsc, node);
1106 for (; gIter != NULL; gIter = gIter->next) {
1121 check_actions(data_set);
1126 convert_const_pointer(
const void *ptr)
1133 sort_rsc_process_order(gconstpointer a, gconstpointer b, gpointer
data)
1139 const char *reason =
"existence";
1141 GList *nodes = (GList *)
data;
1147 GList *gIter = NULL;
1148 GHashTable *r1_nodes = NULL;
1149 GHashTable *r2_nodes = NULL;
1151 reason =
"priority";
1155 if (r1_weight > r2_weight) {
1160 if (r1_weight < r2_weight) {
1165 reason =
"no node list";
1166 if (nodes == NULL) {
1171 resource1->
id, NULL, NULL, 1,
1177 resource2->
id, NULL, NULL, 1,
1183 reason =
"current location";
1188 r1_node = pe__current_node(resource1);
1189 r1_node = g_hash_table_lookup(r1_nodes, r1_node->
details->
id);
1190 if (r1_node != NULL) {
1191 r1_weight = r1_node->
weight;
1195 r2_node = pe__current_node(resource2);
1196 r2_node = g_hash_table_lookup(r2_nodes, r2_node->
details->
id);
1197 if (r2_node != NULL) {
1198 r2_weight = r2_node->
weight;
1202 if (r1_weight > r2_weight) {
1207 if (r1_weight < r2_weight) {
1213 for (gIter = nodes; gIter != NULL; gIter = gIter->next) {
1221 r1_node = g_hash_table_lookup(r1_nodes, node->
details->
id);
1224 r1_weight = r1_node->
weight;
1229 r2_node = g_hash_table_lookup(r2_nodes, node->
details->
id);
1232 r2_weight = r2_node->
weight;
1235 if (r1_weight > r2_weight) {
1240 if (r1_weight < r2_weight) {
1247 crm_trace(
"%s (%d) on %s %c %s (%d) on %s: %s",
1248 resource1->
id, r1_weight, r1_node ? r1_node->
details->
id :
"n/a",
1249 rc < 0 ? '>
' : rc > 0 ? '<
' : '=
', 1250 resource2->id, r2_weight, r2_node ? r2_node->details->id : "n/a", reason); 1253 g_hash_table_destroy(r1_nodes); 1256 g_hash_table_destroy(r2_nodes); 1263 allocate_resources(pe_working_set_t * data_set) 1265 GList *gIter = NULL; 1267 if (pcmk_is_set(data_set->flags, pe_flag_have_remote_nodes)) { 1268 /* Allocate remote connection resources first (which will also allocate 1269 * any colocation dependencies). If the connection is migrating, always 1270 * prefer the partial migration target. 1272 for (gIter = data_set->resources; gIter != NULL; gIter = gIter->next) { 1273 pe_resource_t *rsc = (pe_resource_t *) gIter->data; 1274 if (rsc->is_remote_node == FALSE) { 1277 pe_rsc_trace(rsc, "Allocating remote connection resource '%s
'", 1279 rsc->cmds->allocate(rsc, rsc->partial_migration_target, data_set); 1283 /* now do the rest of the resources */ 1284 for (gIter = data_set->resources; gIter != NULL; gIter = gIter->next) { 1285 pe_resource_t *rsc = (pe_resource_t *) gIter->data; 1286 if (rsc->is_remote_node == TRUE) { 1289 pe_rsc_trace(rsc, "Allocating %s resource '%s
'", 1290 crm_element_name(rsc->xml), rsc->id); 1291 rsc->cmds->allocate(rsc, NULL, data_set); 1295 /* We always use pe_order_preserve with these convenience functions to exempt 1296 * internally generated constraints from the prohibition of user constraints 1297 * involving remote connection resources. 1299 * The start ordering additionally uses pe_order_runnable_left so that the 1300 * specified action is not runnable if the start is not runnable. 1304 order_start_then_action(pe_resource_t *lh_rsc, pe_action_t *rh_action, 1305 enum pe_ordering extra, pe_working_set_t *data_set) 1307 if (lh_rsc && rh_action && data_set) { 1308 custom_action_order(lh_rsc, start_key(lh_rsc), NULL, 1309 rh_action->rsc, NULL, rh_action, 1310 pe_order_preserve | pe_order_runnable_left | extra, 1316 order_action_then_stop(pe_action_t *lh_action, pe_resource_t *rh_rsc, 1317 enum pe_ordering extra, pe_working_set_t *data_set) 1319 if (lh_action && rh_rsc && data_set) { 1320 custom_action_order(lh_action->rsc, NULL, lh_action, 1321 rh_rsc, stop_key(rh_rsc), NULL, 1322 pe_order_preserve | extra, data_set); 1326 // Clear fail counts for orphaned rsc on all online nodes 1328 cleanup_orphans(pe_resource_t * rsc, pe_working_set_t * data_set) 1330 GList *gIter = NULL; 1332 for (gIter = data_set->nodes; gIter != NULL; gIter = gIter->next) { 1333 pe_node_t *node = (pe_node_t *) gIter->data; 1335 if (node->details->online 1336 && pe_get_failcount(node, rsc, NULL, pe_fc_effective, NULL, 1339 pe_action_t *clear_op = NULL; 1341 clear_op = pe__clear_failcount(rsc, node, "it is orphaned", 1344 /* We can't use order_action_then_stop() here because its
1358 GList *gIter = NULL;
1361 GList *nodes = g_list_copy(data_set->
nodes);
1365 g_list_sort_with_data(data_set->
resources, sort_rsc_process_order, nodes);
1370 gIter = data_set->
nodes;
1371 for (; gIter != NULL; gIter = gIter->next) {
1375 out->
message(out,
"node-capacity", node,
"Original");
1382 allocate_resources(data_set);
1384 gIter = data_set->
nodes;
1385 for (; gIter != NULL; gIter = gIter->next) {
1389 out->
message(out,
"node-capacity", node,
"Remaining");
1438 for (gIter = data_set->
resources; gIter != NULL; gIter = gIter->next) {
1445 cleanup_orphans(rsc, data_set);
1452 for (gIter = data_set->
resources; gIter != NULL; gIter = gIter->next) {
1471 for (; gIter != NULL; gIter = gIter->next) {
1474 if (is_managed(child_rsc)) {
1488 for (; gIter != NULL; gIter = gIter->next) {
1491 if (is_managed(rsc)) {
1518 const char *fence_action =
"off";
1527 fence_action =
"reboot";
1534 stonith_op =
pe_fence_op(node, fence_action, FALSE,
"guest is unclean", FALSE, data_set);
1543 crm_info(
"Implying guest node %s is down (action %d) after %s fencing",
1551 crm_info(
"Implying guest node %s is down (action %d) " 1552 "after container %s is stopped (action %d)",
1554 container->
id, stop->
id);
1568 crm_info(
"Implying guest node %s is down (action %d) " 1569 "after connection is stopped (action %d)",
1575 crm_info(
"Implying guest node %s is down (action %d) ",
1592 gboolean integrity_lost = FALSE;
1593 gboolean need_stonith = TRUE;
1595 GList *stonith_ops = NULL;
1596 GList *shutdown_ops = NULL;
1604 crm_trace(
"Creating remote ordering constraints");
1605 apply_remote_node_ordering(data_set);
1607 crm_trace(
"Processing fencing and shutdown cases");
1608 if (any_managed_resources(data_set) == FALSE) {
1609 crm_notice(
"Delaying fencing operations until there are resources to manage");
1610 need_stonith = FALSE;
1614 for (gIter = data_set->
nodes; gIter != NULL; gIter = gIter->next) {
1623 fence_guest(node, data_set);
1633 stonith_op =
pe_fence_op(node, NULL, FALSE,
"node is unclean", FALSE, data_set);
1640 dc_down = stonith_op;
1645 && (stonith_ops != NULL)) {
1656 stonith_ops = g_list_prepend(stonith_ops, stonith_op);
1672 shutdown_ops = g_list_prepend(shutdown_ops, down_op);
1677 integrity_lost = TRUE;
1682 if (integrity_lost) {
1684 pe_warn(
"YOUR RESOURCES ARE NOW LIKELY COMPROMISED");
1685 pe_err(
"ENABLE STONITH TO KEEP YOUR RESOURCES SAFE");
1688 crm_notice(
"Cannot fence unclean nodes until quorum is" 1689 " attained (or no-quorum-policy is set to ignore)");
1693 if (dc_down != NULL) {
1702 for (gIter = shutdown_ops; gIter != NULL; gIter = gIter->next) {
1705 crm_debug(
"Ordering shutdown on %s before %s on DC %s",
1719 for (gIter = stonith_ops; gIter != NULL; gIter = gIter->next) {
1723 }
else if (stonith_ops) {
1733 g_list_free(stonith_ops);
1734 g_list_free(shutdown_ops);
1746 find_actions_by_task(GList *actions,
pe_resource_t * rsc,
const char *original_key)
1755 guint interval_ms = 0;
1757 if (
parse_op_key(original_key, NULL, &task, &interval_ms)) {
1762 crm_err(
"search key: %s", original_key);
1776 GList *gIter = NULL;
1777 GList *rh_actions = NULL;
1786 crm_trace(
"Processing RH of ordering constraint %d", order->
id);
1788 if (rh_action != NULL) {
1789 rh_actions = g_list_prepend(NULL, rh_action);
1791 }
else if (rsc != NULL) {
1795 if (rh_actions == NULL) {
1796 pe_rsc_trace(rsc,
"No RH-Side (%s/%s) found for constraint..." 1804 if ((lh_action != NULL) && (lh_action->
rsc == rsc)
1813 for (; gIter != NULL; gIter = gIter->next) {
1827 g_list_free(rh_actions);
1834 GList *gIter = NULL;
1835 GList *lh_actions = NULL;
1839 crm_trace(
"Processing LH of ordering constraint %d", order->
id);
1842 if (lh_action != NULL) {
1843 lh_actions = g_list_prepend(NULL, lh_action);
1849 if (lh_actions == NULL && lh_rsc != rh_rsc) {
1851 char *op_type = NULL;
1852 guint interval_ms = 0;
1859 pe_rsc_trace(lh_rsc,
"No LH-Side (%s/%s) found for constraint %d with %s - ignoring",
1865 pe_rsc_trace(lh_rsc,
"No LH-Side (%s/%s) found for constraint %d with %s - ignoring",
1869 pe_rsc_trace(lh_rsc,
"No LH-Side (%s/%s) found for constraint %d with %s - creating",
1871 lh_action =
custom_action(lh_rsc, key, op_type, NULL, TRUE, TRUE, data_set);
1872 lh_actions = g_list_prepend(NULL, lh_action);
1879 for (; gIter != NULL; gIter = gIter->next) {
1882 if (rh_rsc == NULL && order->
rh_action) {
1886 rsc_order_then(lh_action_iter, rh_rsc, order);
1893 g_list_free(lh_actions);
1909 return (interval_ms > 0);
1930 remote_rsc =
action->node->details->remote_rsc;
1940 crm_trace(
"Order %s action %s relative to %s%s for %s%s",
1991 if (is_recurring_action(
action)) {
1997 order_start_then_action(remote_rsc,
action,
2019 cluster_node = pe__current_node(remote_rsc);
2059 }
else if (cluster_node == NULL) {
2068 }
else if (pcmk__list_of_multiple(remote_rsc->
running_on)
2094 if (
action->rsc == NULL) {
2101 remote_rsc =
action->node->details->remote_rsc;
2104 crm_trace(
"Order %s action %s relative to %s%s (state: %s)",
2107 remote_rsc->
id, state2text(state));
2127 order_start_then_action(remote_rsc,
action, order_opts, data_set);
2132 order_action_then_stop(
action, remote_rsc,
2142 pe_fence_node(data_set,
action->node,
"resources are active and the connection is unrecoverable", FALSE);
2149 order_action_then_stop(
action, remote_rsc,
2173 if (is_recurring_action(
action)) {
2178 order_start_then_action(remote_rsc,
action,
2182 pe_node_t *cluster_node = pe__current_node(remote_rsc);
2190 pe_fence_node(data_set,
action->node,
"resources are in an unknown state and the connection is unrecoverable", FALSE);
2201 order_action_then_stop(
action, remote_rsc,
2220 for (GList *gIter = data_set->
actions; gIter != NULL; gIter = gIter->next) {
2225 if (
action->rsc == NULL) {
2233 if (
action->rsc->is_remote_node &&
2249 if (
action->node == NULL) {
2267 remote =
action->node->details->remote_rsc;
2268 if (remote == NULL) {
2279 for (GList *item =
action->rsc->actions; item != NULL;
2280 item = item->next) {
2286 action->rsc, NULL, rsc_action,
2301 if (remote->container) {
2303 apply_container_ordering(
action, data_set);
2307 apply_remote_ordering(
action, data_set);
2323 const char *op = g_hash_table_lookup(rh_action->
meta,
"stonith_action");
2342 GList *gIter = NULL;
2355 GList *probes = NULL;
2356 GList *rh_actions = NULL;
2358 GList *pIter = NULL;
2360 if (lh_rsc == NULL) {
2363 }
else if (rh_rsc && lh_rsc == rh_rsc) {
2367 if (lh_action == NULL && lh_action_task == NULL) {
2371 if (rh_action == NULL && rh_action_task == NULL) {
2382 }
else if (lh_action == NULL
2392 if (rh_rsc && lh_rsc->
container == rh_rsc) {
2396 }
else if (rh_action == NULL && rh_action_task
2419 order_type = order->
type;
2423 if (probes == NULL) {
2428 rh_actions = g_list_prepend(rh_actions, rh_action);
2430 }
else if (rh_rsc && rh_action_task) {
2434 if (rh_actions == NULL) {
2435 g_list_free(probes);
2439 crm_trace(
"Processing for LH probe based on ordering constraint %s -> %s" 2440 " (id=%d, type=%.6x)",
2441 lh_action ? lh_action->
uuid : lh_action_task,
2442 rh_action ? rh_action->
uuid : rh_action_task,
2445 for (pIter = probes; pIter != NULL; pIter = pIter->next) {
2447 GList *rIter = NULL;
2449 for (rIter = rh_actions; rIter != NULL; rIter = rIter->next) {
2452 if (order_first_probe_unneeded(probe, rh_action_iter)) {
2459 g_list_free(rh_actions);
2460 g_list_free(probes);
2465 order_first_probe_then_restart_repromote(
pe_action_t * probe,
2469 GList *gIter = NULL;
2470 bool interleave = FALSE;
2474 || probe->
rsc == NULL
2491 crm_trace(
"Processing based on %s %s -> %s %s",
2503 && probe->
rsc != after->
rsc) {
2505 GList *then_actions = NULL;
2515 for (gIter = then_actions; gIter != NULL; gIter = gIter->next) {
2525 g_list_free(then_actions);
2530 const char *interleave_s = g_hash_table_lookup(after->
rsc->
meta,
2546 for (gIter = after->
actions_after; gIter != NULL; gIter = gIter->next) {
2565 if (after->
rsc == NULL
2578 && interleave == TRUE
2579 && (compatible_rsc == NULL
2580 || compatible_rsc != after_wrapper->
action->
rsc)) {
2585 crm_trace(
"Proceeding through %s %s -> %s %s (type=0x%.6x)",
2590 after_wrapper->
type);
2592 order_first_probe_then_restart_repromote(probe, after_wrapper->
action, data_set);
2598 GList *gIter = NULL;
2600 for (gIter = data_set->
actions; gIter != NULL; gIter = gIter->next) {
2612 GList *gIter = NULL;
2613 GList *probes = NULL;
2615 for (gIter = rsc->
children; gIter != NULL; gIter = gIter->next) {
2618 order_first_rsc_probes(child, data_set);
2627 for (gIter = probes; gIter != NULL; gIter= gIter->next) {
2629 GList *aIter = NULL;
2631 for (aIter = probe->
actions_after; aIter != NULL; aIter = aIter->next) {
2634 order_first_probe_then_restart_repromote(probe, after_wrapper->
action, data_set);
2635 clear_actions_tracking_flag(data_set);
2639 g_list_free(probes);
2645 GList *gIter = NULL;
2647 for (gIter = data_set->
resources; gIter != NULL; gIter = gIter->next) {
2650 order_first_rsc_probes(rsc, data_set);
2653 order_first_probes_imply_stops(data_set);
2660 GList *gIter = NULL;
2662 for (gIter = data_set->
resources; gIter != NULL; gIter = gIter->next) {
2708 GList *actions = NULL;
2709 GList *probes = NULL;
2714 start = actions->data;
2715 g_list_free(actions);
2719 crm_err(
"No start action for %s", rsc->
id);
2725 for (actions = start->actions_before; actions != NULL; actions = actions->next) {
2728 GList *pIter = NULL;
2732 if(first->required_runnable_before) {
2733 GList *clone_actions = NULL;
2734 for (clone_actions = first->actions_before; clone_actions != NULL; clone_actions = clone_actions->next) {
2745 crm_trace(
"Not a start op %s for %s", first->uuid, start->uuid);
2748 if(first_rsc == NULL) {
2752 crm_trace(
"Same parent %s for %s", first_rsc->id, start->uuid);
2755 }
else if(FALSE && pe_rsc_is_clone(
uber_parent(first_rsc)) == FALSE) {
2756 crm_trace(
"Not a clone %s for %s", first_rsc->id, start->uuid);
2760 crm_err(
"Applying %s before %s %d", first->uuid, start->uuid,
uber_parent(first_rsc)->variant);
2762 for (pIter = probes; pIter != NULL; pIter = pIter->next) {
2765 crm_err(
"Ordering %s before %s", first->uuid, probe->
uuid);
2776 order_first_probes(data_set);
2777 order_then_probes(data_set);
2785 GList *gIter = NULL;
2787 crm_trace(
"Applying ordering constraints");
2801 crm_trace(
"Applying ordering constraint: %d", order->
id);
2805 rsc_order_first(rsc, order, data_set);
2812 rsc_order_then(order->
lh_action, rsc, order);
2820 for (gIter = data_set->
actions; gIter != NULL; gIter = gIter->next) {
2827 order_probes(data_set);
2830 for (gIter = data_set->
actions; gIter != NULL; gIter = gIter->next) {
2837 for (gIter = data_set->
actions; gIter != NULL; gIter = gIter->next) {
2841 for (GList *input_iter =
action->actions_before;
2842 input_iter != NULL; input_iter = input_iter->next) {
2860 data_set->
priv = out;
2865 for (gIter = data_set->
resources; gIter != NULL; gIter = gIter->next) {
2875 data_set->
priv = prev_out;
2879 static int transition_id = -1;
2891 crm_err(
"Calculated transition %d (with errors)%s%s",
2893 (filename == NULL)?
"" :
", saving inputs in ",
2894 (filename == NULL)?
"" : filename);
2897 crm_warn(
"Calculated transition %d (with warnings)%s%s",
2899 (filename == NULL)?
"" :
", saving inputs in ",
2900 (filename == NULL)?
"" : filename);
2905 (filename == NULL)?
"" :
", saving inputs in ",
2906 (filename == NULL)?
"" : filename);
2909 crm_notice(
"Configuration errors found during scheduler processing," 2910 " please run \"crm_verify -L\" to identify issues");
2920 GList *gIter = NULL;
2921 const char *value = NULL;
2922 long long limit = 0LL;
2925 crm_trace(
"Creating transition graph %d.", transition_id);
2954 char *recheck_epoch = NULL;
2959 free(recheck_epoch);
2976 for (; gIter != NULL; gIter = gIter->next) {
2989 crm_trace(
"processing non-resource actions");
2992 for (; gIter != NULL; gIter = gIter->next) {
2997 &&
action->node->details->shutdown
2999 && !pcmk_any_flags_set(
action->flags,
3009 crm_crit(
"Cannot %s node '%s' because of %s:%s%s (%s)",
3010 action->node->details->unclean ?
"fence" :
"shut down",
3022 crm_trace(
"Created transition graph %d.", transition_id);
3031 GList *gIter = NULL;
3033 for (gIter = data_set->
actions; gIter != NULL; gIter = gIter->next) {
3034 char *node_name = NULL;
3038 if (
action->rsc != NULL) {
3046 }
else if(
action->node) {
3052 task = strdup(
"Shutdown");
3054 const char *op = g_hash_table_lookup(
action->meta,
"stonith_action");
3058 out->
message(out,
"node-action", task, node_name,
action->reason);
void(* end_list)(pcmk__output_t *out)
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)
void pe__foreach_param_check(pe_working_set_t *data_set, void(*cb)(pe_resource_t *, pe_node_t *, xmlNode *, enum pe_check_parameters, pe_working_set_t *))
#define CRM_CHECK(expr, failure_action)
void complex_set_cmds(pe_resource_t *rsc)
xmlNode * find_xml_node(xmlNode *cib, const char *node_path, gboolean must_find)
void group_append_meta(pe_resource_t *rsc, xmlNode *xml)
enum pe_action_flags clone_action_flags(pe_action_t *action, pe_node_t *node)
gboolean stage7(pe_working_set_t *data_set)
enum pe_quorum_policy no_quorum_policy
void clone_append_meta(pe_resource_t *rsc, xmlNode *xml)
void pcmk__order_vs_fence(pe_action_t *stonith_op, pe_working_set_t *data_set)
gboolean parse_op_key(const char *key, char **rsc_id, char **op_type, guint *interval_ms)
#define crm_notice(fmt, args...)
#define CRMD_ACTION_MIGRATED
#define pe_flag_stop_action_orphans
bool pe__is_guest_or_remote_node(const pe_node_t *node)
enum pe_action_flags pcmk__bundle_action_flags(pe_action_t *action, pe_node_t *node)
#define pe_rsc_debug(rsc, fmt, args...)
#define XML_CONFIG_ATTR_SHUTDOWN_LOCK
#define crm_crit(fmt, args...)
#define pe__set_action_flags(action, flags_to_set)
#define pe__show_node_weights(level, rsc, text, nodes, data_set)
#define XML_ATTR_TRANSITION_MAGIC
GList * sort_nodes_by_weight(GList *nodes, pe_node_t *active_node, pe_working_set_t *data_set)
#define stop_action(rsc, node, optional)
void pe__add_param_check(xmlNode *rsc_op, pe_resource_t *rsc, pe_node_t *node, enum pe_check_parameters, pe_working_set_t *data_set)
pe_resource_t * container
bool pcmk__strcase_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
pe_node_t * partial_migration_source
int(* message)(pcmk__output_t *out, const char *message_id,...)
gboolean stage3(pe_working_set_t *data_set)
#define pe_flag_concurrent_fencing
void pe__update_recheck_time(time_t recheck, pe_working_set_t *data_set)
void pcmk__output_set_log_level(pcmk__output_t *out, int log_level)
#define XML_CIB_TAG_CONSTRAINTS
resource_alloc_functions_t * cmds
#define pe_flag_symmetric_cluster
void native_rsc_colocation_lh(pe_resource_t *lh_rsc, pe_resource_t *rh_rsc, pcmk__colocation_t *constraint, pe_working_set_t *data_set)
bool pcmk__ordering_is_invalid(pe_action_t *action, pe_action_wrapper_t *input)
GList * find_actions(GList *input, const char *key, const pe_node_t *on_node)
gboolean stage4(pe_working_set_t *data_set)
xmlNode * get_object_root(const char *object_type, xmlNode *the_root)
#define pe_flag_no_compat
enum rsc_role_e next_role
void add_maintenance_update(pe_working_set_t *data_set)
const char * crm_xml_add_int(xmlNode *node, const char *name, int value)
Create an XML attribute with specified name and integer value.
gboolean exclusive_discover
int char2score(const char *score)
pe_resource_t * remote_rsc
pe_action_t * sched_shutdown_op(pe_node_t *node, pe_working_set_t *data_set)
resource_object_functions_t * fns
#define XML_LRM_TAG_RESOURCE
void pe_action_set_flag_reason(const char *function, long line, pe_action_t *action, pe_action_t *reason, const char *text, enum pe_action_flags flags, bool overwrite)
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
void ReloadRsc(pe_resource_t *rsc, pe_node_t *node, pe_working_set_t *data_set)
bool pe__bundle_needs_remote_name(pe_resource_t *rsc, pe_working_set_t *data_set)
gint sort_op_by_callid(gconstpointer a, gconstpointer b)
gboolean unpack_constraints(xmlNode *xml_constraints, pe_working_set_t *data_set)
#define pe_flag_have_status
gboolean stage2(pe_working_set_t *data_set)
void group_rsc_location(pe_resource_t *rsc, pe__location_t *constraint)
enum action_tasks text2task(const char *task)
time_t get_effective_time(pe_working_set_t *data_set)
gboolean stage5(pe_working_set_t *data_set)
const char * pe_pref(GHashTable *options, const char *name)
int(* info)(pcmk__output_t *out, const char *format,...) G_GNUC_PRINTF(2
void(* internal_constraints)(pe_resource_t *, pe_working_set_t *)
void resource_location(pe_resource_t *rsc, pe_node_t *node, int score, const char *tag, pe_working_set_t *data_set)
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)
void native_expand(pe_resource_t *rsc, pe_working_set_t *data_set)
enum crm_ais_msg_types type
void native_rsc_location(pe_resource_t *rsc, pe__location_t *constraint)
pe_node_t * partial_migration_target
GHashTable * pcmk__native_merge_weights(pe_resource_t *rsc, const char *rhs, GHashTable *nodes, const char *attr, float factor, uint32_t flags)
gboolean remote_was_fenced
bool pcmk__ends_with(const char *s, const char *match)
gboolean can_run_resources(const pe_node_t *node)
#define pe_flag_have_quorum
void pcmk__bundle_rsc_colocation_lh(pe_resource_t *lh_rsc, pe_resource_t *rh_rsc, pcmk__colocation_t *constraint, pe_working_set_t *data_set)
#define CRM_SCORE_INFINITY
gboolean remote_requires_reset
void LogNodeActions(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 CRMD_ACTION_START
bool pe__is_remote_node(const pe_node_t *node)
#define XML_LRM_ATTR_TASK
void clone_rsc_colocation_lh(pe_resource_t *lh_rsc, pe_resource_t *rh_rsc, pcmk__colocation_t *constraint, pe_working_set_t *data_set)
pe__location_t * rsc2node_new(const char *id, pe_resource_t *rsc, int weight, const char *discovery_mode, pe_node_t *node, pe_working_set_t *data_set)
void native_internal_constraints(pe_resource_t *rsc, pe_working_set_t *data_set)
void group_rsc_colocation_rh(pe_resource_t *lh_rsc, pe_resource_t *rh_rsc, pcmk__colocation_t *constraint, pe_working_set_t *data_set)
#define CRM_OP_CLEAR_FAILCOUNT
gboolean crm_config_error
int pcmk__scan_ll(const char *text, long long *result, long long default_value)
#define pe_flag_have_remote_nodes
#define crm_warn(fmt, args...)
guint remote_reconnect_ms
void native_create_actions(pe_resource_t *rsc, pe_working_set_t *data_set)
gboolean(* create_probe)(pe_resource_t *, pe_node_t *, pe_action_t *, gboolean, pe_working_set_t *)
void clone_expand(pe_resource_t *rsc, pe_working_set_t *data_set)
void native_rsc_colocation_rh(pe_resource_t *lh_rsc, pe_resource_t *rh_rsc, pcmk__colocation_t *constraint, pe_working_set_t *data_set)
int pcmk__guint_from_hash(GHashTable *table, const char *key, guint default_val, guint *result)
int crm_element_value_ms(const xmlNode *data, const char *name, guint *dest)
Retrieve the millisecond value of an XML attribute.
#define crm_debug(fmt, args...)
pe_resource_t * uber_parent(pe_resource_t *rsc)
#define pe_flag_sanitized
#define pe__clear_order_flags(order_flags, flags_to_clear)
pe_node_t * pcmk__clone_allocate(pe_resource_t *rsc, pe_node_t *preferred, pe_working_set_t *data_set)
#define XML_CIB_ATTR_SHUTDOWN
pcmk__output_t * pcmk__new_logger(void)
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
void clone_rsc_colocation_rh(pe_resource_t *lh_rsc, pe_resource_t *rh_rsc, pcmk__colocation_t *constraint, pe_working_set_t *data_set)
#define XML_CIB_TAG_STATE
bool pe__is_guest_node(const pe_node_t *node)
gboolean stage0(pe_working_set_t *data_set)
enum pe_graph_flags group_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 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...)
enum rsc_digest_cmp_val rc
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.
char * digest_secure_calc
void calculate_active_ops(GList *sorted_op_list, int *start_index, int *stop_index)
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
struct pe_node_shared_s * details
bool pe__shutdown_requested(pe_node_t *node)
#define XML_AGENT_ATTR_PROVIDER
gboolean order_actions(pe_action_t *lh_action, pe_action_t *rh_action, enum pe_ordering order)
void(* expand)(pe_resource_t *, pe_working_set_t *)
GHashTable * pcmk__group_merge_weights(pe_resource_t *rsc, const char *rhs, GHashTable *nodes, const char *attr, float factor, uint32_t flags)
Wrappers for and extensions to libxml2.
#define XML_ATTR_TE_NOWAIT
xmlNode * find_rsc_op_entry(pe_resource_t *rsc, const char *key)
void(* finish)(pcmk__output_t *out, crm_exit_t exit_status, bool print, void **copy_dest)
void LogActions(pe_resource_t *rsc, pe_working_set_t *data_set)
xmlNode * create_xml_node(xmlNode *parent, const char *name)
void pcmk__log_transition_summary(const char *filename)
#define pe_flag_stonith_enabled
const char * pe_node_attribute_raw(pe_node_t *node, const char *name)
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 XML_LRM_ATTR_RESTART_DIGEST
void group_internal_constraints(pe_resource_t *rsc, pe_working_set_t *data_set)
pe_node_t * pcmk__bundle_allocate(pe_resource_t *rsc, pe_node_t *preferred, pe_working_set_t *data_set)
enum pe_obj_types variant
gboolean xml_has_children(const xmlNode *root)
void pcmk__bundle_rsc_colocation_rh(pe_resource_t *lh_rsc, pe_resource_t *rh_rsc, pcmk__colocation_t *constraint, pe_working_set_t *data_set)
const char * placement_strategy
void pe__free_param_checks(pe_working_set_t *data_set)
char * pcmk__op_key(const char *rsc_id, const char *op_type, guint interval_ms)
Generate an operation key (RESOURCE_ACTION_INTERVAL)
gboolean pcmk__bundle_create_probe(pe_resource_t *rsc, pe_node_t *node, pe_action_t *complete, gboolean force, pe_working_set_t *data_set)
void pcmk__output_free(pcmk__output_t *out)
pe_node_t * pe_find_node_id(GList *node_list, const char *id)
bool pe_can_fence(pe_working_set_t *data_set, pe_node_t *node)
pe_resource_t * find_compatible_child(pe_resource_t *local_child, pe_resource_t *rsc, enum rsc_role_e filter, gboolean current, pe_working_set_t *data_set)
#define PCMK_RESOURCE_CLASS_STONITH
gboolean rsc_discovery_enabled
#define XML_LRM_ATTR_SECURE_DIGEST
void group_create_actions(pe_resource_t *rsc, pe_working_set_t *data_set)
enum rsc_role_e(* state)(const pe_resource_t *, gboolean)
gboolean probe_resources(pe_working_set_t *data_set)
enum pe_action_flags group_action_flags(pe_action_t *action, pe_node_t *node)
void update_colo_start_chain(pe_action_t *action, pe_working_set_t *data_set)
Cluster status and scheduling.
GList * ordering_constraints
void add_hash_param(GHashTable *hash, const char *name, const char *value)
#define pe_flag_show_utilization
void pcmk__bundle_rsc_location(pe_resource_t *rsc, pe__location_t *constraint)
void clone_rsc_location(pe_resource_t *rsc, pe__location_t *constraint)
#define XML_LRM_TAG_RESOURCES
int pe__add_scores(int score1, int score2)
#define crm_err(fmt, args...)
pe_action_t * pe__clear_failcount(pe_resource_t *rsc, pe_node_t *node, const char *reason, pe_working_set_t *data_set)
Schedule a controller operation to clear a fail count.
op_digest_cache_t * rsc_action_digest_cmp(pe_resource_t *rsc, xmlNode *xml_op, pe_node_t *node, pe_working_set_t *data_set)
gboolean cluster_status(pe_working_set_t *data_set)
This structure contains everything that makes up a single output formatter.
void(* rsc_location)(pe_resource_t *, pe__location_t *)
#define XML_LRM_ATTR_INTERVAL_MS
#define crm_log_xml_info(xml, text)
gboolean stage8(pe_working_set_t *data_set)
void clone_create_actions(pe_resource_t *rsc, pe_working_set_t *data_set)
#define XML_LRM_ATTR_CALLID
#define CRMD_ACTION_MIGRATE
void(* begin_list)(pcmk__output_t *out, const char *singular_noun, const char *plural_noun, const char *format,...) G_GNUC_PRINTF(4
void pcmk__bundle_expand(pe_resource_t *rsc, pe_working_set_t *data_set)
gboolean clone_create_probe(pe_resource_t *rsc, pe_node_t *node, pe_action_t *complete, gboolean force, pe_working_set_t *data_set)
void native_append_meta(pe_resource_t *rsc, xmlNode *xml)
void(* create_actions)(pe_resource_t *, pe_working_set_t *)
enum pe_action_flags flags
#define pe_rsc_maintenance
#define pe_rsc_failure_ignored
GList * placement_constraints
pe_working_set_t * cluster
#define XML_CIB_TAG_STATUS
bool pe__resource_is_remote_conn(const pe_resource_t *rsc, const pe_working_set_t *data_set)
#define crm_log_xml_trace(xml, text)
gboolean crm_is_true(const char *s)
bool pcmk__starts_with(const char *str, const char *prefix)
Check whether a string starts with a certain sequence.
CRM_TRACE_INIT_DATA(pacemaker)
#define XML_LRM_TAG_RSC_OP
#define pe_rsc_trace(rsc, fmt, args...)
#define pe__set_order_flags(order_flags, flags_to_set)
gboolean was_processing_error
#define XML_RSC_ATTR_INTERLEAVE
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)
gboolean stage6(pe_working_set_t *data_set)
resource_alloc_functions_t resource_class_alloc_functions[]
gboolean was_processing_warning
void clone_internal_constraints(pe_resource_t *rsc, pe_working_set_t *data_set)
#define pe_flag_start_failure_fatal
gboolean DeleteRsc(pe_resource_t *rsc, pe_node_t *node, gboolean optional, pe_working_set_t *data_set)
void group_expand(pe_resource_t *rsc, pe_working_set_t *data_set)
void pcmk__bundle_create_actions(pe_resource_t *rsc, pe_working_set_t *data_set)
void graph_element_from_action(pe_action_t *action, pe_working_set_t *data_set)
#define crm_info(fmt, args...)
enum pe_action_flags native_action_flags(pe_action_t *action, pe_node_t *node)
enum pe_graph_flags pcmk__multi_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)
pe_action_t * find_first_action(GList *input, const char *uuid, const char *task, pe_node_t *on_node)
void pcmk__bundle_internal_constraints(pe_resource_t *rsc, pe_working_set_t *data_set)
void set_alloc_actions(pe_working_set_t *data_set)
void pcmk__bundle_append_meta(pe_resource_t *rsc, xmlNode *xml)
int pe_get_failcount(pe_node_t *node, pe_resource_t *rsc, time_t *last_failure, uint32_t flags, xmlNode *xml_op, pe_working_set_t *data_set)
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)
void group_rsc_colocation_lh(pe_resource_t *lh_rsc, pe_resource_t *rh_rsc, pcmk__colocation_t *constraint, pe_working_set_t *data_set)
#define pe_flag_shutdown_lock
#define pe_rsc_info(rsc, fmt, args...)
pe_node_t * pcmk__native_allocate(pe_resource_t *rsc, pe_node_t *preferred, pe_working_set_t *data_set)
#define XML_AGENT_ATTR_CLASS
GHashTable * allowed_nodes
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)
#define pe_flag_startup_probes
pe_node_t * pcmk__group_allocate(pe_resource_t *rsc, pe_node_t *preferred, pe_working_set_t *data_set)
#define pe_flag_stop_rsc_orphans