25#define action_type_str(flags) \
26 (pcmk_is_set((flags), pcmk__action_pseudo)? "pseudo-action" : "action")
28#define action_optional_str(flags) \
29 (pcmk_is_set((flags), pcmk__action_optional)? "optional" : "required")
31#define action_runnable_str(flags) \
32 (pcmk_is_set((flags), pcmk__action_runnable)? "runnable" : "unrunnable")
34#define action_node_str(a) \
35 (((a)->node == NULL)? "no node" : (a)->node->priv->name)
45add_node_to_xml_by_id(
const char *
id, xmlNode *xml)
65 add_node_to_xml_by_id(node->
priv->
id, (xmlNode *) xml);
81 xmlNode *maintenance = NULL;
88 iter != NULL; iter = iter->next) {
91 if (!pcmk__is_pacemaker_remote_node(node)) {
99 if (maintenance != NULL) {
108 crm_trace(
"%s %d nodes in need of maintenance mode update in state",
109 ((maintenance == NULL)?
"Counted" :
"Added"), count);
124 if (add_maintenance_nodes(NULL,
scheduler) != 0) {
151 add_node_to_xml_by_id(
action->node->priv->id, downed);
157 const char *fence = g_hash_table_lookup(
action->meta,
162 add_node_to_xml_by_id(
action->node->priv->id, downed);
164 action->node, add_node_to_xml, downed);
167 }
else if ((
action->rsc != NULL)
178 bool migrating =
false;
180 for (iter =
action->actions_before; iter != NULL; iter = iter->next) {
182 if ((
input->rsc != NULL)
192 add_node_to_xml_by_id(
action->rsc->id, downed);
210 const char *n_type = g_hash_table_lookup(
action->meta,
"notify_type");
211 const char *n_task = g_hash_table_lookup(
action->meta,
236 if (router_node != NULL) {
251 xmlNode *rsc_xml = NULL;
252 const char *attr_list[] = {
264 (
long long)
action->rsc->priv->lock_time);
270 (
const char *)
action->rsc->priv->xml->name);
272 && (
action->rsc->priv->history_id != NULL)) {
281 crm_debug(
"Using orphan clone name %s instead of history ID %s",
287 const char *xml_id = pcmk__xe_id(
action->rsc->priv->xml);
289 crm_debug(
"Using anonymous clone name %s for %s (aka %s)",
290 xml_id,
action->rsc->id,
action->rsc->priv->history_id);
307 if ((
action->rsc->priv->history_id != NULL)
308 && !pcmk__str_eq(xml_id,
action->rsc->priv->history_id,
311 action->rsc->priv->history_id);
321 for (
int lpc = 0; lpc <
PCMK__NELEM(attr_list); lpc++) {
323 g_hash_table_lookup(
action->rsc->priv->meta,
338 xmlNode *args_xml = NULL;
350 if ((rsc != NULL) && (
action->node != NULL)) {
359 }
else if ((rsc != NULL)
394 bool needs_node_info =
true;
395 bool needs_maintenance_info =
false;
396 xmlNode *action_xml = NULL;
426 needs_maintenance_info =
true;
429 needs_node_info =
false;
438 if ((
action->rsc != NULL) && (
action->rsc->priv->history_id != NULL)) {
439 char *clone_key = NULL;
446 clone_key = clone_op_key(
action, interval_ms);
455 if (needs_node_info && (
action->node != NULL)) {
456 add_node_details(
action, action_xml);
458 action->node->priv->name);
471 add_resource_details(
action, action_xml);
475 add_action_attributes(
action, action_xml);
478 if (needs_node_info && (
action->node != NULL)) {
479 add_downed_nodes(action_xml,
action);
482 if (needs_maintenance_info) {
483 add_maintenance_nodes(action_xml,
scheduler);
499 crm_trace(
"Ignoring action %s (%d): unrunnable",
506 crm_trace(
"Ignoring action %s (%d): optional",
518 const char *interval_ms_s;
527 crm_trace(
"Ignoring action %s (%d): for unmanaged resource (%s)",
542 if (
action->node == NULL) {
544 "Skipping action %s (%d) "
545 "because it was not assigned to a node (bug?)",
552 crm_trace(
"Action %s (%d) should be dumped: "
553 "can run on DC instead of %s",
556 }
else if (pcmk__is_guest_or_bundle_node(
action->node)
559 crm_trace(
"Action %s (%d) should be dumped: "
560 "assuming will be runnable on guest %s",
563 }
else if (!
action->node->details->online) {
565 "Skipping action %s (%d) "
566 "because it was scheduled for offline node (bug?)",
571 }
else if (
action->node->details->unclean) {
573 "Skipping action %s (%d) "
574 "because it was scheduled for unclean node (bug?)",
593 return pcmk_any_flags_set(ordering->
flags,
614 if (
input->graphed) {
619 crm_trace(
"Ignoring %s (%d) input %s (%d): "
626 && !ordering_can_change_actions(
input)) {
627 crm_trace(
"Ignoring %s (%d) input %s (%d): "
628 "optional and input unrunnable",
635 crm_trace(
"Ignoring %s (%d) input %s (%d): "
636 "minimum number of instances required but input unrunnable",
643 crm_trace(
"Ignoring %s (%d) input %s (%d): "
644 "input blocked if 'then' unmigratable",
651 crm_trace(
"Ignoring %s (%d) input %s (%d): ordering applies "
652 "only if input is unmigratable, but it is migratable",
660 crm_trace(
"Ignoring %s (%d) input %s (%d): "
661 "optional but stop in migration",
679 if (!pcmk__same_node(input_node, assigned)) {
680 crm_trace(
"Ignoring %s (%d) input %s (%d): "
681 "migration target %s is not same as input node %s",
684 (assigned? assigned->
priv->
name :
"<none>"),
685 (input_node? input_node->
priv->
name :
"<none>"));
690 }
else if (!pcmk__same_node(input_node,
action->node)) {
691 crm_trace(
"Ignoring %s (%d) input %s (%d): "
692 "not on same node (%s vs %s)",
696 (input_node? input_node->
priv->
name :
"<none>"));
701 crm_trace(
"Ignoring %s (%d) input %s (%d): "
711 && !pcmk__same_node(
input->action->node,
action->node)) {
712 crm_trace(
"Ignoring %s (%d) input %s (%d): "
713 "not on same node (%s vs %s)",
716 pcmk__node_name(
action->node),
717 pcmk__node_name(
input->action->node));
722 crm_trace(
"Ignoring %s (%d) input %s (%d): optional",
729 }
else if (
input->action->rsc
734 && pcmk__is_clone(
action->rsc)) {
735 crm_warn(
"Ignoring requirement that %s complete before %s:"
736 " unmanaged failed resources cannot prevent clone shutdown",
741 && !pcmk_any_flags_set(
input->action->flags,
744 && !should_add_action_to_graph(
input->action)) {
745 crm_trace(
"Ignoring %s (%d) input %s (%d): "
752 crm_trace(
"%s (%d) input %s %s (%d) on %s should be dumped: %s %s %#.6x",
777 bool has_loop =
false;
780 crm_trace(
"Breaking tracking loop: %s@%s -> %s@%s (%#.6x)",
782 input->action->node?
input->action->node->priv->name :
"",
794 if (
input->action == init_action) {
795 crm_debug(
"Input loop found in %s@%s ->...-> %s@%s",
805 crm_trace(
"Checking inputs of action %s@%s input %s@%s (%#.6x)"
806 "for graph loop with %s@%s ",
810 input->action->node?
input->action->node->priv->name :
"",
816 for (GList *iter =
input->action->actions_before;
817 iter != NULL; iter = iter->next) {
830 crm_trace(
"No input loop found in %s@%s -> %s@%s (%#.6x)",
832 input->action->node?
input->action->node->priv->name :
"",
852 int synapse_priority = 0;
857 if (
action->rsc != NULL) {
858 synapse_priority =
action->rsc->priv->priority;
860 if (
action->priority > synapse_priority) {
861 synapse_priority =
action->priority;
863 if (synapse_priority > 0) {
886add_action_to_graph(gpointer
data, gpointer user_data)
905 || !should_add_action_to_graph(
action)) {
910 crm_trace(
"Adding action %d (%s%s%s) to graph",
912 ((
action->node == NULL)?
"" :
" on "),
913 ((
action->node == NULL)?
"" :
action->node->priv->name));
921 for (GList *lpc =
action->actions_before; lpc != NULL; lpc = lpc->next) {
927 input->graphed =
true;
933static int transition_id = 0;
944 const char *filename)
948 crm_err(
"Calculated transition %d (with errors)%s%s",
950 (filename == NULL)?
"" :
", saving inputs in ",
951 (filename == NULL)?
"" : filename);
955 crm_warn(
"Calculated transition %d (with warnings)%s%s",
957 (filename == NULL)?
"" :
", saving inputs in ",
958 (filename == NULL)?
"" : filename);
963 (filename == NULL)?
"" :
", saving inputs in ",
964 (filename == NULL)?
"" : filename);
967 crm_notice(
"Configuration errors found during scheduler processing,"
968 " please run \"crm_verify -L\" to identify issues");
988 g_list_foreach(rsc->
priv->
actions, add_action_to_graph,
992 for (iter = rsc->
priv->
children; iter != NULL; iter = iter->next) {
1009 const char *value = NULL;
1010 long long limit = 0LL;
1015 crm_trace(
"Creating transition graph %d", transition_id);
1045 }
else if (limit > 0) {
1050 char *recheck_epoch = NULL;
1055 free(recheck_epoch);
1078 if ((
action->rsc != NULL)
1079 && (
action->node != NULL)
1080 &&
action->node->details->shutdown
1082 && !pcmk_any_flags_set(
action->flags,
1096 crm_crit(
"Cannot %s %s because of %s:%s%s (%s)",
1097 action->node->details->unclean?
"fence" :
"shut down",
1099 (managed?
" blocked" :
" unmanaged"),
1100 (failed?
" failed" :
""),
action->uuid);
@ pcmk__ar_if_first_unmigratable
Relation applies only if 'first' cannot be part of a live migration.
@ pcmk__ar_then_implies_first_graphed
If 'then' is required, 'first' must be added to the transition graph.
@ pcmk__ar_min_runnable
'then' action is runnable if certain number of 'first' instances are
@ pcmk__ar_none
No relation (compare with equality rather than bit set)
@ pcmk__ar_first_implies_then_graphed
If 'first' is required and runnable, 'then' must be in graph.
@ pcmk__ar_if_required_on_same_node
Ordering applies only if 'first' is required and on same node as 'then'.
@ pcmk__ar_unmigratable_then_blocks
@ pcmk__ar_ordered
Actions are ordered (optionally, if no other flags are set)
@ pcmk__ar_if_on_same_node_or_target
Actions are ordered if on same node (or migration target for migrate_to)
#define PCMK_ACTION_MAINTENANCE_NODES
#define PCMK_ACTION_LRM_DELETE
#define PCMK_ACTION_CLEAR_FAILCOUNT
#define PCMK_ACTION_MIGRATE_FROM
#define PCMK_ACTION_MIGRATE_TO
#define PCMK_ACTION_MONITOR
#define PCMK_ACTION_STONITH
#define PCMK_ACTION_DO_SHUTDOWN
#define PCMK_ACTION_NOTIFY
@ pcmk__action_inputs_deduplicated
@ pcmk__action_always_in_graph
@ pcmk__action_added_to_graph
@ pcmk__action_migratable
@ pcmk__action_detect_loop
char * pcmk__notify_key(const char *rsc_id, const char *notify_type, const char *op_type)
#define pcmk__set_action_flags(action, flags_to_set)
char * pcmk__op_key(const char *rsc_id, const char *op_type, guint interval_ms)
Generate an operation key (RESOURCE_ACTION_INTERVAL)
bool pcmk__is_fencing_action(const char *action)
#define pcmk__clear_action_flags(action, flags_to_clear)
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
GHashTable * pe_rsc_params(pcmk_resource_t *rsc, const pcmk_node_t *node, pcmk_scheduler_t *scheduler)
Get a table of resource parameters.
G_GNUC_INTERNAL void pcmk__substitute_remote_addr(pcmk_resource_t *rsc, GHashTable *params)
G_GNUC_INTERNAL void pcmk__log_action(const char *pre_text, const pcmk_action_t *action, bool details)
G_GNUC_INTERNAL pcmk_node_t * pcmk__connection_host_for_action(const pcmk_action_t *action)
G_GNUC_INTERNAL bool pcmk__action_locks_rsc_to_node(const pcmk_action_t *action)
G_GNUC_INTERNAL void pcmk__deduplicate_action_inputs(pcmk_action_t *action)
G_GNUC_INTERNAL void pcmk__add_guest_meta_to_xml(xmlNode *args_xml, const pcmk_action_t *action)
Add special guest node meta-attributes to XML.
#define crm_warn(fmt, args...)
#define crm_crit(fmt, args...)
#define crm_notice(fmt, args...)
#define CRM_CHECK(expr, failure_action)
#define crm_debug(fmt, args...)
#define crm_err(fmt, args...)
#define crm_log_xml_trace(xml, text)
#define crm_trace(fmt, args...)
bool pcmk__config_has_error
bool pcmk__config_has_warning
pcmk_scheduler_t * scheduler
@ pcmk__node_remote_maint
@ pcmk__node_remote_reset
void hash2metafield(gpointer key, gpointer value, gpointer user_data)
Set XML attribute based on hash table entry, as meta-attribute name.
void hash2field(gpointer key, gpointer value, gpointer user_data)
Set XML attribute based on hash table entry.
void hash2smartfield(gpointer key, gpointer value, gpointer user_data)
Safely add hash table entry to XML as attribute or name-value pair.
#define PCMK_META_INTERVAL
#define PCMK_OPT_BATCH_LIMIT
#define PCMK_OPT_CLUSTER_DELAY
#define PCMK_OPT_MIGRATION_LIMIT
#define PCMK_OPT_STONITH_TIMEOUT
#define PCMK_VALUE_INFINITY
#define PCMK_OPT_SHUTDOWN_LOCK
const char * pcmk__cluster_option(GHashTable *options, const char *name)
#define PCMK__META_ON_NODE_UUID
#define PCMK__META_ON_NODE
#define PCMK__META_STONITH_ACTION
#define action_type_str(flags)
bool pcmk__graph_has_loop(const pcmk_action_t *init_action, const pcmk_action_t *action, pcmk__related_action_t *input)
void pcmk__create_graph(pcmk_scheduler_t *scheduler)
#define action_node_str(a)
#define action_runnable_str(flags)
void pcmk__log_transition_summary(const pcmk_scheduler_t *scheduler, const char *filename)
void pcmk__add_rsc_actions_to_graph(pcmk_resource_t *rsc)
#define action_optional_str(flags)
pcmk_action_t * get_pseudo_op(const char *name, pcmk_scheduler_t *scheduler)
void pe_foreach_guest_node(const pcmk_scheduler_t *scheduler, const pcmk_node_t *host, void(*helper)(const pcmk_node_t *, void *), void *user_data)
@ pcmk__rsc_is_remote_connection
@ pcmk__rsc_variant_primitive
Primitive resource.
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code.
#define pcmk__assert(expr)
@ pcmk_no_quorum_ignore
Act as if partition still holds quorum.
#define pcmk__sched_err(scheduler, fmt...)
#define pcmk__rsc_trace(rsc, fmt, args...)
@ pcmk__sched_start_failure_fatal
@ pcmk__sched_processing_warning
@ pcmk__sched_processing_error
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
void pcmk__insert_dup(GHashTable *table, const char *name, const char *value)
int pcmk__scan_ll(const char *text, long long *result, long long default_value)
bool pcmk__strcase_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
bool pcmk__ends_with(const char *s, const char *match)
int pcmk__guint_from_hash(GHashTable *table, const char *key, guint default_val, guint *result)
bool pcmk__str_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
void(* add_actions_to_graph)(pcmk_resource_t *rsc)
pcmk_scheduler_t * scheduler
enum pcmk__rsc_variant variant
const pcmk__assignment_methods_t * cmds
pcmk__resource_private_t * priv
pcmk__scheduler_private_t * priv
enum pe_quorum_policy no_quorum_policy
pcmk__node_private_t * priv
struct pcmk__node_details * details
Wrappers for and extensions to libxml2.
const char * crm_xml_add_int(xmlNode *node, const char *name, int value)
Create an XML attribute with specified name and integer value.
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.
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
xmlNode * pcmk__xe_create(xmlNode *parent, const char *name)
void pcmk__xe_sort_attrs(xmlNode *xml)
#define PCMK_XA_OPERATION
#define PCMK_XA_CRM_FEATURE_SET
#define PCMK__XA_PRIORITY
#define PCMK__XE_TRANSITION_GRAPH
#define PCMK__XE_CRM_EVENT
#define PCMK__XA_FAILED_STOP_OFFSET
#define PCMK__XE_PSEUDO_EVENT
#define PCMK__XE_ACTION_SET
#define PCMK__XA_ROUTER_NODE
#define PCMK__XA_FAILED_START_OFFSET
#define PCMK__XA_OPERATION_KEY
#define PCMK__XE_ATTRIBUTES
#define PCMK__XE_MAINTENANCE
#define PCMK__XA_NODE_IN_MAINTENANCE