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