34#define set_config_flag(data_set, option, flag) do { \
35 const char *scf_value = pe_pref((data_set)->config_hash, (option)); \
36 if (scf_value != NULL) { \
37 if (crm_is_true(scf_value)) { \
38 (data_set)->flags = pcmk__set_flags_as(__func__, __LINE__, \
39 LOG_TRACE, "Working set", \
40 crm_system_name, (data_set)->flags, \
43 (data_set)->flags = pcmk__clear_flags_as(__func__, __LINE__,\
44 LOG_TRACE, "Working set", \
45 crm_system_name, (data_set)->flags, \
52 xmlNode **last_failure,
57static void add_node_attrs(xmlNode *attrs,
pe_node_t *node,
bool overwrite,
59static void determine_online_status(xmlNode *node_state,
pe_node_t *this_node,
62static void unpack_node_lrm(
pe_node_t *node, xmlNode *xml,
96 const char *reason,
bool priority_delay)
107 "(otherwise would because %s): "
108 "its guest resource %s is unmanaged",
109 pe__node_name(node), reason, rsc->
id);
111 crm_warn(
"Guest node %s will be fenced "
112 "(by recovering its guest resource %s): %s",
113 pe__node_name(node), rsc->
id, reason);
124 }
else if (is_dangling_guest_node(node)) {
125 crm_info(
"Cleaning up dangling connection for guest node %s: "
126 "fencing was already done because %s, "
127 "and guest resource no longer exists",
128 pe__node_name(node), reason);
137 "(otherwise would because %s): connection is unmanaged",
138 pe__node_name(node), reason);
151 crm_trace(
"Cluster node %s %s because %s",
169#define XPATH_UNFENCING_NVPAIR XML_CIB_TAG_NVPAIR \
170 "[(@" XML_NVPAIR_ATTR_NAME "='" PCMK_STONITH_PROVIDES "'" \
171 "or @" XML_NVPAIR_ATTR_NAME "='" XML_RSC_ATTR_REQUIRES "') " \
172 "and @" XML_NVPAIR_ATTR_VALUE "='" PCMK__VALUE_UNFENCING "']"
175#define XPATH_ENABLE_UNFENCING \
176 "/" XML_TAG_CIB "/" XML_CIB_TAG_CONFIGURATION "/" XML_CIB_TAG_RESOURCES \
177 "//" XML_TAG_META_SETS "/" XPATH_UNFENCING_NVPAIR \
178 "|/" XML_TAG_CIB "/" XML_CIB_TAG_CONFIGURATION "/" XML_CIB_TAG_RSCCONFIG \
179 "/" XML_TAG_META_SETS "/" XPATH_UNFENCING_NVPAIR
184 xmlXPathObjectPtr
result = NULL;
198 const char *value = NULL;
219 crm_info(
"Startup probes: disabled (dangerous)");
224 crm_info(
"Watchdog-based self-fencing will be performed via SBD if "
225 "fencing is required and stonith-watchdog-timeout is nonzero");
239 crm_debug(
"STONITH of failed nodes is %s",
245 "Support for stonith-action of 'poweroff' is deprecated "
246 "and will be removed in a future release (use 'off' instead)");
263 crm_debug(
"Stop all active resources: %s",
268 crm_debug(
"Cluster is symmetric" " - resources can run anywhere by default");
291 crm_notice(
"Resetting no-quorum-policy to 'stop': cluster has never had quorum");
296 "fencing is disabled");
306 crm_debug(
"On loss of quorum: Freeze resources");
309 crm_debug(
"On loss of quorum: Stop ALL resources");
313 "Demote promotable resources and stop other resources");
316 crm_notice(
"On loss of quorum: Fence all remaining nodes");
328 crm_trace(
"Orphan resource actions are %s",
335#ifndef PCMK__COMPAT_2_0
337 "Support for the remove-after-stop cluster property is"
338 " deprecated and will be removed in a future release");
357 crm_trace(
"Unseen nodes will be fenced");
368 crm_trace(
"Resources will%s be locked to cleanly shut down nodes",
391 if (new_node == NULL) {
396 new_node->
fixed = FALSE;
399 if (new_node->
details == NULL) {
426 "assuming 'ping'", pcmk__s(
uname,
"without name"),
430 "Support for nodes of type 'ping' (such as %s) is "
431 "deprecated and will be removed in a future release",
432 pcmk__s(
uname,
"unnamed node"));
458 xmlNode *attr_set = NULL;
459 xmlNode *attr = NULL;
461 const char *container_id =
ID(xml_obj);
462 const char *remote_name = NULL;
463 const char *remote_server = NULL;
464 const char *remote_port = NULL;
465 const char *connect_timeout =
"60s";
466 const char *remote_allow_migrate=NULL;
467 const char *is_managed = NULL;
469 for (attr_set = pcmk__xe_first_child(xml_obj); attr_set != NULL;
470 attr_set = pcmk__xe_next(attr_set)) {
477 for (attr = pcmk__xe_first_child(attr_set); attr != NULL;
478 attr = pcmk__xe_next(attr)) {
485 remote_server = value;
489 connect_timeout = value;
491 remote_allow_migrate=value;
498 if (remote_name == NULL) {
507 remote_allow_migrate, is_managed,
508 connect_timeout, remote_server, remote_port);
540 xmlNode *xml_obj = NULL;
542 const char *
id = NULL;
543 const char *
uname = NULL;
544 const char *
type = NULL;
545 const char *score = NULL;
556 for (xml_obj = pcmk__xe_first_child(xml_nodes); xml_obj != NULL;
557 xml_obj = pcmk__xe_next(xml_obj)) {
570 "> entry in configuration without id");
575 if (new_node == NULL) {
579 handle_startup_fencing(
data_set, new_node);
581 add_node_attrs(xml_obj, new_node, FALSE,
data_set);
591 crm_info(
"Creating a fake local node");
602 const char *container_id = NULL;
617 pe_rsc_trace(rsc,
"Resource %s's container is %s", rsc->
id, container_id);
619 pe_err(
"Resource %s: Unknown resource container (%s)", rsc->
id, container_id);
627 xmlNode *xml_obj = NULL;
632 for (xml_obj = pcmk__xe_first_child(xml_resources); xml_obj != NULL;
633 xml_obj = pcmk__xe_next(xml_obj)) {
635 const char *new_node_id = NULL;
641 new_node_id =
ID(xml_obj);
645 crm_trace(
"Found remote node %s defined by resource %s",
646 new_node_id,
ID(xml_obj));
661 new_node_id = expand_remote_rsc_meta(xml_obj, xml_resources,
data_set);
663 crm_trace(
"Found guest node %s in resource %s",
664 new_node_id,
ID(xml_obj));
675 xmlNode *xml_obj2 = NULL;
676 for (xml_obj2 = pcmk__xe_first_child(xml_obj); xml_obj2 != NULL;
677 xml_obj2 = pcmk__xe_next(xml_obj2)) {
679 new_node_id = expand_remote_rsc_meta(xml_obj2, xml_resources,
data_set);
682 crm_trace(
"Found guest node %s in resource %s inside group %s",
683 new_node_id,
ID(xml_obj2),
ID(xml_obj));
718 pe_rsc_trace(new_rsc,
"Linking remote connection resource %s to %s",
719 new_rsc->
id, pe__node_name(remote_node));
726 handle_startup_fencing(
data_set, remote_node);
733 strdup(
"container"));
738destroy_tag(gpointer
data)
744 g_list_free_full(tag->
refs, free);
764 xmlNode *xml_obj = NULL;
769 for (xml_obj = pcmk__xe_first_child(xml_resources); xml_obj != NULL;
770 xml_obj = pcmk__xe_next(xml_obj)) {
773 const char *
id =
ID(xml_obj);
775 if (pcmk__str_empty(
id)) {
777 crm_element_name(xml_obj));
784 NULL, NULL) == FALSE) {
791 crm_trace(
"Unpacking <%s id='%s'>", crm_element_name(xml_obj),
id);
799 "because configuration is invalid",
800 crm_element_name(xml_obj),
id);
819 pcmk__config_err(
"Resource start-up disabled since no STONITH resources have been defined");
820 pcmk__config_err(
"Either configure some or disable STONITH with the stonith-enabled option");
821 pcmk__config_err(
"NOTE: Clusters with shared data need STONITH to ensure data integrity");
830 xmlNode *xml_tag = NULL;
834 for (xml_tag = pcmk__xe_first_child(xml_tags); xml_tag != NULL;
835 xml_tag = pcmk__xe_next(xml_tag)) {
837 xmlNode *xml_obj_ref = NULL;
838 const char *tag_id =
ID(xml_tag);
844 if (tag_id == NULL) {
846 crm_element_name(xml_tag));
850 for (xml_obj_ref = pcmk__xe_first_child(xml_tag); xml_obj_ref != NULL;
851 xml_obj_ref = pcmk__xe_next(xml_obj_ref)) {
853 const char *obj_ref =
ID(xml_obj_ref);
859 if (obj_ref == NULL) {
861 crm_element_name(xml_obj_ref), tag_id);
879 const char *ticket_id = NULL;
880 const char *granted = NULL;
881 const char *last_granted = NULL;
882 const char *standby = NULL;
883 xmlAttrPtr xIter = NULL;
887 ticket_id =
ID(xml_ticket);
888 if (pcmk__str_empty(ticket_id)) {
892 crm_trace(
"Processing ticket state for %s", ticket_id);
895 if (ticket == NULL) {
897 if (ticket == NULL) {
902 for (xIter = xml_ticket->properties; xIter; xIter = xIter->next) {
903 const char *prop_name = (
const char *)xIter->name;
909 g_hash_table_replace(ticket->
state, strdup(prop_name), strdup(prop_value));
912 granted = g_hash_table_lookup(ticket->
state,
"granted");
918 crm_info(
"We do not have ticket '%s'", ticket->
id);
921 last_granted = g_hash_table_lookup(ticket->
state,
"last-granted");
923 long long last_granted_ll;
929 standby = g_hash_table_lookup(ticket->
state,
"standby");
933 crm_info(
"Granted ticket '%s' is in standby-mode", ticket->
id);
939 crm_trace(
"Done with ticket state for %s", ticket_id);
947 xmlNode *xml_obj = NULL;
949 for (xml_obj = pcmk__xe_first_child(xml_tickets); xml_obj != NULL;
950 xml_obj = pcmk__xe_next(xml_obj)) {
955 unpack_ticket_state(xml_obj,
data_set);
964 const char *resource_discovery_enabled = NULL;
965 xmlNode *attrs = NULL;
975 crm_trace(
"Processing Pacemaker Remote node %s", pe__node_name(this_node));
986 add_node_attrs(attrs, this_node, TRUE,
data_set);
989 crm_info(
"%s is shutting down", pe__node_name(this_node));
994 crm_info(
"%s is in standby mode", pe__node_name(this_node));
1000 crm_info(
"%s is in maintenance mode", pe__node_name(this_node));
1005 if (resource_discovery_enabled && !
crm_is_true(resource_discovery_enabled)) {
1009 " attribute on Pacemaker Remote node %s"
1010 " because fencing is disabled",
1011 pe__node_name(this_node));
1018 crm_info(
"%s has resource discovery disabled",
1019 pe__node_name(this_node));
1034unpack_transient_attributes(xmlNode *state,
pe_node_t *node,
1037 const char *discovery = NULL;
1040 add_node_attrs(attrs, node, TRUE,
data_set);
1043 crm_info(
"%s is in standby mode", pe__node_name(node));
1048 crm_info(
"%s is in maintenance mode", pe__node_name(node));
1053 if ((discovery != NULL) && !
crm_is_true(discovery)) {
1055 " attribute for %s because disabling resource discovery "
1056 "is not allowed for cluster nodes", pe__node_name(node));
1075 const char *
id = NULL;
1076 const char *
uname = NULL;
1087 if (
uname == NULL) {
1094 if (this_node == NULL) {
1096 "it is no longer in the configuration",
uname);
1111 unpack_transient_attributes(state, this_node,
data_set);
1119 crm_trace(
"Determining online status of cluster node %s (id %s)",
1120 pe__node_name(this_node),
id);
1121 determine_online_status(state, this_node,
data_set);
1161 const char *
id =
ID(state);
1165 if ((
id == NULL) || (
uname == NULL)) {
1167 crm_trace(
"Not unpacking resource history from malformed "
1173 if (this_node == NULL) {
1175 crm_trace(
"Not unpacking resource history for node %s because "
1176 "no longer in configuration",
id);
1181 crm_trace(
"Not unpacking resource history for node %s because "
1182 "already unpacked",
id);
1198 crm_trace(
"Not unpacking resource history for guest node %s "
1199 "because container and connection are not known to "
1215 crm_trace(
"Not unpacking resource history for remote node %s "
1216 "because connection is not known to be up",
id);
1228 crm_trace(
"Not unpacking resource history for offline "
1229 "cluster node %s",
id);
1234 determine_remote_online_status(
data_set, this_node);
1235 unpack_handle_remote_attrs(this_node, state,
data_set);
1238 crm_trace(
"Unpacking resource history for %snode %s",
1239 (fence?
"unseen " :
""),
id);
1242 unpack_node_lrm(this_node, state,
data_set);
1255 xmlNode *state = NULL;
1263 for (state = pcmk__xe_first_child(status); state != NULL;
1264 state = pcmk__xe_next(state)) {
1267 unpack_tickets_state((xmlNode *) state,
data_set);
1270 unpack_node_state(state,
data_set);
1274 while (unpack_node_history(status, FALSE,
data_set) == EAGAIN) {
1275 crm_trace(
"Another pass through node resource histories is needed");
1279 unpack_node_history(status,
1289 pe_node_t *node = pe__current_node(container);
1303 for (GList *gIter =
data_set->
nodes; gIter != NULL; gIter = gIter->next) {
1315 determine_remote_online_status(
data_set, this_node);
1326 gboolean online = FALSE;
1333 crm_trace(
"Node is down: in_cluster=%s",
1334 pcmk__s(in_cluster,
"<null>"));
1340 crm_debug(
"Node is not ready to run resources: %s", join);
1345 "in_cluster=%s is_peer=%s join=%s expected=%s",
1346 pcmk__s(in_cluster,
"<null>"), pcmk__s(is_peer,
"<null>"),
1347 pcmk__s(join,
"<null>"), pcmk__s(exp_state,
"<null>"));
1352 crm_info(
"in_cluster=%s is_peer=%s join=%s expected=%s",
1353 pcmk__s(in_cluster,
"<null>"), pcmk__s(is_peer,
"<null>"),
1354 pcmk__s(join,
"<null>"), pcmk__s(exp_state,
"<null>"));
1363 gboolean online = FALSE;
1364 gboolean do_terminate = FALSE;
1365 bool crmd_online = FALSE;
1380 do_terminate = TRUE;
1382 }
else if (terminate != NULL && strlen(terminate) > 0) {
1384 char t = terminate[0];
1386 if (t !=
'0' && isdigit(t)) {
1387 do_terminate = TRUE;
1391 crm_trace(
"%s: in_cluster=%s is_peer=%s join=%s expected=%s term=%d",
1392 pe__node_name(this_node), pcmk__s(in_cluster,
"<null>"),
1393 pcmk__s(is_peer,
"<null>"), pcmk__s(join,
"<null>"),
1394 pcmk__s(exp_state,
"<null>"), do_terminate);
1398 if (exp_state == NULL) {
1403 crm_debug(
"%s is shutting down", pe__node_name(this_node));
1406 online = crmd_online;
1408 }
else if (in_cluster == NULL) {
1413 "peer failed Pacemaker membership criteria", FALSE);
1418 crm_info(
"- %s is not ready to run resources",
1419 pe__node_name(this_node));
1424 crm_trace(
"%s is down or still coming up",
1425 pe__node_name(this_node));
1429 &&
crm_is_true(in_cluster) == FALSE && !crmd_online) {
1430 crm_info(
"%s was just shot", pe__node_name(this_node));
1437 }
else if (!crmd_online) {
1441 }
else if (do_terminate) {
1445 crm_info(
"%s is active", pe__node_name(this_node));
1448 crm_info(
"%s is not ready to run resources", pe__node_name(this_node));
1454 crm_warn(
"%s: in-cluster=%s is-peer=%s join=%s expected=%s term=%d shutdown=%d",
1455 pe__node_name(this_node), pcmk__s(in_cluster,
"<null>"),
1456 pcmk__s(is_peer,
"<null>"), pcmk__s(join,
"<null>"),
1457 pcmk__s(exp_state,
"<null>"), do_terminate,
1477 goto remote_online_done;
1482 if (container && pcmk__list_of_1(rsc->
running_on)) {
1488 crm_trace(
"%s node %s presumed ONLINE because connection resource is started",
1489 (container?
"Guest" :
"Remote"), this_node->
details->
id);
1495 crm_trace(
"%s node %s shutting down because connection resource is stopping",
1496 (container?
"Guest" :
"Remote"), this_node->
details->
id);
1502 crm_trace(
"Guest node %s UNCLEAN because guest resource failed",
1508 crm_trace(
"%s node %s OFFLINE because connection resource failed",
1509 (container?
"Guest" :
"Remote"), this_node->
details->
id);
1515 crm_trace(
"%s node %s OFFLINE because its resource is stopped",
1516 (container?
"Guest" :
"Remote"), this_node->
details->
id);
1520 }
else if (
host && (
host->details->online == FALSE)
1521 &&
host->details->unclean) {
1522 crm_trace(
"Guest node %s UNCLEAN because host is unclean",
1536 gboolean online = FALSE;
1559 online = determine_online_status_no_fencing(
data_set, node_state, this_node);
1562 online = determine_online_status_fencing(
data_set, node_state, this_node);
1570 this_node->
fixed = TRUE;
1576 this_node->
fixed = TRUE;
1581 crm_info(
"%s is not a Pacemaker node", pe__node_name(this_node));
1584 pe_proc_warn(
"%s is unclean", pe__node_name(this_node));
1587 crm_info(
"%s is %s", pe__node_name(this_node),
1594 crm_trace(
"%s is offline", pe__node_name(this_node));
1609 if (!pcmk__str_empty(
id)) {
1610 const char *end =
id + strlen(
id) - 1;
1612 for (
const char *s = end; s >
id; --s) {
1626 return (s == end)? s : (s - 1);
1650 char *basename = NULL;
1653 basename =
strndup(last_rsc_id, end - last_rsc_id + 1);
1672 size_t base_name_len = end - last_rsc_id + 1;
1676 zero = calloc(base_name_len + 3,
sizeof(
char));
1678 memcpy(zero, last_rsc_id, base_name_len);
1679 zero[base_name_len] =
':';
1680 zero[base_name_len + 1] =
'0';
1701 crm_debug(
"Detected orphaned remote node %s", rsc_id);
1706 link_rsc2remotenode(
data_set, rsc);
1709 crm_trace(
"Setting node %s as shutting down due to orphaned connection resource", rsc_id);
1716 crm_trace(
"Detected orphaned container filler %s", rsc_id);
1738 top->
id,
parent->id, rsc_id, pe__node_name(node));
1760 GList *rIter = NULL;
1763 gboolean skip_inactive = FALSE;
1771 rsc_id, pe__node_name(node),
parent->id);
1772 for (rIter =
parent->children; rsc == NULL && rIter; rIter = rIter->next) {
1773 GList *locations = NULL;
1817 crm_notice(
"Active (now-)anonymous clone %s has "
1818 "multiple (orphan) instance histories on %s",
1819 parent->id, pe__node_name(node));
1820 skip_inactive = TRUE;
1827 g_list_free(locations);
1831 if (!skip_inactive && !inactive_instance
1834 inactive_instance =
parent->fns->find_rsc(child, rsc_id, NULL,
1840 if (inactive_instance && inactive_instance->
pending_node
1842 inactive_instance = NULL;
1848 if ((rsc == NULL) && !skip_inactive && (inactive_instance != NULL)) {
1850 rsc = inactive_instance;
1882 xmlNode * rsc_entry)
1903 crm_trace(
"%s is not known as %s either (orphan)",
1909 crm_trace(
"Resource history for %s is orphaned because it is no longer primitive",
1917 if (pe_rsc_is_anon_clone(
parent)) {
1919 if (pe_rsc_is_bundled(
parent)) {
1934 pe_rsc_debug(rsc,
"Internally renamed %s on %s to %s%s",
1935 rsc_id, pe__node_name(node), rsc->
id,
1947 crm_debug(
"Detected orphan resource %s on %s", rsc_id, pe__node_name(node));
1948 rsc = create_fake_resource(rsc_id, rsc_entry,
data_set);
1970 char *reason = NULL;
1974 pe_rsc_trace(rsc,
"Resource %s is %s on %s: on_fail=%s",
1988 ((rsc->
clone_name == NULL)?
"" :
" also known as "),
2006 gboolean should_fence = FALSE;
2017 should_fence = TRUE;
2031 " revoked if remote connection can "
2032 "be re-established elsewhere)",
2035 should_fence = TRUE;
2039 if (reason == NULL) {
2048 save_on_fail = on_fail;
2109 if (rsc->
container && pe_rsc_is_bundled(rsc)) {
2139 "remote connection is unrecoverable", FALSE);
2171 rsc->
id, pe__node_name(node));
2174 "%s because cluster is configured not to "
2175 "stop active orphans",
2176 rsc->
id, pe__node_name(node));
2204 GList *gIter = possible_matches;
2206 for (; gIter != NULL; gIter = gIter->next) {
2212 g_list_free(possible_matches);
2231 int start_index,
int stop_index,
2235 const char *task = NULL;
2236 const char *status = NULL;
2237 GList *gIter = sorted_op_list;
2240 pe_rsc_trace(rsc,
"%s: Start index %d, stop index = %d", rsc->
id, start_index, stop_index);
2242 for (; gIter != NULL; gIter = gIter->next) {
2243 xmlNode *rsc_op = (xmlNode *) gIter->data;
2245 guint interval_ms = 0;
2247 const char *
id =
ID(rsc_op);
2252 pe_rsc_trace(rsc,
"Skipping %s on %s: node is offline",
2253 rsc->
id, pe__node_name(node));
2257 }
else if (start_index < stop_index && counter <= stop_index) {
2258 pe_rsc_trace(rsc,
"Skipping %s on %s: resource is not active",
2259 id, pe__node_name(node));
2262 }
else if (counter < start_index) {
2264 id, pe__node_name(node), counter);
2269 if (interval_ms == 0) {
2271 id, pe__node_name(node));
2278 id, pe__node_name(node));
2284 pe_rsc_trace(rsc,
"Creating %s on %s", key, pe__node_name(node));
2293 int implied_monitor_start = -1;
2294 int implied_clone_start = -1;
2295 const char *task = NULL;
2296 const char *status = NULL;
2297 GList *gIter = sorted_op_list;
2302 for (; gIter != NULL; gIter = gIter->next) {
2303 xmlNode *rsc_op = (xmlNode *) gIter->data;
2312 *stop_index = counter;
2315 *start_index = counter;
2321 implied_monitor_start = counter;
2324 implied_clone_start = counter;
2328 if (*start_index == -1) {
2329 if (implied_clone_start != -1) {
2330 *start_index = implied_clone_start;
2331 }
else if (implied_monitor_start != -1) {
2332 *start_index = implied_monitor_start;
2342 time_t lock_time = 0;
2345 &lock_time) ==
pcmk_ok) && (lock_time != 0)) {
2350 pe_rsc_info(rsc,
"Shutdown lock for %s on %s expired",
2351 rsc->
id, pe__node_name(node));
2371unpack_lrm_resource(
pe_node_t *node, xmlNode *lrm_resource,
2374 GList *gIter = NULL;
2375 int stop_index = -1;
2376 int start_index = -1;
2379 const char *task = NULL;
2380 const char *rsc_id =
ID(lrm_resource);
2383 GList *op_list = NULL;
2384 GList *sorted_op_list = NULL;
2386 xmlNode *migrate_op = NULL;
2387 xmlNode *rsc_op = NULL;
2388 xmlNode *last_failure = NULL;
2393 if (rsc_id == NULL) {
2395 " entry without id");
2399 rsc_id, pe__node_name(node));
2405 op_list = g_list_prepend(op_list, rsc_op);
2409 if (op_list == NULL) {
2416 rsc = unpack_find_resource(
data_set, node, rsc_id, lrm_resource);
2418 if (op_list == NULL) {
2422 rsc = process_orphan_resource(lrm_resource, node,
data_set);
2429 unpack_shutdown_lock(lrm_resource, rsc, node,
data_set);
2433 saved_role = rsc->
role;
2437 for (gIter = sorted_op_list; gIter != NULL; gIter = gIter->next) {
2438 xmlNode *rsc_op = (xmlNode *) gIter->data;
2442 migrate_op = rsc_op;
2445 unpack_rsc_op(rsc, node, rsc_op, &last_failure, &on_fail,
data_set);
2450 process_recurring(node, rsc, start_index, stop_index, sorted_op_list,
data_set);
2453 g_list_free(sorted_op_list);
2455 process_rsc_state(rsc, node, on_fail, migrate_op,
data_set);
2462 pe_rsc_info(rsc,
"%s: Not overwriting calculated next role %s"
2463 " with requested next role %s",
2468 if (saved_role > rsc->
role) {
2469 rsc->
role = saved_role;
2478 xmlNode *rsc_entry = NULL;
2479 for (rsc_entry = pcmk__xe_first_child(lrm_rsc_list); rsc_entry != NULL;
2480 rsc_entry = pcmk__xe_next(rsc_entry)) {
2485 const char *container_id;
2493 if (container_id == NULL || rsc_id == NULL) {
2498 if (container == NULL) {
2509 pe_rsc_trace(rsc,
"Mapped container of orphaned resource %s to %s",
2510 rsc->
id, container_id);
2527 bool found_orphaned_container_filler =
false;
2547 found_orphaned_container_filler =
true;
2554 if (found_orphaned_container_filler) {
2555 handle_orphaned_container_fillers(xml,
data_set);
2572set_node_score(gpointer key, gpointer value, gpointer user_data)
2575 int *score = user_data;
2580#define XPATH_NODE_STATE "/" XML_TAG_CIB "/" XML_CIB_TAG_STATUS \
2581 "/" XML_CIB_TAG_STATE
2582#define SUB_XPATH_LRM_RESOURCE "/" XML_CIB_TAG_LRM \
2583 "/" XML_LRM_TAG_RESOURCES \
2584 "/" XML_LRM_TAG_RESOURCE
2585#define SUB_XPATH_LRM_RSC_OP "/" XML_LRM_TAG_RSC_OP
2588find_lrm_op(
const char *resource,
const char *op,
const char *node,
const char *source,
2591 GString *xpath = NULL;
2592 xmlNode *xml = NULL;
2594 CRM_CHECK((resource != NULL) && (op != NULL) && (node != NULL),
2597 xpath = g_string_sized_new(256);
2615 g_string_append_c(xpath,
']');
2620 g_string_free(xpath, TRUE);
2622 if (xml && target_rc >= 0) {
2636find_lrm_resource(
const char *rsc_id,
const char *node_name,
2639 GString *xpath = NULL;
2640 xmlNode *xml = NULL;
2642 CRM_CHECK((rsc_id != NULL) && (node_name != NULL),
return NULL);
2644 xpath = g_string_sized_new(256);
2653 g_string_free(xpath, TRUE);
2670 xmlXPathObjectPtr search;
2671 GString *xpath = g_string_sized_new(256);
2679 result = (numXpathResults(search) == 0);
2681 g_string_free(xpath, TRUE);
2697monitor_not_running_after(
const char *rsc_id,
const char *node_name,
2698 xmlNode *xml_op,
bool same_node,
2723non_monitor_after(
const char *rsc_id,
const char *node_name, xmlNode *xml_op,
2726 xmlNode *lrm_resource = NULL;
2728 lrm_resource = find_lrm_resource(rsc_id, node_name,
data_set);
2729 if (lrm_resource == NULL) {
2735 const char * task = NULL;
2766newer_state_after_migrate(
const char *rsc_id,
const char *node_name,
2767 xmlNode *migrate_to, xmlNode *migrate_from,
2770 xmlNode *xml_op = migrate_to;
2771 const char *source = NULL;
2772 const char *
target = NULL;
2773 bool same_node =
false;
2776 xml_op = migrate_from;
2787 xml_op = migrate_from;
2791 xml_op = migrate_to;
2796 xml_op = migrate_to;
2800 xml_op = migrate_from;
2808 return non_monitor_after(rsc_id, node_name, xml_op, same_node,
data_set)
2809 || monitor_not_running_after(rsc_id, node_name, xml_op, same_node,
2856 int from_status = 0;
2859 xmlNode *migrate_from = NULL;
2862 bool source_newer_op =
false;
2863 bool target_newer_state =
false;
2871 source_newer_op = non_monitor_after(rsc->
id, source, xml_op,
true,
2881 if (source_newer_op && migrate_from) {
2888 target_newer_state = newer_state_after_migrate(rsc->
id,
target, xml_op,
2891 if (source_newer_op && target_newer_state) {
2904 pe_rsc_trace(rsc,
"%s op on %s exited with status=%d, rc=%d",
2905 ID(migrate_from),
target, from_status, from_rc);
2914 pe_rsc_trace(rsc,
"Detected dangling migration op: %s on %s",
ID(xml_op),
2923 if (!target_newer_state
2946 && unknown_on_node(rsc,
target)) {
2953 if (!target_newer_state
2969 }
else if (!source_newer_op) {
2984 xmlNode *target_migrate_from = NULL;
3005 !unknown_on_node(rsc,
target)
3009 && !newer_state_after_migrate(rsc->
id,
target, xml_op, target_migrate_from,
3021 }
else if (!non_monitor_after(rsc->
id, source, xml_op,
true,
data_set)) {
3036 xmlNode *source_migrate_to = NULL;
3057 !unknown_on_node(rsc, source)
3061 && !newer_state_after_migrate(rsc->
id, source, source_migrate_to, xml_op,
3075record_failed_op(xmlNode *op,
const pe_node_t *node,
3078 xmlNode *xIter = NULL;
3085 for (xIter =
data_set->
failed->children; xIter; xIter = xIter->next) {
3090 crm_trace(
"Skipping duplicate entry %s on %s",
3091 op_key, pe__node_name(node));
3096 crm_trace(
"Adding entry %s on %s", op_key, pe__node_name(node));
3102static const char *get_op_key(xmlNode *xml_op)
3112last_change_str(
const xmlNode *xml_op)
3115 const char *when_s = NULL;
3122 when_s = strchr(when_s,
' ');
3128 return ((when_s && *when_s)? when_s :
"unknown time");
3218 return first - second;
3222unpack_rsc_op_failure(
pe_resource_t * rsc,
pe_node_t * node,
int rc, xmlNode * xml_op, xmlNode ** last_failure,
3225 bool is_probe =
false;
3228 const char *key = get_op_key(xml_op);
3236 *last_failure = xml_op;
3240 if (exit_reason == NULL) {
3246 crm_trace(
"Unexpected result (%s%s%s) was recorded for "
3247 "%s of %s on %s at %s " CRM_XS " rc=%d id=%s",
3248 services_ocf_exitcode_str(rc),
3249 (*exit_reason?
": " :
""), exit_reason,
3250 (is_probe?
"probe" : task), rsc->
id, pe__node_name(node),
3251 last_change_str(xml_op), rc,
ID(xml_op));
3253 crm_warn(
"Unexpected result (%s%s%s) was recorded for "
3254 "%s of %s on %s at %s " CRM_XS " rc=%d id=%s",
3255 services_ocf_exitcode_str(rc),
3256 (*exit_reason?
": " :
""), exit_reason,
3257 (is_probe?
"probe" : task), rsc->
id, pe__node_name(node),
3258 last_change_str(xml_op), rc,
ID(xml_op));
3267 crm_notice(
"If it is not possible for %s to run on %s, see "
3268 "the resource-discovery option for location constraints",
3269 rsc->
id, pe__node_name(node));
3272 record_failed_op(xml_op, node, rsc,
data_set);
3276 if (cmp_on_fail(*on_fail,
action->on_fail) < 0) {
3279 *on_fail =
action->on_fail;
3286 unpack_migrate_to_failure(rsc, node, xml_op,
data_set);
3289 unpack_migrate_from_failure(rsc, node, xml_op,
data_set);
3298 "demote with on-fail=block");
3323 pe_rsc_trace(rsc,
"Resource %s: role=%s, unclean=%s, on_fail=%s, fail_role=%s",
3340 if (pe_rsc_is_clone(
parent)
3348 crm_notice(
"%s will not be started under current conditions",
3355 g_hash_table_foreach(fail_rsc->
allowed_nodes, set_node_score, &score);
3376 int exit_status,
const xmlNode *xml_op)
3378 const char *exit_reason = NULL;
3388 pe_proc_err(
"No further recovery can be attempted for %s "
3389 "because %s on %s failed (%s%s%s) at %s "
3390 CRM_XS " rc=%d id=%s", rsc->
id, task, pe__node_name(node),
3391 services_ocf_exitcode_str(exit_status),
3392 ((exit_reason == NULL)?
"" :
": "), pcmk__s(exit_reason,
""),
3393 last_change_str(xml_op), exit_status,
ID(xml_op));
3429 int target_rc,
int *rc,
int *status) {
3430 bool is_probe =
false;
3432 const char *key = get_op_key(xml_op);
3439 if (*rc != remapped_rc) {
3440 crm_trace(
"Remapping monitor result %d to %d", *rc, remapped_rc);
3442 record_failed_op(xml_op, node, rsc,
data_set);
3469 if (exit_reason == NULL) {
3479 if (target_rc < 0) {
3489 crm_warn(
"Expected result not found for %s on %s (corrupt or obsolete CIB?)",
3490 key, pe__node_name(node));
3492 }
else if (target_rc != *rc) {
3494 pe_rsc_debug(rsc,
"%s on %s: expected %d (%s), got %d (%s%s%s)",
3495 key, pe__node_name(node),
3496 target_rc, services_ocf_exitcode_str(target_rc),
3497 *rc, services_ocf_exitcode_str(*rc),
3498 (*exit_reason?
": " :
""), exit_reason);
3505 pe_rsc_info(rsc,
"Probe found %s active on %s at %s",
3506 rsc->
id, pe__node_name(node),
3507 last_change_str(xml_op));
3512 if (is_probe || (target_rc == *rc)
3525 if (is_probe && (*rc != target_rc)) {
3528 "Probe found %s active and promoted on %s at %s",
3529 rsc->
id, pe__node_name(node),
3530 last_change_str(xml_op));
3547 guint interval_ms = 0;
3551 if (interval_ms == 0) {
3552 check_recoverable(rsc, node, task, *rc, xml_op);
3563 check_recoverable(rsc, node, task, *rc, xml_op);
3569 crm_info(
"Treating unknown exit status %d from %s of %s "
3570 "on %s at %s as failure",
3571 *rc, task, rsc->
id, pe__node_name(node),
3572 last_change_str(xml_op));
3579 key, pcmk_exec_status_str(*status));
3584should_clear_for_param_change(xmlNode *xml_op,
const char *task,
3588 if (!strcmp(task,
"start") || !strcmp(task,
"monitor")) {
3602 switch (digest_data->
rc) {
3604 crm_trace(
"Resource %s history entry %s on %s"
3605 " has no digest to compare",
3634should_ignore_failure_timeout(
pe_resource_t *rsc, xmlNode *xml_op,
3635 const char *task, guint interval_ms,
3665 if (is_last_failure) {
3666 crm_info(
"Waiting to clear monitor failure for remote node %s"
3667 " until fencing has occurred", rsc->
id);
3701 bool expired = FALSE;
3703 time_t last_run = 0;
3704 guint interval_ms = 0;
3705 int unexpired_fail_count = 0;
3707 const char *clear_reason = NULL;
3718 time_t last_failure = 0;
3722 && !should_ignore_failure_timeout(rsc, xml_op, task, interval_ms,
3733 crm_trace(
"%s@%lld is %sexpired @%lld with unexpired_failures=%d timeout=%ds"
3734 " last-failure@%lld",
3735 ID(xml_op), (
long long) last_run, (expired?
"" :
"not "),
3737 (
long long) last_failure);
3739 if (unexpired_fail_count && (now < last_failure)) {
3749 if (unexpired_fail_count == 0) {
3751 clear_reason =
"it expired";
3767 clear_reason =
"reconnect interval is set";
3771 if (!expired && is_last_failure
3772 && should_clear_for_param_change(xml_op, task, rsc, node,
data_set)) {
3773 clear_reason =
"resource parameters have changed";
3776 if (clear_reason != NULL) {
3791 crm_info(
"Clearing %s failure will wait until any scheduled "
3792 "fencing of %s completes", task, rsc->
id);
3793 order_after_remote_fencing(clear_op, rsc,
data_set);
3841 gboolean clear_past_failure = FALSE;
3850 clear_past_failure = TRUE;
3854 const char *op_key = get_op_key(xml_op);
3855 const char *last_failure_key = get_op_key(last_failure);
3858 clear_past_failure = TRUE;
3868 clear_past_failure = TRUE;
3872 clear_past_failure = TRUE;
3876 clear_past_failure = TRUE;
3882 clear_past_failure = TRUE;
3888 clear_past_failure = TRUE;
3891 unpack_migrate_to_success(rsc, node, xml_op,
data_set);
3894 pe_rsc_trace(rsc,
"%s active on %s", rsc->
id, pe__node_name(node));
3899 if (clear_past_failure) {
3905 pe_rsc_trace(rsc,
"%s.%s is not cleared by a completed stop",
3927 "clear past failures and reset remote");
3943 int old_target_rc = 0;
3945 guint interval_ms = 0;
3946 const char *task = NULL;
3947 const char *task_key = NULL;
3948 const char *exit_reason = NULL;
3949 bool expired =
false;
3952 bool maskable_probe_failure =
false;
3954 CRM_CHECK(rsc && node && xml_op,
return);
3957 task_key = get_op_key(xml_op);
3960 if (exit_reason == NULL) {
3983 pe_rsc_trace(rsc,
"Unpacking task %s/%s (call_id=%d, status=%d, rc=%d) on %s (role=%s)",
3984 task_key, task, task_id, status, rc, pe__node_name(node),
3989 "%s is running on %s, which is unclean (further action "
3990 "depends on value of stop's on-fail attribute)",
3991 rsc->
id, pe__node_name(node));
4007 && check_operation_expiry(rsc, node, rc, xml_op,
data_set)) {
4012 old_target_rc = target_rc;
4014 remap_operation(xml_op, rsc, node,
data_set, on_fail, target_rc,
4019 if (expired && maskable_probe_failure && old_rc != old_target_rc) {
4026 }
else if (expired && (rc != target_rc)) {
4029 if (interval_ms == 0) {
4030 crm_notice(
"Ignoring expired %s failure on %s "
4031 CRM_XS " actual=%d expected=%d magic=%s",
4032 task_key, pe__node_name(node), rc, target_rc, magic);
4046 crm_notice(
"Rescheduling %s after failure expired on %s "
4047 CRM_XS " actual=%d expected=%d magic=%s",
4048 task_key, pe__node_name(node), rc, target_rc, magic);
4054 if (maskable_probe_failure) {
4055 crm_notice(
"Treating probe result '%s' for %s on %s as 'not running'",
4056 services_ocf_exitcode_str(old_rc), rsc->
id,
4057 pe__node_name(node));
4058 update_resource_state(rsc, node, xml_op, task, target_rc, *last_failure,
4062 record_failed_op(xml_op, node, rsc,
data_set);
4070 pe_err(
"Resource history contains cancellation '%s' "
4071 "(%s of %s on %s at %s)",
4072 ID(xml_op), task, rsc->
id, pe__node_name(node),
4073 last_change_str(xml_op));
4114 task, rsc->
id, pe__node_name(node),
4115 last_change_str(xml_op),
ID(xml_op));
4116 update_resource_state(rsc, node, xml_op, task, rc, *last_failure, on_fail,
data_set);
4120 failure_strategy = get_action_on_fail(rsc, task_key, task,
data_set);
4122 crm_warn(
"Cannot ignore failed %s of %s on %s: "
4123 "Resource agent doesn't exist "
4124 CRM_XS " status=%d rc=%d id=%s",
4125 task, rsc->
id, pe__node_name(node), status, rc,
4131 unpack_rsc_op_failure(rsc, node, rc, xml_op, last_failure, on_fail,
data_set);
4162 failure_strategy = get_action_on_fail(rsc, task_key, task,
data_set);
4167 crm_warn(
"Pretending failed %s (%s%s%s) of %s on %s at %s "
4168 "succeeded " CRM_XS " rc=%d id=%s",
4169 task, services_ocf_exitcode_str(rc),
4170 (*exit_reason?
": " :
""), exit_reason, rsc->
id,
4171 pe__node_name(node), last_change_str(xml_op), rc,
4174 update_resource_state(rsc, node, xml_op, task, target_rc, *last_failure,
4179 record_failed_op(xml_op, node, rsc,
data_set);
4183 *on_fail = failure_strategy;
4187 unpack_rsc_op_failure(rsc, node, rc, xml_op, last_failure, on_fail,
4192 "Preventing %s from restarting on %s because "
4193 "of hard failure (%s%s%s)" CRM_XS " rc=%d id=%s",
4194 parent->id, pe__node_name(node),
4195 services_ocf_exitcode_str(rc),
4196 (*exit_reason?
": " :
""), exit_reason,
4201 crm_err(
"Preventing %s from restarting anywhere because "
4202 "of fatal failure (%s%s%s) " CRM_XS " rc=%d id=%s",
4203 parent->id, services_ocf_exitcode_str(rc),
4204 (*exit_reason?
": " :
""), exit_reason,
4211 pe_rsc_trace(rsc,
"Resource %s after %s: role=%s, next=%s",
4217add_node_attrs(xmlNode *xml_obj,
pe_node_t *node,
bool overwrite,
4220 const char *cluster_name = NULL;
4249 strdup(cluster_name));
4263 }
else if (cluster_name) {
4267 strdup(cluster_name));
4273extract_operations(
const char *node,
const char *rsc, xmlNode * rsc_entry, gboolean active_filter)
4276 int stop_index = -1;
4277 int start_index = -1;
4279 xmlNode *rsc_op = NULL;
4281 GList *gIter = NULL;
4282 GList *op_list = NULL;
4283 GList *sorted_op_list = NULL;
4287 sorted_op_list = NULL;
4289 for (rsc_op = pcmk__xe_first_child(rsc_entry);
4290 rsc_op != NULL; rsc_op = pcmk__xe_next(rsc_op)) {
4296 op_list = g_list_prepend(op_list, rsc_op);
4300 if (op_list == NULL) {
4308 if (active_filter == FALSE) {
4309 return sorted_op_list;
4316 for (gIter = sorted_op_list; gIter != NULL; gIter = gIter->next) {
4317 xmlNode *rsc_op = (xmlNode *) gIter->data;
4321 if (start_index < stop_index) {
4322 crm_trace(
"Skipping %s: not active",
ID(rsc_entry));
4325 }
else if (counter < start_index) {
4329 op_list = g_list_append(op_list, rsc_op);
4332 g_list_free(sorted_op_list);
4340 GList *output = NULL;
4341 GList *intermediate = NULL;
4343 xmlNode *tmp = NULL;
4348 xmlNode *node_state = NULL;
4350 for (node_state = pcmk__xe_first_child(status); node_state != NULL;
4351 node_state = pcmk__xe_next(node_state)) {
4361 if(this_node == NULL) {
4366 determine_remote_online_status(
data_set, this_node);
4369 determine_online_status(node_state, this_node,
data_set);
4378 xmlNode *lrm_rsc = NULL;
4383 for (lrm_rsc = pcmk__xe_first_child(tmp); lrm_rsc != NULL;
4384 lrm_rsc = pcmk__xe_next(lrm_rsc)) {
4386 if (pcmk__str_eq((
const char *)lrm_rsc->name,
4395 intermediate = extract_operations(
uname, rsc_id, lrm_rsc, active_filter);
4396 output = g_list_concat(output, intermediate);
pe_resource_t * pe__create_clone_child(pe_resource_t *rsc, pe_working_set_t *data_set)
int pcmk__effective_rc(int rc)
char * pcmk__op_key(const char *rsc_id, const char *op_type, guint interval_ms)
Generate an operation key (RESOURCE_ACTION_INTERVAL)
bool pcmk_xe_is_probe(xmlNode *xml_op)
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.
char guint crm_parse_interval_spec(const char *input)
Parse milliseconds from a Pacemaker interval specification.
bool pcmk_xe_mask_probe_failure(xmlNode *xml_op)
int char2score(const char *score)
Get the integer value of a score string.
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
gboolean crm_is_true(const char *s)
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
@ action_fail_reset_remote
@ action_fail_restart_container
const char * fail2text(enum action_fail_response fail)
const char * role2text(enum rsc_role_e role)
const char * pe_pref(GHashTable *options, const char *name)
rsc_role_e
Possible roles that a resource can be in.
int pe__unpack_resource(xmlNode *xml_obj, pe_resource_t **rsc, pe_resource_t *parent, pe_working_set_t *data_set)
pe_resource_t * uber_parent(pe_resource_t *rsc)
enum crm_ais_msg_types type
#define CRMD_JOINSTATE_NACK
#define CRMD_ACTION_NOTIFY
#define CRM_ATTR_SITE_NAME
#define CRMD_JOINSTATE_DOWN
#define CRMD_ACTION_METADATA
#define CRMD_JOINSTATE_PENDING
#define CRMD_ACTION_MIGRATED
#define CRMD_ACTION_STATUS
#define CRMD_ACTION_DEMOTE
#define CRMD_ACTION_MIGRATE
#define CRMD_ACTION_START
#define CRMD_ACTION_PROMOTE
#define CRM_ATTR_CLUSTER_NAME
#define CRMD_JOINSTATE_MEMBER
const char * pcmk__epoch2str(const time_t *when)
#define crm_info(fmt, args...)
#define do_crm_log(level, fmt, args...)
Log a message.
#define crm_warn(fmt, args...)
#define crm_log_xml_debug(xml, text)
#define CRM_LOG_ASSERT(expr)
#define crm_notice(fmt, args...)
#define CRM_CHECK(expr, failure_action)
#define crm_debug(fmt, args...)
#define crm_err(fmt, args...)
#define crm_trace(fmt, args...)
#define pcmk__config_warn(fmt...)
#define pcmk__config_err(fmt...)
#define XML_NODE_ATTR_RSC_DISCOVERY
#define XML_LRM_TAG_RSC_OP
#define XML_ATTR_TRANSITION_KEY
#define XML_ATTR_HAVE_WATCHDOG
#define XML_RSC_ATTR_TARGET_ROLE
#define XML_CIB_TAG_TICKET_STATE
#define XML_TAG_TRANSIENT_NODEATTRS
#define XML_NVPAIR_ATTR_VALUE
#define XML_RSC_ATTR_REMOTE_NODE
#define XML_RULE_ATTR_SCORE
#define XML_CIB_TAG_OBJ_REF
#define XML_LRM_TAG_RESOURCES
#define XML_RSC_ATTR_MANAGED
#define XML_LRM_ATTR_MIGRATE_SOURCE
#define XML_NODE_IS_FENCED
#define XML_LRM_ATTR_TASK_KEY
#define XML_CONFIG_ATTR_PRIORITY_FENCING_DELAY
#define XML_RSC_ATTR_CONTAINER
#define XML_CIB_TAG_STATE
#define XML_NODE_JOIN_STATE
#define XML_CONFIG_ATTR_SHUTDOWN_LOCK
#define XML_LRM_ATTR_OPSTATUS
#define XML_CIB_TAG_TICKETS
#define XML_TAG_ATTR_SETS
#define XML_NODE_IN_CLUSTER
#define XML_ATTR_TRANSITION_MAGIC
#define XML_LRM_ATTR_RESTART_DIGEST
#define XML_LRM_ATTR_EXIT_REASON
#define XML_NODE_IS_MAINTENANCE
#define XML_TAG_META_SETS
#define XML_BOOLEAN_FALSE
#define XML_ATTR_QUORUM_PANIC
#define XML_CIB_TAG_RSC_TEMPLATE
#define XML_LRM_ATTR_TASK
#define XML_NODE_EXPECTED
#define XML_CIB_TAG_PROPSET
#define XML_LRM_ATTR_MIGRATE_TARGET
#define XML_NVPAIR_ATTR_NAME
#define CIB_OPTIONS_FIRST
#define XML_CIB_TAG_GROUP
#define XML_CIB_TAG_STATUS
#define XML_RSC_OP_LAST_CHANGE
#define XML_LRM_ATTR_CALLID
#define XML_LRM_ATTR_RSCID
#define XML_TAG_UTILIZATION
#define XML_CIB_TAG_RESOURCE
#define XML_CONFIG_ATTR_SHUTDOWN_LOCK_LIMIT
#define XML_LRM_ATTR_INTERVAL_MS
#define XML_LRM_TAG_RESOURCE
pe_working_set_t * data_set
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
int crm_element_value_int(const xmlNode *data, const char *name, int *dest)
Retrieve the integer value of an XML attribute.
int crm_element_value_ms(const xmlNode *data, const char *name, guint *dest)
Retrieve the millisecond value of an XML attribute.
int crm_element_value_epoch(const xmlNode *xml, const char *name, time_t *dest)
Retrieve the seconds-since-epoch value of an XML attribute.
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
pcmk__action_result_t result
void pe__unpack_node_health_scores(pe_working_set_t *data_set)
G_GNUC_INTERNAL gint pe__cmp_rsc_priority(gconstpointer a, gconstpointer b)
#define pe_flag_have_stonith_resource
#define pe_flag_startup_fencing
#define pe_flag_have_quorum
#define pe_flag_maintenance_mode
#define pe_rsc_orphan_container_filler
#define pe_flag_enable_unfencing
#define pe_flag_shutdown_lock
#define pe_flag_symmetric_cluster
#define pe_flag_quick_location
#define pe_flag_stop_everything
#define pe_flag_startup_probes
#define pe_flag_start_failure_fatal
#define pe_rsc_allow_migrate
#define pe_flag_concurrent_fencing
@ pe_find_clone
match only clone instances
#define pe_rsc_is_container
#define pe_flag_stonith_enabled
#define pe_flag_stop_rsc_orphans
#define pe_rsc_needs_fencing
#define pe_flag_remove_after_stop
#define pe_rsc_failure_ignored
#define pe_rsc_promotable
#define pe_flag_have_remote_nodes
#define pe_flag_stop_action_orphans
#define pe_rsc_start_pending
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.
void verify_pe_options(GHashTable *options)
#define pe_warn_once(pe_wo_bit, fmt...)
pe_resource_t * pe__find_bundle_replica(const pe_resource_t *bundle, const pe_node_t *node)
pe_action_t * pe__clear_resource_history(pe_resource_t *rsc, pe_node_t *node, pe_working_set_t *data_set)
const char * pe_node_attribute_raw(const pe_node_t *node, const char *name)
bool pe__is_universal_clone(pe_resource_t *rsc, pe_working_set_t *data_set)
#define demote_action(rsc, node, optional)
void destroy_ticket(gpointer data)
int pe__is_newer_op(const xmlNode *xml_a, const xmlNode *xml_b, bool same_node_default)
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)
GHashTable * pe__node_list2table(GList *list)
pe_action_t * custom_action(pe_resource_t *rsc, char *key, const char *task, const pe_node_t *on_node, gboolean optional, gboolean foo, pe_working_set_t *data_set)
Create or update an action object.
void pe__unpack_dataset_nvpairs(const xmlNode *xml_obj, const char *set_name, pe_rule_eval_data_t *rule_data, GHashTable *hash, const char *always_first, gboolean overwrite, pe_working_set_t *data_set)
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)
void pe__set_next_role(pe_resource_t *rsc, enum rsc_role_e role, const char *why)
gboolean get_target_role(pe_resource_t *rsc, enum rsc_role_e *role)
#define pe__clear_resource_flags(resource, flags_to_clear)
#define pe_rsc_debug(rsc, fmt, args...)
bool pe__bundle_needs_remote_name(pe_resource_t *rsc, pe_working_set_t *data_set)
void pe__free_digests(gpointer ptr)
gint pe__cmp_node_name(gconstpointer a, gconstpointer b)
void pe_free_action(pe_action_t *action)
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)
gboolean order_actions(pe_action_t *lh_action, pe_action_t *rh_action, enum pe_ordering order)
#define pe_rsc_trace(rsc, 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.
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 native_add_running(pe_resource_t *rsc, pe_node_t *node, pe_working_set_t *data_set, gboolean failed)
bool pe__shutdown_requested(pe_node_t *node)
gint sort_op_by_callid(gconstpointer a, gconstpointer b)
void resource_location(pe_resource_t *rsc, pe_node_t *node, int score, const char *tag, pe_working_set_t *data_set)
#define pe__set_resource_flags(resource, flags_to_set)
time_t get_effective_time(pe_working_set_t *data_set)
#define stop_action(rsc, node, optional)
#define pe_rsc_info(rsc, fmt, args...)
pe_ticket_t * ticket_new(const char *ticket_id, pe_working_set_t *data_set)
#define pe_proc_err(fmt...)
void pe__update_recheck_time(time_t recheck, pe_working_set_t *data_set)
pe_node_t * pe__copy_node(const pe_node_t *this_node)
gboolean add_tag_ref(GHashTable *tags, const char *tag_name, const char *obj_ref)
#define pe__set_working_set_flags(working_set, flags_to_set)
#define pe__clear_working_set_flags(working_set, flags_to_clear)
#define pe__set_action_flags(action, flags_to_set)
bool pe_can_fence(pe_working_set_t *data_set, pe_node_t *node)
#define pe_proc_warn(fmt...)
bool pe__is_guest_node(const pe_node_t *node)
bool xml_contains_remote_node(xmlNode *xml)
bool pe__is_guest_or_remote_node(const pe_node_t *node)
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)
bool pe__is_remote_node(const pe_node_t *node)
char * strndup(const char *str, size_t len)
@ PCMK_OCF_INSUFFICIENT_PRIV
Insufficient privileges.
@ PCMK_OCF_FAILED_PROMOTED
Service failed and possibly in promoted role.
@ PCMK_OCF_RUNNING_PROMOTED
Service active and promoted.
@ PCMK_OCF_DEGRADED_PROMOTED
Service promoted but more likely to fail soon.
@ PCMK_OCF_UNIMPLEMENT_FEATURE
Requested action not implemented.
@ PCMK_OCF_NOT_CONFIGURED
Parameter invalid (inherently)
@ PCMK_OCF_DEGRADED
Service active but more likely to fail soon.
@ PCMK_OCF_NOT_INSTALLED
Dependencies not available locally.
@ PCMK_OCF_UNKNOWN_ERROR
Unspecified error.
@ PCMK_OCF_INVALID_PARAM
Parameter invalid (in local context)
@ PCMK_OCF_NOT_RUNNING
Service safely stopped.
@ PCMK_EXEC_CANCELLED
Action was cancelled.
@ PCMK_EXEC_NO_SECRETS
Necessary CIB secrets are unavailable.
@ PCMK_EXEC_ERROR_FATAL
Execution failed, do not retry anywhere.
@ PCMK_EXEC_NOT_INSTALLED
Agent or dependency not available locally.
@ PCMK_EXEC_INVALID
Action cannot be attempted (e.g. shutdown)
@ PCMK_EXEC_DONE
Action completed, result is known.
@ PCMK_EXEC_ERROR
Execution failed, may be retried.
@ PCMK_EXEC_NOT_SUPPORTED
Agent does not implement requested action.
@ PCMK_EXEC_TIMEOUT
Action did not complete in time.
@ PCMK_EXEC_PENDING
Action is in progress.
@ PCMK_EXEC_UNKNOWN
Used only to initialize variables.
@ PCMK_EXEC_ERROR_HARD
Execution failed, do not retry on node.
@ PCMK_EXEC_MAX
Maximum value for this enum.
@ PCMK_EXEC_NO_FENCE_DEVICE
No fence device is configured for target.
@ PCMK_EXEC_NOT_CONNECTED
No connection to executor.
pe_node_t * pe_find_node_any(GList *node_list, const char *id, const char *uname)
pe_node_t * pe_find_node(GList *node_list, const char *uname)
pe_resource_t * pe_find_resource(GList *rsc_list, const char *id_rh)
int pcmk__scan_min_int(const char *text, int *result, int minimum)
GHashTable * pcmk__strkey_table(GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
int pcmk__scan_ll(const char *text, long long *result, long long default_value)
void pcmk__str_update(char **str, const char *value)
bool pcmk__strcase_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
bool pcmk__ends_with(const char *s, const char *match)
bool pcmk__str_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
void pcmk__g_strcat(GString *buffer,...) G_GNUC_NULL_TERMINATED
enum rsc_digest_cmp_val rc
struct pe_node_shared_s * details
GHashTable * digest_cache
cache of calculated resource digests
pe_working_set_t * data_set
Cluster that this node is part of.
pe_resource_t * remote_rsc
gboolean remote_maintenance
gboolean remote_requires_reset
gboolean rsc_discovery_enabled
gboolean remote_was_fenced
enum pe_obj_types variant
pe_working_set_t * cluster
pe_resource_t * container
GHashTable * allowed_nodes
GList * dangling_migrations
pe_node_t * partial_migration_source
guint remote_reconnect_ms
pe_node_t * partial_migration_target
enum rsc_role_e next_role
resource_object_functions_t * fns
const char * stonith_action
const char * placement_strategy
GHashTable * template_rsc_sets
enum pe_quorum_policy no_quorum_policy
int priority_fencing_delay
pe_node_t *(* location)(const pe_resource_t *, GList **, int)
pe_resource_t *(* find_rsc)(pe_resource_t *parent, const char *search, const pe_node_t *node, int flags)
int pe__target_rc_from_xml(xmlNode *xml_op)
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.
gboolean unpack_status(xmlNode *status, pe_working_set_t *data_set)
#define XPATH_ENABLE_UNFENCING
const char * pe_base_name_end(const char *id)
gboolean unpack_config(xmlNode *config, pe_working_set_t *data_set)
GList * find_operations(const char *rsc, const char *node, gboolean active_filter, pe_working_set_t *data_set)
#define SUB_XPATH_LRM_RESOURCE
void calculate_active_ops(GList *sorted_op_list, int *start_index, int *stop_index)
char * clone_zero(const char *last_rsc_id)
gboolean unpack_remote_nodes(xmlNode *xml_resources, pe_working_set_t *data_set)
CRM_TRACE_INIT_DATA(pe_status)
gboolean unpack_nodes(xmlNode *xml_nodes, pe_working_set_t *data_set)
#define SUB_XPATH_LRM_RSC_OP
gboolean unpack_resources(xmlNode *xml_resources, pe_working_set_t *data_set)
char * clone_strip(const char *last_rsc_id)
#define set_config_flag(data_set, option, flag)
pe_node_t * pe_create_node(const char *id, const char *uname, const char *type, const char *score, pe_working_set_t *data_set)
gboolean unpack_tags(xmlNode *xml_tags, pe_working_set_t *data_set)
Wrappers for and extensions to libxml2.
xmlXPathObjectPtr xpath_search(xmlNode *xml_top, const char *path)
xmlNode * first_named_child(const xmlNode *parent, const char *name)
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
xmlNode * crm_next_same_xml(const xmlNode *sibling)
Get next instance of same XML tag.
void freeXpathObject(xmlXPathObjectPtr xpathObj)
void copy_in_properties(xmlNode *target, xmlNode *src)
xmlNode * find_xml_node(const xmlNode *root, const char *search_path, gboolean must_find)
xmlNode * add_node_copy(xmlNode *new_parent, xmlNode *xml_node)
xmlNode * create_xml_node(xmlNode *parent, const char *name)