34 extern xmlNode *
get_object_root(
const char *object_type, xmlNode * the_root);
35 void print_str_str(gpointer key, gpointer value, gpointer user_data);
39 static xmlNode *find_rsc_op_entry_helper(
resource_t * rsc,
const char *key,
40 gboolean include_disabled);
42 #if ENABLE_VERSIONED_ATTRS 43 pe_rsc_action_details_t *
46 pe_rsc_action_details_t *details;
51 action->
action_details = calloc(1,
sizeof(pe_rsc_action_details_t));
56 if (details->versioned_parameters == NULL) {
60 if (details->versioned_meta == NULL) {
69 pe_rsc_action_details_t *details;
77 if (details->versioned_parameters) {
78 free_xml(details->versioned_parameters);
80 if (details->versioned_meta) {
106 for (GList *n = rsc->
running_on; n != NULL; n = n->next) {
128 }
else if(node == NULL) {
145 CRM_CHECK(this_node != NULL,
return NULL);
147 new_node = calloc(1,
sizeof(
node_t));
164 GHashTable *result = hash;
165 node_t *other_node = NULL;
171 g_hash_table_iter_init(&iter, hash);
172 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node)) {
175 if (other_node == NULL) {
177 }
else if (merge_scores) {
182 for (; gIter != NULL; gIter = gIter->next) {
185 other_node = pe_hash_table_lookup(result, node->
details->
id);
187 if (other_node == NULL) {
191 g_hash_table_insert(result, (gpointer) new_node->
details->
id, new_node);
202 for (; gIter != NULL; gIter = gIter->next) {
206 g_hash_table_insert(result, (gpointer) n->details->id, n);
218 for (; gIter != NULL; gIter = gIter->next) {
222 if (filter && this_node->
weight < 0) {
230 if (new_node != NULL) {
231 result = g_list_prepend(result, new_node);
256 pe__output_node_weights(
pe_resource_t *rsc,
const char *comment,
262 GList *list = g_list_sort(g_hash_table_get_values(nodes),
sort_node_uname);
264 for (GList *gIter = list; gIter != NULL; gIter = gIter->next) {
269 printf(
"%s: %s allocation score on %s: %s\n",
272 printf(
"%s: %s = %s\n", comment, node->
details->
uname, score);
290 pe__log_node_weights(
const char *file,
const char *
function,
int line,
300 g_hash_table_iter_init(&iter, nodes);
301 while (g_hash_table_iter_next(&iter, NULL, (
void **) &node)) {
304 qb_log_from_external_source(
function, file,
305 "%s: %s allocation score on %s: %s",
308 node->details->uname, score);
310 qb_log_from_external_source(
function, file,
"%s: %s = %s",
312 comment, node->details->uname,
348 pe__log_node_weights(file,
function, line, rsc, comment, nodes);
350 pe__output_node_weights(rsc, comment, nodes);
355 for (GList *gIter = rsc->
children; gIter != NULL; gIter = gIter->next) {
365 append_dump_text(gpointer key, gpointer value, gpointer user_data)
367 char **dump_text = user_data;
369 char *new_text = NULL;
371 len = strlen(*dump_text) + strlen(
" ") + strlen(key) + strlen(
"=") + strlen(value) + 1;
372 new_text = calloc(1, len);
373 sprintf(new_text,
"%s %s=%s", *dump_text, (
char *)key, (
char *)value);
376 *dump_text = new_text;
383 char *dump_text = NULL;
385 len = strlen(comment) + strlen(
": ") + strlen(node->
details->
uname) + strlen(
" capacity:") + 1;
386 dump_text = calloc(1, len);
387 sprintf(dump_text,
"%s: %s capacity:", comment, node->
details->
uname);
392 fprintf(stdout,
"%s\n", dump_text);
404 char *dump_text = NULL;
406 len = strlen(comment) + strlen(
": ") + strlen(rsc->
id) + strlen(
" utilization on ")
408 dump_text = calloc(1, len);
409 sprintf(dump_text,
"%s: %s utilization on %s:", comment, rsc->
id, node->
details->
uname);
411 g_hash_table_foreach(rsc->
utilization, append_dump_text, &dump_text);
414 fprintf(stdout,
"%s\n", dump_text);
428 if (a == NULL && b == NULL) {
455 if (a == NULL && b == NULL) {
478 node_t * on_node, gboolean optional, gboolean save_action,
485 CRM_CHECK(task != NULL, free(key);
return NULL);
487 if (save_action && rsc != NULL) {
489 }
else if(save_action) {
491 action = g_hash_table_lookup(data_set->
singletons, key);
502 if (possible_matches != NULL) {
503 if (g_list_length(possible_matches) > 1) {
504 pe_warn(
"Action %s for %s on %s exists %d times",
505 task, rsc ? rsc->
id :
"<NULL>",
506 on_node ? on_node->
details->
uname :
"<NULL>", g_list_length(possible_matches));
509 action = g_list_nth_data(possible_matches, 0);
510 pe_rsc_trace(rsc,
"Found existing action (%d) %s for %s on %s",
511 action->
id, task, rsc ? rsc->
id :
"<NULL>",
513 g_list_free(possible_matches);
516 if (action == NULL) {
518 pe_rsc_trace(rsc,
"Creating%s action %d: %s for %s on %s %d",
519 optional ?
"" :
" mandatory", data_set->
action_id, key,
520 rsc ? rsc->
id :
"<NULL>", on_node ? on_node->
details->
uname :
"<NULL>", optional);
523 action = calloc(1,
sizeof(
action_t));
531 action->
task = strdup(task);
535 action->
uuid = strdup(key);
557 action->
extra = crm_str_table_new();
558 action->
meta = crm_str_table_new();
568 action->
op_entry = find_rsc_op_entry_helper(rsc, key, TRUE);
582 if (optional == FALSE) {
592 warn_level = LOG_WARNING;
600 action->
extra, NULL, FALSE, data_set->
now);
606 }
else if (action->
node == NULL) {
620 do_crm_log(warn_level,
"Action %s on %s is unrunnable (offline)",
623 && save_action && a_task ==
stop_rsc 630 do_crm_log(warn_level,
"Action %s on %s is unrunnable (pending)",
644 crm_debug(
"%s\t%s (cancelled : host cannot be fenced)",
656 action->runnable = TRUE;
700 unpack_operation_on_fail(
action_t * action)
710 xmlNode *operation = NULL;
711 const char *name = NULL;
712 const char *role = NULL;
713 const char *on_fail = NULL;
714 const char *interval = NULL;
715 const char *enabled = NULL;
719 for (operation = __xml_first_child_element(action->
rsc->
ops_xml);
720 operation && !value; operation = __xml_next_element(operation)) {
722 if (!
crm_str_eq((
const char *)operation->name,
"op", TRUE)) {
748 find_min_interval_mon(
resource_t * rsc, gboolean include_disabled)
751 int min_interval = -1;
752 const char *name = NULL;
753 const char *value = NULL;
754 const char *interval = NULL;
756 xmlNode *operation = NULL;
758 for (operation = __xml_first_child_element(rsc->
ops_xml); operation != NULL;
759 operation = __xml_next_element(operation)) {
761 if (
crm_str_eq((
const char *)operation->name,
"op", TRUE)) {
765 if (!include_disabled && value &&
crm_is_true(value) == FALSE) {
778 if (min_interval < 0 || number < min_interval) {
779 min_interval = number;
789 unpack_start_delay(
const char *value, GHashTable *meta)
796 if (start_delay < 0) {
810 unpack_interval_origin(
const char *value, xmlNode *xml_obj,
unsigned long long interval_ms,
813 long long result = 0;
814 guint interval_sec = interval_ms / 1000;
818 if ((value == NULL) || (interval_ms == 0) || (now == NULL)) {
824 if (origin == NULL) {
827 (
ID(xml_obj)?
ID(xml_obj) :
"(unspecified)"), value);
836 result = result % interval_sec;
839 result = ((result <= 0)? 0 : interval_sec) - result;
840 crm_info(
"Calculated a start delay of %llds for operation '%s'",
842 (
ID(xml_obj)?
ID(xml_obj) :
"(unspecified)"));
844 if (start_delay != NULL) {
845 *start_delay = result * 1000;
851 unpack_timeout(
const char *value,
action_t *action, xmlNode *xml_obj,
852 unsigned long long interval, GHashTable *config_hash)
856 if (value == NULL && config_hash) {
857 value =
pe_pref(config_hash,
"default-action-timeout");
860 "Support for 'default-action-timeout' cluster property" 861 " is deprecated and will be removed in a future release" 862 " (use 'timeout' in op_defaults instead)");
882 xmlNode *child = NULL;
883 const char *timeout = NULL;
895 GHashTable *action_meta = crm_str_table_new();
897 NULL, action_meta, NULL, FALSE, data_set->
now);
905 if (timeout == NULL) {
910 if (timeout_ms < 0) {
917 #if ENABLE_VERSIONED_ATTRS 919 unpack_versioned_meta(xmlNode *versioned_meta, xmlNode *xml_obj,
unsigned long long interval,
crm_time_t *now)
921 xmlNode *attrs = NULL;
922 xmlNode *attr = NULL;
924 for (attrs = __xml_first_child_element(versioned_meta); attrs != NULL;
925 attrs = __xml_next_element(attrs)) {
927 for (attr = __xml_first_child_element(attrs); attr != NULL;
928 attr = __xml_next_element(attr)) {
934 int start_delay = unpack_start_delay(value, NULL);
938 long long start_delay = 0;
940 if (unpack_interval_origin(value, xml_obj, interval, now,
947 int timeout = unpack_timeout(value, NULL, NULL, 0, NULL);
972 unsigned long long interval = 0;
974 char *value_ms = NULL;
975 const char *value = NULL;
976 const char *field = NULL;
977 char *default_timeout = NULL;
978 #if ENABLE_VERSIONED_ATTRS 979 pe_rsc_action_details_t *rsc_details = NULL;
986 action->
meta, NULL, FALSE, data_set->
now);
990 if (default_timeout) {
991 default_timeout = strdup(default_timeout);
996 xmlAttrPtr xIter = NULL;
1000 NULL, action->
meta, NULL, TRUE,
1005 NULL, action->
meta, NULL, FALSE, data_set->
now);
1007 #if ENABLE_VERSIONED_ATTRS 1008 rsc_details = pe_rsc_action_details(action);
1009 pe_unpack_versioned_attributes(data_set->
input, xml_obj,
1011 rsc_details->versioned_parameters,
1013 pe_unpack_versioned_attributes(data_set->
input, xml_obj,
1015 rsc_details->versioned_meta,
1022 for (xIter = xml_obj->properties; xIter; xIter = xIter->next) {
1023 const char *prop_name = (
const char *)xIter->name;
1026 g_hash_table_replace(action->
meta, strdup(prop_name), strdup(prop_value));
1030 g_hash_table_remove(action->
meta,
"id");
1034 value = g_hash_table_lookup(action->
meta, field);
1035 if (value != NULL) {
1038 }
else if ((xml_obj == NULL) && !strcmp(action->
task,
RSC_STATUS)) {
1039 int interval_ms = 0;
1046 interval = interval_ms;
1050 g_hash_table_replace(action->
meta, strdup(field), value_ms);
1053 g_hash_table_remove(action->
meta, field);
1057 value = g_hash_table_lookup(action->
meta,
"requires");
1060 " is deprecated and will be removed in a future version" 1061 " (use 'requires' resource meta-attribute instead)");
1066 free(default_timeout);
1072 xmlNode *min_interval_mon = find_min_interval_mon(action->
rsc, FALSE);
1074 if (min_interval_mon) {
1077 crm_trace(
"\t%s defaults to minimum-interval monitor's timeout '%s'",
1078 action->
uuid, value);
1079 free(default_timeout);
1080 default_timeout = strdup(value);
1085 if (default_timeout) {
1094 value =
"nothing (not start/promote)";
1106 crm_notice(
"%s requires unfencing but fencing is disabled", action->
rsc->
id);
1113 crm_notice(
"%s requires fencing but fencing is disabled", action->
rsc->
id);
1119 value =
"fencing (resource)";
1123 value =
"quorum (resource)";
1127 value =
"nothing (resource)";
1132 value = unpack_operation_on_fail(action);
1134 if (value == NULL) {
1143 value =
"node fencing";
1146 crm_config_err(
"Specifying on_fail=fence and" " stonith-enabled=false makes no sense");
1149 value =
"stop resource";
1154 value =
"node standby";
1163 value =
"force migration";
1168 value =
"stop resource";
1172 value =
"restart (and possibly migrate)";
1174 }
else if (
safe_str_eq(value,
"restart-container")) {
1177 value =
"restart container (and possibly migrate)";
1184 pe_err(
"Resource %s: Unknown failure type (%s)", action->
rsc->
id, value);
1189 if (value == NULL && container) {
1191 value =
"restart container (and possibly migrate) (default)";
1210 value =
"stop unmanaged baremetal remote node (enforcing default)";
1214 value =
"fence baremetal remote node (default)";
1216 value =
"recover baremetal remote node connection (default)";
1228 value =
"resource fence (default)";
1232 value =
"resource block (default)";
1235 }
else if (value == NULL) {
1237 value =
"restart (and possibly migrate) (default)";
1243 if (xml_obj != NULL) {
1244 value = g_hash_table_lookup(action->
meta,
"role_after_failure");
1262 unpack_start_delay(value, action->
meta);
1264 long long start_delay = 0;
1267 if (unpack_interval_origin(value, xml_obj, interval, data_set->
now,
1275 timeout = unpack_timeout(value, action, xml_obj, interval, data_set->
config_hash);
1278 #if ENABLE_VERSIONED_ATTRS 1279 unpack_versioned_meta(rsc_details->versioned_meta, xml_obj, interval,
1285 find_rsc_op_entry_helper(
resource_t * rsc,
const char *key, gboolean include_disabled)
1287 unsigned long long number = 0;
1288 gboolean do_retry = TRUE;
1289 char *local_key = NULL;
1290 const char *name = NULL;
1291 const char *value = NULL;
1292 const char *interval = NULL;
1293 char *match_key = NULL;
1295 xmlNode *operation = NULL;
1298 for (operation = __xml_first_child_element(rsc->
ops_xml); operation != NULL;
1299 operation = __xml_next_element(operation)) {
1300 if (
crm_str_eq((
const char *)operation->name,
"op", TRUE)) {
1304 if (!include_disabled && value &&
crm_is_true(value) == FALSE) {
1331 if (do_retry == FALSE) {
1341 }
else if (strstr(key,
"_notify_")) {
1353 return find_rsc_op_entry_helper(rsc, key, FALSE);
1360 crm_trace(
"%s%s: <NULL>", pre_text == NULL ?
"" : pre_text, pre_text == NULL ?
"" :
": ");
1365 crm_trace(
"%s%s%sNode %s: (weight=%d, fixed=%s)",
1366 pre_text == NULL ?
"" : pre_text,
1367 pre_text == NULL ?
"" :
": ",
1374 char *pe_mutable = strdup(
"\t\t");
1383 for (; gIter != NULL; gIter = gIter->next) {
1399 user_data == NULL ?
"" : (
char *)user_data,
1400 user_data == NULL ?
"" :
": ", (
char *)key, (
char *)value);
1406 if (action == NULL) {
1411 if (action->
extra) {
1412 g_hash_table_destroy(action->
extra);
1415 g_hash_table_destroy(action->
meta);
1417 #if ENABLE_VERSIONED_ATTRS 1419 pe_free_rsc_action_details(action);
1433 const char *value = NULL;
1439 for (; gIter != NULL; gIter = gIter->next) {
1443 if (value == NULL) {
1449 }
else if (not_on_node == NULL) {
1451 result = g_list_prepend(result, action);
1453 }
else if (action->
node == NULL) {
1457 result = g_list_prepend(result, action);
1478 crm_trace(
"Folding %s back into its atomic counterpart for %s", name, rsc->
id);
1495 for (gIter = input; gIter != NULL; gIter = gIter->next) {
1504 }
else if (on_node == NULL) {
1507 }
else if (action->
node == NULL) {
1526 for (; gIter != NULL; gIter = gIter->next) {
1530 crm_trace(
"%s does not match action %s", key, action->
uuid);
1533 }
else if (on_node == NULL) {
1534 crm_trace(
"Action %s matches (ignoring node)", key);
1535 result = g_list_prepend(result, action);
1537 }
else if (action->
node == NULL) {
1538 crm_trace(
"Action %s matches (unallocated, assigning to %s)",
1542 result = g_list_prepend(result, action);
1546 result = g_list_prepend(result, action);
1549 crm_trace(
"Action %s on node %s does not match requested node %s",
1561 GList *result = NULL;
1565 if (on_node == NULL) {
1566 crm_trace(
"Not searching for action %s because node not specified",
1571 for (GList *gIter = input; gIter != NULL; gIter = gIter->next) {
1574 if (action->
node == NULL) {
1575 crm_trace(
"Skipping comparison of %s vs action %s without node",
1579 crm_trace(
"Desired action %s doesn't match %s", key, action->
uuid);
1583 crm_trace(
"Action %s desired node ID %s doesn't match %s",
1588 result = g_list_prepend(result, action);
1596 resource_node_score(
resource_t * rsc,
node_t * node,
int score,
const char *tag)
1611 for (; gIter != NULL; gIter = gIter->next) {
1614 resource_node_score(child_rsc, node, score, tag);
1620 if (match == NULL) {
1632 resource_node_score(rsc, node, score, tag);
1634 }
else if (data_set != NULL) {
1637 for (; gIter != NULL; gIter = gIter->next) {
1640 resource_node_score(rsc, node_iter, score, tag);
1645 node_t *node_iter = NULL;
1648 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node_iter)) {
1649 resource_node_score(rsc, node_iter, score, tag);
1653 if (node == NULL && score == -
INFINITY) {
1662 #define sort_return(an_int, why) do { \ 1665 crm_trace("%s (%d) %c %s (%d) : %s", \ 1666 a_xml_id, a_call_id, an_int>0?'>':an_int<0?'<':'=', \ 1667 b_xml_id, b_call_id, why); \ 1677 char *a_uuid = NULL;
1678 char *b_uuid = NULL;
1680 const xmlNode *xml_a = a;
1681 const xmlNode *xml_b = b;
1692 pe_err(
"Duplicate lrm_rsc_op entries named %s", a_xml_id);
1699 if (a_call_id == -1 && b_call_id == -1) {
1705 }
else if (a_call_id >= 0 && a_call_id < b_call_id) {
1708 }
else if (b_call_id >= 0 && a_call_id > b_call_id) {
1711 }
else if (b_call_id >= 0 && a_call_id == b_call_id) {
1722 crm_trace(
"rc-change: %d vs %d", last_a, last_b);
1723 if (last_a >= 0 && last_a < last_b) {
1726 }
else if (last_b >= 0 && last_a > last_b) {
1766 if (b_call_id == -1) {
1769 }
else if (a_call_id == -1) {
1773 }
else if ((a_id >= 0 && a_id < b_id) || b_id == -1) {
1776 }
else if ((b_id >= 0 && a_id > b_id) || a_id == -1) {
1790 if (data_set->
now == NULL) {
1809 if (value == NULL ||
safe_str_eq(
"started", value)
1827 crm_config_err(
"%s is not part of a master/slave resource, a %s of '%s' makes no sense",
1848 if (lh_action == NULL || rh_action == NULL) {
1859 for (; gIter != NULL; gIter = gIter->next) {
1862 if (after->
action == rh_action && (after->
type & order)) {
1868 wrapper->
action = rh_action;
1869 wrapper->
type = order;
1872 list = g_list_prepend(list, wrapper);
1881 wrapper->
action = lh_action;
1882 wrapper->
type = order;
1884 list = g_list_prepend(list, wrapper);
1895 op = g_hash_table_lookup(data_set->
singletons, name);
1898 op =
custom_action(NULL, strdup(name), name, NULL, TRUE, TRUE, data_set);
1911 if (ticket->
state) {
1912 g_hash_table_destroy(ticket->
state);
1923 if (ticket_id == NULL || strlen(ticket_id) == 0) {
1927 if (data_set->
tickets == NULL) {
1932 ticket = g_hash_table_lookup(data_set->
tickets, ticket_id);
1933 if (ticket == NULL) {
1935 ticket = calloc(1,
sizeof(
ticket_t));
1936 if (ticket == NULL) {
1937 crm_err(
"Cannot allocate ticket '%s'", ticket_id);
1941 crm_trace(
"Creaing ticket entry for %s", ticket_id);
1943 ticket->
id = strdup(ticket_id);
1947 ticket->
state = crm_str_table_new();
1949 g_hash_table_insert(data_set->
tickets, strdup(ticket->
id), ticket);
1956 filter_parameters(xmlNode * param_set,
const char *param_string,
bool need_present)
1958 if (param_set && param_string) {
1959 xmlAttrPtr xIter = param_set->properties;
1962 const char *prop_name = (
const char *)xIter->name;
1964 char *match = strstr(param_string, name);
1969 xIter = xIter->next;
1971 if (need_present && match == NULL) {
1972 crm_trace(
"%s not found in %s", prop_name, param_string);
1975 }
else if (need_present == FALSE && match) {
1976 crm_trace(
"%s found in %s", prop_name, param_string);
1983 #if ENABLE_VERSIONED_ATTRS 1985 append_versioned_params(xmlNode *versioned_params,
const char *ra_version, xmlNode *params)
1987 GHashTable *hash = pe_unpack_versioned_parameters(versioned_params, ra_version);
1992 g_hash_table_iter_init(&iter, hash);
1993 while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &value)) {
1996 g_hash_table_destroy(hash);
2015 rsc_action_digest(
pe_resource_t *rsc,
const char *task,
const char *key,
2016 pe_node_t *node, xmlNode *xml_op,
bool calc_secure,
2023 GHashTable *local_rsc_params = crm_str_table_new();
2025 #if ENABLE_VERSIONED_ATTRS 2027 const char *ra_version = NULL;
2030 const char *op_version;
2031 const char *restart_list = NULL;
2032 const char *secure_list =
" passwd password ";
2038 #if ENABLE_VERSIONED_ATTRS 2039 pe_get_versioned_attributes(local_versioned_params, rsc, node, data_set);
2046 crm_trace(
"Set address for bundle connection %s (on %s)",
2060 #if ENABLE_VERSIONED_ATTRS 2068 #if ENABLE_VERSIONED_ATTRS 2069 append_versioned_params(local_versioned_params, ra_version, data->
params_all);
2070 append_versioned_params(rsc->versioned_parameters, ra_version, data->
params_all);
2073 pe_rsc_action_details_t *details = pe_rsc_action_details(action);
2074 append_versioned_params(details->versioned_parameters, ra_version, data->
params_all);
2080 g_hash_table_destroy(local_rsc_params);
2116 const char *op_version;
2120 const char *digest_all;
2121 const char *digest_restart;
2131 data = rsc_action_digest(rsc, task, key, node, xml_op,
2137 pe_rsc_info(rsc,
"Parameters to %s on %s changed: was %s vs. now %s (restart:%s) %s",
2143 }
else if (digest_all == NULL) {
2148 pe_rsc_info(rsc,
"Parameters to %s on %s changed: was %s vs. now %s (%s:%s) %s",
2151 (interval > 0)?
"reschedule" :
"reload",
2177 static inline char *
2178 create_unfencing_summary(
const char *rsc_id,
const char *agent_type,
2179 const char *param_digest)
2201 unfencing_digest_matches(
const char *rsc_id,
const char *agent,
2202 const char *digest_calc,
const char *node_summary)
2204 bool matches = FALSE;
2206 if (rsc_id && agent && digest_calc && node_summary) {
2207 char *search_secure = create_unfencing_summary(rsc_id, agent,
2213 matches = (strstr(node_summary, search_secure) != NULL);
2214 crm_trace(
"Calculated unfencing digest '%s' %sfound in '%s'",
2215 search_secure, matches?
"" :
"not ", node_summary);
2216 free(search_secure);
2225 #define STONITH_DIGEST_TASK "stonith-on" 2239 fencing_action_digest_cmp(
pe_resource_t *rsc,
const char *agent,
2242 const char *node_summary = NULL;
2247 node, NULL, TRUE, data_set);
2253 if (node_summary == NULL) {
2271 printf(
"Only 'private' parameters to %s for unfencing %s changed\n",
2281 char *digest = create_unfencing_summary(rsc->
id, agent,
2284 printf(
"Parameters to %s for unfencing %s changed, try '%s'\n",
2294 return ID(rsc->
xml);
2305 for (; gIter != NULL; gIter = gIter->next) {
2318 for (; gIter != NULL; gIter = gIter->next) {
2328 for (
GListPtr gIter = candidates; gIter != NULL; gIter = gIter->next) {
2334 matches = find_unfencing_devices(candidate->
children, matches);
2338 }
else if (
crm_str_eq(provides,
"unfencing", FALSE) ||
crm_str_eq(requires,
"unfencing", FALSE)) {
2339 matches = g_list_prepend(matches, candidate);
2348 int member_count = 0;
2349 int online_count = 0;
2350 int top_priority = 0;
2351 int lowest_priority = 0;
2370 for (gIter = data_set->
nodes; gIter != NULL; gIter = gIter->next) {
2383 if (member_count == 1
2388 if (member_count == 1
2395 if (online_count > member_count / 2) {
2401 if (lowest_priority == top_priority) {
2416 char *op_key = NULL;
2426 stonith_op = g_hash_table_lookup(data_set->
singletons, op_key);
2429 if(stonith_op == NULL) {
2443 long digests_all_offset = 0;
2444 long digests_secure_offset = 0;
2446 char *digests_all = calloc(max,
sizeof(
char));
2447 char *digests_secure = calloc(max,
sizeof(
char));
2450 for (
GListPtr gIter = matches; gIter != NULL; gIter = gIter->next) {
2452 const char *agent = g_hash_table_lookup(match->
meta,
2456 data = fencing_action_digest_cmp(match, agent, node, data_set);
2461 fprintf(stdout,
" notice: Unfencing %s (remote): because the definition of %s changed\n", node->
details->
uname, match->
id);
2465 digests_all_offset += snprintf(
2466 digests_all+digests_all_offset, max-digests_all_offset,
2469 digests_secure_offset += snprintf(
2470 digests_secure+digests_secure_offset, max-digests_secure_offset,
2473 g_hash_table_insert(stonith_op->
meta,
2476 g_hash_table_insert(stonith_op->
meta,
2494 || g_hash_table_lookup(stonith_op->
meta,
2501 char *delay_s =
crm_itoa(node_priority_fencing_delay(node, data_set));
2503 g_hash_table_insert(stonith_op->
meta,
2508 if(optional == FALSE &&
pe_can_fence(data_set, node)) {
2510 }
else if(reason && stonith_op->
reason == NULL) {
2511 stonith_op->
reason = strdup(reason);
2543 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node)) {
2544 if(node->details->online && node->details->unclean == FALSE && node->details->shutdown == FALSE) {
2552 add_tag_ref(GHashTable * tags,
const char * tag_name,
const char * obj_ref)
2556 gboolean is_existing = FALSE;
2558 CRM_CHECK(tags && tag_name && obj_ref,
return FALSE);
2560 tag = g_hash_table_lookup(tags, tag_name);
2562 tag = calloc(1,
sizeof(
tag_t));
2566 tag->
id = strdup(tag_name);
2568 g_hash_table_insert(tags, strdup(tag_name), tag);
2571 for (gIter = tag->
refs; gIter != NULL; gIter = gIter->next) {
2572 const char *existing_ref = (
const char *) gIter->data;
2574 if (
crm_str_eq(existing_ref, obj_ref, TRUE)){
2580 if (is_existing == FALSE) {
2581 tag->
refs = g_list_append(tag->
refs, strdup(obj_ref));
2582 crm_trace(
"Added: tag=%s ref=%s", tag->
id, obj_ref);
2593 bool update = FALSE;
2594 const char *change = NULL;
2598 change =
"unrunnable";
2601 change =
"required";
2603 change =
"fatally failed";
2607 change =
"unrunnable";
2609 change =
"dangling";
2611 change =
"required";
2613 crm_err(
"Unknown flag change to %s by %s: 0x%.16x",
2614 flags, action->
uuid, (reason? reason->
uuid : 0));
2618 if(is_set(action->
flags, flags)) {
2619 action->
flags = crm_clear_bit(
function, line, action->
uuid, action->
flags, flags);
2624 if(is_not_set(action->
flags, flags)) {
2625 action->
flags = crm_set_bit(
function, line, action->
uuid, action->
flags, flags);
2630 if((change && update) || text) {
2631 char *reason_text = NULL;
2632 if(reason == NULL) {
2635 }
else if(reason->
rsc == NULL) {
2641 if(reason_text && action->
rsc != reason->
rsc) {
2650 if (action->
reason != NULL && overwrite) {
2654 }
else if (action->
reason == NULL) {
2662 if (reason != NULL) {
2663 action->
reason = strdup(reason);
2686 return shutdown && strcmp(shutdown,
"0");
2692 const char *target_role = NULL;
#define XML_OP_ATTR_ORIGIN
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)
bool pe__shutdown_requested(pe_node_t *node)
#define CRM_CHECK(expr, failure_action)
#define XML_RSC_OP_LAST_CHANGE
enum rsc_start_requirement needs
long long crm_get_msec(const char *input)
action_t * custom_action(resource_t *rsc, char *key, const char *task, node_t *on_node, gboolean optional, gboolean save_action, pe_working_set_t *data_set)
void destroy_ticket(gpointer data)
#define crm_notice(fmt, args...)
#define CRMD_ACTION_MIGRATED
enum action_tasks get_complex_task(resource_t *rsc, const char *name, gboolean allow_non_atomic)
#define pe_rsc_debug(rsc, fmt, args...)
#define pe_flag_have_stonith_resource
gboolean safe_str_neq(const char *a, const char *b)
#define pe_rsc_needs_unfencing
#define XML_OP_ATTR_DIGESTS_ALL
void hash2field(gpointer key, gpointer value, gpointer user_data)
Set XML attribute based on hash table entry.
time_t get_effective_time(pe_working_set_t *data_set)
#define XML_ATTR_TRANSITION_MAGIC
GHashTable * node_hash_from_list(GListPtr list)
const char * crm_element_value_const(const xmlNode *data, const char *name)
#define pe_flag_enable_unfencing
pe_working_set_t * pe_dataset
void node_list_exclude(GHashTable *hash, GListPtr list, gboolean merge_scores)
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 XML_CONFIG_ATTR_PRIORITY_FENCING_DELAY
struct crm_time_s crm_time_t
#define crm_config_err(fmt...)
int priority_fencing_delay
#define pe_action_required(action, reason, text)
#define pe_rsc_needs_quorum
gboolean exclusive_discover
enum action_fail_response on_fail
const char * crm_xml_add_int(xmlNode *node, const char *name, int value)
Create an XML attribute with specified name and integer value.
#define pcmk__log_else(level, else_action)
gint sort_op_by_callid(gconstpointer a, gconstpointer b)
xmlNode * find_rsc_op_entry(resource_t *rsc, const char *key)
enum pe_obj_types variant
#define XML_LRM_ATTR_INTERVAL
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
#define XML_LRM_ATTR_OP_DIGEST
#define CRMD_ACTION_PROMOTE
#define XML_LRM_ATTR_OP_RESTART
int crm_parse_int(const char *text, const char *default_text)
Parse an integer value from a string.
void get_rsc_attributes(GHashTable *meta_hash, resource_t *rsc, node_t *node, pe_working_set_t *data_set)
#define XML_NVPAIR_ATTR_NAME
#define XML_OP_ATTR_DIGESTS_SECURE
#define CRM_ATTR_DIGESTS_ALL
enum action_tasks text2task(const char *task)
int pe_get_configured_timeout(resource_t *rsc, const char *action, pe_working_set_t *data_set)
no_quorum_policy_t no_quorum_policy
GListPtr find_actions_exact(GListPtr input, const char *key, node_t *on_node)
const char * pe_pref(GHashTable *options, const char *name)
void dump_node_capacity(int level, const char *comment, node_t *node)
action_t * find_first_action(GListPtr input, const char *uuid, const char *task, node_t *on_node)
resource_t * uber_parent(resource_t *rsc)
#define clear_bit(word, bit)
void resource_location(resource_t *rsc, node_t *node, int score, const char *tag, pe_working_set_t *data_set)
#define XML_RSC_ATTR_PROVIDES
void filter_action_parameters(xmlNode *param_set, const char *version)
bool pe_can_fence(pe_working_set_t *data_set, pe_node_t *node)
#define XML_OP_ATTR_ON_FAIL
node_t * node_copy(const node_t *this_node)
gboolean get_target_role(resource_t *rsc, enum rsc_role_e *role)
gboolean order_actions(action_t *lh_action, action_t *rh_action, enum pe_ordering order)
void pe_action_set_reason(pe_action_t *action, const char *reason, bool overwrite)
#define XML_LRM_ATTR_OP_SECURE
gboolean is_rsc_baremetal_remote_node(resource_t *rsc, pe_working_set_t *data_set)
bool pe__resource_is_disabled(pe_resource_t *rsc)
#define CRMD_ACTION_START
xmlNode * copy_xml(xmlNode *src_node)
gboolean ghash_free_str_str(gpointer key, gpointer value, gpointer user_data)
#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)
gboolean add_tag_ref(GHashTable *tags, const char *tag_name, const char *obj_ref)
struct node_shared_s * details
char * calculate_operation_digest(xmlNode *local_cib, const char *version)
Calculate and return digest of XML operation.
#define CRMD_ACTION_DEMOTE
#define set_bit(word, bit)
#define XML_RSC_ATTR_REQUIRES
#define crm_debug(fmt, args...)
int crm_element_value_const_int(const xmlNode *data, const char *name, int *dest)
#define XML_CIB_ATTR_SHUTDOWN
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
GListPtr find_recurring_actions(GListPtr input, node_t *not_on_node)
ticket_t * ticket_new(const char *ticket_id, pe_working_set_t *data_set)
resource_object_functions_t * fns
#define sort_return(an_int, why)
void pe_free_action(action_t *action)
GHashTable * allowed_nodes
unsigned long long crm_get_interval(const char *input)
GHashTable * digest_cache
#define crm_trace(fmt, args...)
#define do_crm_log(level, fmt, args...)
Log a message.
enum rsc_digest_cmp_val rc
void set_bit_recursive(resource_t *rsc, unsigned long long flag)
void pe_fence_node(pe_working_set_t *data_set, pe_node_t *node, const char *reason, bool priority_delay)
Schedule a fence action for a node.
char * digest_secure_calc
void dump_rsc_utilization(int level, const char *comment, resource_t *rsc, node_t *node)
gboolean is_container_remote_node(node_t *node)
gint sort_node_uname(gconstpointer a, gconstpointer b)
const char * stonith_action
#define XML_TAG_OP_VER_META
#define XML_TAG_META_SETS
Wrappers for and extensions to libxml2.
const char * container_fix_remote_addr_in(resource_t *rsc, xmlNode *xml, const char *field)
xmlNode * create_xml_node(xmlNode *parent, const char *name)
long long int crm_time_get_seconds_since_epoch(crm_time_t *dt)
#define CRM_ATTR_DIGESTS_SECURE
const char * pe_node_attribute_raw(pe_node_t *node, const char *name)
xmlNode * crm_next_same_xml(xmlNode *sibling)
Get next instance of same XML tag.
#define CRM_DEFAULT_OP_TIMEOUT_S
xmlNode * get_object_root(const char *object_type, xmlNode *the_root)
#define XML_RSC_ATTR_TARGET_ROLE
#define XML_LRM_ATTR_RESTART_DIGEST
void unpack_operation(action_t *action, xmlNode *xml_obj, resource_t *container, pe_working_set_t *data_set)
Unpack operation XML into an action structure.
#define XML_TAG_RSC_VER_ATTRS
void free_xml(xmlNode *child)
enum rsc_role_e text2role(const char *role)
gboolean crm_str_eq(const char *a, const char *b, gboolean use_case)
int remote_reconnect_interval
#define XML_LRM_ATTR_TARGET_UUID
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.
long long int crm_time_get_seconds(crm_time_t *dt)
gboolean(* active)(resource_t *, gboolean)
void(* print)(resource_t *, const char *, long, void *)
gboolean parse_op_key(const char *key, char **rsc_id, char **op_type, int *interval)
gint sort_rsc_index(gconstpointer a, gconstpointer b)
void trigger_unfencing(resource_t *rsc, node_t *node, const char *reason, action_t *dependency, pe_working_set_t *data_set)
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)
const char * rsc_printable_id(resource_t *rsc)
void add_hash_param(GHashTable *hash, const char *name, const char *value)
#define pe_set_action_bit(action, bit)
GListPtr find_actions(GListPtr input, const char *key, const node_t *on_node)
#define crm_err(fmt, args...)
crm_time_t * crm_time_new(const char *string)
#define pe_clear_action_bit(action, bit)
op_digest_cache_t * rsc_action_digest_cmp(resource_t *rsc, xmlNode *xml_op, node_t *node, pe_working_set_t *data_set)
enum rsc_role_e next_role
void xml_remove_prop(xmlNode *obj, const char *name)
void print_str_str(gpointer key, gpointer value, gpointer user_data)
int merge_weights(int w1, int w2)
#define XML_LRM_ATTR_CALLID
#define CRMD_ACTION_MIGRATE
#define XML_NVPAIR_ATTR_VALUE
void hash2metafield(gpointer key, gpointer value, gpointer user_data)
Set XML attribute based on hash table entry, as meta-attribute name.
enum rsc_role_e fail_role
gboolean remote_requires_reset
#define XML_ATTR_CRM_VERSION
gboolean decode_transition_magic(const char *magic, char **uuid, int *transition_id, int *action_id, int *op_status, int *op_rc, int *target_rc)
node_t * pe_find_node_id(GListPtr node_list, const char *id)
enum pe_action_flags flags
#define XML_OP_ATTR_START_DELAY
#define pe_flag_have_quorum
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)
action_t * get_pseudo_op(const char *name, pe_working_set_t *data_set)
xmlNode * first_named_child(xmlNode *parent, const char *name)
gboolean crm_is_true(const char *s)
#define XML_LRM_ATTR_TARGET
#define pe_rsc_trace(rsc, fmt, args...)
char * generate_op_key(const char *rsc_id, const char *op_type, int interval)
Generate an operation key.
char * crm_itoa(int an_int)
#define pe_rsc_needs_fencing
#define safe_str_eq(a, b)
char * crm_strdup_printf(char const *format,...) __attribute__((__format__(__printf__
gint sort_rsc_priority(gconstpointer a, gconstpointer b)
void print_node(const char *pre_text, node_t *node, gboolean details)
#define pe_flag_sanitized
#define pe_rsc_fence_device
#define STONITH_DIGEST_TASK
#define CRMD_ACTION_CANCEL
#define crm_info(fmt, args...)
char * digest_restart_calc
void g_hash_destroy_str(gpointer data)
GListPtr node_list_dup(GListPtr list1, gboolean reset, gboolean filter)
char * score2char_stack(int score, char *buf, size_t len)
#define XML_ATTR_RA_VERSION
#define XML_TAG_OP_VER_ATTRS
#define pe_flag_stonith_enabled
void clear_bit_recursive(resource_t *rsc, unsigned long long flag)
#define pe_warn_once(pe_wo_bit, fmt...)
#define pe_rsc_info(rsc, fmt, args...)
#define CRMD_ACTION_STATUS
void crm_time_free(crm_time_t *dt)