13 #include <sys/param.h> 33 bool runnable =
false;
46 if ((node == NULL) || !pe_rsc_is_clone(
action->rsc)) {
92 action_uuid_for_ordering(
const char *first_uuid,
const pe_resource_t *first_rsc)
94 guint interval_ms = 0;
97 char *first_task_str = NULL;
102 if ((strstr(first_uuid,
"notify") != NULL)
109 if (interval_ms > 0) {
114 switch (first_task) {
120 remapped_task = first_task + 1;
127 remapped_task = first_task;
134 crm_err(
"Unknown action '%s' in ordering", first_task_str);
145 && ((first_rsc->
parent == NULL)
146 || (pe_rsc_is_clone(first_rsc)
154 "Remapped action UUID %s to %s for ordering purposes",
160 uuid = strdup(first_uuid);
163 free(first_task_str);
191 char *uuid = action_uuid_for_ordering(
action->uuid, rsc);
195 crm_warn(
"Not remapping %s to %s because %s does not have " 196 "remapped action",
action->uuid, uuid, rsc->
id);
243 "%s then %s: mapped pe_order_implies_then_on_node to " 244 "pe_order_implies_then on %s",
245 first->
uuid, then->
uuid, pe__node_name(node));
249 if (then->
rsc != NULL) {
263 (changed?
"changed" :
"unchanged"));
270 first_flags, restart,
275 (changed?
"changed" :
"unchanged"));
279 if (first->
rsc != NULL) {
293 (changed?
"changed" :
"unchanged"));
297 if (then->
rsc != NULL) {
306 "%s then %s: %s after pe_order_promoted_implies_first",
308 (changed?
"changed" :
"unchanged"));
312 if (then->
rsc != NULL) {
336 (changed?
"changed" :
"unchanged"));
344 "%s then %s: ignoring because first is stopping",
357 (changed?
"changed" :
"unchanged"));
361 if (then->
rsc != NULL) {
377 (changed?
"changed" :
"unchanged"));
381 if (then->
rsc != NULL) {
390 "pe_order_implies_first_migratable",
392 (changed?
"changed" :
"unchanged"));
396 if (then->
rsc != NULL) {
406 (changed?
"changed" :
"unchanged"));
410 if (then->
rsc != NULL) {
420 (changed?
"changed" :
"unchanged"));
424 if (then->
rsc != NULL) {
434 (changed?
"changed" :
"unchanged"));
459 && (first->
rsc != NULL)
470 "is blocked, unmanaged, unrunnable stop",
472 (changed?
"changed" :
"unchanged"));
480 #define action_type_str(flags) \ 481 (pcmk_is_set((flags), pe_action_pseudo)? "pseudo-action" : "action") 483 #define action_optional_str(flags) \ 484 (pcmk_is_set((flags), pe_action_optional)? "optional" : "required") 486 #define action_runnable_str(flags) \ 487 (pcmk_is_set((flags), pe_action_runnable)? "runnable" : "unrunnable") 489 #define action_node_str(a) \ 490 (((a)->node == NULL)? "no node" : (a)->node->details->uname) 504 int last_flags = then->
flags;
539 if ((first->
rsc != NULL)
544 if (first_node != NULL) {
546 pe__node_name(first_node), first->
uuid);
550 if ((then->
rsc != NULL)
555 if (then_node != NULL) {
557 pe__node_name(then_node), then->
uuid);
563 && (first_node != NULL) && (then_node != NULL)
564 && (first_node->details != then_node->details)) {
567 "Disabled ordering %s on %s then %s on %s: not same node",
568 other->
action->
uuid, pe__node_name(first_node),
569 then->
uuid, pe__node_name(then_node));
576 if ((first->
rsc != NULL)
589 if ((first->
rsc != NULL) && (then->
rsc != NULL)
591 first = action_for_ordering(first);
593 if (first != other->
action) {
599 "%s (%#.6x) then %s (%#.6x): type=%#.6x node=%s",
603 if (first == other->
action) {
610 first_flags = action_flags_for_ordering(first, then_node);
611 then_flags = action_flags_for_ordering(then, first_node);
613 changed |= update_action_for_ordering_flags(first, then,
614 first_flags, then_flags,
626 "Disabled ordering %s then %s in favor of %s then %s",
634 crm_trace(
"Re-processing %s and its 'after' actions " 635 "because it changed", first->
uuid);
647 if (last_flags == then->
flags) {
655 crm_trace(
"Re-processing %s and its 'after' actions because it changed",
662 for (lpc = then->
actions_after; lpc != NULL; lpc = lpc->next) {
684 #define clear_action_flag_because(action, flag, reason) do { \ 685 if (pcmk_is_set((action)->flags, (flag))) { \ 686 pe__clear_action_flags(action, flag); \ 687 if ((action)->rsc != (reason)->rsc) { \ 688 char *reason_text = pe__action2reason((reason), (flag)); \ 689 pe_action_set_reason((action), reason_text, \ 690 ((flag) == pe_action_migrate_runnable)); \ 755 const char *reason = NULL;
774 && (first->
rsc == then->
rsc)) {
778 if (reason == NULL) {
832 uint32_t filter, uint32_t
type,
836 uint32_t then_flags = then->
flags;
837 uint32_t first_flags = first->
flags;
840 handle_asymmetric_ordering(first, then);
876 if (!pcmk_all_flags_set(then->
flags,
913 handle_restart_ordering(first, then, filter);
916 if (then_flags != then->
flags) {
919 "%s on %s: flags are now %#.6x (was %#.6x) " 920 "because of 'first' %s (%#.6x)",
921 then->
uuid, pe__node_name(then->
node),
924 if ((then->
rsc != NULL) && (then->
rsc->
parent != NULL)) {
930 if (first_flags != first->
flags) {
933 "%s on %s: flags are now %#.6x (was %#.6x) " 934 "because of 'then' %s (%#.6x)",
935 first->
uuid, pe__node_name(first->
node),
953 const char *node_uname = NULL;
954 const char *node_uuid = NULL;
955 const char *desc = NULL;
960 if (
action->node != NULL) {
961 node_uname =
action->node->details->uname;
962 node_uuid =
action->node->details->id;
964 node_uname =
"<none>";
976 desc =
"!!Non-Startable!! ";
980 desc =
"(Provisional) ";
982 crm_trace(
"%s%s%sAction %d: %s%s%s%s%s%s",
983 ((pre_text == NULL)?
"" : pre_text),
984 ((pre_text == NULL)?
"" :
": "),
986 (node_uname?
"\ton " :
""), (node_uname? node_uname :
""),
987 (node_uuid?
"\t\t(" :
""), (node_uuid? node_uuid :
""),
988 (node_uuid?
")" :
""));
996 desc =
"!!Non-Startable!! ";
1000 desc =
"(Provisional) ";
1002 crm_trace(
"%s%s%sAction %d: %s %s%s%s%s%s%s",
1003 ((pre_text == NULL)?
"" : pre_text),
1004 ((pre_text == NULL)?
"" :
": "),
1007 (node_uname?
"\ton " :
""), (node_uname? node_uname :
""),
1008 (node_uuid?
"\t\t(" :
""), (node_uuid? node_uuid :
""),
1009 (node_uuid?
")" :
""));
1014 const GList *iter = NULL;
1017 crm_trace(
"\t\t====== Preceding Actions");
1018 for (iter =
action->actions_before; iter != NULL; iter = iter->next) {
1022 crm_trace(
"\t\t====== Subsequent Actions");
1023 for (iter =
action->actions_after; iter != NULL; iter = iter->next) {
1031 g_list_length(
action->actions_before),
1032 g_list_length(
action->actions_after));
1047 char *shutdown_id = NULL;
1077 char *digest = NULL;
1078 xmlNode *args_xml = NULL;
1080 if (op->
params == NULL) {
1092 #define FAKE_TE_ID "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" 1109 const char *caller_version,
int target_rc,
1110 const char *node,
const char *origin)
1115 char *op_id_additional = NULL;
1116 char *local_user_data = NULL;
1117 const char *exit_reason = NULL;
1119 xmlNode *xml_op = NULL;
1120 const char *task = NULL;
1123 crm_trace(
"Creating history XML for %s-interval %s action for %s on %s " 1124 "(DC version: %s, origin: %s)",
1126 ((node == NULL)?
"no node" : node), caller_version, origin);
1171 op_id = strdup(key);
1182 op_id = strdup(key);
1190 if (xml_op == NULL) {
1203 if (magic == NULL) {
1226 "): last=%u change=%u exec=%u queue=%u",
1236 (
long long) op->
t_run);
1256 add_op_digest_to_xml(op, xml_op);
1258 if (op_id_additional) {
1260 op_id = op_id_additional;
1261 op_id_additional = NULL;
1265 if (local_user_data) {
1266 free(local_user_data);
1294 || (
action->rsc->lock_node == NULL) || (
action->node == NULL)
1295 || (
action->node->details !=
action->rsc->lock_node->details)) {
1302 if (
action->node->details->shutdown && (
action->task != NULL)
1312 sort_action_id(gconstpointer a, gconstpointer b)
1345 action->actions_before = g_list_sort(
action->actions_before,
1347 for (item =
action->actions_before; item != NULL; item = next) {
1351 if ((last_input != NULL)
1353 crm_trace(
"Input %s (%d) duplicate skipped for action %s (%d)",
1367 action->actions_before = g_list_delete_link(
action->actions_before,
1388 for (GList *iter =
data_set->
actions; iter != NULL; iter = iter->next) {
1389 char *node_name = NULL;
1393 if (
action->rsc != NULL) {
1401 task = strdup(
"Shutdown");
1404 const char *op = g_hash_table_lookup(
action->meta,
"stonith_action");
1414 pe__node_name(
action->node),
1415 action->node->details->remote_rsc->container->id);
1416 }
else if (
action->node != NULL) {
1420 out->
message(out,
"node-action", task, node_name,
action->reason);
1445 action_in_config(
const pe_resource_t *rsc,
const char *task, guint interval_ms)
1464 task_for_digest(
const char *task, guint interval_ms)
1469 if ((interval_ms == 0)
1494 only_sanitized_changed(
const xmlNode *xml_op,
1498 const char *digest_secure = NULL;
1522 force_restart(
pe_resource_t *rsc,
const char *task, guint interval_ms,
1548 g_list_foreach(rsc->
children, (GFunc) schedule_reload, (gpointer) node);
1568 pe_rsc_trace(rsc,
"%s: preventing agent reload because start pending",
1606 const xmlNode *xml_op)
1608 guint interval_ms = 0;
1609 const char *task = NULL;
1612 CRM_CHECK((rsc != NULL) && (node != NULL) && (xml_op != NULL),
1621 if (interval_ms > 0) {
1622 if (action_in_config(rsc, task, interval_ms)) {
1623 pe_rsc_trace(rsc,
"%s-interval %s for %s on %s is in configuration",
1625 pe__node_name(node));
1630 task, interval_ms, node,
"orphan");
1633 pe_rsc_debug(rsc,
"%s-interval %s for %s on %s is orphaned",
1635 pe__node_name(node));
1640 crm_trace(
"Checking %s-interval %s for %s on %s for configuration changes",
1642 pe__node_name(node));
1643 task = task_for_digest(task, interval_ms);
1646 if (only_sanitized_changed(xml_op, digest_data, rsc->
cluster)) {
1651 "Only 'private' parameters to %s-interval %s for %s " 1652 "on %s changed: %s",
1654 pe__node_name(node),
1660 switch (digest_data->
rc) {
1663 force_restart(rsc, task, interval_ms, node);
1670 if (interval_ms > 0) {
1682 "Device parameters changed (reload)", NULL,
1685 schedule_reload(rsc, node);
1689 "Restarting %s because agent doesn't support reload",
1693 force_restart(rsc, task, interval_ms, node);
1712 rsc_history_as_list(
const xmlNode *rsc_entry,
int *start_index,
int *stop_index)
1718 ops = g_list_prepend(ops, rsc_op);
1740 process_rsc_history(
const xmlNode *rsc_entry,
pe_resource_t *rsc,
1745 int start_index = 0;
1746 GList *sorted_op_list = NULL;
1751 "Skipping configuration check " 1752 "for orphaned clone instance %s",
1756 "Skipping configuration check and scheduling clean-up " 1757 "for orphaned resource %s", rsc->
id);
1768 "Skipping configuration check for %s " 1769 "because no longer active on %s",
1770 rsc->
id, pe__node_name(node));
1774 pe_rsc_trace(rsc,
"Checking for configuration changes for %s on %s",
1775 rsc->
id, pe__node_name(node));
1781 sorted_op_list = rsc_history_as_list(rsc_entry, &start_index, &stop_index);
1782 if (start_index < stop_index) {
1786 for (GList *iter = sorted_op_list; iter != NULL; iter = iter->next) {
1787 xmlNode *rsc_op = (xmlNode *) iter->data;
1788 const char *task = NULL;
1789 guint interval_ms = 0;
1791 if (++offset < start_index) {
1799 if ((interval_ms > 0)
1805 task, interval_ms, node,
"maintenance mode");
1807 }
else if ((interval_ms > 0)
1833 g_list_free(sorted_op_list);
1850 process_node_history(
pe_node_t *node,
const xmlNode *lrm_rscs)
1852 crm_trace(
"Processing node history for %s", pe__node_name(node));
1861 for (GList *iter =
result; iter != NULL; iter = iter->next) {
1865 process_rsc_history(rsc_entry, rsc, node);
1874 #define XPATH_NODE_HISTORY "/" XML_TAG_CIB "/" XML_CIB_TAG_STATUS \ 1875 "/" XML_CIB_TAG_STATE "[@" XML_ATTR_UNAME "='%s']" \ 1876 "/" XML_CIB_TAG_LRM "/" XML_LRM_TAG_RESOURCES 1893 crm_trace(
"Check resource and action configuration for changes");
1899 for (GList *iter =
data_set->
nodes; iter != NULL; iter = iter->next) {
1910 xmlNode *history = NULL;
1916 process_node_history(node, history);
#define CRM_CHECK(expr, failure_action)
#define XML_RSC_OP_LAST_CHANGE
void pcmk__output_actions(pe_working_set_t *data_set)
xmlNode * find_rsc_op_entry(const pe_resource_t *rsc, const char *key)
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
#define pe_flag_stop_action_orphans
#define pe_rsc_debug(rsc, fmt, args...)
G_GNUC_INTERNAL void pcmk__schedule_cleanup(pe_resource_t *rsc, const pe_node_t *node, bool optional)
#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.
xmlNode * pcmk__xe_match(const xmlNode *parent, const char *node_name, const char *attr_n, const char *attr_v)
const char * crm_xml_add_ms(xmlNode *node, const char *name, guint ms)
Create an XML attribute with specified name and unsigned value.
#define XML_ATTR_TRANSITION_MAGIC
bool pcmk__strcase_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
int(* message)(pcmk__output_t *out, const char *message_id,...)
#define clear_action_flag_because(action, flag, reason)
resource_alloc_functions_t * cmds
Internal tracking for transition graph creation.
xmlNode * first_named_child(const xmlNode *parent, const char *name)
void pcmk__update_action_for_orderings(pe_action_t *then, 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.
pe_action_t * find_first_action(const GList *input, const char *uuid, const char *task, const pe_node_t *on_node)
#define CRMD_ACTION_NOTIFY
#define XML_RSC_OP_T_EXEC
const char * crm_meta_value(GHashTable *hash, const char *field)
resource_object_functions_t * fns
#define XML_LRM_TAG_RESOURCE
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
gint sort_op_by_callid(gconstpointer a, gconstpointer b)
const pe_resource_t * pe__const_top_resource(const pe_resource_t *rsc, bool include_bundle)
xmlNode * pcmk__create_history_xml(xmlNode *parent, lrmd_event_data_t *op, const char *caller_version, int target_rc, const char *node, const char *origin)
void pcmk__filter_op_for_digest(xmlNode *param_set)
enum action_tasks text2task(const char *task)
bool pcmk__check_action_config(pe_resource_t *rsc, pe_node_t *node, const xmlNode *xml_op)
#define CRM_LOG_ASSERT(expr)
int(* info)(pcmk__output_t *out, const char *format,...) G_GNUC_PRINTF(2
enum crm_ais_msg_types type
#define XML_RSC_OP_T_QUEUE
bool pe__bundle_needs_remote_name(pe_resource_t *rsc)
#define pe__set_raw_action_flags(action_flags, action_name, flags_to_set)
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
pe_working_set_t * data_set
Cluster that this node is part of.
bool pcmk__action_locks_rsc_to_node(const pe_action_t *action)
#define pe__set_resource_flags(resource, flags_to_set)
void trigger_unfencing(pe_resource_t *rsc, pe_node_t *node, const char *reason, pe_action_t *dependency, pe_working_set_t *data_set)
#define CRMD_ACTION_START
#define XML_LRM_ATTR_TASK_KEY
#define XML_LRM_ATTR_TASK
void pcmk__deduplicate_action_inputs(pe_action_t *action)
uint32_t pcmk__update_ordered_actions(pe_action_t *first, pe_action_t *then, const pe_node_t *node, uint32_t flags, uint32_t filter, uint32_t type, pe_working_set_t *data_set)
pe_node_t *(* location)(const pe_resource_t *, GList **, int)
char * calculate_operation_digest(xmlNode *local_cib, const char *version)
Calculate and return digest of XML operation.
#define crm_warn(fmt, args...)
#define CRMD_ACTION_RELOAD_AGENT
void pe_action_set_reason(pe_action_t *action, const char *reason, bool overwrite)
#define action_type_str(flags)
char * pcmk__notify_key(const char *rsc_id, const char *notify_type, const char *op_type)
int crm_element_value_ms(const xmlNode *data, const char *name, guint *dest)
Retrieve the millisecond value of an XML attribute.
#define action_node_str(a)
#define crm_debug(fmt, args...)
G_GNUC_INTERNAL bool pcmk__node_available(const pe_node_t *node, bool consider_score, bool consider_guest)
#define pe_flag_sanitized
#define pe__clear_order_flags(order_flags, flags_to_clear)
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
bool pe__is_guest_node(const pe_node_t *node)
#define pe_rsc_start_pending
#define pe__clear_action_flags(action, flags_to_clear)
#define crm_trace(fmt, args...)
enum rsc_digest_cmp_val rc
char * digest_secure_calc
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.
pe_action_t * pe__clear_failcount(pe_resource_t *rsc, const pe_node_t *node, const char *reason, pe_working_set_t *data_set)
Schedule a controller operation to clear a fail count.
struct pe_node_shared_s * details
#define crm_log_xml_debug(xml, text)
gboolean order_actions(pe_action_t *lh_action, pe_action_t *rh_action, enum pe_ordering order)
pe_working_set_t * data_set
#define XML_ATTR_TE_NOWAIT
bool pe__rsc_running_on_only(const pe_resource_t *rsc, const pe_node_t *node)
void(* output_actions)(pe_resource_t *rsc)
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Action completed, result is known.
G_GNUC_INTERNAL void pcmk__new_ordering(pe_resource_t *first_rsc, char *first_task, pe_action_t *first_action, pe_resource_t *then_rsc, char *then_task, pe_action_t *then_action, uint32_t flags, pe_working_set_t *data_set)
void pe__add_param_check(const xmlNode *rsc_op, pe_resource_t *rsc, pe_node_t *node, enum pe_check_parameters, pe_working_set_t *data_set)
#define pcmk__clear_updated_flags(au_flags, action, flags_to_clear)
#define XML_LRM_ATTR_MIGRATE_TARGET
#define XML_LRM_ATTR_EXIT_REASON
#define XML_LRM_ATTR_RESTART_DIGEST
void free_xml(xmlNode *child)
enum pe_obj_types variant
bool pcmk__str_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
gboolean xml_has_children(const xmlNode *root)
G_GNUC_INTERNAL GList * pcmk__rscs_matching_id(const char *id, const pe_working_set_t *data_set)
G_GNUC_INTERNAL void pcmk__reschedule_recurring(pe_resource_t *rsc, const char *task, guint interval_ms, pe_node_t *node)
G_GNUC_INTERNAL void pcmk__order_stops_before_shutdown(pe_node_t *node, pe_action_t *shutdown_op)
char * pcmk__op_key(const char *rsc_id, const char *op_type, guint interval_ms)
Generate an operation key (RESOURCE_ACTION_INTERVAL)
#define CRMD_ACTION_RELOAD
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 pcmk__handle_rsc_config_changes(pe_working_set_t *data_set)
#define XML_ATTR_TRANSITION_KEY
#define XML_LRM_ATTR_SECURE_DIGEST
#define action_runnable_str(flags)
enum rsc_role_e(* state)(const pe_resource_t *, gboolean)
#define action_optional_str(flags)
pe_node_t * pe_find_node_id(const GList *node_list, const char *id)
Find a node by ID in a list of nodes.
G_GNUC_INTERNAL bool pcmk__rsc_agent_changed(pe_resource_t *rsc, pe_node_t *node, const xmlNode *rsc_entry, bool active_on_node)
pcmk__action_result_t result
void add_hash_param(GHashTable *hash, const char *name, const char *value)
gboolean did_rsc_op_fail(lrmd_event_data_t *event, int target_rc)
#define XPATH_NODE_HISTORY
#define pcmk__set_updated_flags(au_flags, action, flags_to_set)
#define crm_err(fmt, args...)
void lrmd__set_result(lrmd_event_data_t *event, enum ocf_exitcode rc, int op_status, const char *exit_reason)
void calculate_active_ops(const GList *sorted_op_list, int *start_index, int *stop_index)
This structure contains everything that makes up a single output formatter.
int compare_version(const char *version1, const char *version2)
#define XML_LRM_ATTR_INTERVAL_MS
#define XML_LRM_ATTR_CALLID
#define CRMD_ACTION_MIGRATE
#define pe__clear_resource_flags(resource, flags_to_clear)
#define XML_LRM_ATTR_OPSTATUS
#define XML_ATTR_CRM_VERSION
char * pcmk__transition_key(int transition_id, int action_id, int target_rc, const char *node)
void pcmk__log_action(const char *pre_text, const pe_action_t *action, bool details)
G_GNUC_INTERNAL void pcmk__schedule_cancel(pe_resource_t *rsc, const char *call_id, const char *task, guint interval_ms, const pe_node_t *node, const char *reason)
rsc_role_e
Possible roles that a resource can be in.
enum pe_action_flags flags
#define pe_rsc_maintenance
pe_working_set_t * cluster
const char * pcmk__readable_interval(guint interval_ms)
#define XML_LRM_ATTR_TARGET
#define XML_LRM_TAG_RSC_OP
#define pe_rsc_trace(rsc, fmt, args...)
#define pe__set_order_flags(order_flags, flags_to_set)
uint32_t(* update_ordered_actions)(pe_action_t *first, pe_action_t *then, const pe_node_t *node, uint32_t flags, uint32_t filter, uint32_t type, pe_working_set_t *data_set)
#define XML_LRM_ATTR_MIGRATE_SOURCE
G_GNUC_INTERNAL void pcmk__block_colocation_dependents(pe_action_t *action, pe_working_set_t *data_set)
int pe_get_failcount(const pe_node_t *node, pe_resource_t *rsc, time_t *last_failure, uint32_t flags, const xmlNode *xml_op)
pe_action_t * custom_action(pe_resource_t *rsc, char *key, const char *task, const pe_node_t *on_node, gboolean optional, gboolean foo, pe_working_set_t *data_set)
Create or update an action object.
op_digest_cache_t * rsc_action_digest_cmp(pe_resource_t *rsc, const xmlNode *xml_op, pe_node_t *node, pe_working_set_t *data_set)
pe_action_t * pcmk__new_shutdown_action(pe_node_t *node)
int required_runnable_before
#define CRMD_ACTION_STATUS
xmlNode * crm_next_same_xml(const xmlNode *sibling)
Get next instance of same XML tag.