pacemaker  2.1.5-b7adf64e51
Scalable High-Availability cluster resource manager
xml.h
Go to the documentation of this file.
1 /*
2  * Copyright 2004-2022 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__CRM_COMMON_XML__H
11 # define PCMK__CRM_COMMON_XML__H
12 
13 
14 # include <stdio.h>
15 # include <sys/types.h>
16 # include <unistd.h>
17 
18 # include <stdlib.h>
19 # include <errno.h>
20 # include <fcntl.h>
21 
22 # include <libxml/tree.h>
23 # include <libxml/xpath.h>
24 
25 # include <crm/crm.h>
26 # include <crm/common/nvpair.h>
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
38 /* Define compression parameters for IPC messages
39  *
40  * Compression costs a LOT, so we don't want to do it unless we're hitting
41  * message limits. Currently, we use 128KB as the threshold, because higher
42  * values don't play well with the heartbeat stack. With an earlier limit of
43  * 10KB, compressing 184 of 1071 messages accounted for 23% of the total CPU
44  * used by the cib.
45  */
46 # define CRM_BZ2_BLOCKS 4
47 # define CRM_BZ2_WORK 20
48 # define CRM_BZ2_THRESHOLD 128 * 1024
49 
50 typedef const xmlChar *pcmkXmlStr;
51 
52 gboolean add_message_xml(xmlNode * msg, const char *field, xmlNode * xml);
53 xmlNode *get_message_xml(const xmlNode *msg, const char *field);
54 
55 xmlDoc *getDocPtr(xmlNode * node);
56 
57 /*
58  * \brief xmlCopyPropList ACLs-sensitive replacement expading i++ notation
59  *
60  * The gist is the same as with \c{xmlCopyPropList(target, src->properties)}.
61  * The function exits prematurely when any attribute cannot be copied for
62  * ACLs violation. Even without bailing out, the result can possibly be
63  * incosistent with expectations in that case, hence the caller shall,
64  * aposteriori, verify that no document-level-tracked denial was indicated
65  * with \c{xml_acl_denied(target)} and drop whole such intermediate object.
66  *
67  * \param[in,out] target Element to receive attributes from #src element
68  * \param[in] src Element carrying attributes to copy over to #target
69  *
70  * \note Original commit 1c632c506 sadly haven't stated which otherwise
71  * assumed behaviours of xmlCopyPropList were missing beyond otherwise
72  * custom extensions like said ACLs and "atomic increment" (that landed
73  * later on, anyway).
74  */
75 void copy_in_properties(xmlNode *target, xmlNode *src);
76 
77 void expand_plus_plus(xmlNode * target, const char *name, const char *value);
78 void fix_plus_plus_recursive(xmlNode * target);
79 
80 /*
81  * Create a node named "name" as a child of "parent"
82  * If parent is NULL, creates an unconnected node.
83  *
84  * Returns the created node
85  *
86  */
87 xmlNode *create_xml_node(xmlNode * parent, const char *name);
88 
89 /*
90  * Create a node named "name" as a child of "parent", giving it the provided
91  * text content.
92  * If parent is NULL, creates an unconnected node.
93  *
94  * Returns the created node
95  *
96  */
97 xmlNode *pcmk_create_xml_text_node(xmlNode * parent, const char *name, const char *content);
98 
99 /*
100  * Create a new HTML node named "element_name" as a child of "parent", giving it the
101  * provided text content. Optionally, apply a CSS #id and #class.
102  *
103  * Returns the created node.
104  */
105 xmlNode *pcmk_create_html_node(xmlNode * parent, const char *element_name, const char *id,
106  const char *class_name, const char *text);
107 
108 /*
109  *
110  */
111 void purge_diff_markers(xmlNode * a_node);
112 
113 /*
114  * Returns a deep copy of src_node
115  *
116  */
117 xmlNode *copy_xml(xmlNode * src_node);
118 
119 /*
120  * Add a copy of xml_node to new_parent
121  */
122 xmlNode *add_node_copy(xmlNode * new_parent, xmlNode * xml_node);
123 
124 int add_node_nocopy(xmlNode * parent, const char *name, xmlNode * child);
125 
126 /*
127  * XML I/O Functions
128  *
129  * Whitespace between tags is discarded.
130  */
131 xmlNode *filename2xml(const char *filename);
132 
133 xmlNode *stdin2xml(void);
134 
135 xmlNode *string2xml(const char *input);
136 
137 int write_xml_fd(xmlNode * xml_node, const char *filename, int fd, gboolean compress);
138 int write_xml_file(xmlNode * xml_node, const char *filename, gboolean compress);
139 
140 char *dump_xml_formatted(xmlNode * msg);
141 /* Also dump the text node with xml_log_option_text enabled */
142 char *dump_xml_formatted_with_text(xmlNode * msg);
143 
144 char *dump_xml_unformatted(xmlNode * msg);
145 
146 /*
147  * Diff related Functions
148  */
149 xmlNode *diff_xml_object(xmlNode * left, xmlNode * right, gboolean suppress);
150 
151 xmlNode *subtract_xml_object(xmlNode * parent, xmlNode * left, xmlNode * right,
152  gboolean full, gboolean * changed, const char *marker);
153 
154 gboolean can_prune_leaf(xmlNode * xml_node);
155 
156 /*
157  * Searching & Modifying
158  */
159 xmlNode *find_xml_node(const xmlNode *root, const char *search_path,
160  gboolean must_find);
161 
162 void xml_remove_prop(xmlNode * obj, const char *name);
163 
164 gboolean replace_xml_child(xmlNode * parent, xmlNode * child, xmlNode * update,
165  gboolean delete_only);
166 
167 gboolean update_xml_child(xmlNode * child, xmlNode * to_update);
168 
169 int find_xml_children(xmlNode ** children, xmlNode * root,
170  const char *tag, const char *field, const char *value,
171  gboolean search_matches);
172 
173 xmlNode *get_xpath_object(const char *xpath, xmlNode * xml_obj, int error_level);
174 xmlNode *get_xpath_object_relative(const char *xpath, xmlNode * xml_obj, int error_level);
175 
176 static inline const char *
177 crm_element_name(const xmlNode *xml)
178 {
179  return xml? (const char *)(xml->name) : NULL;
180 }
181 
182 static inline const char *
183 crm_map_element_name(const xmlNode *xml)
184 {
185  const char *name = crm_element_name(xml);
186 
187  if (strcmp(name, "master") == 0) {
188  return "clone";
189  } else {
190  return name;
191  }
192 }
193 
194 gboolean xml_has_children(const xmlNode * root);
195 
196 char *calculate_on_disk_digest(xmlNode * local_cib);
197 char *calculate_operation_digest(xmlNode * local_cib, const char *version);
198 char *calculate_xml_versioned_digest(xmlNode * input, gboolean sort, gboolean do_filter,
199  const char *version);
200 
201 /* schema-related functions (from schemas.c) */
202 gboolean validate_xml(xmlNode * xml_blob, const char *validation, gboolean to_logs);
203 gboolean validate_xml_verbose(xmlNode * xml_blob);
204 
242 int update_validation(xmlNode **xml_blob, int *best, int max,
243  gboolean transform, gboolean to_logs);
244 
245 int get_schema_version(const char *name);
246 const char *get_schema_name(int version);
247 const char *xml_latest_schema(void);
248 gboolean cli_config_update(xmlNode ** xml, int *best_version, gboolean to_logs);
249 
255 void crm_xml_init(void);
256 void crm_xml_cleanup(void);
257 
258 void pcmk_free_xml_subtree(xmlNode *xml);
259 void free_xml(xmlNode * child);
260 
261 xmlNode *first_named_child(const xmlNode *parent, const char *name);
262 xmlNode *crm_next_same_xml(const xmlNode *sibling);
263 
264 xmlNode *sorted_xml(xmlNode * input, xmlNode * parent, gboolean recursive);
265 xmlXPathObjectPtr xpath_search(xmlNode * xml_top, const char *path);
266 void crm_foreach_xpath_result(xmlNode *xml, const char *xpath,
267  void (*helper)(xmlNode*, void*), void *user_data);
268 xmlNode *expand_idref(xmlNode * input, xmlNode * top);
269 
270 void freeXpathObject(xmlXPathObjectPtr xpathObj);
271 xmlNode *getXpathResult(xmlXPathObjectPtr xpathObj, int index);
272 void dedupXpathResults(xmlXPathObjectPtr xpathObj);
273 
274 static inline int numXpathResults(xmlXPathObjectPtr xpathObj)
275 {
276  if(xpathObj == NULL || xpathObj->nodesetval == NULL) {
277  return 0;
278  }
279  return xpathObj->nodesetval->nodeNr;
280 }
281 
282 bool xml_tracking_changes(xmlNode * xml);
283 bool xml_document_dirty(xmlNode *xml);
284 void xml_track_changes(xmlNode * xml, const char *user, xmlNode *acl_source, bool enforce_acls);
285 void xml_calculate_changes(xmlNode *old_xml, xmlNode *new_xml);
286 void xml_calculate_significant_changes(xmlNode *old_xml, xmlNode *new_xml);
287 void xml_accept_changes(xmlNode * xml);
288 void xml_log_changes(uint8_t level, const char *function, xmlNode *xml);
289 void xml_log_patchset(uint8_t level, const char *function, xmlNode *xml);
290 bool xml_patch_versions(const xmlNode *patchset, int add[3], int del[3]);
291 
292 xmlNode *xml_create_patchset(
293  int format, xmlNode *source, xmlNode *target, bool *config, bool manage_version);
294 int xml_apply_patchset(xmlNode *xml, xmlNode *patchset, bool check_version);
295 
296 void patchset_process_digest(xmlNode *patch, xmlNode *source, xmlNode *target, bool with_digest);
297 
298 void save_xml_to_file(xmlNode * xml, const char *desc, const char *filename);
299 
300 char * crm_xml_escape(const char *text);
301 void crm_xml_sanitize_id(char *id);
302 void crm_xml_set_id(xmlNode *xml, const char *format, ...) G_GNUC_PRINTF(2, 3);
303 
304 #if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
305 #include <crm/common/xml_compat.h>
306 #endif
307 
308 #ifdef __cplusplus
309 }
310 #endif
311 
312 #endif
xmlNode * get_xpath_object_relative(const char *xpath, xmlNode *xml_obj, int error_level)
Definition: xpath.c:192
A dumping ground.
const char * name
Definition: cib.c:24
xmlNode * first_named_child(const xmlNode *parent, const char *name)
Definition: xml.c:2930
void crm_xml_cleanup(void)
Definition: xml.c:2993
xmlNode * pcmk_create_html_node(xmlNode *parent, const char *element_name, const char *id, const char *class_name, const char *text)
Definition: xml.c:786
xmlNode * find_xml_node(const xmlNode *root, const char *search_path, gboolean must_find)
Definition: xml.c:470
void xml_track_changes(xmlNode *xml, const char *user, xmlNode *acl_source, bool enforce_acls)
Definition: xml.c:301
void crm_xml_init(void)
Initialize the CRM XML subsystem.
Definition: xml.c:2971
int write_xml_file(xmlNode *xml_node, const char *filename, gboolean compress)
Write XML to a file.
Definition: xml.c:1361
int get_schema_version(const char *name)
Definition: schemas.c:1033
void copy_in_properties(xmlNode *target, xmlNode *src)
Definition: xml.c:545
void xml_accept_changes(xmlNode *xml)
Definition: xml.c:445
xmlNode * filename2xml(const char *filename)
Definition: xml.c:1106
void dedupXpathResults(xmlXPathObjectPtr xpathObj)
Definition: xpath.c:101
void purge_diff_markers(xmlNode *a_node)
Definition: patchset.c:1397
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
Definition: xpath.c:214
Deprecated Pacemaker XML API.
xmlNode * string2xml(const char *input)
Definition: xml.c:930
void crm_xml_sanitize_id(char *id)
Sanitize a string so it is usable as an XML ID.
Definition: xml.c:1190
gboolean validate_xml(xmlNode *xml_blob, const char *validation, gboolean to_logs)
Definition: schemas.c:707
xmlDoc * getDocPtr(xmlNode *node)
Definition: xml.c:711
gboolean validate_xml_verbose(xmlNode *xml_blob)
Definition: schemas.c:679
void expand_plus_plus(xmlNode *target, const char *name, const char *value)
Update current XML attribute value per parsed integer assignment statement.
Definition: xml.c:612
bool xml_tracking_changes(xmlNode *xml)
Definition: xml.c:316
xmlNode * copy_xml(xmlNode *src_node)
Definition: xml.c:891
char * calculate_operation_digest(xmlNode *local_cib, const char *version)
Calculate and return digest of XML operation.
Definition: digest.c:153
xmlNode * stdin2xml(void)
Definition: xml.c:991
void pcmk_free_xml_subtree(xmlNode *xml)
Definition: xml.c:808
int xml_apply_patchset(xmlNode *xml, xmlNode *patchset, bool check_version)
Definition: patchset.c:1317
gboolean update_xml_child(xmlNode *child, xmlNode *to_update)
Definition: xml.c:2749
xmlNode * pcmk_create_xml_text_node(xmlNode *parent, const char *name, const char *content)
Definition: xml.c:774
xmlNode * add_node_copy(xmlNode *new_parent, xmlNode *xml_node)
Definition: xml.c:727
void crm_xml_set_id(xmlNode *xml, const char *format,...) G_GNUC_PRINTF(2
xmlNode * expand_idref(xmlNode *input, xmlNode *top)
Definition: xml.c:3002
bool xml_document_dirty(xmlNode *xml)
Definition: xml.c:323
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition: xml.c:749
char * dump_xml_formatted(xmlNode *msg)
Definition: xml.c:2106
gboolean add_message_xml(xmlNode *msg, const char *field, xmlNode *xml)
Definition: messages.c:160
void free_xml(xmlNode *child)
Definition: xml.c:885
gboolean xml_has_children(const xmlNode *root)
Definition: xml.c:2136
xmlNode * get_message_xml(const xmlNode *msg, const char *field)
Definition: messages.c:154
char * calculate_on_disk_digest(xmlNode *local_cib)
Calculate and return digest of XML tree, suitable for storing on disk.
Definition: digest.c:134
xmlNode * sorted_xml(xmlNode *input, xmlNode *parent, gboolean recursive)
Definition: xml.c:2898
const char * xml_latest_schema(void)
Definition: schemas.c:113
void patchset_process_digest(xmlNode *patch, xmlNode *source, xmlNode *target, bool with_digest)
Definition: patchset.c:425
const xmlChar * pcmkXmlStr
Definition: xml.h:50
Functionality for manipulating name/value pairs.
int find_xml_children(xmlNode **children, xmlNode *root, const char *tag, const char *field, const char *value, gboolean search_matches)
Definition: xml.c:2783
const char * target
Definition: pcmk_fence.c:29
void xml_log_changes(uint8_t level, const char *function, xmlNode *xml)
Definition: xml.c:410
const char * path
Definition: cib.c:26
xmlXPathObjectPtr xpath_search(xmlNode *xml_top, const char *path)
Definition: xpath.c:139
xmlNode * input
void xml_remove_prop(xmlNode *obj, const char *name)
Definition: xml.c:2145
xmlNode * getXpathResult(xmlXPathObjectPtr xpathObj, int index)
Definition: xpath.c:58
char * calculate_xml_versioned_digest(xmlNode *input, gboolean sort, gboolean do_filter, const char *version)
Calculate and return digest of XML tree.
Definition: digest.c:170
gboolean can_prune_leaf(xmlNode *xml_node)
Definition: xml.c:2526
char * dump_xml_unformatted(xmlNode *msg)
Definition: xml.c:2121
void save_xml_to_file(xmlNode *xml, const char *desc, const char *filename)
Definition: xml.c:2163
void crm_foreach_xpath_result(xmlNode *xml, const char *xpath, void(*helper)(xmlNode *, void *), void *user_data)
Run a supplied function for each result of an xpath search.
Definition: xpath.c:173
int update_validation(xmlNode **xml_blob, int *best, int max, gboolean transform, gboolean to_logs)
Update CIB XML to most recent schema version.
Definition: schemas.c:1050
xmlNode * diff_xml_object(xmlNode *left, xmlNode *right, gboolean suppress)
Definition: patchset.c:1411
int add_node_nocopy(xmlNode *parent, const char *name, xmlNode *child)
Definition: xml.c:741
bool xml_patch_versions(const xmlNode *patchset, int add[3], int del[3])
Definition: patchset.c:793
xmlNode * subtract_xml_object(xmlNode *parent, xmlNode *left, xmlNode *right, gboolean full, gboolean *changed, const char *marker)
Definition: patchset.c:1460
const char * parent
Definition: cib.c:25
void xml_log_patchset(uint8_t level, const char *function, xmlNode *xml)
Definition: patchset.c:456
void xml_calculate_significant_changes(xmlNode *old_xml, xmlNode *new_xml)
Definition: xml.c:2505
int write_xml_fd(xmlNode *xml_node, const char *filename, int fd, gboolean compress)
Write XML to a file descriptor.
Definition: xml.c:1333
char * crm_xml_escape(const char *text)
Replace special characters with their XML escape sequences.
Definition: xml.c:1406
gboolean cli_config_update(xmlNode **xml, int *best_version, gboolean to_logs)
Definition: schemas.c:1197
void fix_plus_plus_recursive(xmlNode *target)
Parse integer assignment statements on this node and all its child nodes.
Definition: xml.c:578
void freeXpathObject(xmlXPathObjectPtr xpathObj)
Definition: xpath.c:39
xmlNode * xml_create_patchset(int format, xmlNode *source, xmlNode *target, bool *config, bool manage_version)
Definition: patchset.c:368
void xml_calculate_changes(xmlNode *old_xml, xmlNode *new_xml)
Definition: xml.c:2512
char * dump_xml_formatted_with_text(xmlNode *msg)
Definition: xml.c:2089
uint32_t version
Definition: remote.c:213
gboolean replace_xml_child(xmlNode *parent, xmlNode *child, xmlNode *update, gboolean delete_only)
Definition: xml.c:2816
const char * get_schema_name(int version)
Definition: schemas.c:1024
xmlNode * crm_next_same_xml(const xmlNode *sibling)
Get next instance of same XML tag.
Definition: xml.c:2956