12 #include <sys/param.h> 51 for (GList *lpc = synapse->
inputs; lpc != NULL; lpc = lpc->next) {
54 if (prereq->
id == action_id) {
55 crm_trace(
"Confirming input %d of synapse %d",
56 action_id, synapse->
id);
61 crm_trace(
"Synapse %d still not ready after action %d",
62 synapse->
id, action_id);
66 crm_trace(
"Synapse %d is now ready to execute", synapse->
id);
80 bool all_confirmed =
true;
82 for (GList *lpc = synapse->
actions; lpc != NULL; lpc = lpc->next) {
85 if (
action->id == action_id) {
86 crm_trace(
"Confirmed action %d of synapse %d",
87 action_id, synapse->
id);
91 all_confirmed =
false;
92 crm_trace(
"Synapse %d still not confirmed after action %d",
93 synapse->
id, action_id);
113 for (GList *lpc = graph->
synapses; lpc != NULL; lpc = lpc->next) {
120 update_synapse_confirmed(synapse,
action->id);
123 update_synapse_ready(synapse,
action->id);
148 crm_debug(
"Setting custom functions for executing transition graphs");
173 for (lpc = synapse->
inputs; lpc != NULL; lpc = lpc->next) {
177 crm_trace(
"Input %d for synapse %d not yet confirmed",
178 prereq->
id, synapse->
id);
183 crm_trace(
"Input %d for synapse %d confirmed but failed",
184 prereq->
id, synapse->
id);
190 crm_trace(
"Synapse %d is ready to execute", synapse->
id);
195 for (lpc = synapse->
actions; lpc != NULL; lpc = lpc->next) {
202 crm_trace(
"Skipping synapse %d: priority %d is less than " 208 }
else if (graph_fns->
allowed && !(graph_fns->
allowed(graph, a))) {
209 crm_trace(
"Deferring synapse %d: not allowed", synapse->
id);
248 crm_trace(
"Executing fencing action %d (%s)",
256 crm_err(
"Unsupported graph action type <%s id='%s'> (bug?)",
257 crm_element_name(
action->xml),
id);
275 for (GList *lpc = synapse->
actions; lpc != NULL; lpc = lpc->next) {
277 int rc = initiate_action(graph,
action);
280 crm_err(
"Failed initiating <%s id=%d> in synapse %d: %s",
307 static int fail = -1;
313 && (fail_ll > 0LL) && (fail_ll <= INT_MAX)) {
314 fail = (int) fail_ll;
321 crm_err(
"Dummy event handler: pretending action %d failed",
action->id);
351 int log_level = LOG_DEBUG;
353 const char *status =
"In progress";
355 if (graph_fns == NULL) {
356 graph_fns = &default_fns;
369 for (lpc = graph->
synapses; lpc != NULL; lpc = lpc->next) {
379 crm_trace(
"Executing graph %d (%d synapses already completed, %d pending)",
383 for (lpc = graph->
synapses; lpc != NULL; lpc = lpc->next) {
389 crm_debug(
"Throttling graph execution: batch limit (%d) reached",
400 }
else if (should_fire_synapse(graph, synapse)) {
402 if (fire_synapse(graph, synapse) !=
pcmk_rc_ok) {
403 crm_err(
"Synapse %d failed to fire", synapse->
id);
424 log_level = LOG_WARNING;
426 status =
"Terminated";
428 }
else if (graph->
skipped != 0) {
429 log_level = LOG_NOTICE;
434 log_level = LOG_NOTICE;
439 }
else if (graph->
fired == 0) {
444 "Transition %d (Complete=%d, Pending=%d," 445 " Fired=%d, Skipped=%d, Incomplete=%d, Source=%s): %s",
471 const char *element =
TYPE(xml_action);
472 const char *value =
ID(xml_action);
475 crm_err(
"Ignoring transition graph action without id (bug?)");
492 crm_err(
"Ignoring transition graph action of unknown type '%s' (bug?)",
500 crm_perror(LOG_CRIT,
"Cannot unpack transition graph action");
509 action->type = action_type;
512 value = g_hash_table_lookup(
action->params,
"CRM_meta_timeout");
516 value = g_hash_table_lookup(
action->params,
"CRM_meta_start_delay");
521 action->timeout += start_delay;
530 value = g_hash_table_lookup(
action->params,
"CRM_meta_can_fail");
533 gboolean can_fail = FALSE;
541 #ifndef PCMK__COMPAT_2_0 543 crm_warn(
"Support for the can_fail meta-attribute is deprecated" 544 " and will be removed in a future release");
564 unpack_synapse(
pcmk__graph_t *new_graph, xmlNode *xml_synapse)
566 const char *value = NULL;
567 xmlNode *action_set = NULL;
570 crm_trace(
"Unpacking synapse %s",
ID(xml_synapse));
573 if (new_synapse == NULL) {
587 crm_trace(
"Unpacking synapse %s action sets",
593 for (xmlNode *
action = pcmk__xml_first_child(action_set);
599 if (new_action == NULL) {
603 crm_trace(
"Adding action %d to synapse %d",
604 new_action->
id, new_synapse->
id);
611 crm_trace(
"Unpacking synapse %s inputs",
ID(xml_synapse));
619 for (xmlNode *
input = pcmk__xml_first_child(trigger);
625 if (new_input == NULL) {
629 crm_trace(
"Adding input %d to synapse %d",
630 new_input->
id, new_synapse->
id);
632 new_synapse->
inputs = g_list_append(new_synapse->
inputs,
670 const char *t_id = NULL;
671 const char *time = NULL;
674 if (new_graph == NULL) {
678 new_graph->
source = strdup((reference == NULL)?
"unknown" : reference);
679 if (new_graph->
source == NULL) {
691 if (xml_graph != NULL) {
728 if (new_synapse != NULL) {
734 crm_debug(
"Unpacked transition %d from %s: %d actions in %d synapses",
753 free_graph_action(gpointer user_data)
759 g_source_remove(
action->timer);
761 if (
action->params != NULL) {
762 g_hash_table_destroy(
action->params);
775 free_graph_synapse(gpointer user_data)
779 g_list_free_full(synapse->
actions, free_graph_action);
780 g_list_free_full(synapse->
inputs, free_graph_action);
794 g_list_free_full(graph->
synapses, free_graph_synapse);
820 int status,
int rc,
const char *exit_reason)
824 const char *
name = NULL;
825 const char *value = NULL;
826 xmlNode *action_resource = NULL;
839 op->
t_run = time(NULL);
843 g_hash_table_iter_init(&iter,
action->params);
844 while (g_hash_table_iter_next(&iter, (
void **)&
name, (
void **)&value)) {
845 g_hash_table_insert(op->
params, strdup(
name), strdup(value));
848 for (xmlNode *xop = pcmk__xml_first_child(resource); xop != NULL;
849 xop = pcmk__xml_next(xop)) {
853 crm_debug(
"Got call_id=%d for %s", tmp,
ID(resource));
#define CRM_CHECK(expr, failure_action)
#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)
void pcmk__free_graph(pcmk__graph_t *graph)
xmlNode * first_named_child(const xmlNode *parent, const char *name)
#define XML_LRM_ATTR_INTERVAL
#define XML_GRAPH_TAG_RSC_OP
#define XML_GRAPH_TAG_CRM_EVENT
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code.
int crm_element_value_int(const xmlNode *data, const char *name, int *dest)
Retrieve the integer value of an XML attribute.
enum pcmk__graph_action_type type
int(* pseudo)(pcmk__graph_t *graph, pcmk__graph_action_t *action)
void pcmk__update_graph(pcmk__graph_t *graph, pcmk__graph_action_t *action)
#define XML_GRAPH_TAG_PSEUDO_EVENT
int(* fence)(pcmk__graph_t *graph, pcmk__graph_action_t *action)
#define XML_CIB_ATTR_PRIORITY
xmlNode * copy_xml(xmlNode *src_node)
#define XML_LRM_ATTR_TASK
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.
int pcmk__guint_from_hash(GHashTable *table, const char *key, guint default_val, guint *result)
#define crm_debug(fmt, args...)
enum pcmk__graph_next completion_action
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
#define XML_CIB_TAG_RESOURCE
#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.
Wrappers for and extensions to libxml2.
enum pcmk__graph_status pcmk__execute_graph(pcmk__graph_t *graph)
#define crm_log_xml_warn(xml, text)
pcmk__graph_t * pcmk__unpack_graph(xmlNode *xml_graph, const char *reference)
#define pcmk__clear_graph_action_flags(action, flags_to_clear)
#define pcmk__clear_synapse_flags(synapse, flags_to_clear)
void free_xml(xmlNode *child)
bool(* allowed)(pcmk__graph_t *graph, pcmk__graph_action_t *action)
void pcmk__set_graph_functions(pcmk__graph_functions_t *fns)
int crm_str_to_boolean(const char *s, int *ret)
lrmd_event_data_t * lrmd_new_event(const char *rsc_id, const char *task, guint interval_ms)
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 crm_err(fmt, args...)
#define pcmk__set_graph_action_flags(action, flags_to_set)
char guint crm_parse_interval_spec(const char *input)
Parse milliseconds from a Pacemaker interval specification.
void lrmd__set_result(lrmd_event_data_t *event, enum ocf_exitcode rc, int op_status, const char *exit_reason)
#define XML_LRM_ATTR_CALLID
int(* cluster)(pcmk__graph_t *graph, pcmk__graph_action_t *action)
#define crm_log_xml_trace(xml, text)
xmlNode * crm_next_same_xml(const xmlNode *sibling)
Get next instance of same XML tag.