31 struct action_history {
40 const char *exit_reason;
43 int expected_exit_status;
52 #define set_config_flag(scheduler, option, flag) do { \ 53 const char *scf_value = pe_pref((scheduler)->config_hash, (option)); \ 54 if (scf_value != NULL) { \ 55 if (crm_is_true(scf_value)) { \ 56 (scheduler)->flags = pcmk__set_flags_as(__func__, __LINE__, \ 57 LOG_TRACE, "Scheduler", \ 58 crm_system_name, (scheduler)->flags, \ 61 (scheduler)->flags = pcmk__clear_flags_as(__func__, __LINE__, \ 62 LOG_TRACE, "Scheduler", \ 63 crm_system_name, (scheduler)->flags, \ 70 xmlNode *xml_op, xmlNode **last_failure,
74 static void add_node_attrs(
const xmlNode *xml_obj,
pcmk_node_t *node,
76 static void determine_online_status(
const xmlNode *node_state,
80 static void unpack_node_lrm(
pcmk_node_t *node,
const xmlNode *xml,
111 const char *reason,
bool priority_delay)
122 "(otherwise would because %s): " 123 "its guest resource %s is unmanaged",
124 pe__node_name(node), reason, rsc->
id);
126 crm_warn(
"Guest node %s will be fenced " 127 "(by recovering its guest resource %s): %s",
128 pe__node_name(node), rsc->
id, reason);
140 }
else if (is_dangling_guest_node(node)) {
141 crm_info(
"Cleaning up dangling connection for guest node %s: " 142 "fencing was already done because %s, " 143 "and guest resource no longer exists",
144 pe__node_name(node), reason);
153 "(otherwise would because %s): connection is unmanaged",
154 pe__node_name(node), reason);
167 crm_trace(
"Cluster node %s %s because %s",
185 #define XPATH_UNFENCING_NVPAIR XML_CIB_TAG_NVPAIR \ 186 "[(@" XML_NVPAIR_ATTR_NAME "='" PCMK_STONITH_PROVIDES "'" \ 187 "or @" XML_NVPAIR_ATTR_NAME "='" XML_RSC_ATTR_REQUIRES "') " \ 188 "and @" XML_NVPAIR_ATTR_VALUE "='" PCMK__VALUE_UNFENCING "']" 191 #define XPATH_ENABLE_UNFENCING \ 192 "/" XML_TAG_CIB "/" XML_CIB_TAG_CONFIGURATION "/" XML_CIB_TAG_RESOURCES \ 193 "//" XML_TAG_META_SETS "/" XPATH_UNFENCING_NVPAIR \ 194 "|/" XML_TAG_CIB "/" XML_CIB_TAG_CONFIGURATION "/" XML_CIB_TAG_RSCCONFIG \ 195 "/" XML_TAG_META_SETS "/" XPATH_UNFENCING_NVPAIR 200 xmlXPathObjectPtr
result = NULL;
214 const char *value = NULL;
236 crm_info(
"Startup probes: disabled (dangerous)");
241 crm_info(
"Watchdog-based self-fencing will be performed via SBD if " 242 "fencing is required and stonith-watchdog-timeout is nonzero");
258 crm_debug(
"STONITH of failed nodes is enabled");
260 crm_debug(
"STONITH of failed nodes is disabled");
267 "Support for stonith-action of 'poweroff' is deprecated " 268 "and will be removed in a future release (use 'off' instead)");
276 crm_debug(
"Concurrent fencing is enabled");
278 crm_debug(
"Concurrent fencing is disabled");
286 crm_trace(
"Priority fencing delay is %ds",
291 crm_debug(
"Stop all active resources: %s",
297 crm_debug(
"Cluster is symmetric" " - resources can run anywhere by default");
320 crm_notice(
"Resetting no-quorum-policy to 'stop': cluster has never had quorum");
325 "fencing is disabled");
335 crm_debug(
"On loss of quorum: Freeze resources");
338 crm_debug(
"On loss of quorum: Stop ALL resources");
342 "Demote promotable resources and stop other resources");
345 crm_notice(
"On loss of quorum: Fence all remaining nodes");
355 crm_trace(
"Orphan resources are stopped");
357 crm_trace(
"Orphan resources are ignored");
363 crm_trace(
"Orphan resource actions are stopped");
365 crm_trace(
"Orphan resource actions are ignored");
372 #ifndef PCMK__COMPAT_2_0 374 "Support for the remove-after-stop cluster property is" 375 " deprecated and will be removed in a future release");
391 crm_trace(
"Start failures are always fatal");
393 crm_trace(
"Start failures are handled by failcount");
401 crm_trace(
"Unseen nodes will be fenced");
409 "placement-strategy");
417 crm_trace(
"Resources will be locked to nodes that were cleanly " 418 "shut down (locks expire after %s)",
421 crm_trace(
"Resources will not be locked to nodes that were cleanly " 431 crm_trace(
"Fence pending nodes after %s",
450 if (new_node == NULL) {
457 if (new_node->
details == NULL) {
484 "assuming 'ping'", pcmk__s(
uname,
"without name"),
488 "Support for nodes of type 'ping' (such as %s) is " 489 "deprecated and will be removed in a future release",
490 pcmk__s(
uname,
"unnamed node"));
516 xmlNode *attr_set = NULL;
517 xmlNode *attr = NULL;
519 const char *container_id =
ID(xml_obj);
520 const char *remote_name = NULL;
521 const char *remote_server = NULL;
522 const char *remote_port = NULL;
523 const char *connect_timeout =
"60s";
524 const char *remote_allow_migrate=NULL;
525 const char *is_managed = NULL;
527 for (attr_set = pcmk__xe_first_child(xml_obj); attr_set != NULL;
528 attr_set = pcmk__xe_next(attr_set)) {
535 for (attr = pcmk__xe_first_child(attr_set); attr != NULL;
536 attr = pcmk__xe_next(attr)) {
543 remote_server = value;
547 connect_timeout = value;
549 remote_allow_migrate=value;
556 if (remote_name == NULL) {
565 remote_allow_migrate, is_managed,
566 connect_timeout, remote_server, remote_port);
599 xmlNode *xml_obj = NULL;
601 const char *
id = NULL;
602 const char *
uname = NULL;
603 const char *
type = NULL;
604 const char *score = NULL;
606 for (xml_obj = pcmk__xe_first_child(xml_nodes); xml_obj != NULL;
607 xml_obj = pcmk__xe_next(xml_obj)) {
620 "> entry in configuration without id");
625 if (new_node == NULL) {
629 handle_startup_fencing(
scheduler, new_node);
631 add_node_attrs(xml_obj, new_node, FALSE,
scheduler);
639 crm_info(
"Creating a fake local node");
650 const char *container_id = NULL;
666 pe_rsc_trace(rsc,
"Resource %s's container is %s", rsc->
id, container_id);
668 pe_err(
"Resource %s: Unknown resource container (%s)", rsc->
id, container_id);
676 xmlNode *xml_obj = NULL;
681 for (xml_obj = pcmk__xe_first_child(xml_resources); xml_obj != NULL;
682 xml_obj = pcmk__xe_next(xml_obj)) {
684 const char *new_node_id = NULL;
690 new_node_id =
ID(xml_obj);
695 crm_trace(
"Found remote node %s defined by resource %s",
696 new_node_id,
ID(xml_obj));
711 new_node_id = expand_remote_rsc_meta(xml_obj, xml_resources,
715 crm_trace(
"Found guest node %s in resource %s",
716 new_node_id,
ID(xml_obj));
727 xmlNode *xml_obj2 = NULL;
728 for (xml_obj2 = pcmk__xe_first_child(xml_obj); xml_obj2 != NULL;
729 xml_obj2 = pcmk__xe_next(xml_obj2)) {
731 new_node_id = expand_remote_rsc_meta(xml_obj2, xml_resources,
736 crm_trace(
"Found guest node %s in resource %s inside group %s",
737 new_node_id,
ID(xml_obj2),
ID(xml_obj));
772 pe_rsc_trace(new_rsc,
"Linking remote connection resource %s to %s",
773 new_rsc->
id, pe__node_name(remote_node));
780 handle_startup_fencing(
scheduler, remote_node);
787 strdup(
"container"));
792 destroy_tag(gpointer
data)
798 g_list_free_full(tag->
refs, free);
818 xmlNode *xml_obj = NULL;
823 for (xml_obj = pcmk__xe_first_child(xml_resources); xml_obj != NULL;
824 xml_obj = pcmk__xe_next(xml_obj)) {
827 const char *
id =
ID(xml_obj);
829 if (pcmk__str_empty(
id)) {
838 NULL, NULL) == FALSE) {
855 "because configuration is invalid",
875 pcmk__config_err(
"Resource start-up disabled since no STONITH resources have been defined");
876 pcmk__config_err(
"Either configure some or disable STONITH with the stonith-enabled option");
877 pcmk__config_err(
"NOTE: Clusters with shared data need STONITH to ensure data integrity");
886 xmlNode *xml_tag = NULL;
890 for (xml_tag = pcmk__xe_first_child(xml_tags); xml_tag != NULL;
891 xml_tag = pcmk__xe_next(xml_tag)) {
893 xmlNode *xml_obj_ref = NULL;
894 const char *tag_id =
ID(xml_tag);
900 if (tag_id == NULL) {
902 (
const char *) xml_tag->name);
906 for (xml_obj_ref = pcmk__xe_first_child(xml_tag); xml_obj_ref != NULL;
907 xml_obj_ref = pcmk__xe_next(xml_obj_ref)) {
909 const char *obj_ref =
ID(xml_obj_ref);
915 if (obj_ref == NULL) {
917 xml_obj_ref->name, tag_id);
935 const char *ticket_id = NULL;
936 const char *granted = NULL;
937 const char *last_granted = NULL;
938 const char *standby = NULL;
939 xmlAttrPtr xIter = NULL;
943 ticket_id =
ID(xml_ticket);
944 if (pcmk__str_empty(ticket_id)) {
948 crm_trace(
"Processing ticket state for %s", ticket_id);
951 if (ticket == NULL) {
953 if (ticket == NULL) {
958 for (xIter = xml_ticket->properties; xIter; xIter = xIter->next) {
959 const char *prop_name = (
const char *)xIter->name;
960 const char *prop_value = pcmk__xml_attr_value(xIter);
965 g_hash_table_replace(ticket->
state, strdup(prop_name), strdup(prop_value));
968 granted = g_hash_table_lookup(ticket->
state,
"granted");
974 crm_info(
"We do not have ticket '%s'", ticket->
id);
977 last_granted = g_hash_table_lookup(ticket->
state,
"last-granted");
979 long long last_granted_ll;
985 standby = g_hash_table_lookup(ticket->
state,
"standby");
989 crm_info(
"Granted ticket '%s' is in standby-mode", ticket->
id);
995 crm_trace(
"Done with ticket state for %s", ticket_id);
1003 xmlNode *xml_obj = NULL;
1005 for (xml_obj = pcmk__xe_first_child(xml_tickets); xml_obj != NULL;
1006 xml_obj = pcmk__xe_next(xml_obj)) {
1011 unpack_ticket_state(xml_obj,
scheduler);
1018 unpack_handle_remote_attrs(
pcmk_node_t *this_node,
const xmlNode *state,
1021 const char *resource_discovery_enabled = NULL;
1022 const xmlNode *attrs = NULL;
1032 crm_trace(
"Processing Pacemaker Remote node %s", pe__node_name(this_node));
1043 add_node_attrs(attrs, this_node, TRUE,
scheduler);
1046 crm_info(
"%s is shutting down", pe__node_name(this_node));
1051 crm_info(
"%s is in standby mode", pe__node_name(this_node));
1057 crm_info(
"%s is in maintenance mode", pe__node_name(this_node));
1062 if (resource_discovery_enabled && !
crm_is_true(resource_discovery_enabled)) {
1066 " attribute on Pacemaker Remote node %s" 1067 " because fencing is disabled",
1068 pe__node_name(this_node));
1075 crm_info(
"%s has resource discovery disabled",
1076 pe__node_name(this_node));
1091 unpack_transient_attributes(
const xmlNode *state,
pcmk_node_t *node,
1094 const char *discovery = NULL;
1098 add_node_attrs(attrs, node, TRUE,
scheduler);
1101 crm_info(
"%s is in standby mode", pe__node_name(node));
1106 crm_info(
"%s is in maintenance mode", pe__node_name(node));
1111 if ((discovery != NULL) && !
crm_is_true(discovery)) {
1113 " attribute for %s because disabling resource discovery " 1114 "is not allowed for cluster nodes", pe__node_name(node));
1133 const char *
id = NULL;
1134 const char *
uname = NULL;
1145 if (
uname == NULL) {
1157 if (this_node == NULL) {
1159 "because it is no longer in the configuration",
1160 id, pcmk__s(
uname,
"uname unknown"));
1175 unpack_transient_attributes(state, this_node,
scheduler);
1183 crm_trace(
"Determining online status of cluster node %s (id %s)",
1184 pe__node_name(this_node),
id);
1185 determine_online_status(state, this_node,
scheduler);
1217 unpack_node_history(
const xmlNode *status,
bool fence,
1226 const char *
id =
ID(state);
1230 if ((
id == NULL) || (
uname == NULL)) {
1232 crm_trace(
"Not unpacking resource history from malformed " 1238 if (this_node == NULL) {
1240 crm_trace(
"Not unpacking resource history for node %s because " 1241 "no longer in configuration",
id);
1246 crm_trace(
"Not unpacking resource history for node %s because " 1247 "already unpacked",
id);
1263 crm_trace(
"Not unpacking resource history for guest node %s " 1264 "because container and connection are not known to " 1280 crm_trace(
"Not unpacking resource history for remote node %s " 1281 "because connection is not known to be up",
id);
1294 crm_trace(
"Not unpacking resource history for offline " 1295 "cluster node %s",
id);
1300 determine_remote_online_status(
scheduler, this_node);
1301 unpack_handle_remote_attrs(this_node, state,
scheduler);
1304 crm_trace(
"Unpacking resource history for %snode %s",
1305 (fence?
"unseen " :
""),
id);
1308 unpack_node_lrm(this_node, state,
scheduler);
1321 xmlNode *state = NULL;
1329 for (state = pcmk__xe_first_child(status); state != NULL;
1330 state = pcmk__xe_next(state)) {
1333 unpack_tickets_state((xmlNode *) state,
scheduler);
1340 while (unpack_node_history(status, FALSE,
scheduler) == EAGAIN) {
1341 crm_trace(
"Another pass through node resource histories is needed");
1345 unpack_node_history(status,
1370 for (GList *gIter =
scheduler->
nodes; gIter != NULL; gIter = gIter->next) {
1382 determine_remote_online_status(
scheduler, this_node);
1406 if (member_time == NULL) {
1422 long long when_member = 0LL;
1425 0LL) !=
pcmk_rc_ok) || (when_member < 0LL)) {
1444 unpack_node_online(
const xmlNode *node_state)
1457 long long when_online = 0LL;
1460 || (when_online < 0)) {
1479 unpack_node_terminate(
const pcmk_node_t *node,
const xmlNode *node_state)
1481 long long value = 0LL;
1487 return (value_i != 0);
1493 "node attribute for %s", value_s, pe__node_name(node));
1499 const xmlNode *node_state,
1502 gboolean online = FALSE;
1505 long long when_member = unpack_node_member(node_state,
scheduler);
1506 long long when_online = unpack_node_online(node_state);
1508 if (when_member <= 0) {
1509 crm_trace(
"Node %s is %sdown", pe__node_name(this_node),
1510 ((when_member < 0)?
"presumed " :
""));
1512 }
else if (when_online > 0) {
1516 crm_debug(
"Node %s is not ready to run resources: %s",
1517 pe__node_name(this_node), join);
1521 crm_trace(
"Node %s controller is down: " 1522 "member@%lld online@%lld join=%s expected=%s",
1523 pe__node_name(this_node), when_member, when_online,
1524 pcmk__s(join,
"<null>"), pcmk__s(exp_state,
"<null>"));
1529 crm_info(
"Node %s member@%lld online@%lld join=%s expected=%s",
1530 pe__node_name(this_node), when_member, when_online,
1531 pcmk__s(join,
"<null>"), pcmk__s(exp_state,
"<null>"));
1551 long long when_member,
long long when_online)
1554 && (when_member > 0) && (when_online <= 0)) {
1571 const xmlNode *node_state,
1574 bool termination_requested = unpack_node_terminate(this_node, node_state);
1577 long long when_member = unpack_node_member(node_state,
scheduler);
1578 long long when_online = unpack_node_online(node_state);
1598 crm_trace(
"Node %s member@%lld online@%lld join=%s expected=%s%s",
1599 pe__node_name(this_node), when_member, when_online,
1600 pcmk__s(join,
"<null>"), pcmk__s(exp_state,
"<null>"),
1601 (termination_requested?
" (termination requested)" :
""));
1604 crm_debug(
"%s is shutting down", pe__node_name(this_node));
1607 return (when_online > 0);
1610 if (when_member < 0) {
1612 "peer has not been seen by the cluster", FALSE);
1618 "peer failed Pacemaker membership criteria", FALSE);
1620 }
else if (termination_requested) {
1621 if ((when_member <= 0) && (when_online <= 0)
1623 crm_info(
"%s was fenced as requested", pe__node_name(this_node));
1631 if (pending_too_long(
scheduler, this_node, when_member, when_online)) {
1633 "peer pending timed out on joining the process group",
1636 }
else if ((when_member > 0) || (when_online > 0)) {
1637 crm_info(
"- %s is not ready to run resources",
1638 pe__node_name(this_node));
1643 crm_trace(
"%s is down or still coming up",
1644 pe__node_name(this_node));
1647 }
else if (when_member <= 0) {
1650 "peer is no longer part of the cluster", TRUE);
1652 }
else if (when_online <= 0) {
1654 "peer process is no longer available", FALSE);
1659 crm_info(
"%s is active", pe__node_name(this_node));
1663 crm_info(
"%s is not ready to run resources", pe__node_name(this_node));
1672 return (when_member > 0);
1689 goto remote_online_done;
1694 if (container && pcmk__list_of_1(rsc->
running_on)) {
1700 crm_trace(
"%s node %s presumed ONLINE because connection resource is started",
1701 (container?
"Guest" :
"Remote"), this_node->
details->
id);
1709 crm_trace(
"%s node %s shutting down because connection resource is stopping",
1710 (container?
"Guest" :
"Remote"), this_node->
details->
id);
1716 crm_trace(
"Guest node %s UNCLEAN because guest resource failed",
1722 crm_trace(
"%s node %s OFFLINE because connection resource failed",
1723 (container?
"Guest" :
"Remote"), this_node->
details->
id);
1727 || ((container != NULL)
1730 crm_trace(
"%s node %s OFFLINE because its resource is stopped",
1731 (container?
"Guest" :
"Remote"), this_node->
details->
id);
1735 }
else if (
host && (
host->details->online == FALSE)
1736 &&
host->details->unclean) {
1737 crm_trace(
"Guest node %s UNCLEAN because host is unclean",
1749 determine_online_status(
const xmlNode *node_state,
pcmk_node_t *this_node,
1752 gboolean online = FALSE;
1775 online = determine_online_status_no_fencing(
scheduler, node_state,
1779 online = determine_online_status_fencing(
scheduler, node_state,
1788 this_node->
fixed = TRUE;
1794 this_node->
fixed = TRUE;
1799 crm_info(
"%s is not a Pacemaker node", pe__node_name(this_node));
1802 pe_proc_warn(
"%s is unclean", pe__node_name(this_node));
1805 crm_info(
"%s is %s", pe__node_name(this_node),
1812 crm_trace(
"%s is offline", pe__node_name(this_node));
1827 if (!pcmk__str_empty(
id)) {
1828 const char *end =
id + strlen(
id) - 1;
1830 for (
const char *s = end; s >
id; --s) {
1844 return (s == end)? s : (s - 1);
1868 char *basename = NULL;
1871 basename = strndup(last_rsc_id, end - last_rsc_id + 1);
1890 size_t base_name_len = end - last_rsc_id + 1;
1894 zero = calloc(base_name_len + 3,
sizeof(
char));
1896 memcpy(zero, last_rsc_id, base_name_len);
1897 zero[base_name_len] =
':';
1898 zero[base_name_len + 1] =
'0';
1903 create_fake_resource(
const char *rsc_id,
const xmlNode *rsc_entry,
1920 crm_debug(
"Detected orphaned remote node %s", rsc_id);
1928 crm_trace(
"Setting node %s as shutting down due to orphaned connection resource", rsc_id);
1935 crm_trace(
"Detected orphaned container filler %s", rsc_id);
1965 top->
id,
parent->id, rsc_id, pe__node_name(node));
1987 GList *rIter = NULL;
1990 gboolean skip_inactive = FALSE;
1998 rsc_id, pe__node_name(node),
parent->id);
1999 for (rIter =
parent->children; rsc == NULL && rIter; rIter = rIter->next) {
2000 GList *locations = NULL;
2034 rsc =
parent->fns->find_rsc(child, rsc_id, NULL,
2045 crm_notice(
"Active (now-)anonymous clone %s has " 2046 "multiple (orphan) instance histories on %s",
2047 parent->id, pe__node_name(node));
2048 skip_inactive = TRUE;
2055 g_list_free(locations);
2059 if (!skip_inactive && !inactive_instance
2062 inactive_instance =
parent->fns->find_rsc(child, rsc_id, NULL,
2068 if (inactive_instance && inactive_instance->
pending_node 2070 inactive_instance = NULL;
2076 if ((rsc == NULL) && !skip_inactive && (inactive_instance != NULL)) {
2078 rsc = inactive_instance;
2132 crm_trace(
"%s is not known as %s either (orphan)",
2138 crm_trace(
"Resource history for %s is orphaned because it is no longer primitive",
2146 if (pe_rsc_is_anon_clone(
parent)) {
2148 if (pe_rsc_is_bundled(
parent)) {
2163 pe_rsc_debug(rsc,
"Internally renamed %s on %s to %s%s",
2164 rsc_id, pe__node_name(node), rsc->
id,
2171 process_orphan_resource(
const xmlNode *rsc_entry,
const pcmk_node_t *node,
2177 crm_debug(
"Detected orphan resource %s on %s", rsc_id, pe__node_name(node));
2178 rsc = create_fake_resource(rsc_id, rsc_entry,
scheduler);
2200 char *reason = NULL;
2204 pe_rsc_trace(rsc,
"Resource %s is %s on %s: on_fail=%s",
2218 ((rsc->
clone_name == NULL)?
"" :
" also known as "),
2236 gboolean should_fence = FALSE;
2248 should_fence = TRUE;
2264 " revoked if remote connection can " 2265 "be re-established elsewhere)",
2268 should_fence = TRUE;
2272 if (reason == NULL) {
2281 save_on_fail = on_fail;
2346 if (rsc->
container && pe_rsc_is_bundled(rsc)) {
2378 "remote connection is unrecoverable", FALSE);
2411 rsc->
id, pe__node_name(node));
2414 "%s because cluster is configured not to " 2415 "stop active orphans",
2416 rsc->
id, pe__node_name(node));
2446 GList *gIter = possible_matches;
2448 for (; gIter != NULL; gIter = gIter->next) {
2454 g_list_free(possible_matches);
2473 int start_index,
int stop_index,
2477 const char *task = NULL;
2478 const char *status = NULL;
2479 GList *gIter = sorted_op_list;
2482 pe_rsc_trace(rsc,
"%s: Start index %d, stop index = %d", rsc->
id, start_index, stop_index);
2484 for (; gIter != NULL; gIter = gIter->next) {
2485 xmlNode *rsc_op = (xmlNode *) gIter->data;
2487 guint interval_ms = 0;
2489 const char *
id =
ID(rsc_op);
2494 pe_rsc_trace(rsc,
"Skipping %s on %s: node is offline",
2495 rsc->
id, pe__node_name(node));
2499 }
else if (start_index < stop_index && counter <= stop_index) {
2500 pe_rsc_trace(rsc,
"Skipping %s on %s: resource is not active",
2501 id, pe__node_name(node));
2504 }
else if (counter < start_index) {
2506 id, pe__node_name(node), counter);
2511 if (interval_ms == 0) {
2513 id, pe__node_name(node));
2520 id, pe__node_name(node));
2526 pe_rsc_trace(rsc,
"Creating %s on %s", key, pe__node_name(node));
2536 int implied_monitor_start = -1;
2537 int implied_clone_start = -1;
2538 const char *task = NULL;
2539 const char *status = NULL;
2544 for (
const GList *iter = sorted_op_list; iter != NULL; iter = iter->next) {
2545 const xmlNode *rsc_op = (
const xmlNode *) iter->data;
2554 *stop_index = counter;
2558 *start_index = counter;
2560 }
else if ((implied_monitor_start <= *stop_index)
2566 implied_monitor_start = counter;
2570 implied_clone_start = counter;
2574 if (*start_index == -1) {
2575 if (implied_clone_start != -1) {
2576 *start_index = implied_clone_start;
2577 }
else if (implied_monitor_start != -1) {
2578 *start_index = implied_monitor_start;
2588 time_t lock_time = 0;
2591 &lock_time) ==
pcmk_ok) && (lock_time != 0)) {
2596 pe_rsc_info(rsc,
"Shutdown lock for %s on %s expired",
2597 rsc->
id, pe__node_name(node));
2621 unpack_lrm_resource(
pcmk_node_t *node,
const xmlNode *lrm_resource,
2624 GList *gIter = NULL;
2625 int stop_index = -1;
2626 int start_index = -1;
2629 const char *rsc_id =
ID(lrm_resource);
2632 GList *op_list = NULL;
2633 GList *sorted_op_list = NULL;
2635 xmlNode *rsc_op = NULL;
2636 xmlNode *last_failure = NULL;
2641 if (rsc_id == NULL) {
2643 " entry without id");
2647 rsc_id, pe__node_name(node));
2653 op_list = g_list_prepend(op_list, rsc_op);
2657 if (op_list == NULL) {
2664 rsc = unpack_find_resource(
scheduler, node, rsc_id);
2666 if (op_list == NULL) {
2670 rsc = process_orphan_resource(lrm_resource, node,
scheduler);
2677 unpack_shutdown_lock(lrm_resource, rsc, node,
scheduler);
2681 saved_role = rsc->
role;
2685 for (gIter = sorted_op_list; gIter != NULL; gIter = gIter->next) {
2686 xmlNode *rsc_op = (xmlNode *) gIter->data;
2688 unpack_rsc_op(rsc, node, rsc_op, &last_failure, &on_fail);
2693 process_recurring(node, rsc, start_index, stop_index, sorted_op_list,
2697 g_list_free(sorted_op_list);
2699 process_rsc_state(rsc, node, on_fail);
2703 || (req_role < rsc->next_role)) {
2708 pe_rsc_info(rsc,
"%s: Not overwriting calculated next role %s" 2709 " with requested next role %s",
2714 if (saved_role > rsc->
role) {
2715 rsc->
role = saved_role;
2722 handle_orphaned_container_fillers(
const xmlNode *lrm_rsc_list,
2725 for (
const xmlNode *rsc_entry = pcmk__xe_first_child(lrm_rsc_list);
2726 rsc_entry != NULL; rsc_entry = pcmk__xe_next(rsc_entry)) {
2731 const char *container_id;
2739 if (container_id == NULL || rsc_id == NULL) {
2744 if (container == NULL) {
2749 if ((rsc == NULL) || (rsc->
container != NULL)
2754 pe_rsc_trace(rsc,
"Mapped container of orphaned resource %s to %s",
2755 rsc->
id, container_id);
2770 unpack_node_lrm(
pcmk_node_t *node,
const xmlNode *xml,
2773 bool found_orphaned_container_filler =
false;
2793 found_orphaned_container_filler =
true;
2800 if (found_orphaned_container_filler) {
2801 handle_orphaned_container_fillers(xml,
scheduler);
2818 set_node_score(gpointer key, gpointer value, gpointer user_data)
2821 int *score = user_data;
2826 #define XPATH_NODE_STATE "/" XML_TAG_CIB "/" XML_CIB_TAG_STATUS \ 2827 "/" XML_CIB_TAG_STATE 2828 #define SUB_XPATH_LRM_RESOURCE "/" XML_CIB_TAG_LRM \ 2829 "/" XML_LRM_TAG_RESOURCES \ 2830 "/" XML_LRM_TAG_RESOURCE 2831 #define SUB_XPATH_LRM_RSC_OP "/" XML_LRM_TAG_RSC_OP 2834 find_lrm_op(
const char *resource,
const char *op,
const char *node,
const char *source,
2837 GString *xpath = NULL;
2838 xmlNode *xml = NULL;
2840 CRM_CHECK((resource != NULL) && (op != NULL) && (node != NULL),
2843 xpath = g_string_sized_new(256);
2856 }
else if ((source != NULL)
2862 g_string_append_c(xpath,
']');
2867 g_string_free(xpath, TRUE);
2869 if (xml && target_rc >= 0) {
2883 find_lrm_resource(
const char *rsc_id,
const char *node_name,
2886 GString *xpath = NULL;
2887 xmlNode *xml = NULL;
2889 CRM_CHECK((rsc_id != NULL) && (node_name != NULL),
return NULL);
2891 xpath = g_string_sized_new(256);
2900 g_string_free(xpath, TRUE);
2917 xmlXPathObjectPtr search;
2918 GString *xpath = g_string_sized_new(256);
2926 result = (numXpathResults(search) == 0);
2928 g_string_free(xpath, TRUE);
2945 monitor_not_running_after(
const char *rsc_id,
const char *node_name,
2946 const xmlNode *xml_op,
bool same_node,
2971 non_monitor_after(
const char *rsc_id,
const char *node_name,
2972 const xmlNode *xml_op,
bool same_node,
2975 xmlNode *lrm_resource = NULL;
2977 lrm_resource = find_lrm_resource(rsc_id, node_name,
scheduler);
2978 if (lrm_resource == NULL) {
2984 const char * task = NULL;
3016 newer_state_after_migrate(
const char *rsc_id,
const char *node_name,
3017 const xmlNode *migrate_to,
3018 const xmlNode *migrate_from,
3021 const xmlNode *xml_op = migrate_to;
3022 const char *source = NULL;
3023 const char *
target = NULL;
3024 bool same_node =
false;
3027 xml_op = migrate_from;
3038 xml_op = migrate_from;
3042 xml_op = migrate_to;
3047 xml_op = migrate_to;
3051 xml_op = migrate_from;
3059 return non_monitor_after(rsc_id, node_name, xml_op, same_node,
scheduler)
3060 || monitor_not_running_after(rsc_id, node_name, xml_op, same_node,
3077 get_migration_node_names(
const xmlNode *entry,
const pcmk_node_t *source_node,
3079 const char **source_name,
const char **target_name)
3083 if ((*source_name == NULL) || (*target_name == NULL)) {
3084 crm_err(
"Ignoring resource history entry %s without " 3090 if ((source_node != NULL)
3091 && !pcmk__str_eq(*source_name, source_node->
details->
uname,
3093 crm_err(
"Ignoring resource history entry %s because " 3095 ID(entry), *source_name, pe__node_name(source_node));
3099 if ((target_node != NULL)
3100 && !pcmk__str_eq(*target_name, target_node->
details->
uname,
3102 crm_err(
"Ignoring resource history entry %s because " 3104 ID(entry), *target_name, pe__node_name(target_node));
3126 pe_rsc_trace(rsc,
"Dangling migration of %s requires stop on %s",
3127 rsc->
id, pe__node_name(node));
3140 unpack_migrate_to_success(
struct action_history *history)
3176 xmlNode *migrate_from = NULL;
3177 const char *source = NULL;
3178 const char *
target = NULL;
3179 bool source_newer_op =
false;
3180 bool target_newer_state =
false;
3181 bool active_on_target =
false;
3184 if (get_migration_node_names(history->xml, history->node, NULL, &source,
3190 source_newer_op = non_monitor_after(history->rsc->id, source, history->xml,
3191 true, history->rsc->cluster);
3195 target, source, -1, history->rsc->cluster);
3196 if (migrate_from != NULL) {
3197 if (source_newer_op) {
3212 target_newer_state = newer_state_after_migrate(history->rsc->id,
target,
3213 history->xml, migrate_from,
3214 history->rsc->cluster);
3215 if (source_newer_op && target_newer_state) {
3224 add_dangling_migration(history->rsc, history->node);
3234 active_on_target = !target_newer_state && (target_node != NULL)
3238 if (active_on_target) {
3257 && unknown_on_node(history->rsc,
target)) {
3261 if (active_on_target) {
3267 if ((source_node != NULL) && source_node->
details->
online) {
3274 history->rsc->partial_migration_target = target_node;
3275 history->rsc->partial_migration_source = source_node;
3278 }
else if (!source_newer_op) {
3293 unpack_migrate_to_failure(
struct action_history *history)
3295 xmlNode *target_migrate_from = NULL;
3296 const char *source = NULL;
3297 const char *
target = NULL;
3300 if (get_migration_node_names(history->xml, history->node, NULL, &source,
3311 target_migrate_from = find_lrm_op(history->rsc->id,
3320 !unknown_on_node(history->rsc,
target)
3324 && !newer_state_after_migrate(history->rsc->id,
target, history->xml,
3325 target_migrate_from,
3326 history->rsc->cluster)) {
3339 }
else if (!non_monitor_after(history->rsc->id, source, history->xml,
true,
3340 history->rsc->cluster)) {
3347 history->rsc->dangling_migrations =
3348 g_list_prepend(history->rsc->dangling_migrations,
3349 (gpointer) history->node);
3360 unpack_migrate_from_failure(
struct action_history *history)
3362 xmlNode *source_migrate_to = NULL;
3363 const char *source = NULL;
3364 const char *
target = NULL;
3367 if (get_migration_node_names(history->xml, NULL, history->node, &source,
3380 history->rsc->cluster);
3387 !unknown_on_node(history->rsc, source)
3391 && !newer_state_after_migrate(history->rsc->id, source,
3392 source_migrate_to, history->xml,
3393 history->rsc->cluster)) {
3414 record_failed_op(
struct action_history *history)
3416 if (!(history->node->details->online)) {
3420 for (
const xmlNode *xIter = history->rsc->cluster->failed->children;
3421 xIter != NULL; xIter = xIter->next) {
3423 const char *key = pe__xe_history_key(xIter);
3427 && pcmk__str_eq(
uname, history->node->details->uname,
3429 crm_trace(
"Skipping duplicate entry %s on %s",
3430 history->key, pe__node_name(history->node));
3435 crm_trace(
"Adding entry for %s on %s to failed action list",
3436 history->key, pe__node_name(history->node));
3443 last_change_str(
const xmlNode *xml_op)
3451 const char *p = strchr(when_s,
' ');
3454 if ((p != NULL) && (*(++p) !=
'\0')) {
3462 result = strdup(
"unknown time");
3556 return first - second;
3571 if (fail_rsc->
parent != NULL) {
3574 if (pe_rsc_is_anon_clone(
parent)) {
3583 crm_notice(
"%s will not be started under current conditions", fail_rsc->
id);
3588 g_hash_table_foreach(fail_rsc->
allowed_nodes, set_node_score, &score);
3600 unpack_failure_handling(
struct action_history *history,
3605 history->interval_ms,
true);
3609 history->interval_ms, config);
3614 history->interval_ms, on_fail_str);
3617 g_hash_table_destroy(meta);
3631 unpack_rsc_op_failure(
struct action_history *history,
3633 enum rsc_role_e fail_role, xmlNode **last_failure,
3636 bool is_probe =
false;
3637 char *last_change_s = NULL;
3639 *last_failure = history->xml;
3642 last_change_s = last_change_str(history->xml);
3646 crm_trace(
"Unexpected result (%s%s%s) was recorded for " 3647 "%s of %s on %s at %s " CRM_XS " exit-status=%d id=%s",
3648 services_ocf_exitcode_str(history->exit_status),
3649 (pcmk__str_empty(history->exit_reason)?
"" :
": "),
3650 pcmk__s(history->exit_reason,
""),
3651 (is_probe?
"probe" : history->task), history->rsc->id,
3652 pe__node_name(history->node), last_change_s,
3653 history->exit_status, history->id);
3655 crm_warn(
"Unexpected result (%s%s%s) was recorded for " 3656 "%s of %s on %s at %s " CRM_XS " exit-status=%d id=%s",
3657 services_ocf_exitcode_str(history->exit_status),
3658 (pcmk__str_empty(history->exit_reason)?
"" :
": "),
3659 pcmk__s(history->exit_reason,
""),
3660 (is_probe?
"probe" : history->task), history->rsc->id,
3661 pe__node_name(history->node), last_change_s,
3662 history->exit_status, history->id);
3664 if (is_probe && (history->exit_status !=
PCMK_OCF_OK)
3671 crm_notice(
"If it is not possible for %s to run on %s, see " 3672 "the resource-discovery option for location constraints",
3673 history->rsc->id, pe__node_name(history->node));
3676 record_failed_op(history);
3679 free(last_change_s);
3681 if (cmp_on_fail(*on_fail, config_on_fail) < 0) {
3685 *on_fail = config_on_fail;
3690 "__stop_fail__", history->rsc->cluster);
3693 unpack_migrate_to_failure(history);
3696 unpack_migrate_from_failure(history);
3705 "demote with on-fail=block");
3722 pe_rsc_trace(history->rsc,
"Leaving %s stopped", history->rsc->id);
3726 pe_rsc_trace(history->rsc,
"Setting %s active", history->rsc->id);
3727 set_active(history->rsc);
3731 "Resource %s: role=%s, unclean=%s, on_fail=%s, fail_role=%s",
3732 history->rsc->id,
role2text(history->rsc->role),
3733 pcmk__btoa(history->node->details->unclean),
3737 && (history->rsc->next_role < fail_role)) {
3742 ban_from_all_nodes(history->rsc);
3756 block_if_unrecoverable(
struct action_history *history)
3758 char *last_change_s = NULL;
3763 if (
pe_can_fence(history->node->details->data_set, history->node)) {
3767 last_change_s = last_change_str(history->xml);
3768 pe_proc_err(
"No further recovery can be attempted for %s " 3769 "because %s on %s failed (%s%s%s) at %s " 3771 history->rsc->id, history->task, pe__node_name(history->node),
3772 services_ocf_exitcode_str(history->exit_status),
3773 (pcmk__str_empty(history->exit_reason)?
"" :
": "),
3774 pcmk__s(history->exit_reason,
""),
3775 last_change_s, history->exit_status, history->id);
3777 free(last_change_s);
3793 remap_because(
struct action_history *history,
const char **why,
int value,
3796 if (history->execution_status != value) {
3797 history->execution_status = value;
3825 remap_operation(
struct action_history *history,
3828 bool is_probe =
false;
3829 int orig_exit_status = history->exit_status;
3830 int orig_exec_status = history->execution_status;
3831 const char *why = NULL;
3832 const char *task = history->task;
3836 if (history->exit_status != orig_exit_status) {
3837 why =
"degraded result";
3838 if (!expired && (!history->node->details->shutdown
3839 || history->node->details->online)) {
3840 record_failed_op(history);
3844 if (!pe_rsc_is_bundled(history->rsc)
3850 why =
"equivalent probe result";
3858 switch (history->execution_status) {
3867 "node-fatal error");
3879 if (history->expected_exit_status < 0) {
3889 "obsolete history format");
3890 crm_warn(
"Expected result not found for %s on %s " 3891 "(corrupt or obsolete CIB?)",
3892 history->key, pe__node_name(history->node));
3894 }
else if (history->exit_status == history->expected_exit_status) {
3900 "%s on %s: expected %d (%s), got %d (%s%s%s)",
3901 history->key, pe__node_name(history->node),
3902 history->expected_exit_status,
3903 services_ocf_exitcode_str(history->expected_exit_status),
3904 history->exit_status,
3905 services_ocf_exitcode_str(history->exit_status),
3906 (pcmk__str_empty(history->exit_reason)?
"" :
": "),
3907 pcmk__s(history->exit_reason,
""));
3910 switch (history->exit_status) {
3914 char *last_change_s = last_change_str(history->xml);
3917 pe_rsc_info(history->rsc,
"Probe found %s active on %s at %s",
3918 history->rsc->id, pe__node_name(history->node),
3920 free(last_change_s);
3926 || (history->expected_exit_status == history->exit_status)
3943 && (history->exit_status != history->expected_exit_status)) {
3944 char *last_change_s = last_change_str(history->xml);
3948 "Probe found %s active and promoted on %s at %s",
3949 history->rsc->id, pe__node_name(history->node),
3951 free(last_change_s);
3954 || (history->exit_status == history->expected_exit_status)) {
3972 guint interval_ms = 0;
3976 if (interval_ms == 0) {
3978 block_if_unrecoverable(history);
3993 block_if_unrecoverable(history);
4000 char *last_change_s = last_change_str(history->xml);
4002 crm_info(
"Treating unknown exit status %d from %s of %s " 4003 "on %s at %s as failure",
4004 history->exit_status, task, history->rsc->id,
4005 pe__node_name(history->node), last_change_s);
4007 "unknown exit status");
4008 free(last_change_s);
4016 "Remapped %s result from [%s: %s] to [%s: %s] " 4018 history->key, pcmk_exec_status_str(orig_exec_status),
4020 pcmk_exec_status_str(history->execution_status),
4027 should_clear_for_param_change(
const xmlNode *xml_op,
const char *task,
4044 switch (digest_data->
rc) {
4046 crm_trace(
"Resource %s history entry %s on %s" 4047 " has no digest to compare",
4048 rsc->
id, pe__xe_history_key(xml_op),
4077 should_ignore_failure_timeout(
const pcmk_resource_t *rsc,
const char *task,
4078 guint interval_ms,
bool is_last_failure)
4102 && (interval_ms != 0)
4108 if (is_last_failure) {
4109 crm_info(
"Waiting to clear monitor failure for remote node %s" 4110 " until fencing has occurred", rsc->
id);
4137 check_operation_expiry(
struct action_history *history)
4139 bool expired =
false;
4140 bool is_last_failure =
pcmk__ends_with(history->id,
"_last_failure_0");
4141 time_t last_run = 0;
4142 int unexpired_fail_count = 0;
4143 const char *clear_reason = NULL;
4147 "Resource history entry %s on %s is not expired: " 4148 "Not Installed does not expire",
4149 history->id, pe__node_name(history->node));
4153 if ((history->rsc->failure_timeout > 0)
4160 time_t last_failure = 0;
4163 if ((now >= (last_run + history->rsc->failure_timeout))
4164 && !should_ignore_failure_timeout(history->rsc, history->task,
4165 history->interval_ms,
4177 crm_trace(
"%s@%lld is %sexpired @%lld with unexpired_failures=%d timeout=%ds" 4178 " last-failure@%lld",
4179 history->id, (
long long) last_run, (expired?
"" :
"not "),
4180 (
long long) now, unexpired_fail_count,
4181 history->rsc->failure_timeout, (
long long) last_failure);
4182 last_failure += history->rsc->failure_timeout + 1;
4183 if (unexpired_fail_count && (now < last_failure)) {
4185 "fail count expiration");
4194 if (unexpired_fail_count == 0) {
4196 clear_reason =
"it expired";
4206 "Resource history entry %s on %s is not expired: " 4207 "Unexpired fail count",
4208 history->id, pe__node_name(history->node));
4212 }
else if (is_last_failure
4213 && (history->rsc->remote_reconnect_ms != 0)) {
4217 clear_reason =
"reconnect interval is set";
4221 if (!expired && is_last_failure
4222 && should_clear_for_param_change(history->xml, history->task,
4223 history->rsc, history->node)) {
4224 clear_reason =
"resource parameters have changed";
4227 if (clear_reason != NULL) {
4232 clear_reason, history->rsc->cluster);
4236 && (history->rsc->remote_reconnect_ms != 0)) {
4245 crm_info(
"Clearing %s failure will wait until any scheduled " 4246 "fencing of %s completes",
4247 history->task, history->rsc->id);
4248 order_after_remote_fencing(clear_op, history->rsc,
4249 history->rsc->cluster);
4253 if (expired && (history->interval_ms == 0)
4255 switch (history->exit_status) {
4263 "Resource history entry %s on %s is not expired: " 4265 history->id, pe__node_name(history->node));
4297 update_resource_state(
struct action_history *history,
int exit_status,
4298 const xmlNode *last_failure,
4301 bool clear_past_failure =
false;
4304 || (!pe_rsc_is_bundled(history->rsc)
4309 clear_past_failure =
true;
4313 if ((last_failure != NULL)
4314 && pcmk__str_eq(history->key, pe__xe_history_key(last_failure),
4316 clear_past_failure =
true;
4319 set_active(history->rsc);
4324 clear_past_failure =
true;
4328 clear_past_failure =
true;
4333 clear_past_failure =
true;
4339 clear_past_failure =
true;
4346 clear_past_failure =
true;
4350 unpack_migrate_to_success(history);
4354 history->rsc->id, pe__node_name(history->node));
4355 set_active(history->rsc);
4358 if (!clear_past_failure) {
4368 "%s (%s) is not cleared by a completed %s",
4369 history->rsc->id,
fail2text(*on_fail), history->task);
4379 "clear past failures");
4383 if (history->rsc->remote_reconnect_ms == 0) {
4392 "clear past failures and reset remote");
4407 can_affect_state(
struct action_history *history)
4436 unpack_action_result(
struct action_history *history)
4439 &(history->execution_status)) < 0)
4443 crm_err(
"Ignoring resource history entry %s for %s on %s " 4445 history->id, history->rsc->id, pe__node_name(history->node),
4451 &(history->exit_status)) < 0)
4452 || (history->exit_status < 0) || (history->exit_status >
CRM_EX_MAX)) {
4458 crm_err(
"Ignoring resource history entry %s for %s on %s " 4460 history->id, history->rsc->id, pe__node_name(history->node),
4484 process_expired_result(
struct action_history *history,
int orig_exit_status)
4486 if (!pe_rsc_is_bundled(history->rsc)
4488 && (orig_exit_status != history->expected_exit_status)) {
4493 crm_trace(
"Ignoring resource history entry %s for probe of %s on %s: " 4494 "Masked failure expired",
4495 history->id, history->rsc->id,
4496 pe__node_name(history->node));
4500 if (history->exit_status == history->expected_exit_status) {
4504 if (history->interval_ms == 0) {
4505 crm_notice(
"Ignoring resource history entry %s for %s of %s on %s: " 4507 history->id, history->task, history->rsc->id,
4508 pe__node_name(history->node));
4512 if (history->node->details->online && !history->node->details->unclean) {
4523 crm_notice(
"Rescheduling %s-interval %s of %s on %s " 4524 "after failure expired",
4526 history->rsc->id, pe__node_name(history->node));
4528 "calculated-failure-timeout");
4545 mask_probe_failure(
struct action_history *history,
int orig_exit_status,
4546 const xmlNode *last_failure,
4555 crm_notice(
"Treating probe result '%s' for %s on %s as 'not running'",
4556 services_ocf_exitcode_str(orig_exit_status), history->rsc->id,
4557 pe__node_name(history->node));
4558 update_resource_state(history, history->expected_exit_status, last_failure,
4562 record_failed_op(history);
4564 history->rsc->cluster);
4579 failure_is_newer(
const struct action_history *history,
4580 const xmlNode *last_failure)
4582 guint failure_interval_ms = 0U;
4583 long long failure_change = 0LL;
4584 long long this_change = 0LL;
4586 if (last_failure == NULL) {
4590 if (!pcmk__str_eq(history->task,
4597 &failure_interval_ms) !=
pcmk_ok)
4598 || (history->interval_ms != failure_interval_ms)) {
4607 || (failure_change < this_change)) {
4622 process_pending_action(
struct action_history *history,
4623 const xmlNode *last_failure)
4634 if (failure_is_newer(history, last_failure)) {
4640 set_active(history->rsc);
4646 && history->node->details->unclean) {
4650 const char *migrate_target = NULL;
4661 if (history->rsc->pending_task != NULL) {
4675 history->rsc->pending_task = strdup(
"probe");
4676 history->rsc->pending_node = history->node;
4679 history->rsc->pending_task = strdup(history->task);
4680 history->rsc->pending_node = history->node;
4689 bool expired =
false;
4694 struct action_history history = {
4701 CRM_CHECK(rsc && node && xml_op,
return);
4703 history.id =
ID(xml_op);
4704 if (history.id == NULL) {
4705 crm_err(
"Ignoring resource history entry for %s on %s without ID",
4706 rsc->
id, pe__node_name(node));
4712 if (history.task == NULL) {
4713 crm_err(
"Ignoring resource history entry %s for %s on %s without " 4718 &(history.interval_ms));
4719 if (!can_affect_state(&history)) {
4721 "Ignoring resource history entry %s for %s on %s " 4722 "with irrelevant action '%s'",
4723 history.id, rsc->
id, pe__node_name(node), history.task);
4727 if (unpack_action_result(&history) !=
pcmk_rc_ok) {
4732 history.key = pe__xe_history_key(xml_op);
4735 pe_rsc_trace(rsc,
"Unpacking %s (%s call %d on %s): %s (%s)",
4736 history.id, history.task, history.call_id, pe__node_name(node),
4737 pcmk_exec_status_str(history.execution_status),
4742 "%s is running on %s, which is unclean (further action " 4743 "depends on value of stop's on-fail attribute)",
4744 rsc->
id, pe__node_name(node));
4747 expired = check_operation_expiry(&history);
4748 old_rc = history.exit_status;
4750 remap_operation(&history, on_fail, expired);
4752 if (expired && (process_expired_result(&history, old_rc) ==
pcmk_rc_ok)) {
4757 mask_probe_failure(&history, old_rc, *last_failure, on_fail);
4765 switch (history.execution_status) {
4767 process_pending_action(&history, *last_failure);
4771 update_resource_state(&history, history.exit_status, *last_failure,
4776 unpack_failure_handling(&history, &failure_strategy, &fail_role);
4778 crm_warn(
"Cannot ignore failed %s of %s on %s: " 4779 "Resource agent doesn't exist " 4780 CRM_XS " status=%d rc=%d id=%s",
4781 history.task, rsc->
id, pe__node_name(node),
4782 history.execution_status, history.exit_status,
4791 unpack_rsc_op_failure(&history, failure_strategy, fail_role,
4792 last_failure, on_fail);
4822 unpack_failure_handling(&history, &failure_strategy, &fail_role);
4827 char *last_change_s = last_change_str(xml_op);
4829 crm_warn(
"Pretending failed %s (%s%s%s) of %s on %s at %s succeeded " 4831 history.task, services_ocf_exitcode_str(history.exit_status),
4832 (pcmk__str_empty(history.exit_reason)?
"" :
": "),
4833 pcmk__s(history.exit_reason,
""), rsc->
id, pe__node_name(node),
4834 last_change_s, history.id);
4835 free(last_change_s);
4837 update_resource_state(&history, history.expected_exit_status,
4838 *last_failure, on_fail);
4842 record_failed_op(&history);
4846 *on_fail = failure_strategy;
4850 unpack_rsc_op_failure(&history, failure_strategy, fail_role,
4851 last_failure, on_fail);
4854 uint8_t log_level = LOG_ERR;
4857 log_level = LOG_NOTICE;
4860 "Preventing %s from restarting on %s because " 4861 "of hard failure (%s%s%s) " CRM_XS " %s",
4862 parent->id, pe__node_name(node),
4863 services_ocf_exitcode_str(history.exit_status),
4864 (pcmk__str_empty(history.exit_reason)?
"" :
": "),
4865 pcmk__s(history.exit_reason,
""), history.id);
4870 crm_err(
"Preventing %s from restarting anywhere because " 4871 "of fatal failure (%s%s%s) " CRM_XS " %s",
4872 parent->id, services_ocf_exitcode_str(history.exit_status),
4873 (pcmk__str_empty(history.exit_reason)?
"" :
": "),
4874 pcmk__s(history.exit_reason,
""), history.id);
4881 pe_rsc_trace(rsc,
"%s role on %s after %s is %s (next %s)",
4882 rsc->
id, pe__node_name(node), history.id,
4887 add_node_attrs(
const xmlNode *xml_obj,
pcmk_node_t *node,
bool overwrite,
4890 const char *cluster_name = NULL;
4919 strdup(cluster_name));
4938 }
else if (cluster_name) {
4942 strdup(cluster_name));
4948 extract_operations(
const char *node,
const char *rsc, xmlNode * rsc_entry, gboolean active_filter)
4951 int stop_index = -1;
4952 int start_index = -1;
4954 xmlNode *rsc_op = NULL;
4956 GList *gIter = NULL;
4957 GList *op_list = NULL;
4958 GList *sorted_op_list = NULL;
4962 sorted_op_list = NULL;
4964 for (rsc_op = pcmk__xe_first_child(rsc_entry);
4965 rsc_op != NULL; rsc_op = pcmk__xe_next(rsc_op)) {
4971 op_list = g_list_prepend(op_list, rsc_op);
4975 if (op_list == NULL) {
4983 if (active_filter == FALSE) {
4984 return sorted_op_list;
4991 for (gIter = sorted_op_list; gIter != NULL; gIter = gIter->next) {
4992 xmlNode *rsc_op = (xmlNode *) gIter->data;
4996 if (start_index < stop_index) {
4997 crm_trace(
"Skipping %s: not active",
ID(rsc_entry));
5000 }
else if (counter < start_index) {
5004 op_list = g_list_append(op_list, rsc_op);
5007 g_list_free(sorted_op_list);
5015 GList *output = NULL;
5016 GList *intermediate = NULL;
5018 xmlNode *tmp = NULL;
5023 xmlNode *node_state = NULL;
5025 for (node_state = pcmk__xe_first_child(status); node_state != NULL;
5026 node_state = pcmk__xe_next(node_state)) {
5036 if(this_node == NULL) {
5041 determine_remote_online_status(
scheduler, this_node);
5044 determine_online_status(node_state, this_node,
scheduler);
5053 xmlNode *lrm_rsc = NULL;
5058 for (lrm_rsc = pcmk__xe_first_child(tmp); lrm_rsc != NULL;
5059 lrm_rsc = pcmk__xe_next(lrm_rsc)) {
5061 if (pcmk__str_eq((
const char *)lrm_rsc->name,
5070 intermediate = extract_operations(
uname, rsc_id, lrm_rsc, active_filter);
5071 output = g_list_concat(output, intermediate);
const pcmk_resource_t * pe__const_top_resource(const pcmk_resource_t *rsc, bool include_bundle)
GHashTable * tags
Configuration tags (ID -> pcmk_tag_t *)
#define CRM_CHECK(expr, failure_action)
bool pe_can_fence(const pcmk_scheduler_t *scheduler, const pcmk_node_t *node)
#define XML_RSC_OP_LAST_CHANGE
void verify_pe_options(GHashTable *options)
enum pe_quorum_policy no_quorum_policy
Response to loss of quorum.
bool pe__shutdown_requested(const pcmk_node_t *node)
pcmk_ticket_t * ticket_new(const char *ticket_id, pcmk_scheduler_t *scheduler)
pcmk_node_t * pe__copy_node(const pcmk_node_t *this_node)
Service failed and possibly in promoted role.
Whether resource has been removed but has a container.
#define crm_notice(fmt, args...)
GHashTable * known_on
Nodes where resource has been probed (key is node ID, not name)
bool pe__is_guest_or_remote_node(const pcmk_node_t *node)
No connection to executor.
pcmk_scheduler_t * cluster
Cluster that resource is part of.
gboolean unpack_nodes(xmlNode *xml_nodes, pcmk_scheduler_t *scheduler)
GHashTable * attrs
Node attributes.
#define pe_rsc_debug(rsc, fmt, args...)
gboolean unseen
Whether node has never joined cluster.
#define XML_CONFIG_ATTR_SHUTDOWN_LOCK
Whether action should not be executed.
pcmk_node_t *(* location)(const pcmk_resource_t *rsc, GList **list, int current)
List nodes where a resource (or any of its children) is.
Service active and promoted.
#define pe__set_action_flags(action, flags_to_set)
bool pe__is_universal_clone(const pcmk_resource_t *rsc, const pcmk_scheduler_t *scheduler)
pcmk_node_t * partial_migration_target
The destination node, if migrate_to completed but migrate_from has not.
#define XML_NODE_IS_FENCED
const char * pe_node_attribute_raw(const pcmk_node_t *node, const char *name)
pcmk_resource_t * pe__find_bundle_replica(const pcmk_resource_t *bundle, const pcmk_node_t *node)
GHashTable * state
XML attributes from ticket state.
int pcmk__scan_min_int(const char *text, int *result, int minimum)
pcmk_resource_t * uber_parent(pcmk_resource_t *rsc)
#define stop_action(rsc, node, optional)
bool pcmk__strcase_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
#define XML_ATTR_QUORUM_PANIC
Whether cluster is symmetric (via symmetric-cluster property)
#define XML_CONFIG_ATTR_PRIORITY_FENCING_DELAY
enum rsc_role_e role
Resource's current role.
#define XML_TAG_UTILIZATION
gint pe__cmp_node_name(gconstpointer a, gconstpointer b)
Whether partition has quorum (via have-quorum property)
#define pcmk__config_warn(fmt...)
Ban resource from current node.
GList * children
Resource's child resources, if any.
Match only clones and their instances, by either clone or instance ID.
#define XML_RULE_ATTR_SCORE
enum pcmk__digest_result rc
#define XML_BOOLEAN_FALSE
gboolean standby
Whether ticket is temporarily suspended.
gboolean order_actions(pcmk_action_t *lh_action, pcmk_action_t *rh_action, uint32_t flags)
int priority_fencing_delay
Priority fencing delay.
xmlNode * first_named_child(const xmlNode *parent, const char *name)
pcmk_resource_t * pe__create_clone_child(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler)
enum rsc_role_e next_role
Resource's scheduled next role.
Fence resource's node.
bool pcmk_is_probe(const char *task, guint interval)
gboolean get_target_role(const pcmk_resource_t *rsc, enum rsc_role_e *role)
void copy_in_properties(xmlNode *target, const xmlNode *src)
Implementation of pcmk_action_t.
int pe__is_newer_op(const xmlNode *xml_a, const xmlNode *xml_b, bool same_node_default)
int char2score(const char *score)
Get the integer value of a score string.
#define pcmk__config_err(fmt...)
xmlNode * find_xml_node(const xmlNode *root, const char *search_path, gboolean must_find)
#define PCMK_ACTION_META_DATA
#define pe_proc_warn(fmt...)
#define XML_TAG_TRANSIENT_NODEATTRS
#define PCMK_ACTION_MONITOR
GHashTable * meta
Resource's meta-attributes.
#define set_config_flag(scheduler, option, flag)
pcmk_action_t * pe_fence_op(pcmk_node_t *node, const char *op, bool optional, const char *reason, bool priority_delay, pcmk_scheduler_t *scheduler)
op_digest_cache_t * rsc_action_digest_cmp(pcmk_resource_t *rsc, const xmlNode *xml_op, pcmk_node_t *node, pcmk_scheduler_t *scheduler)
#define XML_LRM_TAG_RESOURCE
Whether unseen nodes should be fenced (via startup-fencing property)
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
#define pe__set_working_set_flags(scheduler, flags_to_set)
#define PCMK_ACTION_MIGRATE_TO
gboolean pending
Whether controller membership is pending.
#define XML_NVPAIR_ATTR_NAME
#define SUB_XPATH_LRM_RSC_OP
#define XML_NODE_IS_MAINTENANCE
gint sort_op_by_callid(gconstpointer a, gconstpointer b)
#define XML_CIB_TAG_RSC_TEMPLATE
Necessary CIB secrets are unavailable.
Whether concurrent fencing is allowed (via concurrent-fencing property)
action_fail_response
Possible responses to a resource action failure.
#define CRM_LOG_ASSERT(expr)
const char * pe_pref(GHashTable *options, const char *name)
Service promoted but more likely to fail soon.
pcmk_action_t * pe__clear_failcount(pcmk_resource_t *rsc, const pcmk_node_t *node, const char *reason, pcmk_scheduler_t *scheduler)
Schedule a controller operation to clear a fail count.
enum crm_ais_msg_types type
#define XML_CONFIG_ATTR_NODE_PENDING_TIMEOUT
#define CRMD_JOINSTATE_NACK
#define CRM_ATTR_CLUSTER_NAME
Ensure crm_exit_t can hold this.
void pe_fence_node(pcmk_scheduler_t *scheduler, pcmk_node_t *node, const char *reason, bool priority_delay)
Schedule a fence action for a node.
GList * pe__resource_actions(const pcmk_resource_t *rsc, const pcmk_node_t *node, const char *task, bool require_node)
Find all actions of given type for a resource.
Action did not complete in time.
#define XML_OP_ATTR_ON_FAIL
pcmk_scheduler_t * data_set
Cluster that node is part of.
pcmk_resource_t * container
Resource containing this one, if any.
Demote if promotable, else stop.
gboolean remote_was_fenced
int crm_element_value_int(const xmlNode *data, const char *name, int *dest)
Retrieve the integer value of an XML attribute.
Execution failed, do not retry on node.
bool pcmk__ends_with(const char *s, const char *match)
Implementation of pcmk_scheduler_t.
int pe__unpack_resource(xmlNode *xml_obj, pcmk_resource_t **rsc, pcmk_resource_t *parent, pcmk_scheduler_t *scheduler)
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
#define pe_proc_err(fmt...)
gboolean remote_requires_reset
gboolean unpack_resources(const xmlNode *xml_resources, pcmk_scheduler_t *scheduler)
char * dc_uuid
Node ID of designated controller.
int pe_get_failcount(const pcmk_node_t *node, pcmk_resource_t *rsc, time_t *last_failure, uint32_t flags, const xmlNode *xml_op)
No fence device is configured for target.
#define pe__set_resource_flags(resource, flags_to_set)
GList * resources
Resources in cluster.
int stonith_timeout
Value of stonith-timeout property.
#define XML_CIB_TAG_PROPSET
GList * nodes
Nodes in cluster.
int pcmk__effective_rc(int rc)
bool pcmk_xe_is_probe(const xmlNode *xml_op)
#define XML_LRM_ATTR_RSCID
gboolean remote_maintenance
Stop resource and leave stopped.
#define demote_action(rsc, node, optional)
gboolean is_dc
Whether node is cluster's DC.
#define XML_TAG_ATTR_SETS
#define XML_LRM_ATTR_TASK
pcmk_resource_t *(* find_rsc)(pcmk_resource_t *rsc, const char *search, const pcmk_node_t *node, int flags)
Search for a resource ID in a resource and its children.
gboolean decode_transition_key(const char *key, char **uuid, int *transition_id, int *action_id, int *target_rc)
Parse a transition key into its constituent parts.
const char * role2text(enum rsc_role_e role)
xmlNode * pe_create_remote_xml(xmlNode *parent, const char *uname, const char *container_id, const char *migrateable, const char *is_managed, const char *start_timeout, const char *server, const char *port)
#define PCMK__XA_EXPECTED
#define PCMK_ACTION_DEMOTE
int weight
Node score for a given resource.
int pcmk__scan_ll(const char *text, long long *result, long long default_value)
pcmk_resource_t * parent
Resource's parent resource, if any.
GList * dangling_migrations
#define CRMD_JOINSTATE_DOWN
Maximum value for this enum.
#define crm_warn(fmt, args...)
Whether any resource provides or requires unfencing (via CIB resources)
pcmk_resource_t * pe_find_resource(GList *rsc_list, const char *id_rh)
guint remote_reconnect_ms
Retry interval for remote connections.
#define XML_CONFIG_ATTR_SHUTDOWN_LOCK_LIMIT
void pe__set_next_role(pcmk_resource_t *rsc, enum rsc_role_e role, const char *why)
const char * crm_exit_str(crm_exit_t exit_code)
Put resource's node in standby.
char * clone_zero(const char *last_rsc_id)
int crm_element_value_ms(const xmlNode *data, const char *name, guint *dest)
Retrieve the millisecond value of an XML attribute.
Restart resource's container.
Implementation of pcmk_resource_t.
#define crm_debug(fmt, args...)
#define XML_RSC_ATTR_CONTAINER
Used only to initialize variables.
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
#define XML_CIB_TAG_RESOURCE
#define XML_CIB_TAG_STATE
const char * pe_base_name_end(const char *id)
void resource_location(pcmk_resource_t *rsc, const pcmk_node_t *node, int score, const char *tag, pcmk_scheduler_t *scheduler)
Parameter invalid (in local context)
gboolean unpacked
Whether node history has been unpacked.
Whether the cluster includes any Pacemaker Remote nodes (via CIB)
Parameter invalid (inherently)
#define pe_warn_once(pe_wo_bit, fmt...)
Whether resource is considered failed.
bool pcmk_xe_mask_probe_failure(const xmlNode *xml_op)
Whether resource must be stopped (instead of demoted) if it is failed.
#define crm_trace(fmt, args...)
#define CRMD_JOINSTATE_MEMBER
#define do_crm_log(level, fmt, args...)
Log a message.
void pcmk__g_strcat(GString *buffer,...) G_GNUC_NULL_TERMINATED
bool xml_contains_remote_node(xmlNode *xml)
pcmk_node_t * pe_find_node(const GList *node_list, const char *node_name)
Find a node by name in a list of nodes.
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.
xmlNode * add_node_copy(xmlNode *new_parent, xmlNode *xml_node)
const char * stonith_action
Default fencing action.
struct pe_node_shared_s * details
Basic node information.
bool pe__bundle_needs_remote_name(pcmk_resource_t *rsc)
#define crm_log_xml_debug(xml, text)
#define PCMK_ACTION_START
unsigned long long flags
Group of enum pcmk_rsc_flags.
const char * uname
Node name in cluster.
#define XML_TAG_META_SETS
void pcmk__str_update(char **str, const char *value)
Wrappers for and extensions to libxml2.
GHashTable * config_hash
Cluster properties.
char * clone_name
Resource instance ID in history.
gboolean add_tag_ref(GHashTable *tags, const char *tag_name, const char *obj_ref)
#define XML_RSC_ATTR_MANAGED
xmlNode * create_xml_node(xmlNode *parent, const char *name)
void pe__unpack_dataset_nvpairs(const xmlNode *xml_obj, const char *set_name, const pe_rule_eval_data_t *rule_data, GHashTable *hash, const char *always_first, gboolean overwrite, pcmk_scheduler_t *scheduler)
time_t lock_time
When shutdown lock started.
Action completed, result is known.
Ticket constraint object.
int crm_element_value_epoch(const xmlNode *xml, const char *name, time_t *dest)
Retrieve the seconds-since-epoch value of an XML attribute.
GHashTable * pe__node_list2table(const GList *list)
#define PCMK_NODE_ATTR_TERMINATE
time_t last_granted
When cluster was last granted the ticket.
#define XML_RSC_ATTR_TARGET_ROLE
#define XML_LRM_ATTR_MIGRATE_TARGET
Execution failed, do not retry anywhere.
#define CIB_OPTIONS_FIRST
gboolean standby
Whether in standby mode.
#define XML_RSC_ATTR_REMOTE_NODE
#define XML_LRM_ATTR_EXIT_REASON
#define XML_LRM_ATTR_RESTART_DIGEST
void pe__free_digests(gpointer ptr)
gboolean expected_up
Whether expected join state is member.
char * pcmk__op_key(const char *rsc_id, const char *op_type, guint interval_ms)
Generate an operation key (RESOURCE_ACTION_INTERVAL)
Dependencies not available locally.
Whether resource is blocked from further action.
Implementation of pcmk_node_t.
enum pe_obj_types variant
Resource variant.
bool pcmk__str_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
gboolean granted
Whether cluster has been granted the ticket.
const char * placement_strategy
Value of placement-strategy property.
void pe__update_recheck_time(time_t recheck, pcmk_scheduler_t *scheduler, const char *reason)
gboolean unpack_config(xmlNode *config, pcmk_scheduler_t *scheduler)
Whether resource has pending start action in history.
const char * id
Node ID at the cluster layer.
char * id
XML ID of ticket constraint or state.
void native_add_running(pcmk_resource_t *rsc, pcmk_node_t *node, pcmk_scheduler_t *scheduler, gboolean failed)
pcmk_node_t * pe_find_node_any(const GList *node_list, const char *id, const char *node_name)
Find a node by name or ID in a list of nodes.
guint shutdown_lock
How long to lock resources (seconds)
pcmk_action_t * custom_action(pcmk_resource_t *rsc, char *key, const char *task, const pcmk_node_t *on_node, gboolean optional, pcmk_scheduler_t *scheduler)
Create or update an action object.
GList * refs
XML IDs of objects that reference the tag.
GList * fillers
Resources contained by this one, if any.
GList * running_rsc
List of resources active on node.
Whether resource has an ignorable failure.
#define XML_ATTR_TRANSITION_KEY
gboolean rsc_discovery_enabled
Whether probes are allowed on node.
bool pe__is_guest_node(const pcmk_node_t *node)
Requested action not implemented.
int crm_str_to_boolean(const char *s, int *ret)
Basic node information (all node objects for the same node share this)
xmlXPathObjectPtr xpath_search(const xmlNode *xml_top, const char *path)
int pe__target_rc_from_xml(const xmlNode *xml_op)
xmlNode * pcmk__find_action_config(const pcmk_resource_t *rsc, const char *action_name, guint interval_ms, bool include_disabled)
Service active but more likely to fail soon.
gboolean is_remote_node
Whether this is a remote connection.
const char * fail2text(enum action_fail_response fail)
Whether resource requires fencing before recovery if on unclean node.
Agent does not implement requested action.
GHashTable * pcmk__strkey_table(GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
pcmk__action_result_t result
pcmk_rsc_methods_t * fns
Resource object methods.
gboolean unpack_tags(xmlNode *xml_tags, pcmk_scheduler_t *scheduler)
guint node_pending_timeout
Pending join times out after this (ms)
Whether to stop all resources (via stop-all-resources property)
G_GNUC_INTERNAL gint pe__cmp_rsc_priority(gconstpointer a, gconstpointer b)
gboolean unpack_remote_nodes(xmlNode *xml_resources, pcmk_scheduler_t *scheduler)
Whether fencing is enabled (via stonith-enabled property)
#define XML_LRM_TAG_RESOURCES
void pe__unpack_node_health_scores(pcmk_scheduler_t *scheduler)
#define crm_err(fmt, args...)
pcmk_scheduler_t * scheduler
#define XML_CIB_TAG_TICKET_STATE
pcmk_node_t * lock_node
Resource shutdown-locked to this node.
char guint crm_parse_interval_spec(const char *input)
Parse milliseconds from a Pacemaker interval specification.
char * pcmk__epoch2str(const time_t *source, uint32_t flags)
Whether resource is allowed to live-migrate.
#define PCMK_ACTION_MIGRATE_FROM
#define XML_ATTR_HAVE_WATCHDOG
#define XML_NODE_ATTR_RSC_DISCOVERY
Configuration tag object.
#define XML_LRM_ATTR_INTERVAL_MS
#define XML_LRM_ATTR_CALLID
#define XML_NVPAIR_ATTR_VALUE
GHashTable * utilization
Node utilization attributes.
gboolean shutdown
Whether shutting down.
#define pe__clear_resource_flags(resource, flags_to_clear)
#define XML_LRM_ATTR_OPSTATUS
bool pe__is_remote_node(const pcmk_node_t *node)
#define PCMK_ACTION_PROMOTE
#define CRMD_JOINSTATE_PENDING
GList * running_on
Nodes where resource may be active.
CRM_TRACE_INIT_DATA(pe_status)
Agent or dependency not available locally.
gboolean maintenance
Whether in maintenance mode.
void pe__clear_resource_history(pcmk_resource_t *rsc, const pcmk_node_t *node)
GHashTable * digest_cache
Cache of calculated resource digests.
void calculate_active_ops(const GList *sorted_op_list, int *start_index, int *stop_index)
GList * find_operations(const char *rsc, const char *node, gboolean active_filter, pcmk_scheduler_t *scheduler)
gboolean unpack_status(xmlNode *status, pcmk_scheduler_t *scheduler)
void destroy_ticket(gpointer data)
#define XML_CIB_TAG_STATUS
#define XML_CIB_TAG_OBJ_REF
const char * pcmk__readable_interval(guint interval_ms)
pcmk_node_t * pending_node
Node on which pending_task is happening.
#define SUB_XPATH_LRM_RESOURCE
enum action_fail_response pcmk__parse_on_fail(const pcmk_resource_t *rsc, const char *action_name, guint interval_ms, const char *value)
gboolean crm_is_true(const char *s)
#define CRM_ATTR_SITE_NAME
Treat resource as unmanaged.
Whether resource can be promoted and demoted.
Whether cluster has a fencing resource (via CIB resources)
#define XML_CIB_TAG_GROUP
pcmk_node_t * pe_create_node(const char *id, const char *uname, const char *type, const char *score, pcmk_scheduler_t *scheduler)
Resource role is unknown.
#define XML_LRM_TAG_RSC_OP
#define pe_rsc_trace(rsc, fmt, args...)
unsigned long long flags
Group of enum pcmk_scheduler_flags.
Action cannot be attempted (e.g. shutdown)
enum rsc_role_e pcmk__role_after_failure(const pcmk_resource_t *rsc, const char *action_name, enum action_fail_response on_fail, GHashTable *meta)
gboolean standby_onfail
Whether in standby mode due to on-fail.
#define XML_LRM_ATTR_MIGRATE_SOURCE
Whether resource is managed.
time_t get_effective_time(pcmk_scheduler_t *scheduler)
void freeXpathObject(xmlXPathObjectPtr xpathObj)
gboolean unclean
Whether node requires fencing.
void pe__add_param_check(const xmlNode *rsc_op, pcmk_resource_t *rsc, pcmk_node_t *node, enum pcmk__check_parameters, pcmk_scheduler_t *scheduler)
Whether cluster is in maintenance mode (via maintenance-mode property)
#define XPATH_ENABLE_UNFENCING
Whether resource has been removed from the configuration.
enum node_type type
Node variant.
#define XML_CIB_TAG_TICKETS
crm_time_t * now
Current time for evaluation purposes.
Execution failed, may be retried.
#define crm_info(fmt, args...)
GHashTable * template_rsc_sets
Mappings of template ID to resource ID.
GHashTable * pcmk__unpack_action_meta(pcmk_resource_t *rsc, const pcmk_node_t *node, const char *action_name, guint interval_ms, const xmlNode *action_config)
pcmk_node_t * dc_node
Node object for DC.
gboolean online
Whether online.
#define pe__clear_working_set_flags(scheduler, flags_to_clear)
Whether resource is not an anonymous clone instance.
char * clone_strip(const char *last_rsc_id)
Act as if failure didn't happen.
GList * stop_needed
Containers that need stop actions.
pcmk_resource_t * remote_rsc
Remote connection resource for node, if it is a Pacemaker Remote node.
pcmk_node_t * partial_migration_source
The source node, if migrate_to completed but migrate_from has not.
#define PCMK_ACTION_NOTIFY
#define pe_rsc_info(rsc, fmt, args...)
char * id
Resource ID in configuration.
GHashTable * allowed_nodes
Nodes where resource may run (key is node ID, not name)
xmlNode * crm_next_same_xml(const xmlNode *sibling)
Get next instance of same XML tag.