12 #include <sys/param.h>
33 if (pe_rsc_is_clone(action->
rsc) && node) {
61 convert_non_atomic_uuid(
char *old_uuid,
pe_resource_t * rsc, gboolean allow_notify,
62 gboolean free_original)
64 guint interval_ms = 0;
67 char *raw_task = NULL;
72 if (old_uuid == NULL) {
75 }
else if (strstr(old_uuid,
"notify") != NULL) {
83 if (interval_ms > 0) {
108 crm_err(
"Unknown action: %s", raw_task);
120 pe_rsc_trace(rsc,
"Converted %s -> %s", old_uuid, uuid);
125 uuid = strdup(old_uuid);
140 gboolean notify = FALSE;
160 uuid = convert_non_atomic_uuid(action->
uuid, rsc, notify, FALSE);
165 if (result == NULL) {
166 crm_err(
"Couldn't expand %s to %s in %s", action->
uuid, uuid, rsc->
id);
182 gboolean processed = FALSE;
212 pe_order_implies_then, data_set);
231 first_flags, restart,
232 pe_order_restart, data_set);
259 crm_trace(
"implies left: %s (%d) then %s (%d)",
270 pe_order_promoted_implies_first, data_set);
275 "implies left when right resource is promoted: "
276 "%s then %s: changed", first->
uuid, then->
uuid);
278 crm_trace(
"implies left when right resource is promoted: "
279 "%s then %s", first->
uuid, then->
uuid);
317 pe_rsc_trace(then->
rsc,
"Ignoring %s then %s - %s is about to be stopped",
361 pe_order_implies_first_migratable, data_set);
428 if ((type & pe_order_implies_then
429 || type & pe_order_implies_first
430 || type & pe_order_restart)
448 if (processed == FALSE) {
449 crm_trace(
"Constraint 0x%.6x not applicable", type);
462 for (; gIter != NULL; gIter = gIter->next) {
504 for (gIter = rsc->
children; gIter != NULL; gIter = gIter->next) {
512 for (gIter = rsc->
rsc_cons_lhs; gIter != NULL; gIter = gIter->next) {
516 mark_start_blocked(colocate_with->
rsc_lh, action->
rsc, data_set);
526 int last_flags = then->
flags;
571 crm_trace(
"First: Found node %s for %s", first_node->details->uname, first->
uuid);
578 crm_trace(
"Then: Found node %s for %s", then_node->details->uname, then->
uuid);
583 && (first_node != NULL) && (then_node != NULL)
584 && (first_node->details != then_node->details)) {
586 crm_trace(
"Disabled constraint %s on %s -> %s on %s",
587 other->
action->
uuid, first_node->details->uname,
588 then->
uuid, then_node->details->uname);
607 if (first->
rsc && then->
rsc && (first->
rsc != then->
rsc)
609 first = rsc_expand_action(first);
611 if (first != other->
action) {
616 first_flags = get_action_flags(first, then_node);
617 then_flags = get_action_flags(then, first_node);
619 crm_trace(
"Checking %s (%s %s %s) against %s (%s %s %s) filter=0x%.6x type=0x%.6x",
621 pcmk_is_set(then_flags, pe_action_optional)?
"optional" :
"required",
626 pcmk_is_set(first_flags, pe_action_optional)?
"optional" :
"required",
630 first_flags, other->
type);
632 if (first == other->
action) {
647 changed |= graph_update_action(first, then, node, first_flags,
648 then_flags, other, data_set);
662 crm_trace(
"Disabled constraint %s -> %s in favor of %s -> %s",
671 crm_trace(
"Updated %s (first %s %s %s), processing dependents ",
677 for (lpc2 = first->
actions_after; lpc2 != NULL; lpc2 = lpc2->next) {
687 if (last_flags != then->
flags) {
695 crm_trace(
"Updated %s (then %s %s %s), processing dependents ",
707 for (lpc = then->
actions_after; lpc != NULL; lpc = lpc->next) {
725 for (lpc = data_set->
actions; lpc != NULL; lpc = lpc->next) {
728 if (action->
rsc == NULL || action->
node == NULL) {
736 pe_rsc_trace(action->
rsc,
"Skipping %s: node %s is in maintenance mode",
741 }
else if (!pcmk_any_flags_set(action->
rsc->
flags,
755 pe_order_optional | pe_order_runnable_left, data_set);
775 CRM_CHECK(stonith_op && data_set,
return);
776 for (GList *r = data_set->
resources; r != NULL; r = r->next) {
786 bool partial_migration = FALSE;
787 const char *task = action->
task;
801 partial_migration = TRUE;
804 if (began_on == NULL) {
805 crm_trace(
"Routing %s for %s through remote connection's "
806 "next node %s (starting)%s",
807 action->
task, (action->
rsc? action->
rsc->
id :
"no resource"),
809 partial_migration?
" (partial migration)" :
"");
813 if (ended_on == NULL) {
814 crm_trace(
"Routing %s for %s through remote connection's "
815 "current node %s (stopping)%s",
816 action->
task, (action->
rsc? action->
rsc->
id :
"no resource"),
818 partial_migration?
" (partial migration)" :
"");
823 crm_trace(
"Routing %s for %s through remote connection's "
824 "current node %s (not moving)%s",
825 action->
task, (action->
rsc? action->
rsc->
id :
"no resource"),
827 partial_migration?
" (partial migration)" :
"");
839 task = g_hash_table_lookup(action->
meta,
"notify_operation");
855 "migrate_to", NULL) && !partial_migration) {
856 crm_trace(
"Routing %s for %s through remote connection's "
857 "current node %s (moving)%s",
858 action->
task, (action->
rsc? action->
rsc->
id :
"no resource"),
860 partial_migration?
" (partial migration)" :
"");
868 crm_trace(
"Routing %s for %s through remote connection's "
869 "next node %s (moving)%s",
870 action->
task, (action->
rsc? action->
rsc->
id :
"no resource"),
872 partial_migration?
" (partial migration)" :
"");
884 add_node_to_xml_by_id(
const char *
id, xmlNode *xml)
902 add_node_to_xml(
const pe_node_t *node,
void *xml)
904 add_node_to_xml_by_id(node->
details->
id, (xmlNode *) xml);
918 xmlNode *maintenance =
922 for (gIter = data_set->
nodes; gIter != NULL;
923 gIter = gIter->next) {
931 if (details->maintenance != details->remote_maintenance) {
934 add_node_to_xml_by_id(node->
details->
id, maintenance),
940 crm_trace(
"%s %d nodes to adjust maintenance-mode "
941 "to transition", maintenance?
"Added":
"Counted", count);
956 if (add_maintenance_nodes(NULL, data_set)) {
957 crm_trace(
"adding maintenance state update pseudo action");
976 add_downed_nodes(xmlNode *xml,
const pe_action_t *action,
979 CRM_CHECK(xml && action && action->
node && data_set,
return);
990 const char *fence = g_hash_table_lookup(action->
meta,
"stonith_action");
1006 gboolean migrating = FALSE;
1008 for (iter = action->
actions_before; iter != NULL; iter = iter->next) {
1018 add_node_to_xml_by_id(action->
rsc->
id, downed);
1046 gboolean needs_node_info = TRUE;
1047 gboolean needs_maintenance_info = FALSE;
1048 xmlNode *action_xml = NULL;
1049 xmlNode *args_xml = NULL;
1050 #if ENABLE_VERSIONED_ATTRS
1051 pe_rsc_action_details_t *rsc_details = NULL;
1054 if (action == NULL) {
1084 needs_maintenance_info = TRUE;
1087 needs_node_info = FALSE;
1092 #if ENABLE_VERSIONED_ATTRS
1093 rsc_details = pe_rsc_action_details(action);
1100 char *clone_key = NULL;
1110 const char *n_type = g_hash_table_lookup(action->
meta,
"notify_type");
1111 const char *n_task = g_hash_table_lookup(action->
meta,
"notify_operation");
1115 crm_err(
"No notify operation value found for %s", action->
uuid));
1124 action->
task, interval_ms);
1136 if (needs_node_info && action->
node != NULL) {
1137 pe_node_t *router_node = get_router_node(action);
1156 xmlNode *rsc_xml = NULL;
1157 const char *attr_list[] = {
1166 if (should_lock_action(action)) {
1174 crm_element_name(action->
rsc->
xml));
1188 crm_debug(
"Using orphan clone name %s instead of %s", action->
rsc->
id,
1194 const char *xml_id =
ID(action->
rsc->
xml);
1196 crm_debug(
"Using anonymous clone name %s for %s (aka. %s)", xml_id, action->
rsc->
id,
1224 for (lpc = 0; lpc <
PCMK__NELEM(attr_list); lpc++) {
1226 g_hash_table_lookup(action->
rsc->
meta, attr_list[lpc]));
1235 if (action->
rsc != NULL && action->
node) {
1244 const char *remote_addr = g_hash_table_lookup(params,
1250 remote_addr = g_hash_table_lookup(base,
1252 if (remote_addr != NULL) {
1254 strdup(remote_addr));
1260 #if ENABLE_VERSIONED_ATTRS
1264 pe_get_versioned_attributes(versioned_parameters, action->
rsc,
1265 action->
node, data_set);
1278 #if ENABLE_VERSIONED_ATTRS
1285 #if ENABLE_VERSIONED_ATTRS
1288 add_node_copy(action_xml, rsc_details->versioned_parameters);
1298 if (action->
rsc != NULL) {
1299 const char *value = g_hash_table_lookup(action->
rsc->
meta,
"external-ip");
1302 while (parent != NULL) {
1308 hash2smartfield((gpointer)
"pcmk_external_ip", (gpointer)value, (gpointer)args_xml);
1317 const char *n_task = g_hash_table_lookup(action->
meta,
"notify_operation");
1342 (gpointer)g_hash_table_lookup(action->
rsc->
meta, XML_RSC_ATTR_TARGET), (gpointer)args_xml);
1345 (gpointer)args_xml);
1363 if (needs_node_info && (action->
node != NULL)) {
1364 add_downed_nodes(action_xml, action, data_set);
1367 if (needs_maintenance_info) {
1368 add_maintenance_nodes(action_xml, data_set);
1378 CRM_CHECK(action != NULL,
return false);
1403 for (lpc = action->
actions_after; lpc != NULL; lpc = lpc->next) {
1411 || should_dump_action(wrapper->
action)) {
1412 crm_trace(
"Action %s (%d) should be dumped: "
1413 "dependency of %s (%d)",
1414 action->
uuid, action->
id,
1422 crm_trace(
"Ignoring action %s (%d): unrunnable",
1423 action->
uuid, action->
id);
1428 crm_trace(
"Ignoring action %s (%d): optional",
1429 action->
uuid, action->
id);
1436 const char *interval_ms_s = g_hash_table_lookup(action->
meta,
1441 crm_trace(
"Ignoring action %s (%d): for unmanaged resource (%s)",
1453 if (action->
node == NULL) {
1454 pe_err(
"Skipping action %s (%d) "
1455 "because it was not allocated to a node (bug?)",
1456 action->
uuid, action->
id);
1457 log_action(LOG_DEBUG,
"Unallocated action", action,
false);
1461 crm_trace(
"Action %s (%d) should be dumped: "
1462 "can run on DC instead of %s",
1467 crm_trace(
"Action %s (%d) should be dumped: "
1468 "assuming will be runnable on guest node %s",
1472 pe_err(
"Skipping action %s (%d) "
1473 "because it was scheduled for offline node (bug?)",
1474 action->
uuid, action->
id);
1475 log_action(LOG_DEBUG,
"Action for offline node", action, FALSE);
1482 pe_err(
"Skipping action %s (%d) "
1483 "because it was scheduled for unclean node (bug?)",
1484 action->
uuid, action->
id);
1485 log_action(LOG_DEBUG,
"Action for unclean node", action,
false);
1494 sort_action_id(gconstpointer a, gconstpointer b)
1530 int type = input->
type;
1537 |pe_order_implies_then_printed
1538 |pe_order_optional);
1541 crm_trace(
"Ignoring %s (%d) input %s (%d): "
1542 "ordering disabled",
1543 action->
uuid, action->
id,
1550 crm_trace(
"Ignoring %s (%d) input %s (%d): "
1551 "optional and input unrunnable",
1552 action->
uuid, action->
id,
1558 crm_trace(
"Ignoring %s (%d) input %s (%d): "
1559 "one-or-more and input unrunnable",
1560 action->
uuid, action->
id,
1566 crm_trace(
"Ignoring %s (%d) input %s (%d): "
1567 "stonith stop but action is pseudo",
1568 action->
uuid, action->
id,
1572 }
else if (
pcmk_is_set(input->
type, pe_order_implies_first_migratable)
1574 crm_trace(
"Ignoring %s (%d) input %s (%d): "
1575 "implies input migratable but input unrunnable",
1576 action->
uuid, action->
id,
1582 crm_trace(
"Ignoring %s (%d) input %s (%d): "
1583 "only if input unmigratable but input unrunnable",
1584 action->
uuid, action->
id,
1588 }
else if ((input->
type == pe_order_optional)
1591 crm_trace(
"Ignoring %s (%d) input %s (%d): "
1592 "optional but stop in migration",
1593 action->
uuid, action->
id,
1608 if ((input_node == NULL) || (allocated == NULL)
1610 crm_trace(
"Ignoring %s (%d) input %s (%d): "
1611 "load ordering node mismatch %s vs %s",
1612 action->
uuid, action->
id,
1620 }
else if ((input_node == NULL) || (action->
node == NULL)
1622 crm_trace(
"Ignoring %s (%d) input %s (%d): "
1623 "load ordering node mismatch %s vs %s",
1624 action->
uuid, action->
id,
1632 crm_trace(
"Ignoring %s (%d) input %s (%d): "
1633 "load ordering input optional",
1634 action->
uuid, action->
id,
1643 crm_trace(
"Ignoring %s (%d) input %s (%d): "
1644 "anti-colocation node mismatch %s vs %s",
1645 action->
uuid, action->
id,
1653 crm_trace(
"Ignoring %s (%d) input %s (%d): "
1654 "anti-colocation input optional",
1655 action->
uuid, action->
id,
1666 && action->
rsc && pe_rsc_is_clone(action->
rsc)) {
1667 crm_warn(
"Ignoring requirement that %s complete before %s:"
1668 " unmanaged failed resources cannot prevent clone shutdown",
1675 && !should_dump_action(input->
action)) {
1676 crm_trace(
"Ignoring %s (%d) input %s (%d): "
1678 action->
uuid, action->
id,
1683 crm_trace(
"%s (%d) input %s (%d) @ %s should be dumped: %s, %s, %s, 0x%.6x",
1684 action->
uuid, action->
id,
1698 bool has_loop =
false;
1701 crm_trace(
"Breaking tracking loop: %s@%s -> %s@%s (0x%.6x)",
1711 if (!check_dump_input(action, input)) {
1715 if (input->
action == init_action) {
1716 crm_debug(
"Input loop found in %s@%s ->...-> %s@%s",
1726 crm_trace(
"Checking inputs of action %s@%s input %s@%s (0x%.6x)"
1727 "for graph loop with %s@%s ",
1738 iter != NULL; iter = iter->next) {
1740 if (graph_has_loop(init_action, input->
action,
1752 crm_trace(
"No input loop found in %s@%s -> %s@%s (0x%.6x)",
1773 crm_warn(
"Invalid ordering constraint between %s and %s",
1787 && graph_has_loop(action, action, input)) {
1809 crm_trace(
"Input %s (%d) duplicate skipped for action %s (%d)",
1811 action->
uuid, action->
id);
1851 int synapse_priority = 0;
1852 xmlNode *syn = NULL;
1853 xmlNode *set = NULL;
1855 xmlNode *xml_action = NULL;
1862 deduplicate_inputs(action);
1866 if (should_dump_action(action) == FALSE) {
1879 if (action->
rsc != NULL) {
1882 if (action->
priority > synapse_priority) {
1883 synapse_priority = action->
priority;
1885 if (synapse_priority > 0) {
1889 xml_action = action2xml(action, FALSE, data_set);
1892 for (lpc = action->
actions_before; lpc != NULL; lpc = lpc->next) {
1894 if (check_dump_input(action, input)) {
1898 xml_action = action2xml(input->
action, TRUE, data_set);
#define CRM_CHECK(expr, failure_action)
const char * task2text(enum action_tasks task)
void pcmk__order_vs_fence(pe_action_t *stonith_op, pe_working_set_t *data_set)
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
pe_resource_t * container
bool pcmk__strcase_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
resource_alloc_functions_t * cmds
bool pcmk__ordering_is_invalid(pe_action_t *action, pe_action_wrapper_t *input)
Internal tracking for transition graph creation.
enum pe_action_flags(* action_flags)(pe_action_t *, pe_node_t *)
void add_maintenance_update(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)
pe_resource_t * remote_rsc
resource_object_functions_t * fns
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)
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
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)
#define XML_NODE_IS_MAINTENANCE
enum action_tasks text2task(const char *task)
void(* append_meta)(pe_resource_t *rsc, xmlNode *xml)
#define XML_GRAPH_TAG_CRM_EVENT
enum crm_ais_msg_types type
pe_node_t * partial_migration_target
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 XML_RSC_ATTR_TARGET
#define pe__set_raw_action_flags(action_flags, action_name, flags_to_set)
gboolean remote_requires_reset
#define XML_RSC_ATTR_REMOTE_RA_ADDR
#define XML_GRAPH_TAG_PSEUDO_EVENT
#define XML_CIB_ATTR_PRIORITY
#define XML_LRM_ATTR_TASK_KEY
#define XML_LRM_ATTR_TASK
#define CRM_OP_LRM_REFRESH
#define CRM_OP_CLEAR_FAILCOUNT
#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...)
pe_resource_t * uber_parent(pe_resource_t *rsc)
#define pe__clear_order_flags(order_flags, flags_to_clear)
bool pe__is_guest_node(const pe_node_t *node)
gboolean update_action(pe_action_t *action, pe_working_set_t *data_set)
#define pe__clear_action_flags(action, flags_to_clear)
int custom_action_order(pe_resource_t *lh_rsc, char *lh_task, pe_action_t *lh_action, pe_resource_t *rh_rsc, char *rh_task, pe_action_t *rh_action, enum pe_ordering type, pe_working_set_t *data_set)
#define crm_trace(fmt, args...)
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
#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)
void rsc_stonith_ordering(pe_resource_t *rsc, pe_action_t *stonith_op, pe_working_set_t *data_set)
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)
gboolean update_action_flags(pe_action_t *action, enum pe_action_flags flags, const char *source, int line)
#define XML_LRM_ATTR_ROUTER_NODE
#define XML_TAG_RSC_VER_ATTRS
void free_xml(xmlNode *child)
#define PCMK__ENV_PHYSICAL_HOST
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)
void update_colo_start_chain(pe_action_t *action, pe_working_set_t *data_set)
#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
#define pe_rsc_maintenance
pe_node_t *(* location)(const pe_resource_t *, GList **, int)
int add_node_nocopy(xmlNode *parent, const char *name, xmlNode *child)
gboolean rsc_update_action(pe_action_t *first, pe_action_t *then, enum pe_ordering type)
#define crm_log_xml_trace(xml, text)
#define XML_LRM_ATTR_TARGET
#define pe_rsc_trace(rsc, fmt, args...)
#define pe__set_order_flags(order_flags, flags_to_set)
#define CRM_OP_LRM_DELETE
#define pe__clear_raw_action_flags(action_flags, action_name, flags_to_clear)
gboolean shutdown_constraints(pe_node_t *node, pe_action_t *shutdown_op, pe_working_set_t *data_set)
void graph_element_from_action(pe_action_t *action, pe_working_set_t *data_set)
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