12 #include <sys/param.h> 26 #define action_type_str(flags) \ 27 (pcmk_is_set((flags), pcmk_action_pseudo)? "pseudo-action" : "action") 29 #define action_optional_str(flags) \ 30 (pcmk_is_set((flags), pcmk_action_optional)? "optional" : "required") 32 #define action_runnable_str(flags) \ 33 (pcmk_is_set((flags), pcmk_action_runnable)? "runnable" : "unrunnable") 35 #define action_node_str(a) \ 36 (((a)->node == NULL)? "no node" : (a)->node->details->uname) 46 add_node_to_xml_by_id(
const char *
id, xmlNode *xml)
66 add_node_to_xml_by_id(node->
details->
id, (xmlNode *) xml);
82 xmlNode *maintenance = NULL;
89 iter != NULL; iter = iter->next) {
95 if (maintenance != NULL) {
104 crm_trace(
"%s %d nodes in need of maintenance mode update in state",
105 ((maintenance == NULL)?
"Counted" :
"Added"), count);
120 if (add_maintenance_nodes(NULL,
scheduler) != 0) {
147 add_node_to_xml_by_id(
action->node->details->id, downed);
153 const char *fence = g_hash_table_lookup(
action->meta,
"stonith_action");
157 add_node_to_xml_by_id(
action->node->details->id, downed);
159 action->node, add_node_to_xml, downed);
171 bool migrating =
false;
173 for (iter =
action->actions_before; iter != NULL; iter = iter->next) {
175 if ((
input->rsc != NULL)
185 add_node_to_xml_by_id(
action->rsc->id, downed);
203 const char *n_type = g_hash_table_lookup(
action->meta,
"notify_type");
204 const char *n_task = g_hash_table_lookup(
action->meta,
210 }
else if (
action->cancel_task != NULL) {
232 if (router_node != NULL) {
247 xmlNode *rsc_xml = NULL;
248 const char *attr_list[] = {
259 (
long long)
action->rsc->lock_time);
265 (
const char *)
action->rsc->xml->name);
267 && (
action->rsc->clone_name != NULL)) {
276 crm_debug(
"Using orphan clone name %s instead of %s",
282 const char *xml_id =
ID(
action->rsc->xml);
284 crm_debug(
"Using anonymous clone name %s for %s (aka %s)",
301 if ((
action->rsc->clone_name != NULL)
302 && !pcmk__str_eq(xml_id,
action->rsc->clone_name,
314 for (
int lpc = 0; lpc <
PCMK__NELEM(attr_list); lpc++) {
316 g_hash_table_lookup(
action->rsc->meta, attr_list[lpc]));
330 xmlNode *args_xml = NULL;
350 }
else if ((
action->rsc != NULL)
359 if (
action->rsc != NULL) {
370 && (
action->node != NULL)) {
398 bool needs_node_info =
true;
399 bool needs_maintenance_info =
false;
400 xmlNode *action_xml = NULL;
430 needs_maintenance_info =
true;
433 needs_node_info =
false;
442 if ((
action->rsc != NULL) && (
action->rsc->clone_name != NULL)) {
443 char *clone_key = NULL;
450 clone_key = clone_op_key(
action, interval_ms);
459 if (needs_node_info && (
action->node != NULL)) {
460 add_node_details(
action, action_xml);
462 strdup(
action->node->details->uname));
464 strdup(
action->node->details->id));
475 add_resource_details(
action, action_xml);
479 add_action_attributes(
action, action_xml);
482 if (needs_node_info && (
action->node != NULL)) {
483 add_downed_nodes(action_xml,
action);
486 if (needs_maintenance_info) {
487 add_maintenance_nodes(action_xml,
scheduler);
503 crm_trace(
"Ignoring action %s (%d): unrunnable",
510 crm_trace(
"Ignoring action %s (%d): optional",
522 const char *interval_ms_s;
529 interval_ms_s = g_hash_table_lookup(
action->meta,
532 crm_trace(
"Ignoring action %s (%d): for unmanaged resource (%s)",
547 if (
action->node == NULL) {
548 pe_err(
"Skipping action %s (%d) " 549 "because it was not assigned to a node (bug?)",
556 crm_trace(
"Action %s (%d) should be dumped: " 557 "can run on DC instead of %s",
561 && !
action->node->details->remote_requires_reset) {
562 crm_trace(
"Action %s (%d) should be dumped: " 563 "assuming will be runnable on guest %s",
566 }
else if (!
action->node->details->online) {
567 pe_err(
"Skipping action %s (%d) " 568 "because it was scheduled for offline node (bug?)",
573 }
else if (
action->node->details->unclean) {
574 pe_err(
"Skipping action %s (%d) " 575 "because it was scheduled for unclean node (bug?)",
594 return pcmk_any_flags_set(ordering->
type,
620 crm_trace(
"Ignoring %s (%d) input %s (%d): " 627 && !ordering_can_change_actions(
input)) {
628 crm_trace(
"Ignoring %s (%d) input %s (%d): " 629 "optional and input unrunnable",
636 crm_trace(
"Ignoring %s (%d) input %s (%d): " 637 "minimum number of instances required but input unrunnable",
644 crm_trace(
"Ignoring %s (%d) input %s (%d): " 645 "input blocked if 'then' unmigratable",
652 crm_trace(
"Ignoring %s (%d) input %s (%d): ordering applies " 653 "only if input is unmigratable, but it is migratable",
661 crm_trace(
"Ignoring %s (%d) input %s (%d): " 662 "optional but stop in migration",
680 if (!pe__same_node(input_node, assigned)) {
681 crm_trace(
"Ignoring %s (%d) input %s (%d): " 682 "migration target %s is not same as input node %s",
691 }
else if (!pe__same_node(input_node,
action->node)) {
692 crm_trace(
"Ignoring %s (%d) input %s (%d): " 693 "not on same node (%s vs %s)",
696 (
action->node?
action->node->details->uname :
"<none>"),
702 crm_trace(
"Ignoring %s (%d) input %s (%d): " 712 && !pe__same_node(
input->action->node,
action->node)) {
713 crm_trace(
"Ignoring %s (%d) input %s (%d): " 714 "not on same node (%s vs %s)",
717 pe__node_name(
action->node),
718 pe__node_name(
input->action->node));
723 crm_trace(
"Ignoring %s (%d) input %s (%d): optional",
730 }
else if (
input->action->rsc
736 crm_warn(
"Ignoring requirement that %s complete before %s:" 737 " unmanaged failed resources cannot prevent clone shutdown",
742 && !pcmk_any_flags_set(
input->action->flags,
745 && !should_add_action_to_graph(
input->action)) {
746 crm_trace(
"Ignoring %s (%d) input %s (%d): " 753 crm_trace(
"%s (%d) input %s %s (%d) on %s should be dumped: %s %s %#.6x",
778 bool has_loop =
false;
781 crm_trace(
"Breaking tracking loop: %s@%s -> %s@%s (%#.6x)",
783 input->action->node?
input->action->node->details->uname :
"",
795 if (
input->action == init_action) {
796 crm_debug(
"Input loop found in %s@%s ->...-> %s@%s",
806 crm_trace(
"Checking inputs of action %s@%s input %s@%s (%#.6x)" 807 "for graph loop with %s@%s ",
811 input->action->node?
input->action->node->details->uname :
"",
817 for (GList *iter =
input->action->actions_before;
818 iter != NULL; iter = iter->next) {
831 crm_trace(
"No input loop found in %s@%s -> %s@%s (%#.6x)",
833 input->action->node?
input->action->node->details->uname :
"",
853 int synapse_priority = 0;
859 if (
action->rsc != NULL) {
860 synapse_priority =
action->rsc->priority;
862 if (
action->priority > synapse_priority) {
863 synapse_priority =
action->priority;
865 if (synapse_priority > 0) {
888 add_action_to_graph(gpointer
data, gpointer user_data)
907 || !should_add_action_to_graph(
action)) {
912 crm_trace(
"Adding action %d (%s%s%s) to graph",
914 ((
action->node == NULL)?
"" :
" on "),
915 ((
action->node == NULL)?
"" :
action->node->details->uname));
923 for (GList *lpc =
action->actions_before; lpc != NULL; lpc = lpc->next) {
935 static int transition_id = -1;
947 crm_err(
"Calculated transition %d (with errors)%s%s",
949 (filename == NULL)?
"" :
", saving inputs in ",
950 (filename == NULL)?
"" : filename);
953 crm_warn(
"Calculated transition %d (with warnings)%s%s",
955 (filename == NULL)?
"" :
", saving inputs in ",
956 (filename == NULL)?
"" : filename);
961 (filename == NULL)?
"" :
", saving inputs in ",
962 (filename == NULL)?
"" : filename);
965 crm_notice(
"Configuration errors found during scheduler processing," 966 " please run \"crm_verify -L\" to identify issues");
988 for (iter = rsc->
children; iter != NULL; iter = iter->next) {
1005 const char *value = NULL;
1006 long long limit = 0LL;
1009 crm_trace(
"Creating transition graph %d", transition_id);
1038 char *recheck_epoch = NULL;
1043 free(recheck_epoch);
1066 if ((
action->rsc != NULL)
1067 && (
action->node != NULL)
1068 &&
action->node->details->shutdown
1070 && !pcmk_any_flags_set(
action->flags,
1084 crm_crit(
"Cannot %s %s because of %s:%s%s (%s)",
1085 action->node->details->unclean?
"fence" :
"shut down",
1087 (managed?
" blocked" :
" unmanaged"),
1088 (failed?
" failed" :
""),
action->uuid);
pcmk_assignment_methods_t * cmds
Resource assignment methods.
#define CRM_CHECK(expr, failure_action)
enum pe_quorum_policy no_quorum_policy
Response to loss of quorum.
#define crm_notice(fmt, args...)
bool pe__is_guest_or_remote_node(const pcmk_node_t *node)
pcmk_scheduler_t * cluster
Cluster that resource is part of.
Actions are ordered if on same node (or migration target for migrate_to)
#define XML_CONFIG_ATTR_SHUTDOWN_LOCK
#define crm_crit(fmt, args...)
pcmk_action_t * get_pseudo_op(const char *name, pcmk_scheduler_t *scheduler)
Whether action should not be executed.
#define pe__set_action_flags(action, flags_to_set)
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)
Whether action has already been processed by a recursive procedure.
Whether partition has quorum (via have-quorum property)
GList * children
Resource's child resources, if any.
const char * crm_xml_add_int(xmlNode *node, const char *name, int value)
Create an XML attribute with specified name and integer value.
Implementation of pcmk_action_t.
#define PCMK_ACTION_MONITOR
Whether resource, its node, or entire cluster is in maintenance mode.
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
void pcmk__log_transition_summary(const char *filename)
#define XML_GRAPH_TAG_RSC_OP
#define PCMK_ACTION_MIGRATE_TO
#define PCMK_ACTION_DO_SHUTDOWN
#define XML_NODE_IS_MAINTENANCE
GList * actions
Scheduled actions.
#define CRM_LOG_ASSERT(expr)
const char * pe_pref(GHashTable *options, const char *name)
#define XML_GRAPH_TAG_CRM_EVENT
#define PCMK_ACTION_CLEAR_FAILCOUNT
G_GNUC_INTERNAL pcmk_node_t * pcmk__connection_host_for_action(const pcmk_action_t *action)
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
Implementation of pcmk_scheduler_t.
void(* add_actions_to_graph)(pcmk_resource_t *rsc)
GList * resources
Resources in cluster.
#define XML_GRAPH_TAG_PSEUDO_EVENT
GList * nodes
Nodes in cluster.
#define XML_CIB_ATTR_PRIORITY
gboolean remote_maintenance
Whether action's inputs have been de-duplicated yet.
#define PCMK_ACTION_MAINTENANCE_NODES
#define XML_LRM_ATTR_TASK_KEY
#define XML_LRM_ATTR_TASK
gboolean crm_config_error
int pcmk__scan_ll(const char *text, long long *result, long long default_value)
#define crm_warn(fmt, args...)
pcmk_node_t * node
Node to execute action on, if any.
int pcmk__guint_from_hash(GHashTable *table, const char *key, guint default_val, guint *result)
Implementation of pcmk_resource_t.
#define crm_debug(fmt, args...)
Actions are ordered (optionally, if no other flags are set)
G_GNUC_INTERNAL void pcmk__log_action(const char *pre_text, const pcmk_action_t *action, bool details)
Whether resource is considered failed.
#define pe__clear_action_flags(action, flags_to_clear)
#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.
struct pe_node_shared_s * details
Basic node information.
#define XML_AGENT_ATTR_PROVIDER
const char * uname
Node name in cluster.
Wrappers for and extensions to libxml2.
GHashTable * config_hash
Cluster properties.
xmlNode * create_xml_node(xmlNode *parent, const char *name)
time_t recheck_by
Hint to controller when to reschedule.
Ordering applies only if 'first' is required and on same node as 'then'.
#define PCMK_ACTION_STONITH
#define XML_LRM_ATTR_ROUTER_NODE
char * pcmk__op_key(const char *rsc_id, const char *op_type, guint interval_ms)
Generate an operation key (RESOURCE_ACTION_INTERVAL)
void free_xml(xmlNode *child)
Implementation of pcmk_node_t.
bool pcmk__str_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
const char * id
Node ID at the cluster layer.
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 pcmk__add_rsc_actions_to_graph(pcmk_resource_t *rsc)
#define PCMK_ACTION_LRM_DELETE
bool pe__is_guest_node(const pcmk_node_t *node)
bool pcmk__graph_has_loop(const pcmk_action_t *init_action, const pcmk_action_t *action, pcmk__related_action_t *input)
char * pcmk__notify_key(const char *rsc_id, const char *notify_type, const char *op_type)
void pcmk__create_graph(pcmk_scheduler_t *scheduler)
G_GNUC_INTERNAL bool pcmk__action_locks_rsc_to_node(const pcmk_action_t *action)
If 'then' is required, 'first' must be added to the transition graph.
bool pcmk__is_fencing_action(const char *action)
Whether action is runnable.
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)
#define crm_err(fmt, args...)
pcmk_scheduler_t * scheduler
Whether action does not require invoking an agent.
G_GNUC_INTERNAL void pcmk__substitute_remote_addr(pcmk_resource_t *rsc, GHashTable *params)
If 'first' is required and runnable, 'then' must be in graph.
Relation applies only if 'first' cannot be part of a live migration.
Whether action should be added to transition graph even if optional.
#define PCMK_ACTION_MIGRATE_FROM
G_GNUC_INTERNAL void pcmk__deduplicate_action_inputs(pcmk_action_t *action)
#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 XML_ATTR_CRM_VERSION
G_GNUC_INTERNAL void pcmk__add_bundle_meta_to_xml(xmlNode *args_xml, const pcmk_action_t *action)
Add special bundle meta-attributes to XML.
gboolean maintenance
Whether in maintenance mode.
Whether action is allowed to be part of a live migration.
#define crm_log_xml_trace(xml, text)
Whether action has been added to transition graph.
#define XML_LRM_ATTR_TARGET
#define action_optional_str(flags)
#define pe_rsc_trace(rsc, fmt, args...)
#define action_node_str(a)
GHashTable * pe_rsc_params(pcmk_resource_t *rsc, const pcmk_node_t *node, pcmk_scheduler_t *scheduler)
Get a table of resource parameters.
unsigned long long flags
Group of enum pcmk_scheduler_flags.
gboolean was_processing_error
Whether action can be executed on DC rather than own node.
#define action_runnable_str(flags)
Whether resource is managed.
gboolean was_processing_warning
'then' action is runnable if certain number of 'first' instances are
Whether resource has been removed from the configuration.
Whether resource is not an anonymous clone instance.
#define PCMK_ACTION_NOTIFY
No relation (compare with equality rather than bit set)
int num_synapse
Number of transition graph synapses.
#define XML_AGENT_ATTR_CLASS
xmlNode * graph
Transition graph.
char * id
Resource ID in configuration.