22 extern xmlNode *
get_object_root(
const char *object_type, xmlNode * the_root);
23 void print_str_str(gpointer key, gpointer value, gpointer user_data);
27 static xmlNode *find_rsc_op_entry_helper(
resource_t * rsc,
const char *key,
28 gboolean include_disabled);
30 #if ENABLE_VERSIONED_ATTRS
31 pe_rsc_action_details_t *
34 pe_rsc_action_details_t *details;
39 action->
action_details = calloc(1,
sizeof(pe_rsc_action_details_t));
44 if (details->versioned_parameters == NULL) {
48 if (details->versioned_meta == NULL) {
57 pe_rsc_action_details_t *details;
65 if (details->versioned_parameters) {
66 free_xml(details->versioned_parameters);
68 if (details->versioned_meta) {
103 }
else if(node == NULL) {
120 CRM_CHECK(this_node != NULL,
return NULL);
122 new_node = calloc(1,
sizeof(
node_t));
139 GHashTable *result = hash;
140 node_t *other_node = NULL;
146 g_hash_table_iter_init(&iter, hash);
147 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node)) {
150 if (other_node == NULL) {
152 }
else if (merge_scores) {
157 for (; gIter != NULL; gIter = gIter->next) {
160 other_node = pe_hash_table_lookup(result, node->
details->
id);
162 if (other_node == NULL) {
166 g_hash_table_insert(result, (gpointer) new_node->
details->
id, new_node);
175 GHashTable *result = g_hash_table_new_full(
crm_str_hash, g_str_equal, NULL,
178 for (; gIter != NULL; gIter = gIter->next) {
182 g_hash_table_insert(result, (gpointer) n->details->id, n);
194 for (; gIter != NULL; gIter = gIter->next) {
198 if (filter && this_node->
weight < 0) {
206 if (new_node != NULL) {
207 result = g_list_prepend(result, new_node);
217 const char *name_a = ((
const node_t *) a)->details->uname;
218 const char *name_b = ((
const 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) {
268 resource_t * rsc,
const char *comment, GHashTable * nodes)
270 GHashTable *hash = nodes;
285 int len =
sizeof(score);
288 GListPtr list = g_hash_table_get_values(hash);
293 for (; gIter != NULL; gIter = gIter->next) {
299 printf(
"%s: %s allocation score on %s: %s\n",
302 printf(
"%s: %s = %s\n", comment, node->
details->
uname, score);
310 int len =
sizeof(score);
311 g_hash_table_iter_init(&iter, hash);
312 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node)) {
318 "%s: %s allocation score on %s: %s", comment, rsc->
id,
319 node->details->uname, score);
322 node->details->uname, score);
331 for (; gIter != NULL; gIter = gIter->next) {
340 append_dump_text(gpointer key, gpointer value, gpointer user_data)
342 char **dump_text = user_data;
344 *dump_text, (
char *)key, (
char *)value);
347 *dump_text = new_text;
359 fprintf(stdout,
"%s\n", dump_text);
373 g_hash_table_foreach(rsc->
utilization, append_dump_text, &dump_text);
376 fprintf(stdout,
"%s\n", dump_text);
390 if (a == NULL && b == NULL) {
417 if (a == NULL && b == NULL) {
440 node_t * on_node, gboolean optional, gboolean save_action,
447 CRM_CHECK(task != NULL, free(key);
return NULL);
449 if (save_action && rsc != NULL) {
451 }
else if(save_action) {
453 action = g_hash_table_lookup(data_set->
singletons, key);
464 if (possible_matches != NULL) {
465 if (g_list_length(possible_matches) > 1) {
466 pe_warn(
"Action %s for %s on %s exists %d times",
467 task, rsc ? rsc->
id :
"<NULL>",
468 on_node ? on_node->
details->
uname :
"<NULL>", g_list_length(possible_matches));
471 action = g_list_nth_data(possible_matches, 0);
472 pe_rsc_trace(rsc,
"Found existing action %d (%s) for %s (%s) on %s",
474 (rsc? rsc->
id :
"no resource"), task,
476 g_list_free(possible_matches);
479 if (action == NULL) {
481 pe_rsc_trace(rsc,
"Creating %s action %d: %s for %s (%s) on %s",
482 (optional?
"optional" :
" mandatory"),
484 (rsc? rsc->
id :
"no resource"), task,
488 action = calloc(1,
sizeof(
action_t));
496 action->
task = strdup(task);
500 action->
uuid = strdup(key);
509 action->
extra = crm_str_table_new();
510 action->
meta = crm_str_table_new();
520 action->
op_entry = find_rsc_op_entry_helper(rsc, key, TRUE);
544 warn_level = LOG_WARNING;
552 action->
extra, NULL, FALSE, data_set->
now);
558 }
else if (action->
node == NULL) {
563 && g_hash_table_lookup(action->
meta,
573 do_crm_log(warn_level,
"Action %s on %s is unrunnable (offline)",
576 && save_action && a_task ==
stop_rsc
583 do_crm_log(warn_level,
"Action %s on %s is unrunnable (pending)",
597 action->runnable = TRUE;
641 unpack_operation_on_fail(
action_t * action)
651 xmlNode *operation = NULL;
652 const char *name = NULL;
653 const char *role = NULL;
654 const char *on_fail = NULL;
655 const char *interval_spec = NULL;
656 const char *enabled = NULL;
660 for (operation = __xml_first_child(action->
rsc->
ops_xml);
661 operation && !value; operation = __xml_next_element(operation)) {
663 if (!
crm_str_eq((
const char *)operation->name,
"op", TRUE)) {
689 find_min_interval_mon(
resource_t * rsc, gboolean include_disabled)
691 guint interval_ms = 0;
692 guint min_interval_ms = G_MAXUINT;
693 const char *name = NULL;
694 const char *value = NULL;
695 const char *interval_spec = NULL;
697 xmlNode *operation = NULL;
699 for (operation = __xml_first_child(rsc->
ops_xml); operation != NULL;
700 operation = __xml_next_element(operation)) {
702 if (
crm_str_eq((
const char *)operation->name,
"op", TRUE)) {
706 if (!include_disabled && value &&
crm_is_true(value) == FALSE) {
716 if (interval_ms && (interval_ms < min_interval_ms)) {
717 min_interval_ms = interval_ms;
727 unpack_start_delay(
const char *value, GHashTable *meta)
734 if (start_delay < 0) {
747 unpack_interval_origin(
const char *value, GHashTable *meta, xmlNode *xml_obj,
752 if ((interval_ms > 0) && (value != NULL)) {
758 long long delay_s = 0;
759 int interval_sec = interval_ms / 1000;
761 crm_trace(
"Origin: %s, interval: %d", value, interval_sec);
789 start_delay = delay_s * 1000;
792 crm_info(
"Calculated a start delay of %llds for %s", delay_s,
ID(xml_obj));
797 crm_itoa(start_delay));
802 }
else if (!origin && xml_obj) {
812 unpack_timeout(
const char *value)
825 xmlNode *child = NULL;
826 const char *timeout = NULL;
838 GHashTable *action_meta = crm_str_table_new();
840 NULL, action_meta, NULL, FALSE, data_set->
now);
848 if (timeout_ms < 0) {
854 #if ENABLE_VERSIONED_ATTRS
856 unpack_versioned_meta(xmlNode *versioned_meta, xmlNode *xml_obj,
859 xmlNode *attrs = NULL;
860 xmlNode *attr = NULL;
862 for (attrs = __xml_first_child(versioned_meta); attrs != NULL; attrs = __xml_next_element(attrs)) {
863 for (attr = __xml_first_child(attrs); attr != NULL; attr = __xml_next_element(attr)) {
868 int start_delay = unpack_start_delay(value, NULL);
872 int start_delay = unpack_interval_origin(value, NULL, xml_obj,
878 int timeout = unpack_timeout(value);
903 guint interval_ms = 0;
905 char *value_ms = NULL;
906 const char *value = NULL;
907 const char *field = NULL;
908 char *default_timeout = NULL;
909 #if ENABLE_VERSIONED_ATTRS
910 pe_rsc_action_details_t *rsc_details = NULL;
917 action->
meta, NULL, FALSE, data_set->
now);
921 if (default_timeout) {
922 default_timeout = strdup(default_timeout);
927 xmlAttrPtr xIter = NULL;
931 NULL, action->
meta, NULL, TRUE,
934 #if ENABLE_VERSIONED_ATTRS
935 rsc_details = pe_rsc_action_details(action);
936 pe_unpack_versioned_attributes(data_set->
input, xml_obj,
938 rsc_details->versioned_parameters,
940 pe_unpack_versioned_attributes(data_set->
input, xml_obj,
942 rsc_details->versioned_meta,
949 for (xIter = xml_obj->properties; xIter; xIter = xIter->next) {
950 const char *prop_name = (
const char *)xIter->name;
953 g_hash_table_replace(action->
meta, strdup(prop_name), strdup(prop_value));
957 g_hash_table_remove(action->
meta,
"id");
961 value = g_hash_table_lookup(action->
meta, field);
965 }
else if ((xml_obj == NULL) && !strcmp(action->
task,
RSC_STATUS)) {
972 if (interval_ms > 0) {
974 g_hash_table_replace(action->
meta, strdup(field), value_ms);
977 g_hash_table_remove(action->
meta, field);
982 free(default_timeout);
988 xmlNode *min_interval_mon = find_min_interval_mon(action->
rsc, FALSE);
990 if (min_interval_mon) {
993 crm_trace(
"\t%s defaults to minimum-interval monitor's timeout '%s'",
994 action->
uuid, value);
995 free(default_timeout);
996 default_timeout = strdup(value);
1001 if (default_timeout) {
1010 value =
"nothing (not start/promote)";
1014 value =
"fencing (resource)";
1018 value =
"quorum (resource)";
1022 value =
"nothing (resource)";
1027 value = unpack_operation_on_fail(action);
1029 if (value == NULL) {
1038 value =
"node fencing";
1041 crm_config_err(
"Specifying on_fail=fence and" " stonith-enabled=false makes no sense");
1044 value =
"stop resource";
1049 value =
"node standby";
1058 value =
"force migration";
1063 value =
"stop resource";
1067 value =
"restart (and possibly migrate)";
1069 }
else if (
safe_str_eq(value,
"restart-container")) {
1072 value =
"restart container (and possibly migrate)";
1079 pe_err(
"Resource %s: Unknown failure type (%s)", action->
rsc->
id, value);
1084 if (value == NULL && container) {
1086 value =
"restart container (and possibly migrate) (default)";
1105 value =
"stop unmanaged baremetal remote node (enforcing default)";
1109 value =
"fence baremetal remote node (default)";
1111 value =
"recover baremetal remote node connection (default)";
1123 value =
"resource fence (default)";
1127 value =
"resource block (default)";
1130 }
else if (value == NULL) {
1132 value =
"restart (and possibly migrate) (default)";
1138 if (xml_obj != NULL) {
1139 value = g_hash_table_lookup(action->
meta,
"role_after_failure");
1142 "Support for role_after_failure is deprecated and will be removed in a future release");
1161 unpack_start_delay(value, action->
meta);
1164 unpack_interval_origin(value, action->
meta, xml_obj, interval_ms,
1169 timeout = unpack_timeout(value);
1172 #if ENABLE_VERSIONED_ATTRS
1173 unpack_versioned_meta(rsc_details->versioned_meta, xml_obj, interval_ms,
1179 find_rsc_op_entry_helper(
resource_t * rsc,
const char *key, gboolean include_disabled)
1181 guint interval_ms = 0;
1182 gboolean do_retry = TRUE;
1183 char *local_key = NULL;
1184 const char *name = NULL;
1185 const char *value = NULL;
1186 const char *interval_spec = NULL;
1187 char *match_key = NULL;
1189 xmlNode *operation = NULL;
1192 for (operation = __xml_first_child(rsc->
ops_xml); operation != NULL;
1193 operation = __xml_next_element(operation)) {
1194 if (
crm_str_eq((
const char *)operation->name,
"op", TRUE)) {
1198 if (!include_disabled && value &&
crm_is_true(value) == FALSE) {
1225 if (do_retry == FALSE) {
1235 }
else if (strstr(key,
"_notify_")) {
1247 return find_rsc_op_entry_helper(rsc, key, FALSE);
1254 crm_trace(
"%s%s: <NULL>", pre_text == NULL ?
"" : pre_text, pre_text == NULL ?
"" :
": ");
1259 crm_trace(
"%s%s%sNode %s: (weight=%d, fixed=%s)",
1260 pre_text == NULL ?
"" : pre_text,
1261 pre_text == NULL ?
"" :
": ",
1266 char *pe_mutable = strdup(
"\t\t");
1275 for (; gIter != NULL; gIter = gIter->next) {
1290 user_data == NULL ?
"" : (
char *)user_data,
1291 user_data == NULL ?
"" :
": ", (
char *)key, (
char *)value);
1301 pre_text == NULL ?
"" : pre_text, pre_text == NULL ?
"" :
": ");
1307 rsc->
fns->
print(rsc, pre_text, options, &log_level);
1313 if (action == NULL) {
1318 if (action->
extra) {
1319 g_hash_table_destroy(action->
extra);
1322 g_hash_table_destroy(action->
meta);
1324 #if ENABLE_VERSIONED_ATTRS
1326 pe_free_rsc_action_details(action);
1340 const char *value = NULL;
1346 for (; gIter != NULL; gIter = gIter->next) {
1350 if (value == NULL) {
1356 }
else if (not_on_node == NULL) {
1358 result = g_list_prepend(result, action);
1360 }
else if (action->
node == NULL) {
1364 result = g_list_prepend(result, action);
1385 crm_trace(
"Folding %s back into its atomic counterpart for %s", name, rsc->
id);
1402 for (gIter = input; gIter != NULL; gIter = gIter->next) {
1411 }
else if (on_node == NULL) {
1414 }
else if (action->
node == NULL) {
1433 for (; gIter != NULL; gIter = gIter->next) {
1437 crm_trace(
"%s does not match action %s", key, action->
uuid);
1440 }
else if (on_node == NULL) {
1441 crm_trace(
"Action %s matches (ignoring node)", key);
1442 result = g_list_prepend(result, action);
1444 }
else if (action->
node == NULL) {
1445 crm_trace(
"Action %s matches (unallocated, assigning to %s)",
1449 result = g_list_prepend(result, action);
1453 result = g_list_prepend(result, action);
1456 crm_trace(
"Action %s on node %s does not match requested node %s",
1468 GList *result = NULL;
1472 if (on_node == NULL) {
1473 crm_trace(
"Not searching for action %s because node not specified",
1478 for (GList *gIter = input; gIter != NULL; gIter = gIter->next) {
1481 if (action->
node == NULL) {
1482 crm_trace(
"Skipping comparison of %s vs action %s without node",
1486 crm_trace(
"Desired action %s doesn't match %s", key, action->
uuid);
1490 crm_trace(
"Action %s desired node ID %s doesn't match %s",
1495 result = g_list_prepend(result, action);
1503 resource_node_score(
resource_t * rsc,
node_t * node,
int score,
const char *tag)
1518 for (; gIter != NULL; gIter = gIter->next) {
1521 resource_node_score(child_rsc, node, score, tag);
1527 if (match == NULL) {
1539 resource_node_score(rsc, node, score, tag);
1541 }
else if (data_set != NULL) {
1544 for (; gIter != NULL; gIter = gIter->next) {
1547 resource_node_score(rsc, node_iter, score, tag);
1551 GHashTableIter iter;
1552 node_t *node_iter = NULL;
1555 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node_iter)) {
1556 resource_node_score(rsc, node_iter, score, tag);
1560 if (node == NULL && score == -
INFINITY) {
1569 #define sort_return(an_int, why) do { \
1572 crm_trace("%s (%d) %c %s (%d) : %s", \
1573 a_xml_id, a_call_id, an_int>0?'>':an_int<0?'<':'=', \
1574 b_xml_id, b_call_id, why); \
1584 char *a_uuid = NULL;
1585 char *b_uuid = NULL;
1587 const xmlNode *xml_a = a;
1588 const xmlNode *xml_b = b;
1599 pe_err(
"Duplicate lrm_rsc_op entries named %s", a_xml_id);
1606 if (a_call_id == -1 && b_call_id == -1) {
1612 }
else if (a_call_id >= 0 && a_call_id < b_call_id) {
1615 }
else if (b_call_id >= 0 && a_call_id > b_call_id) {
1618 }
else if (b_call_id >= 0 && a_call_id == b_call_id) {
1629 crm_trace(
"rc-change: %d vs %d", last_a, last_b);
1630 if (last_a >= 0 && last_a < last_b) {
1633 }
else if (last_b >= 0 && last_a > last_b) {
1673 if (b_call_id == -1) {
1676 }
else if (a_call_id == -1) {
1680 }
else if ((a_id >= 0 && a_id < b_id) || b_id == -1) {
1683 }
else if ((b_id >= 0 && a_id > b_id) || a_id == -1) {
1697 if (data_set->
now == NULL) {
1716 if (value == NULL ||
safe_str_eq(
"started", value)
1734 crm_config_err(
"%s is not part of a promotable clone resource, a %s of '%s' makes no sense",
1755 if (lh_action == NULL || rh_action == NULL) {
1766 for (; gIter != NULL; gIter = gIter->next) {
1769 if (after->
action == rh_action && (after->
type & order)) {
1775 wrapper->
action = rh_action;
1776 wrapper->
type = order;
1779 list = g_list_prepend(list, wrapper);
1788 wrapper->
action = lh_action;
1789 wrapper->
type = order;
1791 list = g_list_prepend(list, wrapper);
1802 op = g_hash_table_lookup(data_set->
singletons, name);
1805 op =
custom_action(NULL, strdup(name), name, NULL, TRUE, TRUE, data_set);
1818 if (ticket->
state) {
1819 g_hash_table_destroy(ticket->
state);
1830 if (ticket_id == NULL || strlen(ticket_id) == 0) {
1834 if (data_set->
tickets == NULL) {
1840 ticket = g_hash_table_lookup(data_set->
tickets, ticket_id);
1841 if (ticket == NULL) {
1843 ticket = calloc(1,
sizeof(
ticket_t));
1844 if (ticket == NULL) {
1845 crm_err(
"Cannot allocate ticket '%s'", ticket_id);
1849 crm_trace(
"Creaing ticket entry for %s", ticket_id);
1851 ticket->
id = strdup(ticket_id);
1855 ticket->
state = crm_str_table_new();
1857 g_hash_table_insert(data_set->
tickets, strdup(ticket->
id), ticket);
1864 filter_parameters(xmlNode * param_set,
const char *param_string,
bool need_present)
1866 if (param_set && param_string) {
1867 xmlAttrPtr xIter = param_set->properties;
1870 const char *prop_name = (
const char *)xIter->name;
1872 char *match = strstr(param_string, name);
1877 xIter = xIter->next;
1879 if (need_present && match == NULL) {
1880 crm_trace(
"%s not found in %s", prop_name, param_string);
1883 }
else if (need_present == FALSE && match) {
1884 crm_trace(
"%s found in %s", prop_name, param_string);
1891 #if ENABLE_VERSIONED_ATTRS
1893 append_versioned_params(xmlNode *versioned_params,
const char *ra_version, xmlNode *params)
1895 GHashTable *hash = pe_unpack_versioned_parameters(versioned_params, ra_version);
1898 GHashTableIter iter;
1900 g_hash_table_iter_init(&iter, hash);
1901 while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &value)) {
1904 g_hash_table_destroy(hash);
1909 rsc_action_digest(
resource_t * rsc,
const char *task,
const char *key,
1916 GHashTable *local_rsc_params = crm_str_table_new();
1918 #if ENABLE_VERSIONED_ATTRS
1920 const char *ra_version = NULL;
1923 const char *op_version;
1924 const char *restart_list = NULL;
1925 const char *secure_list =
" passwd password ";
1931 #if ENABLE_VERSIONED_ATTRS
1932 pe_get_versioned_attributes(local_versioned_params, rsc, node, data_set);
1939 crm_trace(
"Set address for bundle connection %s (on %s)",
1943 g_hash_table_foreach(local_rsc_params,
hash2field,
data->params_all);
1953 #if ENABLE_VERSIONED_ATTRS
1961 #if ENABLE_VERSIONED_ATTRS
1962 append_versioned_params(local_versioned_params, ra_version,
data->params_all);
1963 append_versioned_params(rsc->versioned_parameters, ra_version,
data->params_all);
1966 pe_rsc_action_details_t *details = pe_rsc_action_details(action);
1967 append_versioned_params(details->versioned_parameters, ra_version,
data->params_all);
1973 g_hash_table_destroy(local_rsc_params);
1981 filter_parameters(
data->params_secure, secure_list, FALSE);
1989 filter_parameters(
data->params_restart, restart_list, TRUE);
2007 guint interval_ms = 0;
2009 const char *op_version;
2013 const char *digest_all;
2014 const char *digest_restart;
2024 data = rsc_action_digest(rsc, task, key, node, xml_op, data_set);
2027 if (digest_restart &&
data->digest_restart_calc && strcmp(
data->digest_restart_calc, digest_restart) != 0) {
2028 pe_rsc_info(rsc,
"Parameters to %s on %s changed: was %s vs. now %s (restart:%s) %s",
2030 crm_str(digest_restart),
data->digest_restart_calc,
2034 }
else if (digest_all == NULL) {
2038 }
else if (strcmp(digest_all,
data->digest_all_calc) != 0) {
2039 pe_rsc_info(rsc,
"Parameters to %s on %s changed: was %s vs. now %s (%s:%s) %s",
2042 (interval_ms > 0)?
"reschedule" :
"reload",
2051 #define STONITH_DIGEST_TASK "stonith-on"
2071 if (digest_all == NULL) {
2075 }
else if (strstr(digest_all, search_all)) {
2078 }
else if(digest_secure &&
data->digest_secure_calc) {
2079 if(strstr(digest_secure, search_secure)) {
2081 printf(
"Only 'private' parameters to %s for unfencing %s changed\n",
2091 &&
data->digest_secure_calc) {
2092 printf(
"Parameters to %s for unfencing %s changed, try '%s:%s:%s'\n",
2095 data->digest_secure_calc);
2100 free(search_secure);
2108 return ID(rsc->
xml);
2119 for (; gIter != NULL; gIter = gIter->next) {
2132 for (; gIter != NULL; gIter = gIter->next) {
2142 for (
GListPtr gIter = candidates; gIter != NULL; gIter = gIter->next) {
2148 matches = find_unfencing_devices(candidate->
children, matches);
2152 }
else if (
crm_str_eq(provides,
"unfencing", FALSE) ||
crm_str_eq(requires,
"unfencing", FALSE)) {
2153 matches = g_list_prepend(matches, candidate);
2163 char *op_key = NULL;
2173 stonith_op = g_hash_table_lookup(data_set->
singletons, op_key);
2176 if(stonith_op == NULL) {
2193 long digests_all_offset = 0;
2194 long digests_secure_offset = 0;
2196 char *digests_all = malloc(max);
2197 char *digests_secure = malloc(max);
2200 for (
GListPtr gIter = matches; gIter != NULL; gIter = gIter->next) {
2208 fprintf(stdout,
" notice: Unfencing %s (remote): because the definition of %s changed\n", node->
details->
uname, match->
id);
2212 digests_all_offset += snprintf(
2213 digests_all+digests_all_offset, max-digests_all_offset,
2216 digests_secure_offset += snprintf(
2217 digests_secure+digests_secure_offset, max-digests_secure_offset,
2218 "%s:%s:%s,", match->
id, (
const char*)g_hash_table_lookup(match->
meta,
XML_ATTR_TYPE),
data->digest_secure_calc);
2220 g_hash_table_insert(stonith_op->
meta,
2223 g_hash_table_insert(stonith_op->
meta,
2232 if(optional == FALSE &&
pe_can_fence(data_set, node)) {
2234 }
else if(reason && stonith_op->
reason == NULL) {
2235 stonith_op->
reason = strdup(reason);
2264 GHashTableIter iter;
2267 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node)) {
2268 if(node->details->online && node->details->unclean == FALSE && node->details->shutdown == FALSE) {
2276 add_tag_ref(GHashTable * tags,
const char * tag_name,
const char * obj_ref)
2280 gboolean is_existing = FALSE;
2282 CRM_CHECK(tags && tag_name && obj_ref,
return FALSE);
2284 tag = g_hash_table_lookup(tags, tag_name);
2286 tag = calloc(1,
sizeof(
tag_t));
2290 tag->
id = strdup(tag_name);
2292 g_hash_table_insert(tags, strdup(tag_name), tag);
2295 for (gIter = tag->
refs; gIter != NULL; gIter = gIter->next) {
2296 const char *existing_ref = (
const char *) gIter->data;
2298 if (
crm_str_eq(existing_ref, obj_ref, TRUE)){
2304 if (is_existing == FALSE) {
2305 tag->
refs = g_list_append(tag->
refs, strdup(obj_ref));
2306 crm_trace(
"Added: tag=%s ref=%s", tag->
id, obj_ref);
2317 bool update = FALSE;
2318 const char *change = NULL;
2322 change =
"unrunnable";
2325 change =
"required";
2329 change =
"unrunnable";
2331 change =
"dangling";
2333 change =
"required";
2335 crm_err(
"Unknown flag change to %x by %s: 0x%s",
2352 if((change && update) || text) {
2353 char *reason_text = NULL;
2354 if(reason == NULL) {
2357 }
else if(reason->
rsc == NULL) {
2363 if(reason_text && action->
rsc != reason->
rsc) {
2372 if(action->
reason && overwrite) {
2377 if(action->
reason == NULL) {
2380 action->
reason = strdup(reason);