23 extern xmlNode *
get_object_root(
const char *object_type, xmlNode * the_root);
24 void print_str_str(gpointer key, gpointer value, gpointer user_data);
28 static xmlNode *find_rsc_op_entry_helper(
pe_resource_t * rsc,
const char *key,
29 gboolean include_disabled);
31 #if ENABLE_VERSIONED_ATTRS
32 pe_rsc_action_details_t *
35 pe_rsc_action_details_t *details;
39 if (
action->action_details == NULL) {
40 action->action_details = calloc(1,
sizeof(pe_rsc_action_details_t));
44 details = (pe_rsc_action_details_t *)
action->action_details;
45 if (details->versioned_parameters == NULL) {
49 if (details->versioned_meta == NULL) {
58 pe_rsc_action_details_t *details;
60 if ((
action == NULL) || (
action->action_details == NULL)) {
64 details = (pe_rsc_action_details_t *)
action->action_details;
66 if (details->versioned_parameters) {
67 free_xml(details->versioned_parameters);
69 if (details->versioned_meta) {
73 action->action_details = NULL;
95 for (GList *n = rsc->
running_on; n != NULL; n = n->next) {
117 }
else if(node == NULL) {
160 GHashTable *result = hash;
167 g_hash_table_iter_init(&iter, hash);
168 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node)) {
171 if (other_node == NULL) {
173 }
else if (merge_scores) {
178 for (; gIter != NULL; gIter = gIter->next) {
181 other_node = pe_hash_table_lookup(result, node->
details->
id);
183 if (other_node == NULL) {
187 g_hash_table_insert(result, (gpointer) new_node->
details->
id, new_node);
203 GHashTable *result = NULL;
205 result = g_hash_table_new_full(
crm_str_hash, g_str_equal, NULL, free);
206 for (GList *gIter = list; gIter != NULL; gIter = gIter->next) {
209 g_hash_table_insert(result, (gpointer) new_node->
details->
id, new_node);
217 const char *name_a = ((
const pe_node_t *) a)->details->uname;
218 const char *name_b = ((
const pe_node_t *) b)->details->uname;
220 while (*name_a && *name_b) {
221 if (isdigit(*name_a) && isdigit(*name_b)) {
226 long num_a = strtol(name_a, &end_a, 10);
227 long num_b = strtol(name_b, &end_b, 10);
230 size_t len_a = end_a - name_a;
231 size_t len_b = end_b - name_b;
235 }
else if (num_a > num_b) {
237 }
else if (len_a < len_b) {
239 }
else if (len_a > len_b) {
246 int lower_a = tolower(*name_a);
247 int lower_b = tolower(*name_b);
249 if (lower_a < lower_b) {
251 }
else if (lower_a > lower_b) {
258 if (!*name_a && *name_b) {
260 }
else if (*name_a && !*name_b) {
275 pe__output_node_weights(
pe_resource_t *rsc,
const char *comment,
281 GList *list = g_list_sort(g_hash_table_get_values(nodes),
sort_node_uname);
283 for (GList *gIter = list; gIter != NULL; gIter = gIter->next) {
288 printf(
"%s: %s allocation score on %s: %s\n",
291 printf(
"%s: %s = %s\n", comment, node->
details->
uname, score);
309 pe__log_node_weights(
const char *file,
const char *
function,
int line,
319 g_hash_table_iter_init(&iter, nodes);
320 while (g_hash_table_iter_next(&iter, NULL, (
void **) &node)) {
323 qb_log_from_external_source(
function, file,
324 "%s: %s allocation score on %s: %s",
327 node->details->uname, score);
329 qb_log_from_external_source(
function, file,
"%s: %s = %s",
331 comment, node->details->uname,
367 pe__log_node_weights(file,
function, line, rsc, comment, nodes);
369 pe__output_node_weights(rsc, comment, nodes);
374 for (GList *gIter = rsc->
children; gIter != NULL; gIter = gIter->next) {
384 append_dump_text(gpointer key, gpointer value, gpointer user_data)
386 char **dump_text = user_data;
388 *dump_text, (
char *)key, (
char *)value);
391 *dump_text = new_text;
403 fprintf(stdout,
"%s\n", dump_text);
417 g_hash_table_foreach(rsc->
utilization, append_dump_text, &dump_text);
420 fprintf(stdout,
"%s\n", dump_text);
436 if (a == NULL && b == NULL) {
463 if (a == NULL && b == NULL) {
511 pe_node_t * on_node, gboolean optional, gboolean save_action,
518 CRM_CHECK(task != NULL, free(key);
return NULL);
520 if (save_action && rsc != NULL) {
522 }
else if(save_action) {
535 if (possible_matches != NULL) {
536 if (pcmk__list_of_multiple(possible_matches)) {
537 pe_warn(
"Action %s for %s on %s exists %d times",
538 task, rsc ? rsc->
id :
"<NULL>",
539 on_node ? on_node->
details->
uname :
"<NULL>", g_list_length(possible_matches));
542 action = g_list_nth_data(possible_matches, 0);
543 pe_rsc_trace(rsc,
"Found existing action %d (%s) for %s (%s) on %s",
545 (rsc? rsc->
id :
"no resource"), task,
547 g_list_free(possible_matches);
552 pe_rsc_trace(rsc,
"Creating %s action %d: %s for %s (%s) on %s",
553 (optional?
"optional" :
"mandatory"),
555 (rsc? rsc->
id :
"no resource"), task,
567 action->task = strdup(task);
571 action->uuid = strdup(key);
585 action->extra = crm_str_table_new();
586 action->meta = crm_str_table_new();
596 action->op_entry = find_rsc_op_entry_helper(rsc, key, TRUE);
617 enum pe_quorum_policy quorum_policy = effective_quorum_policy(rsc, data_set);
621 warn_level = LOG_WARNING;
628 action->node->details->attrs,
629 action->extra, NULL, FALSE, data_set);
635 }
else if (
action->node == NULL) {
640 && g_hash_table_lookup(
action->meta,
648 && !(
action->node->details->online)
650 ||
action->node->details->remote_requires_reset)) {
652 do_crm_log(warn_level,
"Action %s on %s is unrunnable (offline)",
655 && save_action && a_task ==
stop_rsc
656 &&
action->node->details->unclean == FALSE) {
661 &&
action->node->details->pending) {
663 do_crm_log(warn_level,
"Action %s on %s is unrunnable (pending)",
677 crm_debug(
"%s\t%s (cancelled : host cannot be fenced)",
731 valid_stop_on_fail(
const char *value)
742 const char *
name = NULL;
743 const char *role = NULL;
744 const char *on_fail = NULL;
745 const char *interval_spec = NULL;
746 const char *enabled = NULL;
750 && !valid_stop_on_fail(value)) {
753 "action to default value because '%s' is not "
754 "allowed for stop",
action->rsc->id, value);
759 xmlNode *operation = NULL;
763 for (operation = __xml_first_child_element(
action->rsc->ops_xml);
764 operation && !value; operation = __xml_next_element(operation)) {
766 if (!
crm_str_eq((
const char *)operation->name,
"op", TRUE)) {
803 "action to default value because 'demote' is not "
813 find_min_interval_mon(
pe_resource_t * rsc, gboolean include_disabled)
815 guint interval_ms = 0;
816 guint min_interval_ms = G_MAXUINT;
817 const char *
name = NULL;
818 const char *value = NULL;
819 const char *interval_spec = NULL;
821 xmlNode *operation = NULL;
823 for (operation = __xml_first_child_element(rsc->
ops_xml); operation != NULL;
824 operation = __xml_next_element(operation)) {
826 if (
crm_str_eq((
const char *)operation->name,
"op", TRUE)) {
830 if (!include_disabled && value &&
crm_is_true(value) == FALSE) {
840 if (interval_ms && (interval_ms < min_interval_ms)) {
841 min_interval_ms = interval_ms;
851 unpack_start_delay(
const char *value, GHashTable *meta)
858 if (start_delay < 0) {
872 unpack_interval_origin(
const char *value, xmlNode *xml_obj, guint interval_ms,
875 long long result = 0;
876 guint interval_sec = interval_ms / 1000;
880 if ((value == NULL) || (interval_ms == 0) || (now == NULL)) {
886 if (origin == NULL) {
888 "'%s' because '%s' is not valid",
889 (
ID(xml_obj)?
ID(xml_obj) :
"(missing ID)"), value);
898 result = result % interval_sec;
901 result = ((result <= 0)? 0 : interval_sec) - result;
902 crm_info(
"Calculated a start delay of %llds for operation '%s'",
904 (
ID(xml_obj)?
ID(xml_obj) :
"(unspecified)"));
906 if (start_delay != NULL) {
907 *start_delay = result * 1000;
913 unpack_timeout(
const char *value)
926 xmlNode *child = NULL;
928 GHashTable *action_meta = NULL;
940 action_meta = crm_str_table_new();
942 NULL, action_meta, NULL, FALSE, data_set);
950 if (timeout_ms < 0) {
954 if (action_meta != NULL) {
955 g_hash_table_destroy(action_meta);
960 #if ENABLE_VERSIONED_ATTRS
962 unpack_versioned_meta(xmlNode *versioned_meta, xmlNode *xml_obj,
965 xmlNode *attrs = NULL;
966 xmlNode *attr = NULL;
968 for (attrs = __xml_first_child_element(versioned_meta); attrs != NULL;
969 attrs = __xml_next_element(attrs)) {
971 for (attr = __xml_first_child_element(attrs); attr != NULL;
972 attr = __xml_next_element(attr)) {
978 int start_delay = unpack_start_delay(value, NULL);
982 long long start_delay = 0;
984 if (unpack_interval_origin(value, xml_obj, interval_ms, now,
991 int timeout = unpack_timeout(value);
1016 guint interval_ms = 0;
1018 char *value_ms = NULL;
1019 const char *value = NULL;
1020 const char *field = NULL;
1021 char *default_timeout = NULL;
1022 #if ENABLE_VERSIONED_ATTRS
1023 pe_rsc_action_details_t *rsc_details = NULL;
1030 action->meta, NULL, FALSE, data_set);
1034 if (default_timeout) {
1035 default_timeout = strdup(default_timeout);
1040 xmlAttrPtr xIter = NULL;
1044 action->meta, NULL, TRUE, data_set);
1046 #if ENABLE_VERSIONED_ATTRS
1047 rsc_details = pe_rsc_action_details(
action);
1048 pe_unpack_versioned_attributes(data_set->
input, xml_obj,
1050 rsc_details->versioned_parameters,
1051 data_set->
now, NULL);
1052 pe_unpack_versioned_attributes(data_set->
input, xml_obj,
1054 rsc_details->versioned_meta,
1055 data_set->
now, NULL);
1061 for (xIter = xml_obj->properties; xIter; xIter = xIter->next) {
1062 const char *prop_name = (
const char *)xIter->name;
1065 g_hash_table_replace(
action->meta, strdup(prop_name), strdup(prop_value));
1069 g_hash_table_remove(
action->meta,
"id");
1073 value = g_hash_table_lookup(
action->meta, field);
1074 if (value != NULL) {
1084 if (interval_ms > 0) {
1086 g_hash_table_replace(
action->meta, strdup(field), value_ms);
1089 g_hash_table_remove(
action->meta, field);
1094 free(default_timeout);
1100 xmlNode *min_interval_mon = find_min_interval_mon(
action->rsc, FALSE);
1102 if (min_interval_mon) {
1105 crm_trace(
"\t%s defaults to minimum-interval monitor's timeout '%s'",
1107 free(default_timeout);
1108 default_timeout = strdup(value);
1113 if (default_timeout) {
1122 value =
"nothing (not start/promote)";
1126 value =
"fencing (resource)";
1130 value =
"quorum (resource)";
1134 value =
"nothing (resource)";
1139 value = unpack_operation_on_fail(
action);
1141 if (value == NULL) {
1150 value =
"node fencing";
1154 "operation '%s' to 'stop' because 'fence' is not "
1155 "valid when fencing is disabled",
action->uuid);
1158 value =
"stop resource";
1163 value =
"node standby";
1172 value =
"force migration";
1177 value =
"stop resource";
1181 value =
"restart (and possibly migrate)";
1183 }
else if (
safe_str_eq(value,
"restart-container")) {
1186 value =
"restart container (and possibly migrate)";
1194 value =
"demote instance";
1197 pe_err(
"Resource %s: Unknown failure type (%s)",
action->rsc->id, value);
1202 if (value == NULL && container) {
1204 value =
"restart container (and possibly migrate) (default)";
1222 value =
"stop unmanaged remote node (enforcing default)";
1226 value =
"fence remote node (default)";
1228 value =
"recover remote node connection (default)";
1231 if (
action->rsc->remote_reconnect_ms) {
1240 value =
"resource fence (default)";
1244 value =
"resource block (default)";
1247 }
else if (value == NULL) {
1249 value =
"restart (and possibly migrate) (default)";
1255 if (xml_obj != NULL) {
1256 value = g_hash_table_lookup(
action->meta,
"role_after_failure");
1259 "Support for role_after_failure is deprecated and will be removed in a future release");
1278 unpack_start_delay(value,
action->meta);
1280 long long start_delay = 0;
1283 if (unpack_interval_origin(value, xml_obj, interval_ms, data_set->
now,
1291 timeout = unpack_timeout(value);
1294 #if ENABLE_VERSIONED_ATTRS
1295 unpack_versioned_meta(rsc_details->versioned_meta, xml_obj, interval_ms,
1301 find_rsc_op_entry_helper(
pe_resource_t * rsc,
const char *key, gboolean include_disabled)
1303 guint interval_ms = 0;
1304 gboolean do_retry = TRUE;
1305 char *local_key = NULL;
1306 const char *
name = NULL;
1307 const char *value = NULL;
1308 const char *interval_spec = NULL;
1309 char *match_key = NULL;
1311 xmlNode *operation = NULL;
1314 for (operation = __xml_first_child_element(rsc->
ops_xml); operation != NULL;
1315 operation = __xml_next_element(operation)) {
1316 if (
crm_str_eq((
const char *)operation->name,
"op", TRUE)) {
1320 if (!include_disabled && value &&
crm_is_true(value) == FALSE) {
1347 if (do_retry == FALSE) {
1357 }
else if (strstr(key,
"_notify_")) {
1369 return find_rsc_op_entry_helper(rsc, key, FALSE);
1376 crm_trace(
"%s%s: <NULL>", pre_text == NULL ?
"" : pre_text, pre_text == NULL ?
"" :
": ");
1381 crm_trace(
"%s%s%sNode %s: (weight=%d, fixed=%s)",
1382 pre_text == NULL ?
"" : pre_text,
1383 pre_text == NULL ?
"" :
": ",
1390 char *pe_mutable = strdup(
"\t\t");
1399 for (; gIter != NULL; gIter = gIter->next) {
1415 user_data == NULL ?
"" : (
char *)user_data,
1416 user_data == NULL ?
"" :
": ", (
char *)key, (
char *)value);
1425 g_list_free_full(
action->actions_before, free);
1426 g_list_free_full(
action->actions_after, free);
1428 g_hash_table_destroy(
action->extra);
1431 g_hash_table_destroy(
action->meta);
1433 #if ENABLE_VERSIONED_ATTRS
1435 pe_free_rsc_action_details(
action);
1438 free(
action->cancel_task);
1449 const char *value = NULL;
1455 for (; gIter != NULL; gIter = gIter->next) {
1459 if (value == NULL) {
1465 }
else if (not_on_node == NULL) {
1467 result = g_list_prepend(result,
action);
1469 }
else if (
action->node == NULL) {
1473 result = g_list_prepend(result,
action);
1494 crm_trace(
"Folding %s back into its atomic counterpart for %s",
name, rsc->
id);
1511 for (gIter = input; gIter != NULL; gIter = gIter->next) {
1520 }
else if (on_node == NULL) {
1523 }
else if (
action->node == NULL) {
1542 for (; gIter != NULL; gIter = gIter->next) {
1549 }
else if (on_node == NULL) {
1550 crm_trace(
"Action %s matches (ignoring node)", key);
1551 result = g_list_prepend(result,
action);
1553 }
else if (
action->node == NULL) {
1554 crm_trace(
"Action %s matches (unallocated, assigning to %s)",
1558 result = g_list_prepend(result,
action);
1562 result = g_list_prepend(result,
action);
1565 crm_trace(
"Action %s on node %s does not match requested node %s",
1566 key,
action->node->details->uname,
1577 GList *result = NULL;
1581 if (on_node == NULL) {
1582 crm_trace(
"Not searching for action %s because node not specified",
1587 for (GList *gIter = input; gIter != NULL; gIter = gIter->next) {
1590 if (
action->node == NULL) {
1591 crm_trace(
"Skipping comparison of %s vs action %s without node",
1598 action->node->details->id)) {
1599 crm_trace(
"Action %s desired node ID %s doesn't match %s",
1604 result = g_list_prepend(result,
action);
1625 const char *task,
bool require_node)
1627 GList *result = NULL;
1655 for (; gIter != NULL; gIter = gIter->next) {
1658 resource_node_score(child_rsc, node, score, tag);
1664 if (match == NULL) {
1676 resource_node_score(rsc, node, score, tag);
1678 }
else if (data_set != NULL) {
1681 for (; gIter != NULL; gIter = gIter->next) {
1684 resource_node_score(rsc, node_iter, score, tag);
1688 GHashTableIter iter;
1692 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node_iter)) {
1693 resource_node_score(rsc, node_iter, score, tag);
1697 if (node == NULL && score == -
INFINITY) {
1706 #define sort_return(an_int, why) do { \
1709 crm_trace("%s (%d) %c %s (%d) : %s", \
1710 a_xml_id, a_call_id, an_int>0?'>':an_int<0?'<':'=', \
1711 b_xml_id, b_call_id, why); \
1721 char *a_uuid = NULL;
1722 char *b_uuid = NULL;
1724 const xmlNode *xml_a = a;
1725 const xmlNode *xml_b = b;
1736 pe_err(
"Duplicate lrm_rsc_op entries named %s", a_xml_id);
1743 if (a_call_id == -1 && b_call_id == -1) {
1749 }
else if (a_call_id >= 0 && a_call_id < b_call_id) {
1752 }
else if (b_call_id >= 0 && a_call_id > b_call_id) {
1755 }
else if (b_call_id >= 0 && a_call_id == b_call_id) {
1767 (
long long) last_a, (
long long) last_b);
1768 if (last_a >= 0 && last_a < last_b) {
1771 }
else if (last_b >= 0 && last_a > last_b) {
1812 if (b_call_id == -1) {
1815 }
else if (a_call_id == -1) {
1819 }
else if ((a_id >= 0 && a_id < b_id) || b_id == -1) {
1822 }
else if ((b_id >= 0 && a_id > b_id) || a_id == -1) {
1836 if (data_set->
now == NULL) {
1855 if (value == NULL ||
safe_str_eq(
"started", value)
1863 "because '%s' is not valid", rsc->
id, value);
1875 "because '%s' only makes sense for promotable "
1876 "clones", rsc->
id, value);
1896 if (lh_action == NULL || rh_action == NULL) {
1907 for (; gIter != NULL; gIter = gIter->next) {
1910 if (after->
action == rh_action && (after->
type & order)) {
1916 wrapper->
action = rh_action;
1917 wrapper->
type = order;
1920 list = g_list_prepend(list, wrapper);
1929 wrapper->
action = lh_action;
1930 wrapper->
type = order;
1932 list = g_list_prepend(list, wrapper);
1959 if (ticket->
state) {
1960 g_hash_table_destroy(ticket->
state);
1971 if (ticket_id == NULL || strlen(ticket_id) == 0) {
1975 if (data_set->
tickets == NULL) {
1981 ticket = g_hash_table_lookup(data_set->
tickets, ticket_id);
1982 if (ticket == NULL) {
1985 if (ticket == NULL) {
1986 crm_err(
"Cannot allocate ticket '%s'", ticket_id);
1990 crm_trace(
"Creaing ticket entry for %s", ticket_id);
1992 ticket->
id = strdup(ticket_id);
1996 ticket->
state = crm_str_table_new();
1998 g_hash_table_insert(data_set->
tickets, strdup(ticket->
id), ticket);
2005 filter_parameters(xmlNode * param_set,
const char *param_string,
bool need_present)
2007 if (param_set && param_string) {
2008 xmlAttrPtr xIter = param_set->properties;
2011 const char *prop_name = (
const char *)xIter->name;
2013 char *match = strstr(param_string,
name);
2018 xIter = xIter->next;
2020 if (need_present && match == NULL) {
2021 crm_trace(
"%s not found in %s", prop_name, param_string);
2024 }
else if (need_present == FALSE && match) {
2025 crm_trace(
"%s found in %s", prop_name, param_string);
2032 #if ENABLE_VERSIONED_ATTRS
2034 append_versioned_params(xmlNode *versioned_params,
const char *ra_version, xmlNode *params)
2036 GHashTable *hash = pe_unpack_versioned_parameters(versioned_params, ra_version);
2039 GHashTableIter iter;
2041 g_hash_table_iter_init(&iter, hash);
2042 while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &value)) {
2045 g_hash_table_destroy(hash);
2064 rsc_action_digest(
pe_resource_t *rsc,
const char *task,
const char *key,
2065 pe_node_t *node, xmlNode *xml_op,
bool calc_secure,
2072 GHashTable *local_rsc_params = crm_str_table_new();
2074 #if ENABLE_VERSIONED_ATTRS
2076 const char *ra_version = NULL;
2079 const char *op_version;
2080 const char *restart_list = NULL;
2081 const char *secure_list =
" passwd password ";
2087 #if ENABLE_VERSIONED_ATTRS
2088 pe_get_versioned_attributes(local_versioned_params, rsc, node, data_set);
2096 crm_trace(
"Set address for bundle connection %s (on %s)",
2100 g_hash_table_foreach(local_rsc_params,
hash2field,
data->params_all);
2110 #if ENABLE_VERSIONED_ATTRS
2118 #if ENABLE_VERSIONED_ATTRS
2119 append_versioned_params(local_versioned_params, ra_version,
data->params_all);
2120 append_versioned_params(rsc->versioned_parameters, ra_version,
data->params_all);
2123 pe_rsc_action_details_t *details = pe_rsc_action_details(
action);
2124 append_versioned_params(details->versioned_parameters, ra_version,
data->params_all);
2130 g_hash_table_destroy(local_rsc_params);
2138 filter_parameters(
data->params_secure, secure_list, FALSE);
2146 filter_parameters(
data->params_restart, restart_list, TRUE);
2164 guint interval_ms = 0;
2166 const char *op_version;
2168 const char *digest_all;
2169 const char *digest_restart;
2179 data = rsc_action_digest(rsc, task, key, node, xml_op,
2184 if (digest_restart &&
data->digest_restart_calc && strcmp(
data->digest_restart_calc, digest_restart) != 0) {
2185 pe_rsc_info(rsc,
"Parameters to %s on %s changed: was %s vs. now %s (restart:%s) %s",
2187 crm_str(digest_restart),
data->digest_restart_calc,
2191 }
else if (digest_all == NULL) {
2195 }
else if (strcmp(digest_all,
data->digest_all_calc) != 0) {
2196 pe_rsc_info(rsc,
"Parameters to %s on %s changed: was %s vs. now %s (%s:%s) %s",
2199 (interval_ms > 0)?
"reschedule" :
"reload",
2225 static inline char *
2226 create_unfencing_summary(
const char *rsc_id,
const char *agent_type,
2227 const char *param_digest)
2249 unfencing_digest_matches(
const char *rsc_id,
const char *agent,
2250 const char *digest_calc,
const char *node_summary)
2252 bool matches = FALSE;
2254 if (rsc_id && agent && digest_calc && node_summary) {
2255 char *search_secure = create_unfencing_summary(rsc_id, agent,
2261 matches = (strstr(node_summary, search_secure) != NULL);
2262 crm_trace(
"Calculated unfencing digest '%s' %sfound in '%s'",
2263 search_secure, matches?
"" :
"not ", node_summary);
2264 free(search_secure);
2273 #define STONITH_DIGEST_TASK "stonith-on"
2287 fencing_action_digest_cmp(
pe_resource_t *rsc,
const char *agent,
2290 const char *node_summary = NULL;
2295 node, NULL, TRUE, data_set);
2301 if (node_summary == NULL) {
2307 if (unfencing_digest_matches(rsc->
id, agent,
data->digest_all_calc,
2315 if (unfencing_digest_matches(rsc->
id, agent,
data->digest_secure_calc,
2319 printf(
"Only 'private' parameters to %s for unfencing %s changed\n",
2328 &&
data->digest_secure_calc) {
2329 char *digest = create_unfencing_summary(rsc->
id, agent,
2330 data->digest_secure_calc);
2332 printf(
"Parameters to %s for unfencing %s changed, try '%s'\n",
2342 return ID(rsc->
xml);
2353 for (; gIter != NULL; gIter = gIter->next) {
2366 for (; gIter != NULL; gIter = gIter->next) {
2376 for (
GListPtr gIter = candidates; gIter != NULL; gIter = gIter->next) {
2382 matches = find_unfencing_devices(candidate->
children, matches);
2386 }
else if (
crm_str_eq(provides,
"unfencing", FALSE) ||
crm_str_eq(requires,
"unfencing", FALSE)) {
2387 matches = g_list_prepend(matches, candidate);
2396 int member_count = 0;
2397 int online_count = 0;
2398 int top_priority = 0;
2399 int lowest_priority = 0;
2418 for (gIter = data_set->
nodes; gIter != NULL; gIter = gIter->next) {
2431 if (member_count == 1
2436 if (member_count == 1
2443 if (online_count > member_count / 2) {
2449 if (lowest_priority == top_priority) {
2464 char *op_key = NULL;
2474 stonith_op = g_hash_table_lookup(data_set->
singletons, op_key);
2477 if(stonith_op == NULL) {
2492 long digests_all_offset = 0;
2493 long digests_secure_offset = 0;
2495 char *digests_all = calloc(max,
sizeof(
char));
2496 char *digests_secure = calloc(max,
sizeof(
char));
2499 for (
GListPtr gIter = matches; gIter != NULL; gIter = gIter->next) {
2501 const char *agent = g_hash_table_lookup(match->
meta,
2505 data = fencing_action_digest_cmp(match, agent, node, data_set);
2510 fprintf(stdout,
" notice: Unfencing %s (remote): because the definition of %s changed\n", node->
details->
uname, match->
id);
2514 digests_all_offset += snprintf(
2515 digests_all+digests_all_offset, max-digests_all_offset,
2516 "%s:%s:%s,", match->
id, agent,
data->digest_all_calc);
2518 digests_secure_offset += snprintf(
2519 digests_secure+digests_secure_offset, max-digests_secure_offset,
2520 "%s:%s:%s,", match->
id, agent,
data->digest_secure_calc);
2522 g_hash_table_insert(stonith_op->
meta,
2525 g_hash_table_insert(stonith_op->
meta,
2543 || g_hash_table_lookup(stonith_op->
meta,
2550 char *delay_s = crm_itoa(node_priority_fencing_delay(node, data_set));
2552 g_hash_table_insert(stonith_op->
meta,
2557 if(optional == FALSE &&
pe_can_fence(data_set, node)) {
2559 }
else if(reason && stonith_op->
reason == NULL) {
2560 stonith_op->
reason = strdup(reason);
2589 GHashTableIter iter;
2592 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node)) {
2593 if(node->details->online && node->details->unclean == FALSE && node->details->shutdown == FALSE) {
2601 add_tag_ref(GHashTable * tags,
const char * tag_name,
const char * obj_ref)
2605 gboolean is_existing = FALSE;
2607 CRM_CHECK(tags && tag_name && obj_ref,
return FALSE);
2609 tag = g_hash_table_lookup(tags, tag_name);
2615 tag->
id = strdup(tag_name);
2617 g_hash_table_insert(tags, strdup(tag_name), tag);
2620 for (gIter = tag->
refs; gIter != NULL; gIter = gIter->next) {
2621 const char *existing_ref = (
const char *) gIter->data;
2623 if (
crm_str_eq(existing_ref, obj_ref, TRUE)){
2629 if (is_existing == FALSE) {
2630 tag->
refs = g_list_append(tag->
refs, strdup(obj_ref));
2631 crm_trace(
"Added: tag=%s ref=%s", tag->
id, obj_ref);
2642 bool update = FALSE;
2643 const char *change = NULL;
2647 change =
"unrunnable";
2650 change =
"required";
2654 change =
"unrunnable";
2656 change =
"dangling";
2658 change =
"required";
2660 crm_err(
"Unknown flag change to %x by %s: 0x%s",
2677 if((change && update) || text) {
2678 char *reason_text = NULL;
2679 if(reason == NULL) {
2682 }
else if(reason->
rsc == NULL) {
2688 if(reason_text &&
action->rsc != reason->
rsc) {
2697 if (
action->reason != NULL && overwrite) {
2701 }
else if (
action->reason == NULL) {
2709 if (reason != NULL) {
2710 action->reason = strdup(reason);
2733 return shutdown && strcmp(shutdown,
"0");
2759 GHashTable *node_hash, GHashTable *hash,
2760 const char *always_first, gboolean overwrite,
2766 always_first, overwrite, data_set->
now, next_change);
2778 const char *target_role = NULL;
void pcmk__filter_op_for_digest(xmlNode *param_set)
char * pcmk__op_key(const char *rsc_id, const char *op_type, guint interval_ms)
Generate an operation key (RESOURCE_ACTION_INTERVAL)
#define pcmk__config_err(fmt...)
gboolean parse_op_key(const char *key, char **rsc_id, char **op_type, guint *interval_ms)
char * crm_strdup_printf(char const *format,...) __attribute__((__format__(__printf__
gboolean crm_str_eq(const char *a, const char *b, gboolean use_case)
gboolean safe_str_neq(const char *a, const char *b)
long long crm_get_msec(const char *input)
Parse a time+units string and return milliseconds equivalent.
gboolean pcmk__str_in_list(GList *lst, const gchar *s)
#define CRM_DEFAULT_OP_TIMEOUT_S
gboolean crm_is_true(const char *s)
#define safe_str_eq(a, b)
gboolean decode_transition_magic(const char *magic, char **uuid, int *transition_id, int *action_id, int *op_status, int *op_rc, int *target_rc)
Parse a transition magic string into its constituent parts.
char * score2char_stack(int score, char *buf, size_t len)
guint crm_parse_interval_spec(const char *input)
Parse milliseconds from a Pacemaker interval specification.
enum action_tasks text2task(const char *task)
@ action_fail_reset_remote
@ action_fail_restart_container
const char * role2text(enum rsc_role_e role)
enum rsc_role_e text2role(const char *role)
void get_rsc_attributes(GHashTable *meta_hash, pe_resource_t *rsc, pe_node_t *node, pe_working_set_t *data_set)
pe_resource_t * uber_parent(pe_resource_t *rsc)
#define CRMD_ACTION_CANCEL
#define CRM_ATTR_DIGESTS_ALL
#define CRMD_ACTION_MIGRATED
#define CRMD_ACTION_STATUS
#define CRMD_ACTION_DEMOTE
#define CRMD_ACTION_MIGRATE
#define CRMD_ACTION_START
#define CRM_OP_LRM_DELETE
#define CRMD_ACTION_PROMOTE
#define CRM_ATTR_DIGESTS_SECURE
#define clear_bit(word, bit)
#define set_bit(word, bit)
crm_time_t * crm_time_new(const char *string)
crm_time_t * crm_time_new_undefined(void)
Allocate memory for an uninitialized time object.
long long int crm_time_get_seconds_since_epoch(crm_time_t *dt)
void crm_time_free(crm_time_t *dt)
bool crm_time_is_defined(const crm_time_t *t)
Check whether a time object has been initialized yet.
long long int crm_time_get_seconds(crm_time_t *dt)
struct crm_time_s crm_time_t
#define crm_info(fmt, args...)
#define do_crm_log(level, fmt, args...)
Log a message.
#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__log_else(level, else_action)
#define XML_ATTR_CRM_VERSION
#define XML_RSC_ATTR_TARGET_ROLE
#define XML_LRM_ATTR_OP_DIGEST
#define XML_NVPAIR_ATTR_VALUE
#define XML_TAG_RSC_VER_ATTRS
#define XML_LRM_ATTR_OP_SECURE
#define XML_CONFIG_ATTR_PRIORITY_FENCING_DELAY
#define XML_RSC_ATTR_REQUIRES
#define XML_TAG_OP_VER_ATTRS
#define XML_LRM_ATTR_TARGET_UUID
#define XML_TAG_ATTR_SETS
#define XML_LRM_ATTR_INTERVAL
#define XML_LRM_ATTR_OP_RESTART
#define XML_ATTR_TRANSITION_MAGIC
#define XML_LRM_ATTR_RESTART_DIGEST
#define XML_TAG_META_SETS
#define XML_LRM_ATTR_TASK
#define XML_CIB_ATTR_SHUTDOWN
#define XML_OP_ATTR_DIGESTS_ALL
#define XML_NVPAIR_ATTR_NAME
#define XML_LRM_ATTR_TARGET
#define XML_TAG_OP_VER_META
#define XML_OP_ATTR_ON_FAIL
#define XML_RSC_OP_LAST_CHANGE
#define XML_OP_ATTR_DIGESTS_SECURE
#define XML_OP_ATTR_ORIGIN
#define XML_LRM_ATTR_CALLID
#define XML_RSC_ATTR_REMOTE_RA_ADDR
#define XML_RSC_ATTR_PROVIDES
#define XML_OP_ATTR_START_DELAY
#define XML_LRM_ATTR_INTERVAL_MS
#define XML_ATTR_RA_VERSION
int crm_element_value_int(const xmlNode *data, const char *name, int *dest)
Retrieve the integer value of an XML attribute.
void hash2metafield(gpointer key, gpointer value, gpointer user_data)
Set XML attribute based on hash table entry, as meta-attribute name.
void hash2field(gpointer key, gpointer value, gpointer user_data)
Set XML attribute based on hash table entry.
const char * crm_xml_add_ll(xmlNode *node, const char *name, long long value)
Create an XML attribute with specified name and long long int value.
int crm_element_value_ms(const xmlNode *data, const char *name, guint *dest)
Retrieve the millisecond value of an XML attribute.
const char * crm_xml_add_int(xmlNode *node, const char *name, int value)
Create an XML attribute with specified name and integer value.
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the 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.
#define pe_rsc_needs_quorum
#define pe_rsc_fence_device
#define pe_flag_have_stonith_resource
#define pe_flag_have_quorum
#define pe_flag_enable_unfencing
@ pe_action_have_node_attrs
@ pe_action_dc
Internal state tracking when creating graph.
@ pe_action_migrate_runnable
#define pe_flag_stonith_enabled
#define pe_rsc_needs_fencing
#define pe_flag_sanitized
#define pe_rsc_promotable
const char * pe_node_attribute_raw(pe_node_t *node, const char *name)
#define pe_warn_once(pe_wo_bit, fmt...)
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.
#define pe_clear_action_bit(action, bit)
#define pe_rsc_debug(rsc, fmt, args...)
#define pe_action_required(action, reason, text)
#define pe_rsc_trace(rsc, fmt, args...)
int pe__add_scores(int score1, int score2)
const char * pe__add_bundle_remote_name(pe_resource_t *rsc, xmlNode *xml, const char *field)
#define pe_rsc_info(rsc, fmt, args...)
#define pe_set_action_bit(action, bit)
void add_hash_param(GHashTable *hash, const char *name, const char *value)
gboolean pe__resource_is_remote_conn(pe_resource_t *rsc, pe_working_set_t *data_set)
gboolean pe__is_guest_node(pe_node_t *node)
gboolean pe__is_guest_or_remote_node(pe_node_t *node)
void node_list_exclude(GHashTable *hash, GListPtr list, gboolean merge_scores)
bool pcmk__rsc_is_filtered(pe_resource_t *rsc, GListPtr only_show)
const char * rsc_printable_id(pe_resource_t *rsc)
void set_bit_recursive(pe_resource_t *rsc, unsigned long long flag)
void clear_bit_recursive(pe_resource_t *rsc, unsigned long long flag)
void destroy_ticket(gpointer data)
GList * pe__resource_actions(const pe_resource_t *rsc, const pe_node_t *node, const char *task, bool require_node)
Find all actions of given type for a resource.
pe_action_t * pe__clear_resource_history(pe_resource_t *rsc, pe_node_t *node, pe_working_set_t *data_set)
void pe_action_set_flag_reason(const char *function, long line, pe_action_t *action, pe_action_t *reason, const char *text, enum pe_action_flags flags, bool overwrite)
#define STONITH_DIGEST_TASK
void trigger_unfencing(pe_resource_t *rsc, pe_node_t *node, const char *reason, pe_action_t *dependency, pe_working_set_t *data_set)
bool pe__resource_is_disabled(pe_resource_t *rsc)
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)
pe_action_t * get_pseudo_op(const char *name, pe_working_set_t *data_set)
GListPtr find_actions(GListPtr input, const char *key, const pe_node_t *on_node)
gboolean get_target_role(pe_resource_t *rsc, enum rsc_role_e *role)
xmlNode * find_rsc_op_entry(pe_resource_t *rsc, const char *key)
gint sort_node_uname(gconstpointer a, gconstpointer b)
gboolean ghash_free_str_str(gpointer key, gpointer value, gpointer user_data)
enum action_tasks get_complex_task(pe_resource_t *rsc, const char *name, gboolean allow_non_atomic)
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 pe_free_action(pe_action_t *action)
gboolean order_actions(pe_action_t *lh_action, pe_action_t *rh_action, enum pe_ordering order)
bool pe__rsc_running_on_any_node_in_list(pe_resource_t *rsc, GListPtr node_list)
void print_node(const char *pre_text, pe_node_t *node, gboolean details)
gint sort_rsc_priority(gconstpointer a, gconstpointer b)
void pe__show_node_weights_as(const char *file, const char *function, int line, bool to_log, pe_resource_t *rsc, const char *comment, GHashTable *nodes)
void print_str_str(gpointer key, gpointer value, gpointer user_data)
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)
GListPtr find_recurring_actions(GListPtr input, pe_node_t *not_on_node)
#define sort_return(an_int, why)
time_t get_effective_time(pe_working_set_t *data_set)
void dump_rsc_utilization(int level, const char *comment, pe_resource_t *rsc, pe_node_t *node)
gint sort_rsc_index(gconstpointer a, gconstpointer b)
pe_ticket_t * ticket_new(const char *ticket_id, pe_working_set_t *data_set)
GHashTable * pe__node_list2table(GList *list)
xmlNode * get_object_root(const char *object_type, xmlNode *the_root)
void pe__update_recheck_time(time_t recheck, pe_working_set_t *data_set)
void dump_node_capacity(int level, const char *comment, pe_node_t *node)
pe_action_t * find_first_action(GListPtr input, const char *uuid, const char *task, pe_node_t *on_node)
void unpack_operation(pe_action_t *action, xmlNode *xml_obj, pe_resource_t *container, pe_working_set_t *data_set)
Unpack operation XML into an action structure.
void pe_action_set_reason(pe_action_t *action, const char *reason, bool overwrite)
int pe_get_configured_timeout(pe_resource_t *rsc, const char *action, 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)
void pe__unpack_dataset_nvpairs(xmlNode *xml_obj, const char *set_name, GHashTable *node_hash, GHashTable *hash, const char *always_first, gboolean overwrite, pe_working_set_t *data_set)
GList * find_actions_exact(GList *input, const char *key, const pe_node_t *on_node)
bool pe_can_fence(pe_working_set_t *data_set, pe_node_t *node)
pe_action_t * custom_action(pe_resource_t *rsc, char *key, const char *task, pe_node_t *on_node, gboolean optional, gboolean save_action, pe_working_set_t *data_set)
void pe_unpack_nvpairs(xmlNode *top, xmlNode *xml_obj, const char *set_name, GHashTable *node_hash, GHashTable *hash, const char *always_first, gboolean overwrite, crm_time_t *now, crm_time_t *next_change)
Extract nvpair blocks contained by an XML element into a hash table.
pe_node_t * pe_find_node_id(GListPtr node_list, const char *id)
enum pe_action_flags flags
struct pe_node_shared_s * details
GHashTable * digest_cache
cache of calculated resource digests
pe_resource_t * remote_rsc
enum pe_obj_types variant
gboolean exclusive_discover
pe_resource_t * container
GHashTable * allowed_nodes
enum rsc_role_e next_role
resource_object_functions_t * fns
const char * stonith_action
enum pe_quorum_policy no_quorum_policy
int priority_fencing_delay
gboolean(* active)(pe_resource_t *, gboolean)
void(* print)(pe_resource_t *, const char *, long, void *)
Wrappers for and extensions to libxml2.
xmlNode * copy_xml(xmlNode *src_node)
xmlNode * crm_next_same_xml(const xmlNode *sibling)
Get next instance of same XML tag.
char * calculate_operation_digest(xmlNode *local_cib, const char *version)
Calculate and return digest of XML operation.
void free_xml(xmlNode *child)
xmlNode * create_xml_node(xmlNode *parent, const char *name)
xmlNode * first_named_child(const xmlNode *parent, const char *name)
void xml_remove_prop(xmlNode *obj, const char *name)