pacemaker 3.0.1-16e74fc4da
Scalable High-Availability cluster resource manager
Loading...
Searching...
No Matches
pcmk_graph_logging.c
Go to the documentation of this file.
1/*
2 * Copyright 2004-2024 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/common/xml.h>
14#include <pacemaker-internal.h>
15
24const char *
26{
27 switch (state) {
29 return "active";
31 return "pending";
33 return "complete";
35 return "terminated";
36 }
37 return "unknown";
38}
39
40static const char *
41actiontype2text(enum pcmk__graph_action_type type)
42{
43 switch (type) {
45 return "pseudo";
47 return "resource";
49 return "cluster";
50 }
51 return "invalid";
52}
53
63static const pcmk__graph_action_t *
64find_graph_action_by_id(const pcmk__graph_t *graph, int id)
65{
66 if (graph == NULL) {
67 return NULL;
68 }
69
70 for (const GList *synapse_iter = graph->synapses;
71 synapse_iter != NULL; synapse_iter = synapse_iter->next) {
72
73 const pcmk__graph_synapse_t *synapse = synapse_iter->data;
74
75 for (const GList *action_iter = synapse->actions;
76 action_iter != NULL; action_iter = action_iter->next) {
77
78 const pcmk__graph_action_t *action = action_iter->data;
79 if (action->id == id) {
80 return action;
81 }
82 }
83 }
84 return NULL;
85}
86
87static const char *
88synapse_state_str(pcmk__graph_synapse_t *synapse)
89{
90 if (pcmk_is_set(synapse->flags, pcmk__synapse_failed)) {
91 return "Failed";
92
93 } else if (pcmk_is_set(synapse->flags, pcmk__synapse_confirmed)) {
94 return "Completed";
95
96 } else if (pcmk_is_set(synapse->flags, pcmk__synapse_executed)) {
97 return "In-flight";
98
99 } else if (pcmk_is_set(synapse->flags, pcmk__synapse_ready)) {
100 return "Ready";
101 }
102 return "Pending";
103}
104
118static GString *
119synapse_pending_inputs(const pcmk__graph_t *graph,
120 const pcmk__graph_synapse_t *synapse)
121{
122 GString *pending = NULL;
123
124 for (const GList *lpc = synapse->inputs; lpc != NULL; lpc = lpc->next) {
125 const pcmk__graph_action_t *input = (pcmk__graph_action_t *) lpc->data;
126
128 pcmk__add_word(&pending, 1024, pcmk__xe_id(input->xml));
129
130 } else if (pcmk_is_set(input->flags, pcmk__graph_action_confirmed)) {
131 // Confirmed successful inputs are not pending
132
133 } else if (find_graph_action_by_id(graph, input->id) != NULL) {
134 // In-flight or pending
135 pcmk__add_word(&pending, 1024, pcmk__xe_id(input->xml));
136 }
137 }
138 return pending;
139}
140
141// Log synapse inputs that aren't in graph
142static void
143log_unresolved_inputs(unsigned int log_level, pcmk__graph_t *graph,
144 pcmk__graph_synapse_t *synapse)
145{
146 for (GList *lpc = synapse->inputs; lpc != NULL; lpc = lpc->next) {
148 const char *key = crm_element_value(input->xml, PCMK__XA_OPERATION_KEY);
149 const char *host = crm_element_value(input->xml, PCMK__META_ON_NODE);
150
151 if (find_graph_action_by_id(graph, input->id) == NULL) {
152 do_crm_log(log_level,
153 " * [Input %2d]: Unresolved dependency %s op %s%s%s",
154 input->id, actiontype2text(input->type), key,
155 (host? " on " : ""), (host? host : ""));
156 }
157 }
158}
159
160static void
161log_synapse_action(unsigned int log_level, pcmk__graph_synapse_t *synapse,
162 pcmk__graph_action_t *action, const char *pending_inputs)
163{
164 const char *key = crm_element_value(action->xml, PCMK__XA_OPERATION_KEY);
165 const char *host = crm_element_value(action->xml, PCMK__META_ON_NODE);
166 char *desc = crm_strdup_printf("%s %s op %s",
167 synapse_state_str(synapse),
168 actiontype2text(action->type), key);
169
170 do_crm_log(log_level,
171 "[Action %4d]: %-50s%s%s (priority: %d, waiting: %s)",
172 action->id, desc, (host? " on " : ""), (host? host : ""),
173 synapse->priority, pending_inputs);
174 free(desc);
175}
176
177static void
178log_synapse(unsigned int log_level, pcmk__graph_t *graph,
179 pcmk__graph_synapse_t *synapse)
180{
181 GString *g_pending = NULL;
182 const char *pending = "none";
183
184 if (!pcmk_is_set(synapse->flags, pcmk__synapse_executed)) {
185 g_pending = synapse_pending_inputs(graph, synapse);
186
187 if (g_pending != NULL) {
188 pending = (const char *) g_pending->str;
189 }
190 }
191
192 for (GList *lpc = synapse->actions; lpc != NULL; lpc = lpc->next) {
193 log_synapse_action(log_level, synapse,
194 (pcmk__graph_action_t *) lpc->data, pending);
195 }
196
197 if (g_pending != NULL) {
198 g_string_free(g_pending, TRUE);
199 }
200
201 if (!pcmk_is_set(synapse->flags, pcmk__synapse_executed)) {
202 log_unresolved_inputs(log_level, graph, synapse);
203 }
204}
205
206void
208{
209 log_synapse(log_level, NULL, action->synapse);
210}
211
212void
213pcmk__log_graph(unsigned int log_level, pcmk__graph_t *graph)
214{
215 if ((graph == NULL) || (graph->num_actions == 0)) {
216 if (log_level == LOG_TRACE) {
217 crm_debug("Empty transition graph");
218 }
219 return;
220 }
221
222 do_crm_log(log_level,
223 "Graph %d with %d actions: " PCMK_OPT_BATCH_LIMIT "=%d jobs, "
224 "network-delay=%ums",
225 graph->id, graph->num_actions,
226 graph->batch_limit, graph->network_delay);
227
228 for (GList *lpc = graph->synapses; lpc != NULL; lpc = lpc->next) {
229 log_synapse(log_level, graph, (pcmk__graph_synapse_t *) lpc->data);
230 }
231}
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
Definition util.h:80
pcmk__cpg_host_t host
Definition cpg.c:4
enum pcmk_ipc_server type
Definition cpg.c:3
A dumping ground.
#define do_crm_log(level, fmt, args...)
Log a message.
Definition logging.h:149
#define crm_debug(fmt, args...)
Definition logging.h:368
#define LOG_TRACE
Definition logging.h:38
xmlNode * input
#define PCMK_OPT_BATCH_LIMIT
Definition options.h:27
#define PCMK__META_ON_NODE
const char * action
Definition pcmk_fence.c:32
void pcmk__log_graph_action(int log_level, pcmk__graph_action_t *action)
const char * pcmk__graph_status2text(enum pcmk__graph_status state)
void pcmk__log_graph(unsigned int log_level, pcmk__graph_t *graph)
@ pcmk__graph_action_confirmed
@ pcmk__graph_action_failed
@ pcmk__synapse_ready
@ pcmk__synapse_executed
@ pcmk__synapse_confirmed
@ pcmk__synapse_failed
pcmk__graph_status
@ pcmk__graph_pending
@ pcmk__graph_terminated
@ pcmk__graph_active
@ pcmk__graph_complete
pcmk__graph_action_type
@ pcmk__pseudo_graph_action
@ pcmk__cluster_graph_action
@ pcmk__rsc_graph_action
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
Wrappers for and extensions to libxml2.
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
#define PCMK__XA_OPERATION_KEY