This source file includes following definitions.
- build_uname_list
- build_rsc_list
- failure_count
- get_operation_list
- print_rsc_history
- print_node_history
- add_extra_info
- print_node_attribute
- print_node_summary
- print_cluster_tickets
- print_neg_locations
- print_node_attributes
- print_failed_actions
- print_status
- print_xml_status
- print_html_status
1
2
3
4
5
6
7
8
9
10 #include <glib.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <time.h>
14
15 #ifndef PCMK__CONFIG_H
16 # define PCMK__CONFIG_H
17 # include <config.h>
18 #endif
19
20 #include <crm/cib/util.h>
21 #include <crm/common/curses_internal.h>
22 #include <crm/common/iso8601_internal.h>
23 #include <crm/common/xml.h>
24 #include <crm/msg_xml.h>
25 #include <crm/pengine/internal.h>
26 #include <crm/pengine/pe_types.h>
27 #include <crm/stonith-ng.h>
28 #include <crm/common/internal.h>
29 #include <crm/common/xml_internal.h>
30 #include <crm/common/util.h>
31 #include <crm/fencing/internal.h>
32
33 #include "crm_mon.h"
34
35 static int print_rsc_history(pcmk__output_t *out, pe_working_set_t *data_set,
36 pe_node_t *node, xmlNode *rsc_entry, unsigned int mon_ops,
37 GListPtr op_list);
38 static int print_node_history(pcmk__output_t *out, pe_working_set_t *data_set,
39 pe_node_t *node, xmlNode *node_state, gboolean operations,
40 unsigned int mon_ops, GListPtr only_node, GListPtr only_rsc);
41 static gboolean add_extra_info(pcmk__output_t *out, pe_node_t * node, GListPtr rsc_list,
42 const char *attrname, int *expected_score);
43 static void print_node_attribute(gpointer name, gpointer user_data);
44 static int print_node_summary(pcmk__output_t *out, pe_working_set_t * data_set,
45 gboolean operations, unsigned int mon_ops,
46 GListPtr only_node, GListPtr only_rsc, gboolean print_spacer);
47 static int print_cluster_tickets(pcmk__output_t *out, pe_working_set_t * data_set,
48 gboolean print_spacer);
49 static int print_neg_locations(pcmk__output_t *out, pe_working_set_t *data_set,
50 unsigned int mon_ops, const char *prefix,
51 GListPtr only_rsc, gboolean print_spacer);
52 static int print_node_attributes(pcmk__output_t *out, pe_working_set_t *data_set,
53 unsigned int mon_ops, GListPtr only_node,
54 GListPtr only_rsc, gboolean print_spacer);
55 static int print_failed_actions(pcmk__output_t *out, pe_working_set_t *data_set,
56 GListPtr only_node, GListPtr only_rsc, gboolean print_spacer);
57
58 static GListPtr
59 build_uname_list(pe_working_set_t *data_set, const char *s) {
60 GListPtr unames = NULL;
61
62 if (pcmk__str_eq(s, "*", pcmk__str_null_matches)) {
63
64
65
66
67 unames = g_list_prepend(unames, strdup("*"));
68 } else {
69 pe_node_t *node = pe_find_node(data_set->nodes, s);
70
71 if (node) {
72
73
74
75 unames = g_list_prepend(unames, strdup(s));
76 } else {
77
78
79
80
81
82
83 unames = pe__unames_with_tag(data_set, s);
84 }
85 }
86
87 return unames;
88 }
89
90 static GListPtr
91 build_rsc_list(pe_working_set_t *data_set, const char *s) {
92 GListPtr resources = NULL;
93
94 if (pcmk__str_eq(s, "*", pcmk__str_null_matches)) {
95 resources = g_list_prepend(resources, strdup("*"));
96 } else {
97 pe_resource_t *rsc = pe_find_resource_with_flags(data_set->resources, s,
98 pe_find_renamed|pe_find_any);
99
100 if (rsc) {
101
102
103
104
105
106 if (strstr(s, ":") != NULL) {
107 resources = g_list_prepend(resources, strdup(rsc->id));
108 } else {
109 resources = g_list_prepend(resources, strdup(rsc_printable_id(rsc)));
110 }
111 } else {
112
113
114
115
116 resources = pe__rscs_with_tag(data_set, s);
117 }
118 }
119
120 return resources;
121 }
122
123 static int
124 failure_count(pe_working_set_t *data_set, pe_node_t *node, pe_resource_t *rsc, time_t *last_failure) {
125 return rsc ? pe_get_failcount(node, rsc, last_failure, pe_fc_default,
126 NULL, data_set)
127 : 0;
128 }
129
130 static GListPtr
131 get_operation_list(xmlNode *rsc_entry) {
132 GListPtr op_list = NULL;
133 xmlNode *rsc_op = NULL;
134
135 for (rsc_op = pcmk__xe_first_child(rsc_entry); rsc_op != NULL;
136 rsc_op = pcmk__xe_next(rsc_op)) {
137 const char *task = crm_element_value(rsc_op, XML_LRM_ATTR_TASK);
138 const char *interval_ms_s = crm_element_value(rsc_op,
139 XML_LRM_ATTR_INTERVAL_MS);
140 const char *op_rc = crm_element_value(rsc_op, XML_LRM_ATTR_RC);
141 int op_rc_i = crm_parse_int(op_rc, "0");
142
143
144 if (pcmk__str_eq(task, CRMD_ACTION_STATUS, pcmk__str_casei)
145 && pcmk__str_eq(interval_ms_s, "0", pcmk__str_null_matches | pcmk__str_casei)) {
146 task = "probe";
147 }
148
149
150 if (pcmk__str_eq(task, CRMD_ACTION_NOTIFY, pcmk__str_casei) || (pcmk__str_eq(task, "probe", pcmk__str_casei) && (op_rc_i == 7))) {
151 continue;
152 }
153
154 if (pcmk__str_eq((const char *)rsc_op->name, XML_LRM_TAG_RSC_OP, pcmk__str_none)) {
155 op_list = g_list_append(op_list, rsc_op);
156 }
157 }
158
159 op_list = g_list_sort(op_list, sort_op_by_callid);
160 return op_list;
161 }
162
163
164
165
166
167
168
169
170
171
172
173
174 static int
175 print_rsc_history(pcmk__output_t *out, pe_working_set_t *data_set, pe_node_t *node,
176 xmlNode *rsc_entry, unsigned int mon_ops, GListPtr op_list)
177 {
178 GListPtr gIter = NULL;
179 int rc = pcmk_rc_no_output;
180 const char *rsc_id = crm_element_value(rsc_entry, XML_ATTR_ID);
181 pe_resource_t *rsc = pe_find_resource(data_set->resources, rsc_id);
182
183
184 for (gIter = op_list; gIter != NULL; gIter = gIter->next) {
185 xmlNode *xml_op = (xmlNode *) gIter->data;
186 const char *task = crm_element_value(xml_op, XML_LRM_ATTR_TASK);
187 const char *interval_ms_s = crm_element_value(xml_op,
188 XML_LRM_ATTR_INTERVAL_MS);
189 const char *op_rc = crm_element_value(xml_op, XML_LRM_ATTR_RC);
190 int op_rc_i = crm_parse_int(op_rc, "0");
191
192
193 if (pcmk__str_eq(task, CRMD_ACTION_STATUS, pcmk__str_casei)
194 && pcmk__str_eq(interval_ms_s, "0", pcmk__str_null_matches | pcmk__str_casei)) {
195 task = "probe";
196 }
197
198
199 if (rc == pcmk_rc_no_output) {
200 time_t last_failure = 0;
201 int failcount = failure_count(data_set, node, rsc, &last_failure);
202
203 out->message(out, "resource-history", rsc, rsc_id, TRUE, failcount, last_failure, TRUE);
204 rc = pcmk_rc_ok;
205 }
206
207
208 out->message(out, "op-history", xml_op, task, interval_ms_s,
209 op_rc_i, pcmk_is_set(mon_ops, mon_op_print_timing));
210 }
211
212
213 g_list_free(op_list);
214
215 PCMK__OUTPUT_LIST_FOOTER(out, rc);
216 return rc;
217 }
218
219
220
221
222
223
224
225
226
227
228
229 static int
230 print_node_history(pcmk__output_t *out, pe_working_set_t *data_set,
231 pe_node_t *node, xmlNode *node_state, gboolean operations,
232 unsigned int mon_ops, GListPtr only_node, GListPtr only_rsc)
233 {
234 xmlNode *lrm_rsc = NULL;
235 xmlNode *rsc_entry = NULL;
236 int rc = pcmk_rc_no_output;
237
238 lrm_rsc = find_xml_node(node_state, XML_CIB_TAG_LRM, FALSE);
239 lrm_rsc = find_xml_node(lrm_rsc, XML_LRM_TAG_RESOURCES, FALSE);
240
241
242 for (rsc_entry = pcmk__xe_first_child(lrm_rsc); rsc_entry != NULL;
243 rsc_entry = pcmk__xe_next(rsc_entry)) {
244
245 const char *rsc_id = crm_element_value(rsc_entry, XML_ATTR_ID);
246 pe_resource_t *rsc = pe_find_resource(data_set->resources, rsc_id);
247
248 if (!pcmk__str_eq((const char *)rsc_entry->name, XML_LRM_TAG_RESOURCE, pcmk__str_none)) {
249 continue;
250 }
251
252
253
254
255
256
257
258
259
260 if (uber_parent(rsc)->variant == pe_group) {
261 if (!pcmk__str_in_list(only_rsc, rsc_printable_id(rsc)) &&
262 !pcmk__str_in_list(only_rsc, rsc_printable_id(uber_parent(rsc)))) {
263 continue;
264 }
265 } else {
266 if (rsc->fns->is_filtered(rsc, only_rsc, TRUE)) {
267 continue;
268 }
269 }
270
271 if (operations == FALSE) {
272 time_t last_failure = 0;
273 int failcount = failure_count(data_set, node, rsc, &last_failure);
274
275 if (failcount <= 0) {
276 continue;
277 }
278
279 if (rc == pcmk_rc_no_output) {
280 rc = pcmk_rc_ok;
281 out->message(out, "node", node, get_resource_display_options(mon_ops),
282 FALSE, NULL,
283 pcmk_is_set(mon_ops, mon_op_print_clone_detail),
284 pcmk_is_set(mon_ops, mon_op_print_brief),
285 pcmk_is_set(mon_ops, mon_op_group_by_node),
286 only_node, only_rsc);
287 }
288
289 out->message(out, "resource-history", rsc, rsc_id, FALSE,
290 failcount, last_failure, FALSE);
291 } else {
292 GListPtr op_list = get_operation_list(rsc_entry);
293
294 if (op_list == NULL) {
295 continue;
296 }
297
298 if (rc == pcmk_rc_no_output) {
299 rc = pcmk_rc_ok;
300 out->message(out, "node", node, get_resource_display_options(mon_ops),
301 FALSE, NULL,
302 pcmk_is_set(mon_ops, mon_op_print_clone_detail),
303 pcmk_is_set(mon_ops, mon_op_print_brief),
304 pcmk_is_set(mon_ops, mon_op_group_by_node),
305 only_node, only_rsc);
306 }
307
308 print_rsc_history(out, data_set, node, rsc_entry, mon_ops, op_list);
309 }
310 }
311
312 PCMK__OUTPUT_LIST_FOOTER(out, rc);
313 return rc;
314 }
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331 static gboolean
332 add_extra_info(pcmk__output_t *out, pe_node_t *node, GListPtr rsc_list,
333 const char *attrname, int *expected_score)
334 {
335 GListPtr gIter = NULL;
336
337 for (gIter = rsc_list; gIter != NULL; gIter = gIter->next) {
338 pe_resource_t *rsc = (pe_resource_t *) gIter->data;
339 const char *type = g_hash_table_lookup(rsc->meta, "type");
340 const char *name = NULL;
341
342 if (rsc->children != NULL) {
343 if (add_extra_info(out, node, rsc->children, attrname, expected_score)) {
344 return TRUE;
345 }
346 }
347
348 if (!pcmk__strcase_any_of(type, "ping", "pingd", NULL)) {
349 continue;
350 }
351
352 name = g_hash_table_lookup(rsc->parameters, "name");
353
354 if (name == NULL) {
355 name = "pingd";
356 }
357
358
359 if (pcmk__str_eq(name, attrname, pcmk__str_casei)) {
360 int host_list_num = 0;
361
362 const char *hosts = g_hash_table_lookup(rsc->parameters, "host_list");
363 const char *multiplier = g_hash_table_lookup(rsc->parameters, "multiplier");
364
365 if (hosts) {
366 char **host_list = g_strsplit(hosts, " ", 0);
367 host_list_num = g_strv_length(host_list);
368 g_strfreev(host_list);
369 }
370
371
372 *expected_score = host_list_num * crm_parse_int(multiplier, "1");
373
374 return TRUE;
375 }
376 }
377 return FALSE;
378 }
379
380
381 struct mon_attr_data {
382 pcmk__output_t *out;
383 pe_node_t *node;
384 };
385
386 static void
387 print_node_attribute(gpointer name, gpointer user_data)
388 {
389 const char *value = NULL;
390 int expected_score = 0;
391 gboolean add_extra = FALSE;
392 struct mon_attr_data *data = (struct mon_attr_data *) user_data;
393
394 value = pe_node_attribute_raw(data->node, name);
395
396 add_extra = add_extra_info(data->out, data->node, data->node->details->running_rsc,
397 name, &expected_score);
398
399
400 data->out->message(data->out, "node-attribute", name, value, add_extra,
401 expected_score);
402 }
403
404
405
406
407
408
409
410
411
412
413 static int
414 print_node_summary(pcmk__output_t *out, pe_working_set_t * data_set,
415 gboolean operations, unsigned int mon_ops, GListPtr only_node,
416 GListPtr only_rsc, gboolean print_spacer)
417 {
418 xmlNode *node_state = NULL;
419 xmlNode *cib_status = get_object_root(XML_CIB_TAG_STATUS, data_set->input);
420 int rc = pcmk_rc_no_output;
421
422 if (xmlChildElementCount(cib_status) == 0) {
423 return rc;
424 }
425
426
427 for (node_state = pcmk__xe_first_child(cib_status); node_state != NULL;
428 node_state = pcmk__xe_next(node_state)) {
429 pe_node_t *node;
430
431 if (!pcmk__str_eq((const char *)node_state->name, XML_CIB_TAG_STATE, pcmk__str_none)) {
432 continue;
433 }
434
435 node = pe_find_node_id(data_set->nodes, ID(node_state));
436
437 if (!node || !node->details || !node->details->online) {
438 continue;
439 }
440
441 if (!pcmk__str_in_list(only_node, node->details->uname)) {
442 continue;
443 }
444
445 PCMK__OUTPUT_LIST_HEADER(out, print_spacer, rc, operations ? "Operations" : "Migration Summary");
446
447 print_node_history(out, data_set, node, node_state, operations, mon_ops,
448 only_node, only_rsc);
449 }
450
451 PCMK__OUTPUT_LIST_FOOTER(out, rc);
452 return rc;
453 }
454
455
456
457
458
459
460
461
462 static int
463 print_cluster_tickets(pcmk__output_t *out, pe_working_set_t * data_set,
464 gboolean print_spacer)
465 {
466 GHashTableIter iter;
467 gpointer key, value;
468
469 if (g_hash_table_size(data_set->tickets) == 0) {
470 return pcmk_rc_no_output;
471 }
472
473 PCMK__OUTPUT_SPACER_IF(out, print_spacer);
474
475
476 out->begin_list(out, NULL, NULL, "Tickets");
477
478
479 g_hash_table_iter_init(&iter, data_set->tickets);
480 while (g_hash_table_iter_next(&iter, &key, &value)) {
481 pe_ticket_t *ticket = (pe_ticket_t *) value;
482 out->message(out, "ticket", ticket);
483 }
484
485
486 out->end_list(out);
487 return pcmk_rc_ok;
488 }
489
490
491
492
493
494
495
496
497
498
499 static int
500 print_neg_locations(pcmk__output_t *out, pe_working_set_t *data_set,
501 unsigned int mon_ops, const char *prefix, GListPtr only_rsc,
502 gboolean print_spacer)
503 {
504 GListPtr gIter, gIter2;
505 int rc = pcmk_rc_no_output;
506
507
508 for (gIter = data_set->placement_constraints; gIter != NULL; gIter = gIter->next) {
509 pe__location_t *location = gIter->data;
510
511 if (prefix != NULL && !g_str_has_prefix(location->id, prefix))
512 continue;
513
514 if (!pcmk__str_in_list(only_rsc, rsc_printable_id(location->rsc_lh)) &&
515 !pcmk__str_in_list(only_rsc, rsc_printable_id(uber_parent(location->rsc_lh)))) {
516 continue;
517 }
518
519 for (gIter2 = location->node_list_rh; gIter2 != NULL; gIter2 = gIter2->next) {
520 pe_node_t *node = (pe_node_t *) gIter2->data;
521
522 if (node->weight < 0) {
523 PCMK__OUTPUT_LIST_HEADER(out, print_spacer, rc, "Negative Location Constraints");
524 out->message(out, "ban", node, location,
525 pcmk_is_set(mon_ops, mon_op_print_clone_detail));
526 }
527 }
528 }
529
530 PCMK__OUTPUT_LIST_FOOTER(out, rc);
531 return rc;
532 }
533
534
535
536
537
538
539
540
541
542 static int
543 print_node_attributes(pcmk__output_t *out, pe_working_set_t *data_set,
544 unsigned int mon_ops, GListPtr only_node,
545 GListPtr only_rsc, gboolean print_spacer)
546 {
547 GListPtr gIter = NULL;
548 int rc = pcmk_rc_no_output;
549
550
551
552
553 for (gIter = data_set->resources; gIter != NULL; gIter = gIter->next) {
554 crm_mon_get_parameters(gIter->data, data_set);
555 }
556
557
558 for (gIter = data_set->nodes; gIter != NULL; gIter = gIter->next) {
559 struct mon_attr_data data;
560
561 data.out = out;
562 data.node = (pe_node_t *) gIter->data;
563
564 if (data.node && data.node->details && data.node->details->online) {
565 GList *attr_list = NULL;
566 GHashTableIter iter;
567 gpointer key, value;
568
569 g_hash_table_iter_init(&iter, data.node->details->attrs);
570 while (g_hash_table_iter_next (&iter, &key, &value)) {
571 attr_list = append_attr_list(attr_list, key);
572 }
573
574 if (attr_list == NULL) {
575 continue;
576 }
577
578 if (!pcmk__str_in_list(only_node, data.node->details->uname)) {
579 continue;
580 }
581
582 PCMK__OUTPUT_LIST_HEADER(out, print_spacer, rc, "Node Attributes");
583
584 out->message(out, "node", data.node, get_resource_display_options(mon_ops),
585 FALSE, NULL,
586 pcmk_is_set(mon_ops, mon_op_print_clone_detail),
587 pcmk_is_set(mon_ops, mon_op_print_brief),
588 pcmk_is_set(mon_ops, mon_op_group_by_node),
589 only_node, only_rsc);
590 g_list_foreach(attr_list, print_node_attribute, &data);
591 g_list_free(attr_list);
592 out->end_list(out);
593 }
594 }
595
596 PCMK__OUTPUT_LIST_FOOTER(out, rc);
597 return rc;
598 }
599
600
601
602
603
604
605
606
607 static int
608 print_failed_actions(pcmk__output_t *out, pe_working_set_t *data_set,
609 GListPtr only_node, GListPtr only_rsc, gboolean print_spacer)
610 {
611 xmlNode *xml_op = NULL;
612 int rc = pcmk_rc_no_output;
613
614 const char *id = NULL;
615
616 if (xmlChildElementCount(data_set->failed) == 0) {
617 return rc;
618 }
619
620 for (xml_op = pcmk__xml_first_child(data_set->failed); xml_op != NULL;
621 xml_op = pcmk__xml_next(xml_op)) {
622 char *rsc = NULL;
623
624 if (!pcmk__str_in_list(only_node, crm_element_value(xml_op, XML_ATTR_UNAME))) {
625 continue;
626 }
627
628 id = crm_element_value(xml_op, XML_LRM_ATTR_TASK_KEY);
629 if (parse_op_key(id ? id : ID(xml_op), &rsc, NULL, NULL) == FALSE) {
630 continue;
631 }
632
633 if (!pcmk__str_in_list(only_rsc, rsc)) {
634 free(rsc);
635 continue;
636 }
637
638 free(rsc);
639
640 PCMK__OUTPUT_LIST_HEADER(out, print_spacer, rc, "Failed Resource Actions");
641 out->message(out, "failed-action", xml_op);
642 }
643
644 PCMK__OUTPUT_LIST_FOOTER(out, rc);
645 return rc;
646 }
647
648 #define CHECK_RC(retcode, retval) \
649 if (retval == pcmk_rc_ok) { \
650 retcode = pcmk_rc_ok; \
651 }
652
653
654
655
656
657
658
659
660
661
662
663
664 void
665 print_status(pcmk__output_t *out, pe_working_set_t *data_set,
666 stonith_history_t *stonith_history, unsigned int mon_ops,
667 unsigned int show, char *prefix, char *only_node, char *only_rsc)
668 {
669 GListPtr unames = NULL;
670 GListPtr resources = NULL;
671
672 unsigned int print_opts = get_resource_display_options(mon_ops);
673 int rc = pcmk_rc_no_output;
674
675 CHECK_RC(rc, out->message(out, "cluster-summary", data_set,
676 pcmk_is_set(mon_ops, mon_op_print_clone_detail),
677 pcmk_is_set(show, mon_show_stack),
678 pcmk_is_set(show, mon_show_dc),
679 pcmk_is_set(show, mon_show_times),
680 pcmk_is_set(show, mon_show_counts),
681 pcmk_is_set(show, mon_show_options)));
682
683 unames = build_uname_list(data_set, only_node);
684 resources = build_rsc_list(data_set, only_rsc);
685
686 if (pcmk_is_set(show, mon_show_nodes) && unames) {
687 PCMK__OUTPUT_SPACER_IF(out, rc == pcmk_rc_ok);
688 CHECK_RC(rc, out->message(out, "node-list", data_set->nodes, unames,
689 resources, print_opts,
690 pcmk_is_set(mon_ops, mon_op_print_clone_detail),
691 pcmk_is_set(mon_ops, mon_op_print_brief),
692 pcmk_is_set(mon_ops, mon_op_group_by_node)));
693 }
694
695
696 if (pcmk_is_set(show, mon_show_resources)) {
697 CHECK_RC(rc, out->message(out, "resource-list", data_set, print_opts,
698 pcmk_is_set(mon_ops, mon_op_group_by_node),
699 pcmk_is_set(mon_ops, mon_op_inactive_resources),
700 pcmk_is_set(mon_ops, mon_op_print_brief), TRUE, unames,
701 resources, rc == pcmk_rc_ok));
702 }
703
704
705 if (pcmk_is_set(show, mon_show_attributes)) {
706 CHECK_RC(rc, print_node_attributes(out, data_set, mon_ops, unames, resources,
707 rc == pcmk_rc_ok));
708 }
709
710
711
712
713 if (pcmk_is_set(show, mon_show_operations)
714 || pcmk_is_set(show, mon_show_failcounts)) {
715
716 CHECK_RC(rc, print_node_summary(out, data_set,
717 pcmk_is_set(show, mon_show_operations),
718 mon_ops, unames, resources,
719 (rc == pcmk_rc_ok)));
720 }
721
722
723 if (pcmk_is_set(show, mon_show_failures)
724 && xml_has_children(data_set->failed)) {
725
726 CHECK_RC(rc, print_failed_actions(out, data_set, unames, resources,
727 rc == pcmk_rc_ok));
728 }
729
730
731 if (pcmk_is_set(show, mon_show_fence_failed)
732 && pcmk_is_set(mon_ops, mon_op_fence_history)) {
733
734 stonith_history_t *hp = stonith__first_matching_event(stonith_history, stonith__event_state_eq,
735 GINT_TO_POINTER(st_failed));
736
737 if (hp) {
738 CHECK_RC(rc, out->message(out, "failed-fencing-history", stonith_history, unames,
739 pcmk_is_set(mon_ops, mon_op_fence_full_history),
740 rc == pcmk_rc_ok));
741 }
742 }
743
744
745 if (pcmk_is_set(show, mon_show_tickets)) {
746 CHECK_RC(rc, print_cluster_tickets(out, data_set, rc == pcmk_rc_ok));
747 }
748
749
750 if (pcmk_is_set(show, mon_show_bans)) {
751 CHECK_RC(rc, print_neg_locations(out, data_set, mon_ops, prefix, resources,
752 rc == pcmk_rc_ok));
753 }
754
755
756 if (pcmk_is_set(mon_ops, mon_op_fence_history)) {
757 if (pcmk_is_set(show, mon_show_fence_worked)) {
758 stonith_history_t *hp = stonith__first_matching_event(stonith_history, stonith__event_state_neq,
759 GINT_TO_POINTER(st_failed));
760
761 if (hp) {
762 CHECK_RC(rc, out->message(out, "fencing-history", hp, unames,
763 pcmk_is_set(mon_ops, mon_op_fence_full_history),
764 rc == pcmk_rc_ok));
765 }
766 } else if (pcmk_is_set(show, mon_show_fence_pending)) {
767 stonith_history_t *hp = stonith__first_matching_event(stonith_history, stonith__event_state_pending, NULL);
768
769 if (hp) {
770 CHECK_RC(rc, out->message(out, "pending-fencing-actions", hp, unames,
771 pcmk_is_set(mon_ops, mon_op_fence_full_history),
772 rc == pcmk_rc_ok));
773 }
774 }
775 }
776
777 g_list_free_full(unames, free);
778 }
779
780
781
782
783
784
785
786
787
788
789
790
791 void
792 print_xml_status(pcmk__output_t *out, pe_working_set_t *data_set,
793 crm_exit_t history_rc, stonith_history_t *stonith_history,
794 unsigned int mon_ops, unsigned int show, char *prefix,
795 char *only_node, char *only_rsc)
796 {
797 GListPtr unames = NULL;
798 GListPtr resources = NULL;
799 unsigned int print_opts = get_resource_display_options(mon_ops);
800
801 out->message(out, "cluster-summary", data_set,
802 pcmk_is_set(mon_ops, mon_op_print_clone_detail),
803 pcmk_is_set(show, mon_show_stack),
804 pcmk_is_set(show, mon_show_dc),
805 pcmk_is_set(show, mon_show_times),
806 pcmk_is_set(show, mon_show_counts),
807 pcmk_is_set(show, mon_show_options));
808
809 unames = build_uname_list(data_set, only_node);
810 resources = build_rsc_list(data_set, only_rsc);
811
812
813 if (pcmk_is_set(show, mon_show_nodes)) {
814 out->message(out, "node-list", data_set->nodes, unames,
815 resources, print_opts,
816 pcmk_is_set(mon_ops, mon_op_print_clone_detail),
817 pcmk_is_set(mon_ops, mon_op_print_brief),
818 pcmk_is_set(mon_ops, mon_op_group_by_node));
819 }
820
821
822 if (pcmk_is_set(show, mon_show_resources)) {
823 out->message(out, "resource-list", data_set, print_opts,
824 pcmk_is_set(mon_ops, mon_op_group_by_node),
825 pcmk_is_set(mon_ops, mon_op_inactive_resources),
826 FALSE, FALSE, unames, resources, FALSE);
827 }
828
829
830 if (pcmk_is_set(show, mon_show_attributes)) {
831 print_node_attributes(out, data_set, mon_ops, unames, resources, FALSE);
832 }
833
834
835
836
837 if (pcmk_is_set(show, mon_show_operations)
838 || pcmk_is_set(show, mon_show_failcounts)) {
839
840 print_node_summary(out, data_set,
841 pcmk_is_set(show, mon_show_operations),
842 mon_ops, unames, resources, FALSE);
843 }
844
845
846 if (pcmk_is_set(show, mon_show_failures)
847 && xml_has_children(data_set->failed)) {
848
849 print_failed_actions(out, data_set, unames, resources, FALSE);
850 }
851
852
853 if (pcmk_is_set(show, mon_show_fencing_all)
854 && pcmk_is_set(mon_ops, mon_op_fence_history)) {
855
856 out->message(out, "full-fencing-history", history_rc, stonith_history,
857 unames, pcmk_is_set(mon_ops, mon_op_fence_full_history),
858 FALSE);
859 }
860
861
862 if (pcmk_is_set(show, mon_show_tickets)) {
863 print_cluster_tickets(out, data_set, FALSE);
864 }
865
866
867 if (pcmk_is_set(show, mon_show_bans)) {
868 print_neg_locations(out, data_set, mon_ops, prefix, resources, FALSE);
869 }
870
871 g_list_free_full(unames, free);
872 g_list_free_full(resources, free);
873 }
874
875
876
877
878
879
880
881
882
883
884
885
886 int
887 print_html_status(pcmk__output_t *out, pe_working_set_t *data_set,
888 stonith_history_t *stonith_history, unsigned int mon_ops,
889 unsigned int show, char *prefix, char *only_node,
890 char *only_rsc)
891 {
892 GListPtr unames = NULL;
893 GListPtr resources = NULL;
894
895 unsigned int print_opts = get_resource_display_options(mon_ops);
896
897 out->message(out, "cluster-summary", data_set,
898 pcmk_is_set(mon_ops, mon_op_print_clone_detail),
899 pcmk_is_set(show, mon_show_stack),
900 pcmk_is_set(show, mon_show_dc),
901 pcmk_is_set(show, mon_show_times),
902 pcmk_is_set(show, mon_show_counts),
903 pcmk_is_set(show, mon_show_options));
904
905 unames = build_uname_list(data_set, only_node);
906 resources = build_rsc_list(data_set, only_rsc);
907
908
909 if (pcmk_is_set(show, mon_show_nodes) && unames) {
910 out->message(out, "node-list", data_set->nodes, unames,
911 resources, print_opts,
912 pcmk_is_set(mon_ops, mon_op_print_clone_detail),
913 pcmk_is_set(mon_ops, mon_op_print_brief),
914 pcmk_is_set(mon_ops, mon_op_group_by_node));
915 }
916
917
918 if (pcmk_is_set(show, mon_show_resources)) {
919 out->message(out, "resource-list", data_set, print_opts,
920 pcmk_is_set(mon_ops, mon_op_group_by_node),
921 pcmk_is_set(mon_ops, mon_op_inactive_resources),
922 pcmk_is_set(mon_ops, mon_op_print_brief), TRUE, unames,
923 resources, FALSE);
924 }
925
926
927 if (pcmk_is_set(show, mon_show_attributes)) {
928 print_node_attributes(out, data_set, mon_ops, unames, resources, FALSE);
929 }
930
931
932
933
934 if (pcmk_is_set(show, mon_show_operations)
935 || pcmk_is_set(show, mon_show_failcounts)) {
936
937 print_node_summary(out, data_set,
938 pcmk_is_set(show, mon_show_operations),
939 mon_ops, unames, resources, FALSE);
940 }
941
942
943 if (pcmk_is_set(show, mon_show_failures)
944 && xml_has_children(data_set->failed)) {
945
946 print_failed_actions(out, data_set, unames, resources, FALSE);
947 }
948
949
950 if (pcmk_is_set(show, mon_show_fence_failed)
951 && pcmk_is_set(mon_ops, mon_op_fence_history)) {
952
953 stonith_history_t *hp = stonith__first_matching_event(stonith_history, stonith__event_state_eq,
954 GINT_TO_POINTER(st_failed));
955
956 if (hp) {
957 out->message(out, "failed-fencing-history", stonith_history, unames,
958 pcmk_is_set(mon_ops, mon_op_fence_full_history), FALSE);
959 }
960 }
961
962
963 if (pcmk_is_set(mon_ops, mon_op_fence_history)) {
964 if (pcmk_is_set(show, mon_show_fence_worked)) {
965 stonith_history_t *hp = stonith__first_matching_event(stonith_history, stonith__event_state_neq,
966 GINT_TO_POINTER(st_failed));
967
968 if (hp) {
969 out->message(out, "fencing-history", hp, unames,
970 pcmk_is_set(mon_ops, mon_op_fence_full_history),
971 FALSE);
972 }
973 } else if (pcmk_is_set(show, mon_show_fence_pending)) {
974 stonith_history_t *hp = stonith__first_matching_event(stonith_history, stonith__event_state_pending, NULL);
975
976 if (hp) {
977 out->message(out, "pending-fencing-actions", hp, unames,
978 pcmk_is_set(mon_ops, mon_op_fence_full_history),
979 FALSE);
980 }
981 }
982 }
983
984
985 if (pcmk_is_set(show, mon_show_tickets)) {
986 print_cluster_tickets(out, data_set, FALSE);
987 }
988
989
990 if (pcmk_is_set(show, mon_show_bans)) {
991 print_neg_locations(out, data_set, mon_ops, prefix, resources, FALSE);
992 }
993
994 g_list_free_full(unames, free);
995 g_list_free_full(resources, free);
996 return 0;
997 }