This source file includes following definitions.
- time_t_string
- PCMK__OUTPUT_ARGS
- PCMK__OUTPUT_ARGS
- PCMK__OUTPUT_ARGS
- PCMK__OUTPUT_ARGS
- PCMK__OUTPUT_ARGS
- PCMK__OUTPUT_ARGS
- PCMK__OUTPUT_ARGS
- PCMK__OUTPUT_ARGS
- PCMK__OUTPUT_ARGS
- PCMK__OUTPUT_ARGS
- PCMK__OUTPUT_ARGS
- PCMK__OUTPUT_ARGS
- PCMK__OUTPUT_ARGS
- PCMK__OUTPUT_ARGS
- stonith__register_messages
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11 #include <stdarg.h>
12
13 #include <crm/stonith-ng.h>
14 #include <crm/common/iso8601.h>
15 #include <crm/common/util.h>
16 #include <crm/common/xml.h>
17 #include <crm/common/output_internal.h>
18 #include <crm/fencing/internal.h>
19 #include <crm/pengine/internal.h>
20
21 static char *
22 time_t_string(time_t when) {
23 crm_time_t *crm_when = crm_time_new(NULL);
24 char *buf = NULL;
25
26 crm_time_set_timet(crm_when, &when);
27 buf = crm_time_as_string(crm_when, crm_time_log_date | crm_time_log_timeofday | crm_time_log_with_timezone);
28 crm_time_free(crm_when);
29 return buf;
30 }
31
32 PCMK__OUTPUT_ARGS("failed-fencing-history", "stonith_history_t *", "GListPtr", "gboolean", "gboolean")
33 int
34 stonith__failed_history(pcmk__output_t *out, va_list args) {
35 stonith_history_t *history = va_arg(args, stonith_history_t *);
36 GListPtr only_node = va_arg(args, GListPtr);
37 gboolean full_history = va_arg(args, gboolean);
38 gboolean print_spacer = va_arg(args, gboolean);
39
40 int rc = pcmk_rc_no_output;
41
42 for (stonith_history_t *hp = history; hp; hp = hp->next) {
43 if (hp->state != st_failed) {
44 continue;
45 }
46
47 if (!pcmk__str_in_list(only_node, hp->target)) {
48 continue;
49 }
50
51 PCMK__OUTPUT_LIST_HEADER(out, print_spacer, rc, "Failed Fencing Actions");
52 out->message(out, "stonith-event", hp, full_history, stonith__later_succeeded(hp, history));
53 out->increment_list(out);
54 }
55
56 PCMK__OUTPUT_LIST_FOOTER(out, rc);
57 return rc;
58 }
59
60 PCMK__OUTPUT_ARGS("fencing-history", "stonith_history_t *", "GListPtr", "gboolean", "gboolean")
61 int
62 stonith__history(pcmk__output_t *out, va_list args) {
63 stonith_history_t *history = va_arg(args, stonith_history_t *);
64 GListPtr only_node = va_arg(args, GListPtr);
65 gboolean full_history = va_arg(args, gboolean);
66 gboolean print_spacer = va_arg(args, gboolean);
67
68 int rc = pcmk_rc_no_output;
69
70 for (stonith_history_t *hp = history; hp; hp = hp->next) {
71 if (!pcmk__str_in_list(only_node, hp->target)) {
72 continue;
73 }
74
75 if (hp->state != st_failed) {
76 PCMK__OUTPUT_LIST_HEADER(out, print_spacer, rc, "Fencing History");
77 out->message(out, "stonith-event", hp, full_history, stonith__later_succeeded(hp, history));
78 out->increment_list(out);
79 }
80 }
81
82 PCMK__OUTPUT_LIST_FOOTER(out, rc);
83 return rc;
84 }
85
86 PCMK__OUTPUT_ARGS("full-fencing-history", "crm_exit_t", "stonith_history_t *", "GListPtr", "gboolean", "gboolean")
87 int
88 stonith__full_history(pcmk__output_t *out, va_list args) {
89 crm_exit_t history_rc G_GNUC_UNUSED = va_arg(args, crm_exit_t);
90 stonith_history_t *history = va_arg(args, stonith_history_t *);
91 GListPtr only_node = va_arg(args, GListPtr);
92 gboolean full_history = va_arg(args, gboolean);
93 gboolean print_spacer = va_arg(args, gboolean);
94
95 int rc = pcmk_rc_no_output;
96
97 for (stonith_history_t *hp = history; hp; hp = hp->next) {
98 if (!pcmk__str_in_list(only_node, hp->target)) {
99 continue;
100 }
101
102 PCMK__OUTPUT_LIST_HEADER(out, print_spacer, rc, "Fencing History");
103 out->message(out, "stonith-event", hp, full_history, stonith__later_succeeded(hp, history));
104 out->increment_list(out);
105 }
106
107 PCMK__OUTPUT_LIST_FOOTER(out, rc);
108 return rc;
109 }
110
111 PCMK__OUTPUT_ARGS("full-fencing-history", "crm_exit_t", "stonith_history_t *", "GListPtr", "gboolean", "gboolean")
112 int
113 stonith__full_history_xml(pcmk__output_t *out, va_list args) {
114 crm_exit_t history_rc = va_arg(args, crm_exit_t);
115 stonith_history_t *history = va_arg(args, stonith_history_t *);
116 GListPtr only_node = va_arg(args, GListPtr);
117 gboolean full_history = va_arg(args, gboolean);
118 gboolean print_spacer G_GNUC_UNUSED = va_arg(args, gboolean);
119
120 int rc = pcmk_rc_no_output;
121
122 if (history_rc == 0) {
123 for (stonith_history_t *hp = history; hp; hp = hp->next) {
124 if (!pcmk__str_in_list(only_node, hp->target)) {
125 continue;
126 }
127
128 PCMK__OUTPUT_LIST_HEADER(out, FALSE, rc, "Fencing History");
129 out->message(out, "stonith-event", hp, full_history, stonith__later_succeeded(hp, history));
130 out->increment_list(out);
131 }
132
133 PCMK__OUTPUT_LIST_FOOTER(out, rc);
134 } else {
135 xmlNodePtr node = pcmk__output_create_xml_node(out, "fence_history");
136 char *rc_s = crm_itoa(history_rc);
137
138 xmlSetProp(node, (pcmkXmlStr) "status", (pcmkXmlStr) rc_s);
139 free(rc_s);
140
141 rc = pcmk_rc_ok;
142 }
143
144 return rc;
145 }
146
147 PCMK__OUTPUT_ARGS("last-fenced", "const char *", "time_t")
148 int
149 stonith__last_fenced_html(pcmk__output_t *out, va_list args) {
150 const char *target = va_arg(args, const char *);
151 time_t when = va_arg(args, time_t);
152
153 if (when) {
154 char *buf = crm_strdup_printf("Node %s last fenced at: %s", target, ctime(&when));
155 pcmk__output_create_html_node(out, "div", NULL, NULL, buf);
156 free(buf);
157 return pcmk_rc_ok;
158 } else {
159 return pcmk_rc_no_output;
160 }
161 }
162
163 PCMK__OUTPUT_ARGS("last-fenced", "const char *", "time_t")
164 int
165 stonith__last_fenced_text(pcmk__output_t *out, va_list args) {
166 const char *target = va_arg(args, const char *);
167 time_t when = va_arg(args, time_t);
168
169 if (when) {
170 pcmk__indented_printf(out, "Node %s last fenced at: %s", target, ctime(&when));
171 } else {
172 pcmk__indented_printf(out, "Node %s has never been fenced\n", target);
173 }
174
175 return pcmk_rc_ok;
176 }
177
178 PCMK__OUTPUT_ARGS("last-fenced", "const char *", "time_t")
179 int
180 stonith__last_fenced_xml(pcmk__output_t *out, va_list args) {
181 const char *target = va_arg(args, const char *);
182 time_t when = va_arg(args, time_t);
183
184 if (when) {
185 xmlNodePtr node = pcmk__output_create_xml_node(out, "last-fenced");
186 char *buf = time_t_string(when);
187
188 xmlSetProp(node, (pcmkXmlStr) "target", (pcmkXmlStr) target);
189 xmlSetProp(node, (pcmkXmlStr) "when", (pcmkXmlStr) buf);
190
191 free(buf);
192 return pcmk_rc_ok;
193 } else {
194 return pcmk_rc_no_output;
195 }
196 }
197
198 PCMK__OUTPUT_ARGS("pending-fencing-actions", "stonith_history_t *", "GListPtr", "gboolean", "gboolean")
199 int
200 stonith__pending_actions(pcmk__output_t *out, va_list args) {
201 stonith_history_t *history = va_arg(args, stonith_history_t *);
202 GListPtr only_node = va_arg(args, GListPtr);
203 gboolean full_history = va_arg(args, gboolean);
204 gboolean print_spacer = va_arg(args, gboolean);
205
206 int rc = pcmk_rc_no_output;
207
208 for (stonith_history_t *hp = history; hp; hp = hp->next) {
209 if (!pcmk__str_in_list(only_node, hp->target)) {
210 continue;
211 }
212
213
214 if ((hp->state == st_failed) || (hp->state == st_done)) {
215 break;
216 }
217
218 PCMK__OUTPUT_LIST_HEADER(out, print_spacer, rc, "Pending Fencing Actions");
219 out->message(out, "stonith-event", hp, full_history, stonith__later_succeeded(hp, history));
220 out->increment_list(out);
221 }
222
223 PCMK__OUTPUT_LIST_FOOTER(out, rc);
224 return rc;
225 }
226
227 PCMK__OUTPUT_ARGS("stonith-event", "stonith_history_t *", "gboolean", "gboolean")
228 int
229 stonith__event_html(pcmk__output_t *out, va_list args) {
230 stonith_history_t *event = va_arg(args, stonith_history_t *);
231 gboolean full_history = va_arg(args, gboolean);
232 gboolean later_succeeded = va_arg(args, gboolean);
233
234 switch(event->state) {
235 case st_done: {
236 char *completed_s = time_t_string(event->completed);
237
238 out->list_item(out, "successful-stonith-event",
239 "%s of %s successful: delegate=%s, client=%s, origin=%s, %s='%s'",
240 stonith_action_str(event->action), event->target,
241 event->delegate ? event->delegate : "",
242 event->client, event->origin,
243 full_history ? "completed" : "last-successful",
244 completed_s);
245 free(completed_s);
246 break;
247 }
248
249 case st_failed: {
250 char *failed_s = time_t_string(event->completed);
251
252 out->list_item(out, "failed-stonith-event",
253 "%s of %s failed : delegate=%s, client=%s, origin=%s, %s='%s' %s",
254 stonith_action_str(event->action), event->target,
255 event->delegate ? event->delegate : "",
256 event->client, event->origin,
257 full_history ? "completed" : "last-failed",
258 failed_s,
259 later_succeeded ? "(a later attempt succeeded)" : "");
260 free(failed_s);
261 break;
262 }
263
264 default:
265 out->list_item(out, "pending-stonith-event",
266 "%s of %s pending: client=%s, origin=%s",
267 stonith_action_str(event->action), event->target,
268 event->client, event->origin);
269 break;
270 }
271
272 return pcmk_rc_ok;
273 }
274
275 PCMK__OUTPUT_ARGS("stonith-event", "stonith_history_t *", "gboolean", "gboolean")
276 int
277 stonith__event_text(pcmk__output_t *out, va_list args) {
278 stonith_history_t *event = va_arg(args, stonith_history_t *);
279 gboolean full_history = va_arg(args, gboolean);
280 gboolean later_succeeded = va_arg(args, gboolean);
281
282 char *buf = time_t_string(event->completed);
283
284 switch (event->state) {
285 case st_failed:
286 pcmk__indented_printf(out, "%s of %s failed: delegate=%s, client=%s, origin=%s, %s='%s' %s\n",
287 stonith_action_str(event->action), event->target,
288 event->delegate ? event->delegate : "",
289 event->client, event->origin,
290 full_history ? "completed" : "last-failed", buf,
291 later_succeeded ? "(a later attempt succeeded)" : "");
292 break;
293
294 case st_done:
295 pcmk__indented_printf(out, "%s of %s successful: delegate=%s, client=%s, origin=%s, %s='%s'\n",
296 stonith_action_str(event->action), event->target,
297 event->delegate ? event->delegate : "",
298 event->client, event->origin,
299 full_history ? "completed" : "last-successful", buf);
300 break;
301
302 default:
303 pcmk__indented_printf(out, "%s of %s pending: client=%s, origin=%s\n",
304 stonith_action_str(event->action), event->target,
305 event->client, event->origin);
306 break;
307 }
308
309 free(buf);
310 return pcmk_rc_ok;
311 }
312
313 PCMK__OUTPUT_ARGS("stonith-event", "stonith_history_t *", "gboolean", "gboolean")
314 int
315 stonith__event_xml(pcmk__output_t *out, va_list args) {
316 xmlNodePtr node = pcmk__output_create_xml_node(out, "fence_event");
317 stonith_history_t *event = va_arg(args, stonith_history_t *);
318 gboolean full_history G_GNUC_UNUSED = va_arg(args, gboolean);
319 gboolean later_succeeded G_GNUC_UNUSED = va_arg(args, gboolean);
320
321 char *buf = NULL;
322
323 switch (event->state) {
324 case st_failed:
325 xmlSetProp(node, (pcmkXmlStr) "status", (pcmkXmlStr) "failed");
326 break;
327
328 case st_done:
329 xmlSetProp(node, (pcmkXmlStr) "status", (pcmkXmlStr) "success");
330 break;
331
332 default: {
333 char *state = crm_itoa(event->state);
334 xmlSetProp(node, (pcmkXmlStr) "status", (pcmkXmlStr) "pending");
335 xmlSetProp(node, (pcmkXmlStr) "extended-status", (pcmkXmlStr) state);
336 free(state);
337 break;
338 }
339 }
340
341 if (event->delegate != NULL) {
342 xmlSetProp(node, (pcmkXmlStr) "delegate", (pcmkXmlStr) event->delegate);
343 }
344
345 xmlSetProp(node, (pcmkXmlStr) "action", (pcmkXmlStr) event->action);
346 xmlSetProp(node, (pcmkXmlStr) "target", (pcmkXmlStr) event->target);
347 xmlSetProp(node, (pcmkXmlStr) "client", (pcmkXmlStr) event->client);
348 xmlSetProp(node, (pcmkXmlStr) "origin", (pcmkXmlStr) event->origin);
349
350 if (event->state == st_failed || event->state == st_done) {
351 buf = time_t_string(event->completed);
352 xmlSetProp(node, (pcmkXmlStr) "completed", (pcmkXmlStr) buf);
353 free(buf);
354 }
355
356 return pcmk_rc_ok;
357 }
358
359 PCMK__OUTPUT_ARGS("validate", "const char *", "const char *", "char *", "char *", "int")
360 int
361 stonith__validate_agent_html(pcmk__output_t *out, va_list args) {
362 const char *agent = va_arg(args, const char *);
363 const char *device = va_arg(args, const char *);
364 char *output = va_arg(args, char *);
365 char *error_output = va_arg(args, char *);
366 int rc = va_arg(args, int);
367
368 if (device) {
369 char *buf = crm_strdup_printf("Validation of %s on %s %s", agent, device,
370 rc ? "failed" : "succeeded");
371 pcmk__output_create_html_node(out, "div", NULL, NULL, buf);
372 free(buf);
373 } else {
374 char *buf = crm_strdup_printf("Validation of %s %s", agent,
375 rc ? "failed" : "succeeded");
376 pcmk__output_create_html_node(out, "div", NULL, NULL, buf);
377 free(buf);
378 }
379
380 out->subprocess_output(out, rc, output, error_output);
381 return rc;
382 }
383
384 PCMK__OUTPUT_ARGS("validate", "const char *", "const char *", "char *", "char *", "int")
385 int
386 stonith__validate_agent_text(pcmk__output_t *out, va_list args) {
387 const char *agent = va_arg(args, const char *);
388 const char *device = va_arg(args, const char *);
389 char *output = va_arg(args, char *);
390 char *error_output = va_arg(args, char *);
391 int rc = va_arg(args, int);
392
393 if (device) {
394 pcmk__indented_printf(out, "Validation of %s on %s %s\n", agent, device,
395 rc ? "failed" : "succeeded");
396 } else {
397 pcmk__indented_printf(out, "Validation of %s %s\n", agent,
398 rc ? "failed" : "succeeded");
399 }
400
401 if (output) {
402 puts(output);
403 }
404
405 if (error_output) {
406 puts(error_output);
407 }
408
409 return rc;
410 }
411
412 PCMK__OUTPUT_ARGS("validate", "const char *", "const char *", "char *", "char *", "int")
413 int
414 stonith__validate_agent_xml(pcmk__output_t *out, va_list args) {
415 xmlNodePtr node = pcmk__output_create_xml_node(out, "validate");
416
417 const char *agent = va_arg(args, const char *);
418 const char *device = va_arg(args, const char *);
419 char *output = va_arg(args, char *);
420 char *error_output = va_arg(args, char *);
421 int rc = va_arg(args, int);
422
423 xmlSetProp(node, (pcmkXmlStr) "agent", (pcmkXmlStr) agent);
424 if (device != NULL) {
425 xmlSetProp(node, (pcmkXmlStr) "device", (pcmkXmlStr) device);
426 }
427 xmlSetProp(node, (pcmkXmlStr) "valid", (pcmkXmlStr) pcmk__btoa(rc));
428
429 pcmk__output_xml_push_parent(out, node);
430 out->subprocess_output(out, rc, output, error_output);
431 pcmk__output_xml_pop_parent(out);
432
433 return rc;
434 }
435
436 static pcmk__message_entry_t fmt_functions[] = {
437 { "failed-fencing-history", "default", stonith__failed_history },
438 { "fencing-history", "default", stonith__history },
439 { "full-fencing-history", "default", stonith__full_history },
440 { "full-fencing-history", "xml", stonith__full_history_xml },
441 { "last-fenced", "html", stonith__last_fenced_html },
442 { "last-fenced", "log", stonith__last_fenced_text },
443 { "last-fenced", "text", stonith__last_fenced_text },
444 { "last-fenced", "xml", stonith__last_fenced_xml },
445 { "pending-fencing-actions", "default", stonith__pending_actions },
446 { "stonith-event", "html", stonith__event_html },
447 { "stonith-event", "log", stonith__event_text },
448 { "stonith-event", "text", stonith__event_text },
449 { "stonith-event", "xml", stonith__event_xml },
450 { "validate", "html", stonith__validate_agent_html },
451 { "validate", "log", stonith__validate_agent_text },
452 { "validate", "text", stonith__validate_agent_text },
453 { "validate", "xml", stonith__validate_agent_xml },
454
455 { NULL, NULL, NULL }
456 };
457
458 void
459 stonith__register_messages(pcmk__output_t *out) {
460 pcmk__register_messages(out, fmt_functions);
461 }