34 #define set_config_flag(data_set, option, flag) do { \
35 const char *tmp = pe_pref(data_set->config_hash, option); \
37 if(crm_is_true(tmp)) { \
38 set_bit(data_set->flags, flag); \
40 clear_bit(data_set->flags, flag); \
50 is_dangling_container_remote_node(
node_t *node)
74 crm_warn(
"Guest node %s will be fenced (by recovering %s) %s",
80 }
else if (is_dangling_container_remote_node(node)) {
81 crm_info(
"Cleaning up dangling connection resource for guest node %s %s"
82 " (fencing is already done, guest resource no longer exists)",
110 const char *value = NULL;
111 GHashTable *config_hash =
114 xmlXPathObjectPtr xpathObj = NULL;
117 xpathObj =
xpath_search(data_set->
input,
"//nvpair[@name='provides' and @value='unfencing']");
118 if(xpathObj && numXpathResults(xpathObj) > 0) {
125 xpathObj =
xpath_search(data_set->
input,
"//nvpair[@name='requires' and @value='unfencing']");
126 if(xpathObj && numXpathResults(xpathObj) > 0) {
133 #ifdef REDHAT_COMPAT_6
136 if(xpathObj && numXpathResults(xpathObj) > 0) {
152 crm_info(
"Startup probes: disabled (dangerous)");
157 crm_notice(
"Watchdog will be used via SBD if fencing is required");
166 crm_debug(
"STONITH of failed nodes is %s",
177 crm_debug(
"Stop all active resources: %s",
182 crm_debug(
"Cluster is symmetric" " - resources can run anywhere by default");
198 gboolean do_panic = FALSE;
204 (
"Setting no-quorum-policy=suicide makes no sense if stonith-enabled=false");
211 crm_notice(
"Resetting no-quorum-policy to 'stop': The cluster has never had quorum");
221 crm_debug(
"On loss of CCM Quorum: Freeze resources");
224 crm_debug(
"On loss of CCM Quorum: Stop ALL resources");
227 crm_notice(
"On loss of CCM Quorum: Fence all remaining nodes");
239 crm_trace(
"Orphan resource actions are %s",
243 crm_trace(
"Stopped resources are removed from the status section: %s",
255 crm_trace(
"By default resources are %smanaged",
260 is_set(data_set->
flags,
267 crm_debug(
"Node scores: 'red' = %s, 'yellow' = %s, 'green' = %s",
279 destroy_digest_cache(gpointer ptr)
301 " - this is rarely intended", uname);
304 new_node = calloc(1,
sizeof(
node_t));
305 if (new_node == NULL) {
310 new_node->
fixed = FALSE;
313 if (new_node->
details == NULL) {
318 crm_trace(
"Creating node for entry %s/%s", uname,
id);
330 }
else if (type == NULL ||
safe_str_eq(type,
"member")
340 g_hash_table_insert(new_node->
details->
attrs, strdup(
"#kind"), strdup(
"remote"));
342 g_hash_table_insert(new_node->
details->
attrs, strdup(
"#kind"), strdup(
"cluster"));
351 destroy_digest_cache);
358 expand_remote_rsc_meta(xmlNode *xml_obj, xmlNode *parent, GHashTable **rsc_name_check)
360 xmlNode *xml_rsc = NULL;
361 xmlNode *xml_tmp = NULL;
362 xmlNode *attr_set = NULL;
363 xmlNode *attr = NULL;
365 const char *container_id =
ID(xml_obj);
366 const char *remote_name = NULL;
367 const char *remote_server = NULL;
368 const char *remote_port = NULL;
369 const char *connect_timeout =
"60s";
370 const char *remote_allow_migrate=NULL;
373 for (attr_set = __xml_first_child(xml_obj); attr_set != NULL; attr_set = __xml_next_element(attr_set)) {
378 for (attr = __xml_first_child(attr_set); attr != NULL; attr = __xml_next_element(attr)) {
385 remote_server = value;
388 }
else if (
safe_str_eq(name,
"remote-connect-timeout")) {
389 connect_timeout = value;
390 }
else if (
safe_str_eq(name,
"remote-allow-migrate")) {
391 remote_allow_migrate=value;
396 if (remote_name == NULL) {
400 if (*rsc_name_check == NULL) {
401 *rsc_name_check = g_hash_table_new(
crm_str_hash, g_str_equal);
402 for (xml_rsc = __xml_first_child(parent); xml_rsc != NULL; xml_rsc = __xml_next_element(xml_rsc)) {
403 const char *
id =
ID(xml_rsc);
406 g_hash_table_insert(*rsc_name_check, (
char *)
id, (
char *)
id);
410 if (g_hash_table_lookup(*rsc_name_check, remote_name)) {
412 crm_err(
"Naming conflict with remote-node=%s. remote-nodes can not have the same name as a resource.",
430 tmp_id =
crm_concat(remote_name,
"meta-attributes-container",
'_');
437 tmp_id =
crm_concat(remote_name,
"meta-attributes-internal",
'_');
443 if (remote_allow_migrate) {
445 tmp_id =
crm_concat(remote_name,
"meta-attributes-container",
'_');
454 tmp_id =
crm_concat(remote_name,
"monitor-interval-30s",
'_');
461 if (connect_timeout) {
463 tmp_id =
crm_concat(remote_name,
"start-interval-0",
'_');
471 if (remote_port || remote_server) {
479 tmp_id =
crm_concat(remote_name,
"instance-attributes-addr",
'_');
487 tmp_id =
crm_concat(remote_name,
"instance-attributes-port",
'_');
501 static const char *blind_faith = NULL;
502 static gboolean unseen_are_unclean = TRUE;
503 static gboolean need_warning = TRUE;
516 unseen_are_unclean = FALSE;
518 crm_warn(
"Blind faith: not fencing unseen nodes");
521 need_warning = FALSE;
526 || unseen_are_unclean == FALSE) {
545 xmlNode *xml_obj = NULL;
547 const char *
id = NULL;
548 const char *uname = NULL;
549 const char *type = NULL;
550 const char *score = NULL;
552 for (xml_obj = __xml_first_child(xml_nodes); xml_obj != NULL; xml_obj = __xml_next_element(xml_obj)) {
560 crm_trace(
"Processing node %s/%s", uname,
id);
566 new_node = create_node(
id, uname, type, score, data_set);
568 if (new_node == NULL) {
578 handle_startup_fencing(data_set, new_node);
589 crm_info(
"Creating a fake local node");
599 const char *container_id = NULL;
604 for (; gIter != NULL; gIter = gIter->next) {
607 setup_container(child_rsc, data_set);
619 pe_rsc_trace(rsc,
"Resource %s's container is %s", rsc->
id, container_id);
621 pe_err(
"Resource %s: Unknown resource container (%s)", rsc->
id, container_id);
629 xmlNode *xml_obj = NULL;
630 GHashTable *rsc_name_check = NULL;
633 for (xml_obj = __xml_first_child(xml_resources); xml_obj != NULL; xml_obj = __xml_next_element(xml_obj)) {
634 const char *new_node_id = NULL;
639 new_node_id =
ID(xml_obj);
643 crm_trace(
"Found baremetal remote node %s in container resource %s", new_node_id,
ID(xml_obj));
644 create_node(new_node_id, new_node_id,
"remote", NULL, data_set);
659 new_node_id = expand_remote_rsc_meta(xml_obj, xml_resources, &rsc_name_check);
662 crm_trace(
"Found guest remote node %s in container resource %s", new_node_id,
ID(xml_obj));
663 create_node(new_node_id, new_node_id,
"remote", NULL, data_set);
668 xmlNode *xml_obj2 = NULL;
670 for (xml_obj2 = __xml_first_child(xml_obj); xml_obj2 != NULL; xml_obj2 = __xml_next_element(xml_obj2)) {
672 new_node_id = expand_remote_rsc_meta(xml_obj2, xml_resources, &rsc_name_check);
675 crm_trace(
"Found guest remote node %s in container resource %s which is in group %s", new_node_id,
ID(xml_obj2),
ID(xml_obj));
676 create_node(new_node_id, new_node_id,
"remote", NULL, data_set);
681 if (rsc_name_check) {
682 g_hash_table_destroy(rsc_name_check);
700 node_t *remote_node = NULL;
721 handle_startup_fencing(data_set, remote_node);
725 g_hash_table_replace(remote_node->
details->
attrs, strdup(
"#kind"), strdup(
"container"));
730 destroy_tag(gpointer
data)
736 g_list_free_full(tag->
refs, free);
744 xmlNode *xml_obj = NULL;
751 for (xml_obj = __xml_first_child(xml_resources); xml_obj != NULL; xml_obj = __xml_next_element(xml_obj)) {
755 const char *template_id =
ID(xml_obj);
758 template_id, NULL, NULL) == FALSE) {
765 crm_trace(
"Beginning unpack... <%s id=%s... >", crm_element_name(xml_obj),
ID(xml_obj));
777 if (new_rsc != NULL && new_rsc->
fns != NULL) {
783 for (gIter = data_set->
resources; gIter != NULL; gIter = gIter->next) {
786 setup_container(rsc, data_set);
787 link_rsc2remotenode(data_set, rsc);
797 crm_config_err(
"Resource start-up disabled since no STONITH resources have been defined");
798 crm_config_err(
"Either configure some or disable STONITH with the stonith-enabled option");
799 crm_config_err(
"NOTE: Clusters with shared data need STONITH to ensure data integrity");
808 xmlNode *xml_tag = NULL;
813 for (xml_tag = __xml_first_child(xml_tags); xml_tag != NULL; xml_tag = __xml_next_element(xml_tag)) {
814 xmlNode *xml_obj_ref = NULL;
815 const char *tag_id =
ID(xml_tag);
821 if (tag_id == NULL) {
827 for (xml_obj_ref = __xml_first_child(xml_tag); xml_obj_ref != NULL; xml_obj_ref = __xml_next_element(xml_obj_ref)) {
828 const char *obj_ref =
ID(xml_obj_ref);
834 if (obj_ref == NULL) {
835 crm_config_err(
"Failed unpacking %s for tag %s: %s should be specified",
836 crm_element_name(xml_obj_ref), tag_id,
XML_ATTR_ID);
854 const char *ticket_id = NULL;
855 const char *granted = NULL;
856 const char *last_granted = NULL;
857 const char *standby = NULL;
858 xmlAttrPtr xIter = NULL;
862 ticket_id =
ID(xml_ticket);
863 if (ticket_id == NULL || strlen(ticket_id) == 0) {
867 crm_trace(
"Processing ticket state for %s", ticket_id);
869 ticket = g_hash_table_lookup(data_set->
tickets, ticket_id);
870 if (ticket == NULL) {
872 if (ticket == NULL) {
877 for (xIter = xml_ticket->properties; xIter; xIter = xIter->next) {
878 const char *prop_name = (
const char *)xIter->name;
884 g_hash_table_replace(ticket->
state, strdup(prop_name), strdup(prop_value));
887 granted = g_hash_table_lookup(ticket->
state,
"granted");
893 crm_info(
"We do not have ticket '%s'", ticket->
id);
896 last_granted = g_hash_table_lookup(ticket->
state,
"last-granted");
901 standby = g_hash_table_lookup(ticket->
state,
"standby");
905 crm_info(
"Granted ticket '%s' is in standby-mode", ticket->
id);
911 crm_trace(
"Done with ticket state for %s", ticket_id);
919 xmlNode *xml_obj = NULL;
921 for (xml_obj = __xml_first_child(xml_tickets); xml_obj != NULL; xml_obj = __xml_next_element(xml_obj)) {
925 unpack_ticket_state(xml_obj, data_set);
934 get_ticket_state_legacy(gpointer key, gpointer value, gpointer user_data)
936 const char *long_key = key;
937 char *state_key = NULL;
939 const char *granted_prefix =
"granted-ticket-";
940 const char *last_granted_prefix =
"last-granted-";
941 static int granted_prefix_strlen = 0;
942 static int last_granted_prefix_strlen = 0;
944 const char *ticket_id = NULL;
945 const char *is_granted = NULL;
946 const char *last_granted = NULL;
947 const char *sep = NULL;
952 if (granted_prefix_strlen == 0) {
953 granted_prefix_strlen = strlen(granted_prefix);
956 if (last_granted_prefix_strlen == 0) {
957 last_granted_prefix_strlen = strlen(last_granted_prefix);
960 if (strstr(long_key, granted_prefix) == long_key) {
961 ticket_id = long_key + granted_prefix_strlen;
962 if (strlen(ticket_id)) {
963 state_key = strdup(
"granted");
966 }
else if (strstr(long_key, last_granted_prefix) == long_key) {
967 ticket_id = long_key + last_granted_prefix_strlen;
968 if (strlen(ticket_id)) {
969 state_key = strdup(
"last-granted");
970 last_granted = value;
972 }
else if ((sep = strrchr(long_key,
'-'))) {
974 state_key =
strndup(long_key, strlen(long_key) - strlen(sep));
977 if (ticket_id == NULL || strlen(ticket_id) == 0) {
982 if (state_key == NULL || strlen(state_key) == 0) {
987 ticket = g_hash_table_lookup(data_set->
tickets, ticket_id);
988 if (ticket == NULL) {
990 if (ticket == NULL) {
996 g_hash_table_replace(ticket->
state, state_key, strdup(value));
1004 crm_info(
"We do not have ticket '%s'", ticket->
id);
1007 }
else if (last_granted) {
1018 const char *
id = NULL;
1019 const char *uname = NULL;
1021 xmlNode *state = NULL;
1022 xmlNode *lrm_rsc = NULL;
1023 node_t *this_node = NULL;
1027 if (data_set->
tickets == NULL) {
1032 for (state = __xml_first_child(status); state != NULL; state = __xml_next_element(state)) {
1034 xmlNode *xml_tickets = state;
1035 GHashTable *state_hash = NULL;
1044 state_hash, NULL, TRUE, data_set->
now);
1046 g_hash_table_foreach(state_hash, get_ticket_state_legacy, data_set);
1049 g_hash_table_destroy(state_hash);
1053 unpack_tickets_state(xml_tickets, data_set);
1057 xmlNode *attrs = NULL;
1058 const char *resource_discovery_enabled = NULL;
1064 if (uname == NULL) {
1068 }
else if (this_node == NULL) {
1082 crm_trace(
"Processing node id=%s, uname=%s",
id, uname);
1103 if (resource_discovery_enabled && !
crm_is_true(resource_discovery_enabled)) {
1104 crm_warn(
"ignoring %s attribute on node %s, disabling resource discovery is not allowed on cluster nodes",
1115 pe_fence_node(data_set, this_node,
"because the cluster does not have quorum");
1121 for (state = __xml_first_child(status); state != NULL; state = __xml_next_element(state)) {
1130 if (this_node == NULL) {
1131 crm_info(
"Node %s is unknown",
id);
1140 crm_trace(
"Processing lrm resource entries on healthy node: %s",
1158 const char *
id = NULL;
1159 const char *uname = NULL;
1160 const char *shutdown = NULL;
1164 xmlNode *state = NULL;
1165 xmlNode *lrm_rsc = NULL;
1166 node_t *this_node = NULL;
1174 for (gIter = data_set->
nodes; gIter != NULL; gIter = gIter->next) {
1175 this_node = gIter->data;
1177 if ((this_node == NULL) || (
is_remote_node(this_node) == FALSE)) {
1180 determine_remote_online_status(data_set, this_node);
1184 for (state = __xml_first_child(status); state != NULL; state = __xml_next_element(state)) {
1185 const char *resource_discovery_enabled = NULL;
1186 xmlNode *attrs = NULL;
1195 if ((this_node == NULL) || (
is_remote_node(this_node) == FALSE)) {
1198 crm_trace(
"Processing remote node id=%s, uname=%s",
id, uname);
1227 if (resource_discovery_enabled && !
crm_is_true(resource_discovery_enabled)) {
1229 crm_warn(
"ignoring %s attribute on baremetal remote node %s, disabling resource discovery requires stonith to be enabled.",
1243 for (state = __xml_first_child(status); state != NULL; state = __xml_next_element(state)) {
1252 if ((this_node == NULL) || (
is_remote_node(this_node) == FALSE)) {
1255 crm_trace(
"Processing lrm resource entries on healthy remote node: %s",
1266 determine_online_status_no_fencing(
pe_working_set_t * data_set, xmlNode * node_state,
1269 gboolean online = FALSE;
1282 crm_debug(
"Node is not ready to run resources: %s", join);
1287 crm_trace(
"\tis_peer=%s, join=%s, expected=%s",
1292 pe_fence_node(data_set, this_node,
"because node is unexpectedly down");
1293 crm_info(
"\tin_cluster=%s, is_peer=%s, join=%s, expected=%s",
1300 determine_online_status_fencing(
pe_working_set_t * data_set, xmlNode * node_state,
1303 gboolean online = FALSE;
1304 gboolean do_terminate = FALSE;
1309 const char *terminate = g_hash_table_lookup(this_node->
details->
attrs,
"terminate");
1319 do_terminate = TRUE;
1321 }
else if (terminate != NULL && strlen(terminate) > 0) {
1323 char t = terminate[0];
1325 if (t !=
'0' && isdigit(t)) {
1326 do_terminate = TRUE;
1330 crm_trace(
"%s: in_cluster=%s, is_peer=%s, join=%s, expected=%s, term=%d",
1338 if (exp_state == NULL) {
1348 }
else if (in_cluster == NULL) {
1349 pe_fence_node(data_set, this_node,
"because the peer has not been seen by the cluster");
1352 pe_fence_node(data_set, this_node,
"because it failed the pacemaker membership criteria");
1371 pe_fence_node(data_set, this_node,
"because the node is no longer part of the cluster");
1374 pe_fence_node(data_set, this_node,
"because our peer process is no longer available");
1377 }
else if (do_terminate) {
1378 pe_fence_node(data_set, this_node,
"because termination was requested");
1390 pe_fence_node(data_set, this_node,
"because the peer was in an unknown state");
1391 crm_warn(
"%s: in-cluster=%s, is-peer=%s, join=%s, expected=%s, term=%d, shutdown=%d",
1407 goto remote_online_done;
1416 crm_trace(
"Remote node %s is set to ONLINE. role == started", this_node->
details->
id);
1422 crm_trace(
"Remote node %s shutdown. transition from start to stop role", this_node->
details->
id);
1439 crm_trace(
"Remote node %s is set to OFFLINE. node is stopped.", this_node->
details->
id);
1453 gboolean online = FALSE;
1454 const char *shutdown = NULL;
1457 if (this_node == NULL) {
1481 online = determine_online_status_no_fencing(data_set, node_state, this_node);
1484 online = determine_online_status_fencing(data_set, node_state, this_node);
1492 this_node->
fixed = TRUE;
1498 this_node->
fixed = TRUE;
1528 CRM_CHECK(last_rsc_id != NULL,
return NULL);
1529 lpc = strlen(last_rsc_id);
1531 switch (last_rsc_id[lpc]) {
1533 crm_err(
"Empty string: %s", last_rsc_id);
1548 zero = calloc(1, lpc + 1);
1549 memcpy(zero, last_rsc_id, lpc);
1557 zero = strdup(last_rsc_id);
1567 CRM_CHECK(last_rsc_id != NULL,
return NULL);
1568 if (last_rsc_id != NULL) {
1569 lpc = strlen(last_rsc_id);
1573 switch (last_rsc_id[lpc]) {
1589 zero = calloc(1, lpc + 3);
1590 memcpy(zero, last_rsc_id, lpc);
1592 zero[lpc + 1] =
'0';
1600 lpc = strlen(last_rsc_id);
1601 zero = calloc(1, lpc + 3);
1602 memcpy(zero, last_rsc_id, lpc);
1604 zero[lpc + 1] =
'0';
1606 crm_trace(
"%s -> %s", last_rsc_id, zero);
1611 create_fake_resource(
const char *rsc_id, xmlNode * rsc_entry,
pe_working_set_t * data_set)
1627 crm_debug(
"Detected orphaned remote node %s", rsc_id);
1631 node = create_node(rsc_id, rsc_id,
"remote", NULL, data_set);
1633 link_rsc2remotenode(data_set, rsc);
1636 crm_trace(
"Setting node %s as shutting down due to orphaned connection resource", rsc_id);
1643 crm_trace(
"Detected orphaned container filler %s", rsc_id);
1659 gboolean skip_inactive = FALSE;
1667 for (rIter = parent->
children; rsc == NULL && rIter; rIter = rIter->next) {
1673 if (locations == NULL) {
1678 for (nIter = locations; nIter && rsc == NULL; nIter = nIter->next) {
1679 node_t *childnode = nIter->data;
1692 if (rsc && rsc->running_on) {
1693 crm_notice(
"/Anonymous/ clone %s is already running on %s",
1695 skip_inactive = TRUE;
1700 g_list_free(locations);
1704 if (skip_inactive == FALSE) {
1705 pe_rsc_trace(parent,
"Looking for %s anywhere", rsc_id);
1706 for (rIter = parent->
children; rsc == NULL && rIter; rIter = rIter->next) {
1716 if (locations == NULL) {
1721 g_list_free(locations);
1733 pe_rsc_debug(parent,
"Created orphan %s for %s: %s on %s", top->
id, parent->
id, rsc_id,
1738 pe_rsc_debug(rsc,
"Internally renamed %s on %s to %s%s",
1748 xmlNode * rsc_entry)
1765 crm_trace(
"%s is not known as %s either", rsc_id, tmp);
1771 crm_trace(
"%s not found: %s", rsc_id, parent ? parent->
id :
"orphan");
1774 crm_trace(
"%s is no longer a primitive resource, the lrm_resource entry is obsolete",
1786 rsc = find_anonymous_clone(data_set, node, parent, base);
1807 rsc = create_fake_resource(rsc_id, rsc_entry, data_set);
1828 pe_rsc_trace(rsc,
"Resource %s is %s on %s: on_fail=%s",
1856 char *reason = NULL;
1857 gboolean should_fence = FALSE;
1868 should_fence = TRUE;
1878 reason =
crm_strdup_printf(
"because %s is active there. Fencing will be revoked if remote-node connection can be re-established on another cluster-node.", rsc->
id);
1880 should_fence = TRUE;
1884 if (reason == NULL) {
1908 pe_fence_node(data_set, node,
"because of resource failure(s)");
1964 pe_fence_node(data_set, tmpnode,
"because of connection failure(s)");
1999 " %s must be stopped manually on %s",
2022 for (; gIter != NULL; gIter = gIter->next) {
2028 g_list_free(possible_matches);
2036 int start_index,
int stop_index,
2040 const char *task = NULL;
2041 const char *status = NULL;
2045 pe_rsc_trace(rsc,
"%s: Start index %d, stop index = %d", rsc->
id, start_index, stop_index);
2047 for (; gIter != NULL; gIter = gIter->next) {
2048 xmlNode *rsc_op = (xmlNode *) gIter->data;
2052 const char *
id =
ID(rsc_op);
2053 const char *interval_s = NULL;
2062 }
else if (start_index < stop_index && counter <= stop_index) {
2066 }
else if (counter < start_index) {
2073 if (interval == 0) {
2095 int implied_monitor_start = -1;
2096 int implied_master_start = -1;
2097 const char *task = NULL;
2098 const char *status = NULL;
2104 for (; gIter != NULL; gIter = gIter->next) {
2105 xmlNode *rsc_op = (xmlNode *) gIter->data;
2123 implied_monitor_start =
counter;
2126 implied_master_start =
counter;
2130 if (*start_index == -1) {
2131 if (implied_master_start != -1) {
2132 *start_index = implied_master_start;
2133 }
else if (implied_monitor_start != -1) {
2134 *start_index = implied_monitor_start;
2143 int stop_index = -1;
2144 int start_index = -1;
2147 const char *task = NULL;
2154 xmlNode *migrate_op = NULL;
2155 xmlNode *rsc_op = NULL;
2156 xmlNode *last_failure = NULL;
2162 crm_element_name(rsc_entry), rsc_id, node->
details->
uname);
2166 sorted_op_list = NULL;
2168 for (rsc_op = __xml_first_child(rsc_entry); rsc_op != NULL; rsc_op = __xml_next_element(rsc_op)) {
2170 op_list = g_list_prepend(op_list, rsc_op);
2174 if (op_list == NULL) {
2180 rsc = unpack_find_resource(data_set, node, rsc_id, rsc_entry);
2182 rsc = process_orphan_resource(rsc_entry, node, data_set);
2187 saved_role = rsc->
role;
2192 for (gIter = sorted_op_list; gIter != NULL; gIter = gIter->next) {
2193 xmlNode *rsc_op = (xmlNode *) gIter->data;
2197 migrate_op = rsc_op;
2200 unpack_rsc_op(rsc, node, rsc_op, &last_failure, &on_fail, data_set);
2205 process_recurring(node, rsc, start_index, stop_index, sorted_op_list, data_set);
2208 g_list_free(sorted_op_list);
2210 process_rsc_state(rsc, node, on_fail, migrate_op, data_set);
2214 pe_rsc_debug(rsc,
"%s: Overwriting calculated next role %s"
2215 " with requested next role %s",
2220 pe_rsc_info(rsc,
"%s: Not overwriting calculated next role %s"
2221 " with requested next role %s",
2226 if (saved_role > rsc->
role) {
2227 rsc->
role = saved_role;
2234 handle_orphaned_container_fillers(xmlNode * lrm_rsc_list,
pe_working_set_t * data_set)
2236 xmlNode *rsc_entry = NULL;
2237 for (rsc_entry = __xml_first_child(lrm_rsc_list); rsc_entry != NULL;
2238 rsc_entry = __xml_next_element(rsc_entry)) {
2243 const char *container_id;
2251 if (container_id == NULL || rsc_id == NULL) {
2256 if (container == NULL) {
2267 pe_rsc_trace(rsc,
"Mapped orphaned rsc %s's container to %s", rsc->
id, container_id);
2276 xmlNode *rsc_entry = NULL;
2277 gboolean found_orphaned_container_filler = FALSE;
2278 GListPtr unexpected_containers = NULL;
2286 for (rsc_entry = __xml_first_child(lrm_rsc_list); rsc_entry != NULL;
2287 rsc_entry = __xml_next_element(rsc_entry)) {
2291 rsc = unpack_lrm_rsc_state(node, rsc_entry, data_set);
2296 found_orphaned_container_filler = TRUE;
2301 unexpected_containers = g_list_append(unexpected_containers, remote);
2310 for (gIter = unexpected_containers; gIter != NULL; gIter = gIter->next) {
2313 crm_warn(
"Recovering container resource %s. Resource is unexpectedly running and involves a remote-node.", remote->
container->
id);
2321 if (found_orphaned_container_filler) {
2322 handle_orphaned_container_fillers(lrm_rsc_list, data_set);
2324 g_list_free(unexpected_containers);
2341 set_node_score(gpointer key, gpointer value, gpointer user_data)
2344 int *score = user_data;
2349 #define STATUS_PATH_MAX 1024
2351 find_lrm_op(
const char *resource,
const char *op,
const char *node,
const char *source,
2357 offset += snprintf(xpath + offset,
STATUS_PATH_MAX - offset,
"//node_state[@uname='%s']", node);
2411 if (stop_op == NULL || stop_id < task_id) {
2412 int from_rc = 0, from_status = 0;
2413 const char *migrate_source =
2415 const char *migrate_target =
2420 xmlNode *migrate_from =
2428 pe_rsc_trace(rsc,
"%s op on %s exited with status=%d, rc=%d",
2429 ID(migrate_from), migrate_target, from_status, from_rc);
2434 pe_rsc_trace(rsc,
"Detected dangling migration op: %s on %s",
ID(xml_op),
2444 }
else if (migrate_from) {
2446 pe_rsc_trace(rsc,
"Marking active on %s %p %d", migrate_target, target,
2453 pe_rsc_trace(rsc,
"Marking active on %s %p %d", migrate_target, target,
2489 xmlNode *migrate_op =
2503 if (stop_op == NULL || stop_id < migrate_id) {
2519 xmlNode *migrate_op =
2533 if (stop_op == NULL || stop_id < migrate_id) {
2536 pe_rsc_trace(rsc,
"Stop: %p %d, Migrated: %p %d", stop_op, stop_id, migrate_op,
2542 }
else if (migrate_op == NULL) {
2552 xmlNode *xIter = NULL;
2559 for (xIter = data_set->
failed->children; xIter; xIter = xIter->next) {
2574 static const char *get_op_key(xmlNode *xml_op)
2584 unpack_rsc_op_failure(
resource_t * rsc,
node_t * node,
int rc, xmlNode * xml_op, xmlNode ** last_failure,
2588 bool is_probe = FALSE;
2591 const char *key = get_op_key(xml_op);
2597 *last_failure = xml_op;
2606 crm_warn(
"Processing failed op %s for %s on %s: %s (%d)",
2607 task, rsc->
id, node->
details->
uname, services_ocf_exitcode_str(rc),
2610 record_failed_op(xml_op, node, data_set);
2613 crm_trace(
"Processing failed op %s for %s on %s: %s (%d)",
2614 task, rsc->
id, node->
details->
uname, services_ocf_exitcode_str(rc),
2618 action =
custom_action(rsc, strdup(key), task, NULL, TRUE, FALSE, data_set);
2632 unpack_rsc_migration_failure(rsc, node, xml_op, data_set);
2648 crm_warn(
"Forcing %s to stop after a failed demote action", rsc->
id);
2667 pe_rsc_trace(rsc,
"Resource %s: role=%s, unclean=%s, on_fail=%s, fail_role=%s",
2692 crm_warn(
"Making sure %s doesn't come up again", fail_rsc->
id);
2696 g_hash_table_foreach(fail_rsc->
allowed_nodes, set_node_score, &score);
2703 determine_op_status(
2709 const char *key = get_op_key(xml_op);
2712 bool is_probe = FALSE;
2720 if (target_rc >= 0 && target_rc != rc) {
2722 pe_rsc_debug(rsc,
"%s on %s returned '%s' (%d) instead of the expected value: '%s' (%d)",
2724 services_ocf_exitcode_str(rc), rc,
2725 services_ocf_exitcode_str(target_rc), target_rc);
2733 if (is_probe && target_rc == 7) {
2736 pe_rsc_info(rsc,
"Operation %s found resource %s active on %s",
2765 pe_rsc_info(rsc,
"Operation %s found resource %s active in master mode on %s",
2768 }
else if (target_rc == rc) {
2771 }
else if (target_rc >= 0) {
2779 crm_err(
"%s reported %s in master mode on %s",
2807 pe_proc_err(
"No further recovery can be attempted for %s: %s action failed with '%s' (%d)",
2808 rsc->
id, task, services_ocf_exitcode_str(rc), rc);
2817 crm_info(
"Treating %s (rc=%d) on %s as an ERROR",
2828 bool expired = FALSE;
2829 time_t last_failure = 0;
2830 int clear_failcount = 0;
2833 const char *key = get_op_key(xml_op);
2855 if (strstr(
ID(xml_op),
"last_failure")) {
2856 crm_info(
"Waiting to clear monitor failure for remote node %s until fencing has occurred", rsc->
id);
2860 failure_timeout = 0;
2865 if (failure_timeout > 0) {
2871 if (now > (last_run + failure_timeout)) {
2878 if (failure_timeout > 0) {
2882 clear_failcount = 1;
2890 clear_failcount = 1;
2894 }
else if (strstr(
ID(xml_op),
"last_failure") &&
2895 ((strcmp(task,
"start") == 0) || (strcmp(task,
"monitor") == 0))) {
2902 crm_trace(
"rsc op %s/%s on node %s does not have a op digest to compare against", rsc->
id,
2905 clear_failcount = 1;
2907 (
"Clearing failcount for %s on %s, %s failed and now resource parameters have changed.",
2912 if (clear_failcount) {
2941 char *dummy_string = NULL;
2966 update_resource_state(
resource_t * rsc,
node_t * node, xmlNode * xml_op,
const char * task,
int rc,
2969 gboolean clear_past_failure = FALSE;
2975 clear_past_failure = TRUE;
2982 const char *op_key = get_op_key(xml_op);
2983 const char *last_failure_key = get_op_key(last_failure);
2986 clear_past_failure = TRUE;
2996 clear_past_failure = TRUE;
3000 clear_past_failure = TRUE;
3004 clear_past_failure = TRUE;
3012 clear_past_failure = TRUE;
3015 unpack_rsc_migration(rsc, node, xml_op, data_set);
3023 if (clear_past_failure) {
3029 pe_rsc_trace(rsc,
"%s.%s is not cleared by a completed stop",
3060 const char *key = NULL;
3061 const char *task = NULL;
3062 const char *task_key = NULL;
3069 gboolean expired = FALSE;
3075 CRM_CHECK(xml_op != NULL,
return FALSE);
3077 task_key = get_op_key(xml_op);
3100 pe_rsc_trace(rsc,
"Unpacking task %s/%s (call_id=%d, status=%d, rc=%d) on %s (role=%s)",
3104 pe_rsc_trace(rsc,
"Node %s (where %s is running) is unclean."
3105 " Further action depends on the value of the stop's on-fail attribue",
3115 expired = check_operation_expiry(rsc, node, rc, xml_op, data_set);
3125 record_failed_op(xml_op, node, data_set);
3134 record_failed_op(xml_op, node, data_set);
3138 if (expired && target_rc != rc) {
3141 pe_rsc_debug(rsc,
"Expired operation '%s' on %s returned '%s' (%d) instead of the expected value: '%s' (%d)",
3143 services_ocf_exitcode_str(rc), rc,
3144 services_ocf_exitcode_str(target_rc), target_rc);
3147 crm_notice(
"Ignoring expired calculated failure %s (rc=%d, magic=%s) on %s",
3152 crm_notice(
"Re-initiated expired calculated failure %s (rc=%d, magic=%s) on %s",
3161 status = determine_op_status(rsc, rc, target_rc, node, xml_op, on_fail, data_set);
3168 pe_err(
"Don't know what to do for cancelled ops yet");
3206 update_resource_state(rsc, node, xml_op, task, rc, *last_failure, on_fail, data_set);
3210 failure_strategy = get_action_on_fail(rsc, task_key, task, data_set);
3212 crm_warn(
"Cannot ignore failed %s (status=%d, rc=%d) on %s: "
3213 "Resource agent doesn't exist",
3219 unpack_rsc_op_failure(rsc, node, rc, xml_op, last_failure, on_fail, data_set);
3228 failure_strategy = get_action_on_fail(rsc, task_key, task, data_set);
3233 crm_warn(
"Pretending the failure of %s (rc=%d) on %s succeeded",
3236 update_resource_state(rsc, node, xml_op, task, target_rc, *last_failure, on_fail, data_set);
3240 record_failed_op(xml_op, node, data_set);
3243 *on_fail = failure_strategy;
3247 unpack_rsc_op_failure(rsc, node, rc, xml_op, last_failure, on_fail, data_set);
3251 "Preventing %s from re-starting on %s: operation %s failed '%s' (%d)",
3253 task, services_ocf_exitcode_str(rc), rc);
3258 crm_err(
"Preventing %s from re-starting anywhere: operation %s failed '%s' (%d)",
3259 parent->
id, task, services_ocf_exitcode_str(rc), rc);
3275 const char *cluster_name = NULL;
3291 cluster_name = g_hash_table_lookup(data_set->
config_hash,
"cluster-name");
3293 g_hash_table_insert(node->
details->
attrs, strdup(
"#cluster-name"), strdup(cluster_name));
3299 if (g_hash_table_lookup(node->
details->
attrs,
"#site-name") == NULL) {
3300 const char *site_name = g_hash_table_lookup(node->
details->
attrs,
"site-name");
3304 g_hash_table_insert(node->
details->
attrs, strdup(
"#site-name"), strdup(site_name));
3306 }
else if (cluster_name) {
3308 g_hash_table_insert(node->
details->
attrs, strdup(
"#site-name"), strdup(cluster_name));
3315 extract_operations(
const char *node,
const char *rsc, xmlNode * rsc_entry, gboolean active_filter)
3318 int stop_index = -1;
3319 int start_index = -1;
3321 xmlNode *rsc_op = NULL;
3329 sorted_op_list = NULL;
3331 for (rsc_op = __xml_first_child(rsc_entry); rsc_op != NULL; rsc_op = __xml_next_element(rsc_op)) {
3335 op_list = g_list_prepend(op_list, rsc_op);
3339 if (op_list == NULL) {
3347 if (active_filter == FALSE) {
3348 return sorted_op_list;
3355 for (gIter = sorted_op_list; gIter != NULL; gIter = gIter->next) {
3356 xmlNode *rsc_op = (xmlNode *) gIter->data;
3360 if (start_index < stop_index) {
3361 crm_trace(
"Skipping %s: not active",
ID(rsc_entry));
3364 }
else if (counter < start_index) {
3368 op_list = g_list_append(op_list, rsc_op);
3371 g_list_free(sorted_op_list);
3382 xmlNode *tmp = NULL;
3385 node_t *this_node = NULL;
3387 xmlNode *node_state = NULL;
3389 for (node_state = __xml_first_child(status); node_state != NULL;
3390 node_state = __xml_next_element(node_state)) {
3400 if(this_node == NULL) {
3405 determine_remote_online_status(data_set, this_node);
3416 xmlNode *lrm_rsc = NULL;
3421 for (lrm_rsc = __xml_first_child(tmp); lrm_rsc != NULL;
3422 lrm_rsc = __xml_next_element(lrm_rsc)) {
3431 intermediate = extract_operations(uname, rsc_id, lrm_rsc, active_filter);
3432 output = g_list_concat(output, intermediate);
gboolean unpack_config(xmlNode *config, pe_working_set_t *data_set)
#define CRM_CHECK(expr, failure_action)
#define XML_RSC_OP_LAST_CHANGE
gboolean unpack_rsc_op(resource_t *rsc, node_t *node, xmlNode *xml_op, xmlNode **last_failure, enum action_fail_response *failed, pe_working_set_t *data_set)
void verify_pe_options(GHashTable *options)
xmlNode * find_xml_node(xmlNode *cib, const char *node_path, gboolean must_find)
#define crm_notice(fmt, args...)
#define CRMD_ACTION_MIGRATED
node_t *(* location)(resource_t *, GListPtr *, gboolean)
#define pe_rsc_debug(rsc, fmt, args...)
#define pe_flag_have_stonith_resource
gboolean safe_str_neq(const char *a, const char *b)
gint sort_rsc_priority(gconstpointer a, gconstpointer b)
gboolean determine_online_status(xmlNode *node_state, node_t *this_node, pe_working_set_t *data_set)
gboolean get_target_role(resource_t *rsc, enum rsc_role_e *role)
#define XML_NODE_IS_FENCED
#define XML_ATTR_TRANSITION_MAGIC
node_t * node_copy(const node_t *this_node)
gboolean unpack_remote_status(xmlNode *status, pe_working_set_t *data_set)
#define stop_action(rsc, node, optional)
#define pe_flag_enable_unfencing
#define pe_rsc_orphan_container_filler
int default_resource_stickiness
char * clone_strip(const char *last_rsc_id)
#define XML_ATTR_QUORUM_PANIC
bool pe_can_fence(pe_working_set_t *data_set, node_t *node)
#define XML_TAG_UTILIZATION
#define pe_flag_have_remote_nodes
#define XML_RULE_ATTR_SCORE
#define XML_BOOLEAN_FALSE
#define crm_config_err(fmt...)
int get_target_rc(xmlNode *xml_op)
enum action_fail_response on_fail
resource_t * rsc_contains_remote_node(pe_working_set_t *data_set, resource_t *rsc)
int char2score(const char *score)
#define pe_proc_warn(fmt...)
#define XML_TAG_TRANSIENT_NODEATTRS
#define CRMD_ACTION_NOTIFY
#define pe_flag_startup_probes
long long crm_get_msec(const char *input)
GListPtr find_actions(GListPtr input, const char *key, const node_t *on_node)
gboolean common_unpack(xmlNode *xml_obj, resource_t **rsc, resource_t *parent, pe_working_set_t *data_set)
enum pe_obj_types variant
void(* free)(resource_t *)
#define XML_LRM_ATTR_INTERVAL
#define XML_LRM_TAG_RESOURCE
#define pe_flag_stop_rsc_orphans
node_t * partial_migration_source
#define CRMD_ACTION_PROMOTE
int crm_parse_int(const char *text, const char *default_text)
#define XML_NVPAIR_ATTR_NAME
gint sort_op_by_callid(gconstpointer a, gconstpointer b)
#define XML_NODE_EXPECTED
node_t * pe_find_node(GListPtr node_list, const char *uname)
#define XML_CIB_TAG_RSC_TEMPLATE
resource_t * create_child_clone(resource_t *rsc, int sub_id, pe_working_set_t *data_set)
time_t get_effective_time(pe_working_set_t *data_set)
no_quorum_policy_t no_quorum_policy
#define CRM_LOG_ASSERT(expr)
const char * pe_pref(GHashTable *options, const char *name)
resource_t * uber_parent(resource_t *rsc)
#define clear_bit(word, bit)
void copy_in_properties(xmlNode *target, xmlNode *src)
#define CRMD_JOINSTATE_NACK
#define XML_CIB_TAG_NVPAIR
#define pe_rsc_allow_migrate
resource_t *(* find_rsc)(resource_t *parent, const char *search, node_t *node, int flags)
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
#define pe_proc_err(fmt...)
char * strndup(const char *str, size_t len)
#define XML_CIB_TAG_PROPSET
gboolean decode_transition_key(const char *key, char **uuid, int *action, int *transition_id, int *target_rc)
gboolean unpack_resources(xmlNode *xml_resources, pe_working_set_t *data_set)
#define CRMD_ACTION_START
#define XML_LRM_ATTR_TASK_KEY
#define XML_TAG_ATTR_SETS
#define XML_LRM_ATTR_TASK
const char * role2text(enum rsc_role_e role)
gboolean is_remote_node(node_t *node)
#define CRM_OP_CLEAR_FAILCOUNT
struct node_shared_s * details
gboolean unpack_status(xmlNode *status, pe_working_set_t *data_set)
#define CRMD_JOINSTATE_DOWN
#define crm_warn(fmt, args...)
#define CRMD_ACTION_DEMOTE
#define set_bit(word, bit)
#define crm_atoi(text, default_text)
#define crm_debug(fmt, args...)
void native_add_running(resource_t *rsc, node_t *node, pe_working_set_t *data_set)
#define XML_CIB_ATTR_SHUTDOWN
#define XML_RSC_ATTR_CONTAINER
#define XML_CIB_TAG_RESOURCE
gboolean unpack_nodes(xmlNode *xml_nodes, pe_working_set_t *data_set)
int get_failcount_full(node_t *node, resource_t *rsc, time_t *last_failure, bool effective, xmlNode *xml_op, pe_working_set_t *data_set)
#define XML_CIB_TAG_STATE
node_t * partial_migration_target
resource_object_functions_t * fns
GHashTable * allowed_nodes
GHashTable * digest_cache
#define set_config_flag(data_set, option, flag)
#define crm_trace(fmt, args...)
#define CRMD_JOINSTATE_MEMBER
#define do_crm_log(level, fmt, args...)
Log a message.
enum rsc_digest_cmp_val rc
gboolean is_baremetal_remote_node(node_t *node)
char * digest_secure_calc
gboolean unpack_remote_nodes(xmlNode *xml_resources, pe_working_set_t *data_set)
gboolean add_node_attrs(xmlNode *xml_obj, node_t *node, gboolean overwrite, pe_working_set_t *data_set)
gboolean is_container_remote_node(node_t *node)
xmlNode * add_node_copy(xmlNode *new_parent, xmlNode *xml_node)
const char * stonith_action
#define crm_log_xml_debug(xml, text)
#define XML_AGENT_ATTR_PROVIDER
#define XML_TAG_META_SETS
Wrappers for and extensions to libxml2.
#define XML_ATTR_TE_NOWAIT
gboolean add_tag_ref(GHashTable *tags, const char *tag_name, const char *obj_ref)
xmlNode * create_xml_node(xmlNode *parent, const char *name)
int crm_element_value_int(xmlNode *data, const char *name, int *dest)
char * clone_zero(const char *last_rsc_id)
const char * crm_element_value(xmlNode *data, const char *name)
action_t * custom_action(resource_t *rsc, char *key, const char *task, node_t *on_node, gboolean optional, gboolean foo, pe_working_set_t *data_set)
#define pe_flag_maintenance_mode
#define XML_LRM_ATTR_MIGRATE_TARGET
#define CIB_OPTIONS_FIRST
#define XML_RSC_ATTR_REMOTE_NODE
#define XML_LRM_ATTR_RESTART_DIGEST
GListPtr dangling_migrations
void free_xml(xmlNode *child)
#define pe_flag_stop_everything
gboolean crm_str_eq(const char *a, const char *b, gboolean use_case)
const char * placement_strategy
int remote_reconnect_interval
#define crm_config_warn(fmt...)
#define XML_ATTR_TRANSITION_KEY
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
GHashTable * node_hash_from_list(GListPtr list)
gboolean xml_contains_remote_node(xmlNode *xml)
node_t * pe_find_node_any(GListPtr node_list, const char *id, const char *uname)
const char * fail2text(enum action_fail_response fail)
void add_hash_param(GHashTable *hash, const char *name, const char *value)
#define pe_flag_quick_location
#define pe_rsc_start_pending
#define XML_LRM_TAG_RESOURCES
#define crm_err(fmt, args...)
#define XML_CIB_TAG_TICKET_STATE
void resource_location(resource_t *rsc, node_t *node, int score, const char *tag, pe_working_set_t *data_set)
xmlXPathObjectPtr xpath_search(xmlNode *xml_top, const char *path)
void pe_fence_node(pe_working_set_t *data_set, node_t *node, const char *reason)
ticket_t * ticket_new(const char *ticket_id, pe_working_set_t *data_set)
enum rsc_role_e next_role
#define XML_ATTR_HAVE_WATCHDOG
#define XML_NODE_ATTR_RSC_DISCOVERY
int compare_version(const char *version1, const char *version2)
gboolean rsc_discovery_enabled
#define pe_flag_remove_after_stop
#define pe_rsc_failure_ignored
#define XML_LRM_ATTR_CALLID
#define CRMD_ACTION_MIGRATE
#define XML_NVPAIR_ATTR_VALUE
enum rsc_role_e fail_role
gboolean remote_requires_reset
#define XML_RSC_ATTR_INTERNAL_RSC
#define XML_ATTR_CRM_VERSION
#define XML_LRM_ATTR_OPSTATUS
gboolean unpack_lrm_resources(node_t *node, xmlNode *lrm_rsc_list, pe_working_set_t *data_set)
#define CRMD_JOINSTATE_PENDING
enum pe_action_flags flags
GListPtr find_operations(const char *rsc, const char *node, gboolean active_filter, pe_working_set_t *data_set)
#define XML_NODE_JOIN_STATE
void pe_free_action(action_t *action)
#define pe_flag_have_quorum
void destroy_ticket(gpointer data)
#define XML_CIB_TAG_STATUS
#define XML_CIB_TAG_OBJ_REF
void unpack_instance_attributes(xmlNode *top, xmlNode *xml_obj, const char *set_name, GHashTable *node_hash, GHashTable *hash, const char *always_first, gboolean overwrite, crm_time_t *now)
#define pe_flag_is_managed_default
gboolean remote_was_fenced
#define XML_NODE_IN_CLUSTER
#define pe_flag_stop_action_orphans
gboolean crm_is_true(const char *s)
void calculate_active_ops(GListPtr sorted_op_list, int *start_index, int *stop_index)
#define XML_CIB_TAG_GROUP
CRM_TRACE_INIT_DATA(pe_status)
#define XML_LRM_TAG_RSC_OP
#define pe_rsc_trace(rsc, fmt, args...)
#define pe_flag_symmetric_cluster
char * crm_concat(const char *prefix, const char *suffix, char join)
char * generate_op_key(const char *rsc_id, const char *op_type, int interval)
void print_resource(int log_level, const char *pre_text, resource_t *rsc, gboolean details)
gboolean unpack_tags(xmlNode *xml_tags, pe_working_set_t *data_set)
resource_t * pe_find_resource(GListPtr rsc_list, const char *id_rh)
#define safe_str_eq(a, b)
op_digest_cache_t * rsc_action_digest_cmp(resource_t *rsc, xmlNode *xml_op, node_t *node, pe_working_set_t *data_set)
char * crm_strdup_printf(char const *format,...) __attribute__((__format__(__printf__
#define XML_LRM_ATTR_MIGRATE_SOURCE
void freeXpathObject(xmlXPathObjectPtr xpathObj)
gint sort_node_uname(gconstpointer a, gconstpointer b)
#define XML_CIB_TAG_TICKETS
#define crm_info(fmt, args...)
char * digest_restart_calc
void g_hash_destroy_str(gpointer data)
GHashTable * template_rsc_sets
#define pe_rsc_unexpectedly_running
#define pe_flag_concurrent_fencing
#define XML_OP_ATTR_ALLOW_MIGRATE
#define pe_flag_start_failure_fatal
#define pe_flag_stonith_enabled
enum crm_ais_msg_types type
#define pe_rsc_info(rsc, fmt, args...)
#define XML_AGENT_ATTR_CLASS
#define CRMD_ACTION_STATUS