12 #include <sys/param.h> 34 if (pe_rsc_is_clone(
action->rsc) && node) {
62 convert_non_atomic_uuid(
char *old_uuid,
pe_resource_t * rsc, gboolean allow_notify,
63 gboolean free_original)
65 guint interval_ms = 0;
68 char *raw_task = NULL;
73 if (old_uuid == NULL) {
76 }
else if (strstr(old_uuid,
"notify") != NULL) {
84 if (interval_ms > 0) {
109 crm_err(
"Unknown action: %s", raw_task);
121 pe_rsc_trace(rsc,
"Converted %s -> %s", old_uuid, uuid);
126 uuid = strdup(old_uuid);
141 gboolean notify = FALSE;
161 uuid = convert_non_atomic_uuid(
action->uuid, rsc, notify, FALSE);
166 if (result == NULL) {
167 crm_err(
"Couldn't expand %s to %s in %s",
action->uuid, uuid, rsc->
id);
203 "%s then %s: mapped pe_order_implies_then_on_node to " 204 "pe_order_implies_then on %s",
221 (changed?
"changed" :
"unchanged"));
228 first_flags, restart,
232 (changed?
"changed" :
"unchanged"));
248 (changed?
"changed" :
"unchanged"));
258 "%s then %s: %s after pe_order_promoted_implies_first",
260 (changed?
"changed" :
"unchanged"));
285 (changed?
"changed" :
"unchanged"));
293 "%s then %s: ignoring because first is stopping",
305 (changed?
"changed" :
"unchanged"));
322 (changed?
"changed" :
"unchanged"));
332 "pe_order_implies_first_migratable",
334 (changed?
"changed" :
"unchanged"));
345 (changed?
"changed" :
"unchanged"));
355 (changed?
"changed" :
"unchanged"));
366 (changed?
"changed" :
"unchanged"));
400 "is blocked, unmanaged, unrunnable stop",
402 (changed?
"changed" :
"unchanged"));
410 #define action_type_str(flags) \ 411 (pcmk_is_set((flags), pe_action_pseudo)? "pseudo-action" : "action") 413 #define action_optional_str(flags) \ 414 (pcmk_is_set((flags), pe_action_optional)? "optional" : "required") 416 #define action_runnable_str(flags) \ 417 (pcmk_is_set((flags), pe_action_runnable)? "runnable" : "unrunnable") 419 #define action_node_str(a) \ 420 (((a)->node == NULL)? "no node" : (a)->node->details->uname) 427 int last_flags = then->
flags;
471 first_node->details->uname, first->
uuid);
479 then_node->details->uname, then->
uuid);
484 && (first_node != NULL) && (then_node != NULL)
485 && (first_node->details != then_node->details)) {
488 "Disabled ordering %s on %s then %s on %s: not same node",
489 other->
action->
uuid, first_node->details->uname,
490 then->
uuid, then_node->details->uname);
509 if (first->
rsc && then->
rsc && (first->
rsc != then->
rsc)
511 first = rsc_expand_action(first);
513 if (first != other->
action) {
518 first_flags = get_action_flags(first, then_node);
519 then_flags = get_action_flags(then, first_node);
522 "%s then %s: type=0x%.6x filter=0x%.6x " 523 "(%s %s %s on %s 0x%.6x then 0x%.6x)",
530 if (first == other->
action) {
545 changed |= graph_update_action(first, then, node, first_flags,
546 then_flags, other, data_set);
561 "Disabled ordering %s then %s in favor of %s then %s",
571 crm_trace(
"Re-processing %s and its 'after' actions since it changed",
573 for (lpc2 = first->
actions_after; lpc2 != NULL; lpc2 = lpc2->next) {
583 if (last_flags != then->
flags) {
591 crm_trace(
"Re-processing %s and its 'after' actions since it changed",
598 for (lpc = then->
actions_after; lpc != NULL; lpc = lpc->next) {
616 add_node_to_xml_by_id(
const char *
id, xmlNode *xml)
634 add_node_to_xml(
const pe_node_t *node,
void *xml)
636 add_node_to_xml_by_id(node->
details->
id, (xmlNode *) xml);
650 xmlNode *maintenance =
654 for (gIter = data_set->
nodes; gIter != NULL;
655 gIter = gIter->next) {
663 if (details->maintenance != details->remote_maintenance) {
666 add_node_to_xml_by_id(node->
details->
id, maintenance),
672 crm_trace(
"%s %d nodes to adjust maintenance-mode " 673 "to transition", maintenance?
"Added":
"Counted", count);
688 if (add_maintenance_nodes(NULL, data_set)) {
689 crm_trace(
"adding maintenance state update pseudo action");
717 add_node_to_xml_by_id(
action->node->details->id, downed);
722 const char *fence = g_hash_table_lookup(
action->meta,
"stonith_action");
726 add_node_to_xml_by_id(
action->node->details->id, downed);
738 gboolean migrating = FALSE;
740 for (iter =
action->actions_before; iter != NULL; iter = iter->next) {
750 add_node_to_xml_by_id(
action->rsc->id, downed);
759 if ((
action->rsc->lock_node == NULL) || (
action->node == NULL)
760 || (
action->node->details !=
action->rsc->lock_node->details)) {
778 gboolean needs_node_info = TRUE;
779 gboolean needs_maintenance_info = FALSE;
780 xmlNode *action_xml = NULL;
781 xmlNode *args_xml = NULL;
782 #if ENABLE_VERSIONED_ATTRS 783 pe_rsc_action_details_t *rsc_details = NULL;
816 needs_maintenance_info = TRUE;
819 needs_node_info = FALSE;
824 #if ENABLE_VERSIONED_ATTRS 825 rsc_details = pe_rsc_action_details(
action);
831 if (
action->rsc != NULL &&
action->rsc->clone_name != NULL) {
832 char *clone_key = NULL;
842 const char *n_type = g_hash_table_lookup(
action->meta,
"notify_type");
843 const char *n_task = g_hash_table_lookup(
action->meta,
"notify_operation");
847 crm_err(
"No notify operation value found for %s",
action->uuid));
851 }
else if(
action->cancel_task) {
853 action->cancel_task, interval_ms);
856 action->task, interval_ms);
868 if (needs_node_info &&
action->node != NULL) {
888 xmlNode *rsc_xml = NULL;
889 const char *attr_list[] = {
898 if (should_lock_action(
action)) {
900 (
long long)
action->rsc->lock_time);
906 crm_element_name(
action->rsc->xml));
908 &&
action->rsc->clone_name) {
926 const char *xml_id =
ID(
action->rsc->xml);
928 crm_debug(
"Using anonymous clone name %s for %s (aka. %s)", xml_id,
action->rsc->id,
956 for (lpc = 0; lpc <
PCMK__NELEM(attr_list); lpc++) {
958 g_hash_table_lookup(
action->rsc->meta, attr_list[lpc]));
975 #if ENABLE_VERSIONED_ATTRS 979 pe_get_versioned_attributes(versioned_parameters,
action->rsc,
993 #if ENABLE_VERSIONED_ATTRS 1000 #if ENABLE_VERSIONED_ATTRS 1003 add_node_copy(action_xml, rsc_details->versioned_parameters);
1013 if (
action->rsc != NULL) {
1014 const char *value = g_hash_table_lookup(
action->rsc->meta,
"external-ip");
1017 while (parent != NULL) {
1023 hash2smartfield((gpointer)
"pcmk_external_ip", (gpointer)value, (gpointer)args_xml);
1042 if (needs_node_info && (
action->node != NULL)) {
1043 add_downed_nodes(action_xml,
action, data_set);
1046 if (needs_maintenance_info) {
1047 add_maintenance_nodes(action_xml, data_set);
1082 for (lpc =
action->actions_after; lpc != NULL; lpc = lpc->next) {
1090 || should_dump_action(wrapper->
action)) {
1091 crm_trace(
"Action %s (%d) should be dumped: " 1092 "dependency of %s (%d)",
1101 crm_trace(
"Ignoring action %s (%d): unrunnable",
1107 crm_trace(
"Ignoring action %s (%d): optional",
1115 const char *interval_ms_s = g_hash_table_lookup(
action->meta,
1120 crm_trace(
"Ignoring action %s (%d): for unmanaged resource (%s)",
1132 if (
action->node == NULL) {
1133 pe_err(
"Skipping action %s (%d) " 1134 "because it was not allocated to a node (bug?)",
1140 crm_trace(
"Action %s (%d) should be dumped: " 1141 "can run on DC instead of %s",
1145 && !
action->node->details->remote_requires_reset) {
1146 crm_trace(
"Action %s (%d) should be dumped: " 1147 "assuming will be runnable on guest node %s",
1150 }
else if (
action->node->details->online ==
false) {
1151 pe_err(
"Skipping action %s (%d) " 1152 "because it was scheduled for offline node (bug?)",
1160 }
else if (
action->node->details->unclean ==
false) {
1161 pe_err(
"Skipping action %s (%d) " 1162 "because it was scheduled for unclean node (bug?)",
1173 sort_action_id(gconstpointer a, gconstpointer b)
1230 crm_trace(
"Ignoring %s (%d) input %s (%d): " 1231 "ordering disabled",
1237 && !ordering_can_change_actions(input)
1239 crm_trace(
"Ignoring %s (%d) input %s (%d): " 1240 "optional and input unrunnable",
1247 crm_trace(
"Ignoring %s (%d) input %s (%d): " 1248 "one-or-more and input unrunnable",
1255 crm_trace(
"Ignoring %s (%d) input %s (%d): " 1256 "stonith stop but action is pseudo",
1263 crm_trace(
"Ignoring %s (%d) input %s (%d): " 1264 "implies input migratable but input unrunnable",
1271 crm_trace(
"Ignoring %s (%d) input %s (%d): " 1272 "only if input unmigratable but input unrunnable",
1280 crm_trace(
"Ignoring %s (%d) input %s (%d): " 1281 "optional but stop in migration",
1297 if ((input_node == NULL) || (allocated == NULL)
1299 crm_trace(
"Ignoring %s (%d) input %s (%d): " 1300 "load ordering node mismatch %s vs %s",
1309 }
else if ((input_node == NULL) || (
action->node == NULL)
1311 crm_trace(
"Ignoring %s (%d) input %s (%d): " 1312 "load ordering node mismatch %s vs %s",
1315 (
action->node?
action->node->details->uname :
"<none>"),
1321 crm_trace(
"Ignoring %s (%d) input %s (%d): " 1322 "load ordering input optional",
1332 crm_trace(
"Ignoring %s (%d) input %s (%d): " 1333 "anti-colocation node mismatch %s vs %s",
1336 action->node->details->uname,
1342 crm_trace(
"Ignoring %s (%d) input %s (%d): " 1343 "anti-colocation input optional",
1356 crm_warn(
"Ignoring requirement that %s complete before %s:" 1357 " unmanaged failed resources cannot prevent clone shutdown",
1364 && !should_dump_action(input->
action)) {
1365 crm_trace(
"Ignoring %s (%d) input %s (%d): " 1372 crm_trace(
"%s (%d) input %s %s (%d) on %s should be dumped: %s %s 0x%.6x",
1385 bool has_loop =
false;
1388 crm_trace(
"Breaking tracking loop: %s@%s -> %s@%s (0x%.6x)",
1398 if (!check_dump_input(
action, input)) {
1402 if (input->
action == init_action) {
1403 crm_debug(
"Input loop found in %s@%s ->...-> %s@%s",
1413 crm_trace(
"Checking inputs of action %s@%s input %s@%s (0x%.6x)" 1414 "for graph loop with %s@%s ",
1425 iter != NULL; iter = iter->next) {
1439 crm_trace(
"No input loop found in %s@%s -> %s@%s (0x%.6x)",
1457 action->actions_before = g_list_sort(
action->actions_before,
1459 for (item =
action->actions_before; item != NULL; item = next) {
1464 crm_trace(
"Input %s (%d) duplicate skipped for action %s (%d)",
1478 action->actions_before = g_list_delete_link(
action->actions_before,
1507 int synapse_priority = 0;
1508 xmlNode *syn = NULL;
1509 xmlNode *
set = NULL;
1511 xmlNode *xml_action = NULL;
1518 deduplicate_inputs(
action);
1522 if (should_dump_action(
action) == FALSE) {
1535 if (
action->rsc != NULL) {
1536 synapse_priority =
action->rsc->priority;
1538 if (
action->priority > synapse_priority) {
1539 synapse_priority =
action->priority;
1541 if (synapse_priority > 0) {
1545 xml_action = action2xml(
action, FALSE, data_set);
1548 for (lpc =
action->actions_before; lpc != NULL; lpc = lpc->next) {
1550 if (check_dump_input(
action, input)) {
1554 xml_action = action2xml(input->
action, TRUE, data_set);
#define CRM_CHECK(expr, failure_action)
G_GNUC_INTERNAL void pcmk__substitute_remote_addr(pe_resource_t *rsc, GHashTable *params, pe_working_set_t *data_set)
const char * task2text(enum action_tasks task)
gboolean parse_op_key(const char *key, char **rsc_id, char **op_type, guint *interval_ms)
#define CRMD_ACTION_MIGRATED
bool pe__is_guest_or_remote_node(const pe_node_t *node)
#define XML_CONFIG_ATTR_SHUTDOWN_LOCK
#define pe__set_action_flags(action, flags_to_set)
gboolean is_parent(pe_resource_t *child, pe_resource_t *rsc)
void hash2field(gpointer key, gpointer value, gpointer user_data)
Set XML attribute based on hash table entry.
#define XML_GRAPH_TAG_MAINTENANCE
bool pcmk__strcase_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
#define action_type_str(flags)
resource_alloc_functions_t * cmds
Internal tracking for transition graph creation.
bool pcmk__graph_has_loop(pe_action_t *init_action, pe_action_t *action, pe_action_wrapper_t *input)
enum pe_graph_flags(* update_actions)(pe_action_t *, pe_action_t *, pe_node_t *, enum pe_action_flags, enum pe_action_flags, enum pe_ordering, pe_working_set_t *data_set)
const char * crm_xml_add_int(xmlNode *node, const char *name, int value)
Create an XML attribute with specified name and integer value.
void pe_foreach_guest_node(const pe_working_set_t *data_set, const pe_node_t *host, void(*helper)(const pe_node_t *, void *), void *user_data)
resource_object_functions_t * fns
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
#define pe__clear_graph_flags(graph_flags, gr_action, flags_to_clear)
#define XML_GRAPH_TAG_RSC_OP
#define XML_NODE_IS_MAINTENANCE
enum action_tasks text2task(const char *task)
#define XML_GRAPH_TAG_CRM_EVENT
enum crm_ais_msg_types type
void add_maintenance_update(pe_working_set_t *data_set)
bool pcmk__ends_with(const char *s, const char *match)
void hash2smartfield(gpointer key, gpointer value, gpointer user_data)
Add hash table entry to XML as (possibly legacy) name/value.
#define XML_GRAPH_TAG_DOWNED
#define pe__set_raw_action_flags(action_flags, action_name, flags_to_set)
#define XML_GRAPH_TAG_PSEUDO_EVENT
#define XML_CIB_ATTR_PRIORITY
G_GNUC_INTERNAL pe_node_t * pcmk__connection_host_for_action(pe_action_t *action)
#define XML_LRM_ATTR_TASK_KEY
#define XML_LRM_ATTR_TASK
#define CRM_OP_LRM_REFRESH
pe_node_t *(* location)(const pe_resource_t *, GList **, int)
#define CRM_OP_CLEAR_FAILCOUNT
gboolean update_action(pe_action_t *then, pe_working_set_t *data_set)
#define crm_warn(fmt, args...)
#define CRMD_ACTION_RELOAD_AGENT
char * pcmk__notify_key(const char *rsc_id, const char *notify_type, const char *op_type)
int pcmk__guint_from_hash(GHashTable *table, const char *key, guint default_val, guint *result)
pe_action_t * get_pseudo_op(const char *name, pe_working_set_t *data_set)
#define crm_debug(fmt, args...)
gboolean rsc_update_action(pe_action_t *first, pe_action_t *then, enum pe_ordering type)
#define pe__clear_order_flags(order_flags, flags_to_clear)
G_GNUC_INTERNAL void pcmk__block_colocated_starts(pe_action_t *action, pe_working_set_t *data_set)
bool pe__is_guest_node(const pe_node_t *node)
#define pe__clear_action_flags(action, flags_to_clear)
#define crm_trace(fmt, args...)
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
xmlNode * add_node_copy(xmlNode *new_parent, xmlNode *xml_node)
struct pe_node_shared_s * details
#define XML_AGENT_ATTR_PROVIDER
gboolean order_actions(pe_action_t *lh_action, pe_action_t *rh_action, enum pe_ordering order)
GHashTable * pe_rsc_params(pe_resource_t *rsc, pe_node_t *node, pe_working_set_t *data_set)
Get a table of resource parameters.
Wrappers for and extensions to libxml2.
Internal state tracking when creating graph.
xmlNode * create_xml_node(xmlNode *parent, const char *name)
#define pe__set_graph_flags(graph_flags, gr_action, flags_to_set)
void(* append_meta)(pe_resource_t *rsc, xmlNode *xml)
#define XML_LRM_ATTR_ROUTER_NODE
#define XML_TAG_RSC_VER_ATTRS
void free_xml(xmlNode *child)
enum pe_obj_types variant
gboolean xml_has_children(const xmlNode *root)
char * pcmk__op_key(const char *rsc_id, const char *op_type, guint interval_ms)
Generate an operation key (RESOURCE_ACTION_INTERVAL)
#define CRM_OP_MAINTENANCE_NODES
xmlNode * sorted_xml(xmlNode *input, xmlNode *parent, gboolean recursive)
#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.
void log_action(unsigned int log_level, const char *pre_text, pe_action_t *action, gboolean details)
G_GNUC_INTERNAL void pcmk__add_bundle_meta_to_xml(xmlNode *args_xml, pe_action_t *action)
Add special bundle meta-attributes to XML.
#define crm_err(fmt, args...)
#define XML_LRM_ATTR_INTERVAL_MS
void hash2metafield(gpointer key, gpointer value, gpointer user_data)
Set XML attribute based on hash table entry, as meta-attribute name.
#define pe__clear_resource_flags(resource, flags_to_clear)
#define XML_ATTR_CRM_VERSION
enum pe_action_flags flags
int add_node_nocopy(xmlNode *parent, const char *name, xmlNode *child)
#define crm_log_xml_trace(xml, text)
#define XML_LRM_ATTR_TARGET
#define action_optional_str(flags)
#define pe_rsc_trace(rsc, fmt, args...)
#define action_node_str(a)
#define pe__set_order_flags(order_flags, flags_to_set)
void graph_element_from_action(pe_action_t *action, pe_working_set_t *data_set)
#define action_runnable_str(flags)
#define CRM_OP_LRM_DELETE
pe_action_t * find_first_action(GList *input, const char *uuid, const char *task, pe_node_t *on_node)
int required_runnable_before
#define XML_AGENT_ATTR_CLASS