pacemaker  2.1.4-dc6eb4362
Scalable High-Availability cluster resource manager
pcmk_graph_logging.c
Go to the documentation of this file.
1 /*
2  * Copyright 2004-2021 the Pacemaker project contributors
3  *
4  * The version control history for this file may have further details.
5  *
6  * This source code is licensed under the GNU Lesser General Public License
7  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
8  */
9 
10 #include <crm_internal.h>
11 
12 #include <crm/crm.h>
13 #include <crm/msg_xml.h>
14 #include <crm/common/xml.h>
15 #include <pacemaker-internal.h>
16 
25 const char *
27 {
28  switch (state) {
29  case transition_active:
30  return "active";
31  case transition_pending:
32  return "pending";
34  return "complete";
35  case transition_stopped:
36  return "stopped";
38  return "terminated";
40  return "failed (action)";
41  case transition_failed:
42  return "failed";
43  }
44  return "unknown";
45 }
46 
47 static const char *
48 actiontype2text(action_type_e type)
49 {
50  switch (type) {
51  case action_type_pseudo:
52  return "pseudo";
53  case action_type_rsc:
54  return "resource";
55  case action_type_crm:
56  return "cluster";
57  }
58  return "invalid";
59 }
60 
70 static crm_action_t *
71 find_graph_action_by_id(crm_graph_t *graph, int id)
72 {
73  if (graph == NULL) {
74  return NULL;
75  }
76 
77  for (GList *sIter = graph->synapses; sIter != NULL; sIter = sIter->next) {
78  synapse_t *synapse = (synapse_t *) sIter->data;
79 
80  for (GList *aIter = synapse->actions; aIter != NULL;
81  aIter = aIter->next) {
82 
83  crm_action_t *action = (crm_action_t *) aIter->data;
84 
85  if (action->id == id) {
86  return action;
87  }
88  }
89  }
90  return NULL;
91 }
92 
93 const char *
95 {
96  if (pcmk_is_set(synapse->flags, pcmk__synapse_failed)) {
97  return "Failed";
98 
99  } else if (pcmk_is_set(synapse->flags, pcmk__synapse_confirmed)) {
100  return "Completed";
101 
102  } else if (pcmk_is_set(synapse->flags, pcmk__synapse_executed)) {
103  return "In-flight";
104 
105  } else if (pcmk_is_set(synapse->flags, pcmk__synapse_ready)) {
106  return "Ready";
107  }
108  return "Pending";
109 }
110 
111 // List action IDs of inputs in graph that haven't completed successfully
112 static char *
113 synapse_pending_inputs(crm_graph_t *graph, synapse_t *synapse)
114 {
115  char *pending = NULL;
116  size_t pending_len = 0;
117 
118  for (GList *lpc = synapse->inputs; lpc != NULL; lpc = lpc->next) {
119  crm_action_t *input = (crm_action_t *) lpc->data;
120 
122  pcmk__add_word(&pending, &pending_len, ID(input->xml));
123 
124  } else if (pcmk_is_set(input->flags, pcmk__graph_action_confirmed)) {
125  // Confirmed successful inputs are not pending
126 
127  } else if (find_graph_action_by_id(graph, input->id) != NULL) {
128  // In-flight or pending
129  pcmk__add_word(&pending, &pending_len, ID(input->xml));
130  }
131  }
132  if (pending == NULL) {
133  pending = strdup("none");
134  }
135  return pending;
136 }
137 
138 // Log synapse inputs that aren't in graph
139 static void
140 log_unresolved_inputs(unsigned int log_level, crm_graph_t *graph,
141  synapse_t *synapse)
142 {
143  for (GList *lpc = synapse->inputs; lpc != NULL; lpc = lpc->next) {
144  crm_action_t *input = (crm_action_t *) lpc->data;
145  const char *key = crm_element_value(input->xml, XML_LRM_ATTR_TASK_KEY);
146  const char *host = crm_element_value(input->xml, XML_LRM_ATTR_TARGET);
147 
148  if (find_graph_action_by_id(graph, input->id) == NULL) {
149  do_crm_log(log_level,
150  " * [Input %2d]: Unresolved dependency %s op %s%s%s",
151  input->id, actiontype2text(input->type), key,
152  (host? " on " : ""), (host? host : ""));
153  }
154  }
155 }
156 
157 static void
158 log_synapse_action(unsigned int log_level, synapse_t *synapse,
159  crm_action_t *action, const char *pending_inputs)
160 {
161  const char *key = crm_element_value(action->xml, XML_LRM_ATTR_TASK_KEY);
162  const char *host = crm_element_value(action->xml, XML_LRM_ATTR_TARGET);
163  char *desc = crm_strdup_printf("%s %s op %s",
164  synapse_state_str(synapse),
165  actiontype2text(action->type), key);
166 
167  do_crm_log(log_level,
168  "[Action %4d]: %-50s%s%s (priority: %d, waiting: %s)",
169  action->id, desc, (host? " on " : ""), (host? host : ""),
170  synapse->priority, pending_inputs);
171  free(desc);
172 }
173 
174 static void
175 log_synapse(unsigned int log_level, crm_graph_t *graph, synapse_t *synapse)
176 {
177  char *pending = NULL;
178 
179  if (!pcmk_is_set(synapse->flags, pcmk__synapse_executed)) {
180  pending = synapse_pending_inputs(graph, synapse);
181  }
182  for (GList *lpc = synapse->actions; lpc != NULL; lpc = lpc->next) {
183  log_synapse_action(log_level, synapse, (crm_action_t *) lpc->data,
184  pending);
185  }
186  free(pending);
187  if (!pcmk_is_set(synapse->flags, pcmk__synapse_executed)) {
188  log_unresolved_inputs(log_level, graph, synapse);
189  }
190 }
191 
192 void
194 {
195  log_synapse(log_level, NULL, action->synapse);
196 }
197 
198 void
199 pcmk__log_graph(unsigned int log_level, crm_graph_t *graph)
200 {
201  if ((graph == NULL) || (graph->num_actions == 0)) {
202  if (log_level == LOG_TRACE) {
203  crm_debug("Empty transition graph");
204  }
205  return;
206  }
207 
208  do_crm_log(log_level, "Graph %d with %d actions:"
209  " batch-limit=%d jobs, network-delay=%ums",
210  graph->id, graph->num_actions,
211  graph->batch_limit, graph->network_delay);
212 
213  for (GList *lpc = graph->synapses; lpc != NULL; lpc = lpc->next) {
214  log_synapse(log_level, graph, (synapse_t *) lpc->data);
215  }
216 }
#define LOG_TRACE
Definition: logging.h:37
pcmk__cpg_host_t host
Definition: cpg.c:49
A dumping ground.
transition_status
enum crm_ais_msg_types type
Definition: cpg.c:48
const char * action
Definition: pcmk_fence.c:29
uint32_t flags
#define XML_LRM_ATTR_TASK_KEY
Definition: msg_xml.h:304
void pcmk__log_graph_action(int log_level, crm_action_t *action)
#define crm_debug(fmt, args...)
Definition: logging.h:363
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
Definition: nvpair.c:529
#define do_crm_log(level, fmt, args...)
Log a message.
Definition: logging.h:167
GList * inputs
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.
Definition: util.h:122
GList * actions
Wrappers for and extensions to libxml2.
void pcmk__log_graph(unsigned int log_level, crm_graph_t *graph)
const char * pcmk__graph_status2text(enum transition_status state)
xmlNode * input
action_type_e
#define XML_LRM_ATTR_TARGET
Definition: msg_xml.h:305
#define ID(x)
Definition: msg_xml.h:460
const char * synapse_state_str(synapse_t *synapse)