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