12 #include <sys/param.h> 33 free_graph_action(gpointer user_data)
39 g_source_remove(
action->timer);
41 if (
action->params != NULL) {
42 g_hash_table_destroy(
action->params);
55 free_graph_synapse(gpointer user_data)
59 g_list_free_full(synapse->
actions, free_graph_action);
60 g_list_free_full(synapse->
inputs, free_graph_action);
74 g_list_free_full(graph->
synapses, free_graph_synapse);
114 for (GList *lpc = synapse->
inputs; lpc != NULL; lpc = lpc->next) {
117 if (prereq->
id == action_id) {
118 crm_trace(
"Confirming input %d of synapse %d",
119 action_id, synapse->
id);
124 crm_trace(
"Synapse %d still not ready after action %d",
125 synapse->
id, action_id);
129 crm_trace(
"Synapse %d is now ready to execute", synapse->
id);
143 bool all_confirmed =
true;
145 for (GList *lpc = synapse->
actions; lpc != NULL; lpc = lpc->next) {
148 if (
action->id == action_id) {
149 crm_trace(
"Confirmed action %d of synapse %d",
150 action_id, synapse->
id);
153 }
else if (all_confirmed &&
155 all_confirmed =
false;
156 crm_trace(
"Synapse %d still not confirmed after action %d",
157 synapse->
id, action_id);
178 for (GList *lpc = graph->
synapses; lpc != NULL; lpc = lpc->next) {
181 if (pcmk_any_flags_set(synapse->
flags,
186 update_synapse_confirmed(synapse,
action->id);
190 update_synapse_ready(synapse,
action->id);
218 crm_debug(
"Setting custom functions for executing transition graphs");
237 for (lpc = synapse->
inputs; lpc != NULL; lpc = lpc->next) {
241 crm_trace(
"Input %d for synapse %d not yet confirmed",
242 prereq->
id, synapse->
id);
247 crm_trace(
"Input %d for synapse %d confirmed but failed",
248 prereq->
id, synapse->
id);
254 crm_trace(
"Synapse %d is ready to execute", synapse->
id);
259 for (lpc = synapse->
actions; lpc != NULL; lpc = lpc->next) {
266 crm_trace(
"Skipping synapse %d: priority %d is less than " 272 }
else if (graph_fns->
allowed && !(graph_fns->
allowed(graph, a))) {
273 crm_trace(
"Deferring synapse %d: not allowed", synapse->
id);
293 const char *
id = pcmk__xe_id(
action->xml);
312 crm_trace(
"Executing fencing action %d (%s)",
340 for (GList *lpc = synapse->
actions; lpc != NULL; lpc = lpc->next) {
342 int rc = initiate_action(graph,
action);
373 static int fail = -1;
379 && (fail_ll > 0LL) && (fail_ll <= INT_MAX)) {
380 fail = (int) fail_ll;
387 crm_err(
"Dummy event handler: pretending action %d failed",
action->id);
417 int log_level = LOG_DEBUG;
419 const char *status =
"In progress";
421 if (graph_fns == NULL) {
422 graph_fns = &default_fns;
435 for (lpc = graph->
synapses; lpc != NULL; lpc = lpc->next) {
446 crm_trace(
"Executing graph %d (%d synapses already completed, %d pending)",
450 for (lpc = graph->
synapses; lpc != NULL; lpc = lpc->next) {
456 crm_debug(
"Throttling graph execution: batch limit (%d) reached",
464 }
else if (pcmk_any_flags_set(synapse->
flags,
469 }
else if (should_fire_synapse(graph, synapse)) {
471 if (fire_synapse(graph, synapse) !=
pcmk_rc_ok) {
472 crm_err(
"Synapse %d failed to fire", synapse->
id);
493 log_level = LOG_WARNING;
495 status =
"Terminated";
497 }
else if (graph->
skipped != 0) {
498 log_level = LOG_NOTICE;
503 log_level = LOG_NOTICE;
508 }
else if (graph->
fired == 0) {
513 "Transition %d (Complete=%d, Pending=%d," 514 " Fired=%d, Skipped=%d, Incomplete=%d, Source=%s): %s",
540 const char *value = pcmk__xe_id(xml_action);
559 crm_err(
"Ignoring transition graph action of unknown type '%s' (bug?)",
567 crm_perror(LOG_CRIT,
"Cannot unpack transition graph action");
576 action->type = action_type;
590 action->timeout += start_delay;
613 unpack_synapse(
pcmk__graph_t *new_graph,
const xmlNode *xml_synapse)
615 const char *value = NULL;
616 xmlNode *action_set = NULL;
619 crm_trace(
"Unpacking synapse %s", pcmk__xe_id(xml_synapse));
622 if (new_synapse == NULL) {
632 free_graph_synapse((gpointer) new_synapse);
return NULL);
636 crm_trace(
"Unpacking synapse %s action sets",
651 if (new_action == NULL) {
655 crm_trace(
"Adding action %d to synapse %d",
656 new_action->
id, new_synapse->id);
658 new_synapse->actions = g_list_append(new_synapse->actions,
663 crm_trace(
"Unpacking synapse %s inputs", pcmk__xe_id(xml_synapse));
681 if (new_input == NULL) {
685 crm_trace(
"Adding input %d to synapse %d",
686 new_input->
id, new_synapse->id);
688 new_synapse->inputs = g_list_append(new_synapse->inputs,
728 if (new_graph == NULL) {
732 new_graph->
source = strdup(pcmk__s(reference,
"unknown"));
733 if (new_graph->
source == NULL) {
741 if (xml_graph != NULL) {
792 if (new_synapse != NULL) {
798 crm_debug(
"Unpacked transition %d from %s: %d actions in %d synapses",
825 int status,
int rc,
const char *exit_reason)
829 const char *
name = NULL;
830 const char *value = NULL;
831 xmlNode *action_resource = NULL;
845 op->
t_run = time(NULL);
849 g_hash_table_iter_init(&iter,
action->params);
850 while (g_hash_table_iter_next(&iter, (
void **)&
name, (
void **)&value)) {
860 crm_debug(
"Got call_id=%d for %s", tmp, pcmk__xe_id(resource));
#define PCMK__XE_ACTION_SET
#define CRM_CHECK(expr, failure_action)
#define PCMK__XA_PRIORITY
xmlNode * pcmk__xml_copy(xmlNode *parent, xmlNode *src)
xmlNode * pcmk__xe_first_child(const xmlNode *parent, const char *node_name, const char *attr_n, const char *attr_v)
#define pcmk__set_synapse_flags(synapse, flags_to_set)
int pcmk__scan_min_int(const char *text, int *result, int minimum)
lrmd_event_data_t * pcmk__event_from_graph_action(const xmlNode *resource, const pcmk__graph_action_t *action, int status, int rc, const char *exit_reason)
#define PCMK_XE_PRIMITIVE
void pcmk__free_graph(pcmk__graph_t *graph)
int crm_element_value_epoch(const xmlNode *xml, const char *name, time_t *dest)
Retrieve the seconds-since-epoch value of an XML attribute.
char * failed_start_offset
Failcount after one failed start action.
#define PCMK__XE_PSEUDO_EVENT
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code.
enum pcmk__graph_action_type type
int(* pseudo)(pcmk__graph_t *graph, pcmk__graph_action_t *action)
#define PCMK_XA_OPERATION
#define PCMK__XA_FAILED_STOP_OFFSET
int(* fence)(pcmk__graph_t *graph, pcmk__graph_action_t *action)
void pcmk__xml_free(xmlNode *xml)
void pcmk__update_graph(pcmk__graph_t *graph, const pcmk__graph_action_t *action)
int pcmk__scan_ll(const char *text, long long *result, long long default_value)
#define crm_warn(fmt, args...)
GHashTable * xml2list(const xmlNode *parent)
Retrieve XML attributes as a hash table.
#define PCMK_OPT_BATCH_LIMIT
int pcmk__guint_from_hash(GHashTable *table, const char *key, guint default_val, guint *result)
char * failed_stop_offset
Failcount after one failed stop action.
#define crm_debug(fmt, args...)
enum pcmk__graph_next completion_action
int pcmk_parse_interval_spec(const char *input, guint *result_ms)
Parse milliseconds from a Pacemaker interval specification.
char * crm_element_value_copy(const xmlNode *data, const char *name)
Retrieve a copy of the value of an XML attribute.
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
#define PCMK_META_START_DELAY
#define crm_trace(fmt, args...)
#define do_crm_log(level, fmt, args...)
Log a message.
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
#define PCMK__XA_FAILED_START_OFFSET
time_t recheck_by
Time (from epoch) by which the controller should re-run the scheduler.
pcmk__graph_t * pcmk__unpack_graph(const xmlNode *xml_graph, const char *reference)
Wrappers for and extensions to libxml2.
enum pcmk__graph_status pcmk__execute_graph(pcmk__graph_t *graph)
#define crm_log_xml_warn(xml, text)
#define PCMK_ACTION_STONITH
#define PCMK_OPT_CLUSTER_DELAY
#define pcmk__clear_synapse_flags(synapse, flags_to_clear)
bool(* allowed)(pcmk__graph_t *graph, pcmk__graph_action_t *action)
void pcmk__set_graph_functions(pcmk__graph_functions_t *fns)
#define PCMK_META_TIMEOUT
xmlNode * pcmk__xe_next(const xmlNode *node, const char *element_name)
#define pcmk__assert(expr)
#define PCMK_OPT_STONITH_TIMEOUT
#define PCMK_META_INTERVAL
GHashTable * pcmk__strkey_table(GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
#define crm_perror(level, fmt, args...)
Send a system error message to both the log and stderr.
int(* rsc)(pcmk__graph_t *graph, pcmk__graph_action_t *action)
#define PCMK__XE_CRM_EVENT
#define crm_err(fmt, args...)
#define pcmk__set_graph_action_flags(action, flags_to_set)
void lrmd__set_result(lrmd_event_data_t *event, enum ocf_exitcode rc, int op_status, const char *exit_reason)
int crm_element_value_int(const xmlNode *data, const char *name, int *dest)
Retrieve the integer value of an XML attribute.
#define PCMK_OPT_MIGRATION_LIMIT
int(* cluster)(pcmk__graph_t *graph, pcmk__graph_action_t *action)
#define crm_log_xml_trace(xml, text)
const char * crm_meta_value(GHashTable *hash, const char *field)
Get the value of a meta-attribute.
lrmd_event_data_t * lrmd_new_event(const char *rsc_id, const char *task, guint interval_ms)
Create a new lrmd_event_data_t object.
void pcmk__insert_dup(GHashTable *table, const char *name, const char *value)
#define PCMK_SCORE_INFINITY
Integer score to use to represent "infinity".