pacemaker 3.0.1-16e74fc4da
Scalable High-Availability cluster resource manager
Loading...
Searching...
No Matches
output_xml.c
Go to the documentation of this file.
1/*
2 * Copyright 2019-2025 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 <ctype.h>
13#include <stdarg.h>
14#include <stdlib.h>
15#include <stdio.h>
16#include <crm/crm.h>
17
18#include <glib.h>
19#include <libxml/tree.h> // xmlNode
20#include <libxml/xmlstring.h> // xmlChar
21
23#include <crm/common/output.h>
24#include <crm/common/xml.h>
25#include <crm/common/xml_internal.h> // pcmk__xml2fd
26
27typedef struct subst_s {
28 const char *from;
29 const char *to;
31
32static const subst_t substitutions[] = {
33 { "Active Resources",
35 { "Assignment Scores",
37 { "Assignment Scores and Utilization Information",
39 { "Cluster Summary",
41 { "Current cluster status",
43 { "Executing Cluster Transition",
45 { "Failed Resource Actions",
47 { "Fencing History",
49 { "Full List of Resources",
51 { "Inactive Resources",
53 { "Migration Summary",
55 { "Negative Location Constraints",
56 PCMK_XE_BANS, },
57 { "Node Attributes",
59 { "Operations",
61 { "Resource Config",
63 { "Resource Operations",
65 { "Revised Cluster Status",
67 { "Timings",
69 { "Transition Summary",
71 { "Utilization Information",
73
74 { NULL, NULL }
75};
76
77/* The first several elements of this struct must be the same as the first
78 * several elements of private_data_s in lib/common/output_html.c. That
79 * struct gets passed to a bunch of the pcmk__output_xml_* functions which
80 * assume an XML private_data_s. Keeping them laid out the same means this
81 * still works.
82 */
83typedef struct private_data_s {
84 /* Begin members that must match the HTML version */
85 xmlNode *root;
86 GQueue *parent_q;
87 GSList *errors;
88 /* End members that must match the HTML version */
89 bool legacy_xml;
90 bool list_element;
92
93static bool
94has_root_node(pcmk__output_t *out)
95{
96 private_data_t *priv = NULL;
97
98 pcmk__assert(out != NULL);
99
100 priv = out->priv;
101 return priv != NULL && priv->root != NULL;
102}
103
104static void
105add_root_node(pcmk__output_t *out)
106{
107 private_data_t *priv = NULL;
108
109 /* has_root_node will assert if out is NULL, so no need to do it here */
110 if (has_root_node(out)) {
111 return;
112 }
113
114 priv = out->priv;
115
116 if (priv->legacy_xml) {
117 priv->root = pcmk__xe_create(NULL, PCMK_XE_CRM_MON);
119 } else {
120 priv->root = pcmk__xe_create(NULL, PCMK_XE_PACEMAKER_RESULT);
122 crm_xml_add(priv->root, PCMK_XA_REQUEST,
123 pcmk__s(out->request, "libpacemaker"));
124 }
125
126 priv->parent_q = g_queue_new();
127 g_queue_push_tail(priv->parent_q, priv->root);
128}
129
130static void
131xml_free_priv(pcmk__output_t *out) {
132 private_data_t *priv = NULL;
133
134 if (out == NULL || out->priv == NULL) {
135 return;
136 }
137
138 priv = out->priv;
139
140 if (has_root_node(out)) {
141 pcmk__xml_free(priv->root);
142 /* The elements of parent_q are xmlNodes that are a part of the
143 * priv->root document, so the above line already frees them. Don't
144 * call g_queue_free_full here.
145 */
146 g_queue_free(priv->parent_q);
147 }
148
149 g_slist_free_full(priv->errors, free);
150 free(priv);
151 out->priv = NULL;
152}
153
154static bool
155xml_init(pcmk__output_t *out) {
156 private_data_t *priv = NULL;
157
158 pcmk__assert(out != NULL);
159
160 /* If xml_init was previously called on this output struct, just return. */
161 if (out->priv != NULL) {
162 return true;
163 } else {
164 out->priv = calloc(1, sizeof(private_data_t));
165 if (out->priv == NULL) {
166 return false;
167 }
168
169 priv = out->priv;
170 }
171
172 priv->errors = NULL;
173
174 return true;
175}
176
177static void
178add_error_node(gpointer data, gpointer user_data) {
179 const char *str = (const char *) data;
180 xmlNodePtr node = (xmlNodePtr) user_data;
181
182 node = pcmk__xe_create(node, PCMK_XE_ERROR);
183 pcmk__xe_set_content(node, "%s", str);
184}
185
186static void
187xml_finish(pcmk__output_t *out, crm_exit_t exit_status, bool print, void **copy_dest) {
188 private_data_t *priv = NULL;
189 xmlNodePtr node;
190
191 pcmk__assert(out != NULL);
192 priv = out->priv;
193
194 if (priv == NULL) {
195 return;
196 }
197
198 add_root_node(out);
199
200 if (priv->legacy_xml) {
201 GSList *node = priv->errors;
202
203 if (exit_status != CRM_EX_OK) {
204 fprintf(stderr, "%s\n", crm_exit_str(exit_status));
205 }
206
207 while (node != NULL) {
208 fprintf(stderr, "%s\n", (char *) node->data);
209 node = node->next;
210 }
211 } else {
212 char *rc_as_str = pcmk__itoa(exit_status);
213
214 node = pcmk__xe_create(priv->root, PCMK_XE_STATUS);
216 PCMK_XA_CODE, rc_as_str,
217 PCMK_XA_MESSAGE, crm_exit_str(exit_status),
218 NULL);
219
220 if (g_slist_length(priv->errors) > 0) {
221 xmlNodePtr errors_node = pcmk__xe_create(node, PCMK_XE_ERRORS);
222 g_slist_foreach(priv->errors, add_error_node, (gpointer) errors_node);
223 }
224
225 free(rc_as_str);
226 }
227
228 if (print) {
229 pcmk__xml2fd(fileno(out->dest), priv->root);
230 }
231
232 if (copy_dest != NULL) {
233 *copy_dest = pcmk__xml_copy(NULL, priv->root);
234 }
235}
236
237static void
238xml_reset(pcmk__output_t *out) {
239 pcmk__assert(out != NULL);
240
241 out->dest = freopen(NULL, "w", out->dest);
242 pcmk__assert(out->dest != NULL);
243
244 xml_free_priv(out);
245 xml_init(out);
246}
247
248static void
249xml_subprocess_output(pcmk__output_t *out, int exit_status,
250 const char *proc_stdout, const char *proc_stderr) {
251 xmlNodePtr node, child_node;
252 char *rc_as_str = NULL;
253
254 pcmk__assert(out != NULL);
255
256 rc_as_str = pcmk__itoa(exit_status);
257
259 PCMK_XA_CODE, rc_as_str,
260 NULL);
261
262 if (proc_stdout != NULL) {
263 child_node = pcmk__xe_create(node, PCMK_XE_OUTPUT);
264 pcmk__xe_set_content(child_node, "%s", proc_stdout);
265 crm_xml_add(child_node, PCMK_XA_SOURCE, "stdout");
266 }
267
268 if (proc_stderr != NULL) {
269 child_node = pcmk__xe_create(node, PCMK_XE_OUTPUT);
270 pcmk__xe_set_content(child_node, "%s", proc_stderr);
271 crm_xml_add(child_node, PCMK_XA_SOURCE, "stderr");
272 }
273
274 free(rc_as_str);
275}
276
277static void
278xml_version(pcmk__output_t *out, bool extended) {
279 const char *author = "Andrew Beekhof and the Pacemaker project "
280 "contributors";
281 pcmk__assert(out != NULL);
282
284 PCMK_XA_PROGRAM, "Pacemaker",
286 PCMK_XA_AUTHOR, author,
289 NULL);
290}
291
292G_GNUC_PRINTF(2, 3)
293static void
294xml_err(pcmk__output_t *out, const char *format, ...) {
295 private_data_t *priv = NULL;
296 int len = 0;
297 char *buf = NULL;
298 va_list ap;
299
300 pcmk__assert((out != NULL) && (out->priv != NULL));
301 priv = out->priv;
302
303 add_root_node(out);
304
305 va_start(ap, format);
306 len = vasprintf(&buf, format, ap);
307 pcmk__assert(len > 0);
308 va_end(ap);
309
310 priv->errors = g_slist_append(priv->errors, buf);
311}
312
313G_GNUC_PRINTF(2, 3)
314static int
315xml_info(pcmk__output_t *out, const char *format, ...) {
316 return pcmk_rc_no_output;
317}
318
319static void
320xml_output_xml(pcmk__output_t *out, const char *name, const char *buf) {
321 xmlNodePtr parent = NULL;
322 xmlNodePtr cdata_node = NULL;
323
324 pcmk__assert(out != NULL);
325
327 if (parent == NULL) {
328 return;
329 }
330 cdata_node = xmlNewCDataBlock(parent->doc, (const xmlChar *) buf,
331 strlen(buf));
332 xmlAddChild(parent, cdata_node);
333}
334
335G_GNUC_PRINTF(4, 5)
336static void
337xml_begin_list(pcmk__output_t *out, const char *singular_noun, const char *plural_noun,
338 const char *format, ...) {
339 va_list ap;
340 char *name = NULL;
341 char *buf = NULL;
342 int len;
343 private_data_t *priv = NULL;
344
345 pcmk__assert((out != NULL) && (out->priv != NULL));
346 priv = out->priv;
347
348 va_start(ap, format);
349 len = vasprintf(&buf, format, ap);
350 pcmk__assert(len >= 0);
351 va_end(ap);
352
353 for (const subst_t *s = substitutions; s->from != NULL; s++) {
354 if (strcmp(s->from, buf) == 0) {
355 name = g_strdup(s->to);
356 break;
357 }
358 }
359
360 if (name == NULL) {
361 name = g_ascii_strdown(buf, -1);
362 }
363
364 if (priv->list_element) {
367 NULL);
368 } else {
370 }
371
372 g_free(name);
373 free(buf);
374}
375
376G_GNUC_PRINTF(3, 4)
377static void
378xml_list_item(pcmk__output_t *out, const char *name, const char *format, ...) {
379 xmlNodePtr item_node = NULL;
380 va_list ap;
381 char *buf = NULL;
382 int len;
383
384 pcmk__assert(out != NULL);
385
386 va_start(ap, format);
387 len = vasprintf(&buf, format, ap);
388 pcmk__assert(len >= 0);
389 va_end(ap);
390
391 item_node = pcmk__output_create_xml_text_node(out, PCMK_XE_ITEM, buf);
392
393 if (name != NULL) {
394 crm_xml_add(item_node, PCMK_XA_NAME, name);
395 }
396
397 free(buf);
398}
399
400static void
401xml_increment_list(pcmk__output_t *out) {
402 /* This function intentially left blank */
403}
404
405static void
406xml_end_list(pcmk__output_t *out) {
407 private_data_t *priv = NULL;
408
409 pcmk__assert((out != NULL) && (out->priv != NULL));
410 priv = out->priv;
411
412 if (priv->list_element) {
413 char *buf = NULL;
414 xmlNodePtr node;
415
416 /* Do not free node here - it's still part of the document */
417 node = g_queue_pop_tail(priv->parent_q);
418 buf = crm_strdup_printf("%lu", xmlChildElementCount(node));
419 crm_xml_add(node, PCMK_XA_COUNT, buf);
420 free(buf);
421 } else {
422 /* Do not free this result - it's still part of the document */
423 g_queue_pop_tail(priv->parent_q);
424 }
425}
426
427static bool
428xml_is_quiet(pcmk__output_t *out) {
429 return false;
430}
431
432static void
433xml_spacer(pcmk__output_t *out) {
434 /* This function intentionally left blank */
435}
436
437static void
438xml_progress(pcmk__output_t *out, bool end) {
439 /* This function intentionally left blank */
440}
441
444 pcmk__output_t *retval = calloc(1, sizeof(pcmk__output_t));
445
446 if (retval == NULL) {
447 return NULL;
448 }
449
450 retval->fmt_name = "xml";
451 retval->request = pcmk__quote_cmdline(argv);
452
453 retval->init = xml_init;
454 retval->free_priv = xml_free_priv;
455 retval->finish = xml_finish;
456 retval->reset = xml_reset;
457
459 retval->message = pcmk__call_message;
460
461 retval->subprocess_output = xml_subprocess_output;
462 retval->version = xml_version;
463 retval->info = xml_info;
464 retval->transient = xml_info;
465 retval->err = xml_err;
466 retval->output_xml = xml_output_xml;
467
468 retval->begin_list = xml_begin_list;
469 retval->list_item = xml_list_item;
470 retval->increment_list = xml_increment_list;
471 retval->end_list = xml_end_list;
472
473 retval->is_quiet = xml_is_quiet;
474 retval->spacer = xml_spacer;
475 retval->progress = xml_progress;
476 retval->prompt = pcmk__text_prompt;
477
478 return retval;
479}
480
481xmlNodePtr
483 va_list args;
484 xmlNodePtr node = NULL;
485
486 pcmk__assert(out != NULL);
487 CRM_CHECK(pcmk__str_any_of(out->fmt_name, "xml", "html", NULL), return NULL);
488
489 node = pcmk__output_create_xml_node(out, name, NULL);
490
491 va_start(args, name);
492 pcmk__xe_set_propv(node, args);
493 va_end(args);
494
496 return node;
497}
498
499void
501 private_data_t *priv = NULL;
502 xmlNodePtr parent = NULL;
503
504 pcmk__assert((out != NULL) && (out->priv != NULL) && (node != NULL));
505 CRM_CHECK(pcmk__str_any_of(out->fmt_name, "xml", "html", NULL), return);
506
507 add_root_node(out);
508
509 priv = out->priv;
510 parent = g_queue_peek_tail(priv->parent_q);
511
512 // Shouldn't happen unless the caller popped priv->root
513 CRM_CHECK(parent != NULL, return);
514
515 pcmk__xml_copy(parent, node);
516}
517
518xmlNodePtr
520 xmlNodePtr node = NULL;
521 private_data_t *priv = NULL;
522 va_list args;
523
524 pcmk__assert((out != NULL) && (out->priv != NULL));
525 CRM_CHECK(pcmk__str_any_of(out->fmt_name, "xml", "html", NULL), return NULL);
526
527 add_root_node(out);
528
529 priv = out->priv;
530
531 node = pcmk__xe_create(g_queue_peek_tail(priv->parent_q), name);
532 va_start(args, name);
533 pcmk__xe_set_propv(node, args);
534 va_end(args);
535
536 return node;
537}
538
539xmlNodePtr
540pcmk__output_create_xml_text_node(pcmk__output_t *out, const char *name, const char *content) {
541 xmlNodePtr node = NULL;
542
543 pcmk__assert(out != NULL);
544 CRM_CHECK(pcmk__str_any_of(out->fmt_name, "xml", "html", NULL), return NULL);
545
546 node = pcmk__output_create_xml_node(out, name, NULL);
547 pcmk__xe_set_content(node, "%s", content);
548 return node;
549}
550
551void
553 private_data_t *priv = NULL;
554
555 pcmk__assert((out != NULL) && (out->priv != NULL) && (parent != NULL));
556 CRM_CHECK(pcmk__str_any_of(out->fmt_name, "xml", "html", NULL), return);
557
558 add_root_node(out);
559
560 priv = out->priv;
561
562 g_queue_push_tail(priv->parent_q, parent);
563}
564
565void
567 private_data_t *priv = NULL;
568
569 pcmk__assert((out != NULL) && (out->priv != NULL));
570 CRM_CHECK(pcmk__str_any_of(out->fmt_name, "xml", "html", NULL), return);
571
572 add_root_node(out);
573
574 priv = out->priv;
575
576 pcmk__assert(g_queue_get_length(priv->parent_q) > 0);
577 /* Do not free this result - it's still part of the document */
578 g_queue_pop_tail(priv->parent_q);
579}
580
581xmlNodePtr
583 private_data_t *priv = NULL;
584
585 pcmk__assert((out != NULL) && (out->priv != NULL));
586 CRM_CHECK(pcmk__str_any_of(out->fmt_name, "xml", "html", NULL), return NULL);
587
588 add_root_node(out);
589
590 priv = out->priv;
591
592 /* If queue is empty NULL will be returned */
593 return g_queue_peek_tail(priv->parent_q);
594}
595
596bool
598{
599 private_data_t *priv = NULL;
600
601 pcmk__assert(out != NULL);
602
603 if (!pcmk__str_eq(out->fmt_name, "xml", pcmk__str_none)) {
604 return false;
605 }
606
607 pcmk__assert(out->priv != NULL);
608
609 priv = out->priv;
610 return priv->legacy_xml;
611}
612
613void
615{
616 private_data_t *priv = NULL;
617
618 pcmk__assert(out != NULL);
619
620 if (!pcmk__str_eq(out->fmt_name, "xml", pcmk__str_none)) {
621 return;
622 }
623
624 pcmk__assert(out->priv != NULL);
625
626 priv = out->priv;
627 priv->legacy_xml = true;
628}
629
630void
632{
633 private_data_t *priv = NULL;
634
635 pcmk__assert(out != NULL);
636
637 if (!pcmk__str_eq(out->fmt_name, "xml", pcmk__str_none)) {
638 return;
639 }
640
641 pcmk__assert(out->priv != NULL);
642
643 priv = out->priv;
644 priv->list_element = true;
645}
const char * parent
Definition cib.c:27
const char * name
Definition cib.c:26
gchar * pcmk__quote_cmdline(gchar **argv)
Definition cmdline.c:163
#define PACEMAKER_VERSION
Definition config.h:430
#define CRM_FEATURES
Definition config.h:30
#define PCMK__API_VERSION
Definition config.h:463
#define BUILD_VERSION
Definition config.h:5
char data[0]
Definition cpg.c:10
A dumping ground.
#define CRM_CHECK(expr, failure_action)
Definition logging.h:213
Control output from tools.
struct private_data_s private_data_t
void void void void void pcmk__text_prompt(const char *prompt, bool echo, char **dest)
int pcmk__call_message(pcmk__output_t *out, const char *message_id,...)
Definition output.c:176
void pcmk__register_message(pcmk__output_t *out, const char *message_id, pcmk__message_fn_t fn)
Definition output.c:198
void pcmk__output_xml_add_node_copy(pcmk__output_t *out, xmlNodePtr node)
Definition output_xml.c:500
void pcmk__output_xml_pop_parent(pcmk__output_t *out)
Definition output_xml.c:566
void pcmk__output_set_legacy_xml(pcmk__output_t *out)
Definition output_xml.c:614
void pcmk__output_xml_push_parent(pcmk__output_t *out, xmlNodePtr parent)
Definition output_xml.c:552
bool pcmk__output_get_legacy_xml(pcmk__output_t *out)
Definition output_xml.c:597
xmlNodePtr pcmk__output_xml_peek_parent(pcmk__output_t *out)
Definition output_xml.c:582
xmlNodePtr pcmk__output_create_xml_node(pcmk__output_t *out, const char *name,...)
Definition output_xml.c:519
xmlNodePtr pcmk__output_xml_create_parent(pcmk__output_t *out, const char *name,...)
Definition output_xml.c:482
struct subst_s subst_t
struct private_data_s private_data_t
void pcmk__output_enable_list_element(pcmk__output_t *out)
Definition output_xml.c:631
pcmk__output_t * pcmk__mk_xml_output(char **argv)
Definition output_xml.c:443
xmlNodePtr pcmk__output_create_xml_text_node(pcmk__output_t *out, const char *name, const char *content)
Definition output_xml.c:540
@ CRM_EX_OK
Success.
Definition results.h:233
@ pcmk_rc_no_output
Definition results.h:128
const char * crm_exit_str(crm_exit_t exit_code)
Definition results.c:757
enum crm_exit_e crm_exit_t
Exit status codes for tools and daemons.
#define pcmk__assert(expr)
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
@ pcmk__str_none
bool pcmk__str_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
Definition strings.c:1053
This structure contains everything that makes up a single output formatter.
void(* end_list)(pcmk__output_t *out)
void(* version)(pcmk__output_t *out, bool extended)
int(* message)(pcmk__output_t *out, const char *message_id,...)
bool(* is_quiet)(pcmk__output_t *out)
const char * fmt_name
The name of this output formatter.
FILE * dest
Where output should be written.
void void void(* increment_list)(pcmk__output_t *out)
void(* register_message)(pcmk__output_t *out, const char *message_id, pcmk__message_fn_t fn)
int int void void(* output_xml)(pcmk__output_t *out, const char *name, const char *buf)
int int void(* err)(pcmk__output_t *out, const char *format,...) G_GNUC_PRINTF(2
void(* finish)(pcmk__output_t *out, crm_exit_t exit_status, bool print, void **copy_dest)
void(* prompt)(const char *prompt, bool echo, char **dest)
void(* subprocess_output)(pcmk__output_t *out, int exit_status, const char *proc_stdout, const char *proc_stderr)
void(* begin_list)(pcmk__output_t *out, const char *singular_noun, const char *plural_noun, const char *format,...) G_GNUC_PRINTF(4
bool(* init)(pcmk__output_t *out)
void * priv
Implementation-specific private data.
void void(* list_item)(pcmk__output_t *out, const char *name, const char *format,...) G_GNUC_PRINTF(3
void(* spacer)(pcmk__output_t *out)
void(* progress)(pcmk__output_t *out, bool end)
void(* reset)(pcmk__output_t *out)
int(* info)(pcmk__output_t *out, const char *format,...) G_GNUC_PRINTF(2
int int(* transient)(pcmk__output_t *out, const char *format,...) G_GNUC_PRINTF(2
void(* free_priv)(pcmk__output_t *out)
gchar * request
A copy of the request that generated this output.
Wrappers for and extensions to libxml2.
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
xmlNode * pcmk__xe_create(xmlNode *parent, const char *name)
void void pcmk__xe_set_propv(xmlNodePtr node, va_list pairs)
void pcmk__xe_set_content(xmlNode *node, const char *format,...) G_GNUC_PRINTF(2
void pcmk__xe_set_props(xmlNodePtr node,...) G_GNUC_NULL_TERMINATED
xmlNode * pcmk__xml_copy(xmlNode *parent, xmlNode *src)
Definition xml.c:832
void pcmk__xml_free(xmlNode *xml)
Definition xml.c:816
int pcmk__xml2fd(int fd, xmlNode *cur)
Definition xml_io.c:583
#define PCMK_XA_SOURCE
Definition xml_names.h:401
#define PCMK_XE_STATUS
Definition xml_names.h:204
#define PCMK_XA_CODE
Definition xml_names.h:248
#define PCMK_XA_PROGRAM
Definition xml_names.h:360
#define PCMK_XE_FAILURES
Definition xml_names.h:111
#define PCMK_XE_ACTIONS
Definition xml_names.h:61
#define PCMK_XE_TRANSITION
Definition xml_names.h:216
#define PCMK_XE_UTILIZATIONS
Definition xml_names.h:218
#define PCMK_XE_ALLOCATIONS
Definition xml_names.h:67
#define PCMK_XE_LIST
Definition xml_names.h:128
#define PCMK_XE_ALLOCATIONS_UTILIZATIONS
Definition xml_names.h:68
#define PCMK_XE_CLUSTER_STATUS
Definition xml_names.h:85
#define PCMK_XE_CRM_MON
Definition xml_names.h:92
#define PCMK_XA_API_VERSION
Definition xml_names.h:235
#define PCMK_XA_FEATURES
Definition xml_names.h:286
#define PCMK_XA_REQUEST
Definition xml_names.h:380
#define PCMK_XA_COUNT
Definition xml_names.h:252
#define PCMK_XA_MESSAGE
Definition xml_names.h:324
#define PCMK_XE_RESOURCES
Definition xml_names.h:179
#define PCMK_XE_VERSION
Definition xml_names.h:220
#define PCMK_XE_NODE_ATTRIBUTES
Definition xml_names.h:138
#define PCMK_XE_RESOURCE_CONFIG
Definition xml_names.h:175
#define PCMK_XE_ERRORS
Definition xml_names.h:108
#define PCMK_XA_VERSION
Definition xml_names.h:444
#define PCMK_XA_AUTHOR
Definition xml_names.h:237
#define PCMK_XE_SUMMARY
Definition xml_names.h:207
#define PCMK_XE_FENCE_HISTORY
Definition xml_names.h:115
#define PCMK_XE_BANS
Definition xml_names.h:71
#define PCMK_XE_PACEMAKER_RESULT
Definition xml_names.h:156
#define PCMK_XA_BUILD
Definition xml_names.h:241
#define PCMK_XE_ERROR
Definition xml_names.h:107
#define PCMK_XE_COMMAND
Definition xml_names.h:86
#define PCMK_XE_ITEM
Definition xml_names.h:124
#define PCMK_XA_NAME
Definition xml_names.h:330
#define PCMK_XE_OUTPUT
Definition xml_names.h:153
#define PCMK_XE_TIMINGS
Definition xml_names.h:215
#define PCMK_XE_OPERATIONS
Definition xml_names.h:151
#define PCMK_XE_NODE_HISTORY
Definition xml_names.h:139
#define PCMK_XE_REVISED_CLUSTER_STATUS
Definition xml_names.h:182