pacemaker 2.1.7-2.1.7
Scalable High-Availability cluster resource manager
Loading...
Searching...
No Matches
xml_internal.h
Go to the documentation of this file.
1/*
2 * Copyright 2017-2023 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#ifndef PCMK__XML_INTERNAL__H
11# define PCMK__XML_INTERNAL__H
12
13/*
14 * Internal-only wrappers for and extensions to libxml2 (libxslt)
15 */
16
17# include <stdlib.h>
18# include <stdio.h>
19# include <string.h>
20
21# include <crm/crm.h> /* transitively imports qblog.h */
23
24# include <libxml/relaxng.h>
25
69#define PCMK__XML_LOG_BASE(priority, dechunk, postemit, prefix, fmt, ap) \
70do { \
71 if (!(dechunk) && (prefix) == NULL) { /* quick pass */ \
72 qb_log_from_external_source_va(__func__, __FILE__, (fmt), \
73 (priority), __LINE__, 0, (ap)); \
74 (void) (postemit); \
75 } else { \
76 int CXLB_len = 0; \
77 char *CXLB_buf = NULL; \
78 static int CXLB_buffer_len = 0; \
79 static char *CXLB_buffer = NULL; \
80 static uint8_t CXLB_priority = 0; \
81 \
82 CXLB_len = vasprintf(&CXLB_buf, (fmt), (ap)); \
83 \
84 if (CXLB_len <= 0 || CXLB_buf[CXLB_len - 1] == '\n' || !(dechunk)) { \
85 if (CXLB_len < 0) { \
86 CXLB_buf = (char *) "LOG CORRUPTION HAZARD"; /*we don't modify*/\
87 CXLB_priority = QB_MIN(CXLB_priority, LOG_ERR); \
88 } else if (CXLB_len > 0 /* && (dechunk) */ \
89 && CXLB_buf[CXLB_len - 1] == '\n') { \
90 CXLB_buf[CXLB_len - 1] = '\0'; \
91 } \
92 if (CXLB_buffer) { \
93 qb_log_from_external_source(__func__, __FILE__, "%s%s%s", \
94 CXLB_priority, __LINE__, 0, \
95 (prefix) != NULL ? (prefix) : "", \
96 CXLB_buffer, CXLB_buf); \
97 free(CXLB_buffer); \
98 } else { \
99 qb_log_from_external_source(__func__, __FILE__, "%s%s", \
100 (priority), __LINE__, 0, \
101 (prefix) != NULL ? (prefix) : "", \
102 CXLB_buf); \
103 } \
104 if (CXLB_len < 0) { \
105 CXLB_buf = NULL; /* restore temporary override */ \
106 } \
107 CXLB_buffer = NULL; \
108 CXLB_buffer_len = 0; \
109 (void) (postemit); \
110 \
111 } else if (CXLB_buffer == NULL) { \
112 CXLB_buffer_len = CXLB_len; \
113 CXLB_buffer = CXLB_buf; \
114 CXLB_buf = NULL; \
115 CXLB_priority = (priority); /* remember as a running severest */ \
116 \
117 } else { \
118 CXLB_buffer = realloc(CXLB_buffer, 1 + CXLB_buffer_len + CXLB_len); \
119 memcpy(CXLB_buffer + CXLB_buffer_len, CXLB_buf, CXLB_len); \
120 CXLB_buffer_len += CXLB_len; \
121 CXLB_buffer[CXLB_buffer_len] = '\0'; \
122 CXLB_priority = QB_MIN(CXLB_priority, (priority)); /* severest? */ \
123 } \
124 free(CXLB_buf); \
125 } \
126} while (0)
127
128/*
129 * \enum pcmk__xml_fmt_options
130 * \brief Bit flags to control format in XML logs and dumps
131 */
135
138
141
144
147
150
151 // @COMPAT Remove when v1 patchsets are removed
154
155 // @COMPAT Remove when v1 patchsets are removed
158
159 // @COMPAT Remove when v1 patchsets are removed
162};
163
164int pcmk__xml_show(pcmk__output_t *out, const char *prefix, const xmlNode *data,
165 int depth, uint32_t options);
166int pcmk__xml_show_changes(pcmk__output_t *out, const xmlNode *xml);
167
168/* XML search strings for guest, remote and pacemaker_remote nodes */
169
170/* search string to find CIB resources entries for cluster nodes */
171#define PCMK__XP_MEMBER_NODE_CONFIG \
172 "//" XML_TAG_CIB "/" XML_CIB_TAG_CONFIGURATION "/" XML_CIB_TAG_NODES \
173 "/" XML_CIB_TAG_NODE "[not(@type) or @type='member']"
174
175/* search string to find CIB resources entries for guest nodes */
176#define PCMK__XP_GUEST_NODE_CONFIG \
177 "//" XML_TAG_CIB "//" XML_CIB_TAG_CONFIGURATION "//" XML_CIB_TAG_RESOURCE \
178 "//" XML_TAG_META_SETS "//" XML_CIB_TAG_NVPAIR \
179 "[@name='" XML_RSC_ATTR_REMOTE_NODE "']"
180
181/* search string to find CIB resources entries for remote nodes */
182#define PCMK__XP_REMOTE_NODE_CONFIG \
183 "//" XML_TAG_CIB "//" XML_CIB_TAG_CONFIGURATION "//" XML_CIB_TAG_RESOURCE \
184 "[@type='remote'][@provider='pacemaker']"
185
186/* search string to find CIB node status entries for pacemaker_remote nodes */
187#define PCMK__XP_REMOTE_NODE_STATUS \
188 "//" XML_TAG_CIB "//" XML_CIB_TAG_STATUS "//" XML_CIB_TAG_STATE \
189 "[@" XML_NODE_IS_REMOTE "='true']"
199int pcmk__xml2fd(int fd, xmlNode *cur);
200
207
208void pcmk__strip_xml_text(xmlNode *xml);
209const char *pcmk__xe_add_last_written(xmlNode *xe);
210
211xmlNode *pcmk__xe_match(const xmlNode *parent, const char *node_name,
212 const char *attr_n, const char *attr_v);
213
214void pcmk__xe_remove_matching_attrs(xmlNode *element,
215 bool (*match)(xmlAttrPtr, void *),
216 void *user_data);
217
218GString *pcmk__element_xpath(const xmlNode *xml);
219
228char *
230
241 const char *filespec);
242
252static inline bool
253pcmk__xe_is(const xmlNode *xml, const char *name)
254{
255 return (xml != NULL) && (xml->name != NULL) && (name != NULL)
256 && (strcmp((const char *) xml->name, name) == 0);
257}
258
267static inline xmlNode *
268pcmk__xml_first_child(const xmlNode *parent)
269{
270 xmlNode *child = (parent? parent->children : NULL);
271
272 while (child && (child->type == XML_TEXT_NODE)) {
273 child = child->next;
274 }
275 return child;
276}
277
286static inline xmlNode *
287pcmk__xml_next(const xmlNode *child)
288{
289 xmlNode *next = (child? child->next : NULL);
290
291 while (next && (next->type == XML_TEXT_NODE)) {
292 next = next->next;
293 }
294 return next;
295}
296
305static inline xmlNode *
306pcmk__xe_first_child(const xmlNode *parent)
307{
308 xmlNode *child = (parent? parent->children : NULL);
309
310 while (child && (child->type != XML_ELEMENT_NODE)) {
311 child = child->next;
312 }
313 return child;
314}
315
324static inline xmlNode *
325pcmk__xe_next(const xmlNode *child)
326{
327 xmlNode *next = child? child->next : NULL;
328
329 while (next && (next->type != XML_ELEMENT_NODE)) {
330 next = next->next;
331 }
332 return next;
333}
334
343void
344pcmk__xe_set_propv(xmlNodePtr node, va_list pairs);
345
356void
357pcmk__xe_set_props(xmlNodePtr node, ...)
358G_GNUC_NULL_TERMINATED;
359
368static inline xmlAttr *
369pcmk__xe_first_attr(const xmlNode *xe)
370{
371 return (xe == NULL)? NULL : xe->properties;
372}
373
383char *
384pcmk__xpath_node_id(const char *xpath, const char *node);
385
386/* internal XML-related utilities */
387
409
410void pcmk__set_xml_doc_flag(xmlNode *xml, enum xml_private_flags flag);
411
432int
433pcmk__xe_foreach_child(xmlNode *xml, const char *child_element_name,
434 int (*handler)(xmlNode *xml, void *userdata),
435 void *userdata);
436
437static inline const char *
438pcmk__xml_attr_value(const xmlAttr *attr)
439{
440 return ((attr == NULL) || (attr->children == NULL))? NULL
441 : (const char *) attr->children->content;
442}
443
444gboolean pcmk__validate_xml(xmlNode *xml_blob, const char *validation,
445 xmlRelaxNGValidityErrorFunc error_handler,
446 void *error_handler_context);
447
448#endif // PCMK__XML_INTERNAL__H
const char * parent
Definition cib.c:27
const char * name
Definition cib.c:26
char data[0]
Definition cpg.c:10
A dumping ground.
Formatted output for pacemaker tools.
This structure contains everything that makes up a single output formatter.
pcmk__xml_fmt_options
@ pcmk__xml_fmt_close
Include the closing tag of an XML element.
@ pcmk__xml_fmt_diff_plus
Log a created XML subtree.
@ pcmk__xml_fmt_children
Include the children of an XML element.
@ pcmk__xml_fmt_open
Include the opening tag of an XML element, and include XML comments.
@ pcmk__xml_fmt_diff_minus
Log a removed XML subtree.
@ pcmk__xml_fmt_pretty
Include indentation and newlines.
@ pcmk__xml_fmt_filtered
Exclude certain XML attributes (for calculating digests)
@ pcmk__xml_fmt_text
Include XML text nodes.
@ pcmk__xml_fmt_diff_short
Log a minimal version of an XML diff (only showing the changes)
gboolean pcmk__validate_xml(xmlNode *xml_blob, const char *validation, xmlRelaxNGValidityErrorFunc error_handler, void *error_handler_context)
Definition schemas.c:679
void pcmk__set_xml_doc_flag(xmlNode *xml, enum xml_private_flags flag)
Definition xml.c:78
xmlNode * pcmk__xe_match(const xmlNode *parent, const char *node_name, const char *attr_n, const char *attr_v)
Definition xml.c:429
void pcmk__xe_remove_matching_attrs(xmlNode *element, bool(*match)(xmlAttrPtr, void *), void *user_data)
Definition xml.c:593
char * pcmk__xml_artefact_root(enum pcmk__xml_artefact_ns ns)
Definition xml.c:2586
const char * pcmk__xe_add_last_written(xmlNode *xe)
Definition xml.c:1089
int pcmk__xe_foreach_child(xmlNode *xml, const char *child_element_name, int(*handler)(xmlNode *xml, void *userdata), void *userdata)
Definition xml.c:2663
xml_private_flags
@ pcmk__xf_acl_create
@ pcmk__xf_deleted
@ pcmk__xf_acl_enabled
@ pcmk__xf_created
@ pcmk__xf_acl_denied
@ pcmk__xf_dirty
@ pcmk__xf_modified
@ pcmk__xf_acl_deny
@ pcmk__xf_skip
@ pcmk__xf_acl_write
@ pcmk__xf_lazy
@ pcmk__xf_tracking
@ pcmk__xf_none
@ pcmk__xf_processed
@ pcmk__xf_moved
@ pcmk__xf_acl_read
void pcmk__strip_xml_text(xmlNode *xml)
Definition xml.c:962
void pcmk__xe_set_propv(xmlNodePtr node, va_list pairs)
Definition xml.c:2636
int pcmk__xml_show_changes(pcmk__output_t *out, const xmlNode *xml)
GString * pcmk__element_xpath(const xmlNode *xml)
Definition xpath.c:278
int pcmk__xml2fd(int fd, xmlNode *cur)
Definition xml.c:1675
void pcmk__xe_set_props(xmlNodePtr node,...) G_GNUC_NULL_TERMINATED
Definition xml.c:2654
int pcmk__xml_show(pcmk__output_t *out, const char *prefix, const xmlNode *data, int depth, uint32_t options)
pcmk__xml_artefact_ns
@ pcmk__xml_artefact_ns_legacy_xslt
@ pcmk__xml_artefact_ns_legacy_rng
@ pcmk__xml_artefact_ns_base_rng
@ pcmk__xml_artefact_ns_base_xslt
char * pcmk__xpath_node_id(const char *xpath, const char *node)
Definition xpath.c:312
char * pcmk__xml_artefact_path(enum pcmk__xml_artefact_ns ns, const char *filespec)
Definition xml.c:2614