pacemaker  1.1.24-3850484742
Scalable High-Availability cluster resource manager
xml.h
Go to the documentation of this file.
1 /*
2  * Copyright 2004-2019 Andrew Beekhof <andrew@beekhof.net>
3  *
4  * This source code is licensed under the GNU Lesser General Public License
5  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
6  */
7 
8 #ifndef CRM_COMMON_XML__H
9 # define CRM_COMMON_XML__H
10 
17 # include <stdio.h>
18 # include <sys/types.h>
19 # include <unistd.h>
20 
21 # include <stdlib.h>
22 # include <errno.h>
23 # include <fcntl.h>
24 
25 # include <libxml/tree.h>
26 # include <libxml/xpath.h>
27 
28 # include <crm/crm.h>
29 # include <crm/common/nvpair.h>
30 
31 /* Define compression parameters for IPC messages
32  *
33  * Compression costs a LOT, so we don't want to do it unless we're hitting
34  * message limits. Currently, we use 128KB as the threshold, because higher
35  * values don't play well with the heartbeat stack. With an earlier limit of
36  * 10KB, compressing 184 of 1071 messages accounted for 23% of the total CPU
37  * used by the cib.
38  */
39 # define CRM_BZ2_BLOCKS 4
40 # define CRM_BZ2_WORK 20
41 # define CRM_BZ2_THRESHOLD 128 * 1024
42 
43 # define XML_PARANOIA_CHECKS 0
44 
45 gboolean add_message_xml(xmlNode * msg, const char *field, xmlNode * xml);
46 xmlNode *get_message_xml(xmlNode * msg, const char *field);
47 
48 xmlDoc *getDocPtr(xmlNode * node);
49 
50 /*
51  * Replacement function for xmlCopyPropList which at the very least,
52  * doesn't work the way *I* would expect it to.
53  *
54  * Copy all the attributes/properties from src into target.
55  *
56  * Not recursive, does not return anything.
57  *
58  */
59 void copy_in_properties(xmlNode * target, xmlNode * src);
60 void expand_plus_plus(xmlNode * target, const char *name, const char *value);
61 void fix_plus_plus_recursive(xmlNode * target);
62 
63 /*
64  * Create a node named "name" as a child of "parent"
65  * If parent is NULL, creates an unconnected node.
66  *
67  * Returns the created node
68  *
69  */
70 xmlNode *create_xml_node(xmlNode * parent, const char *name);
71 
72 /*
73  * Unlink the node and set its doc pointer to NULL so free_xml()
74  * will act appropriately
75  */
76 void unlink_xml_node(xmlNode * node);
77 
78 /*
79  *
80  */
81 void purge_diff_markers(xmlNode * a_node);
82 
83 /*
84  * Returns a deep copy of src_node
85  *
86  */
87 xmlNode *copy_xml(xmlNode * src_node);
88 
89 /*
90  * Add a copy of xml_node to new_parent
91  */
92 xmlNode *add_node_copy(xmlNode * new_parent, xmlNode * xml_node);
93 
94 int add_node_nocopy(xmlNode * parent, const char *name, xmlNode * child);
95 
96 /*
97  * XML I/O Functions
98  *
99  * Whitespace between tags is discarded.
100  */
101 xmlNode *filename2xml(const char *filename);
102 
103 xmlNode *stdin2xml(void);
104 
105 xmlNode *string2xml(const char *input);
106 
107 int write_xml_fd(xmlNode * xml_node, const char *filename, int fd, gboolean compress);
108 int write_xml_file(xmlNode * xml_node, const char *filename, gboolean compress);
109 
110 char *dump_xml_formatted(xmlNode * msg);
111 /* Also dump the text node with xml_log_option_text enabled */
112 char *dump_xml_formatted_with_text(xmlNode * msg);
113 
114 char *dump_xml_unformatted(xmlNode * msg);
115 
116 /*
117  * Diff related Functions
118  */
119 xmlNode *diff_xml_object(xmlNode * left, xmlNode * right, gboolean suppress);
120 
121 xmlNode *subtract_xml_object(xmlNode * parent, xmlNode * left, xmlNode * right,
122  gboolean full, gboolean * changed, const char *marker);
123 
124 gboolean can_prune_leaf(xmlNode * xml_node);
125 
126 void print_xml_diff(FILE * where, xmlNode * diff);
127 
128 gboolean apply_xml_diff(xmlNode * old, xmlNode * diff, xmlNode ** new);
129 
130 /*
131  * Searching & Modifying
132  */
133 xmlNode *find_xml_node(xmlNode * cib, const char *node_path, gboolean must_find);
134 
135 xmlNode *find_entity(xmlNode * parent, const char *node_name, const char *id);
136 
137 void xml_remove_prop(xmlNode * obj, const char *name);
138 
139 gboolean replace_xml_child(xmlNode * parent, xmlNode * child, xmlNode * update,
140  gboolean delete_only);
141 
142 gboolean update_xml_child(xmlNode * child, xmlNode * to_update);
143 
144 int find_xml_children(xmlNode ** children, xmlNode * root,
145  const char *tag, const char *field, const char *value,
146  gboolean search_matches);
147 
148 xmlNode *get_xpath_object(const char *xpath, xmlNode * xml_obj, int error_level);
149 xmlNode *get_xpath_object_relative(const char *xpath, xmlNode * xml_obj, int error_level);
150 
151 static inline const char *
152 crm_element_name(const xmlNode *xml)
153 {
154  return xml? (const char *)(xml->name) : NULL;
155 }
156 
157 void xml_validate(const xmlNode * root);
158 
159 gboolean xml_has_children(const xmlNode * root);
160 
161 char *calculate_on_disk_digest(xmlNode * local_cib);
162 char *calculate_operation_digest(xmlNode * local_cib, const char *version);
163 char *calculate_xml_versioned_digest(xmlNode * input, gboolean sort, gboolean do_filter,
164  const char *version);
165 
166 /* schema-related functions (from schemas.c) */
167 gboolean validate_xml(xmlNode * xml_blob, const char *validation, gboolean to_logs);
168 gboolean validate_xml_verbose(xmlNode * xml_blob);
169 
207 int update_validation(xmlNode **xml_blob, int *best, int max,
208  gboolean transform, gboolean to_logs);
209 
210 int get_schema_version(const char *name);
211 const char *get_schema_name(int version);
212 const char *xml_latest_schema(void);
213 gboolean cli_config_update(xmlNode ** xml, int *best_version, gboolean to_logs);
214 
215 void crm_xml_init(void);
216 void crm_xml_cleanup(void);
217 
218 static inline xmlNode *
219 __xml_first_child(xmlNode * parent)
220 {
221  xmlNode *child = NULL;
222 
223  if (parent) {
224  child = parent->children;
225  while (child && child->type == XML_TEXT_NODE) {
226  child = child->next;
227  }
228  }
229  return child;
230 }
231 
232 static inline xmlNode *
233 __xml_next(xmlNode * child)
234 {
235  if (child) {
236  child = child->next;
237  while (child && child->type == XML_TEXT_NODE) {
238  child = child->next;
239  }
240  }
241  return child;
242 }
243 
244 static inline xmlNode *
245 __xml_first_child_element(xmlNode * parent)
246 {
247  xmlNode *child = NULL;
248 
249  if (parent) {
250  child = parent->children;
251  }
252 
253  while (child) {
254  if(child->type == XML_ELEMENT_NODE) {
255  return child;
256  }
257  child = child->next;
258  }
259  return NULL;
260 }
261 
262 static inline xmlNode *
263 __xml_next_element(xmlNode * child)
264 {
265  while (child) {
266  child = child->next;
267  if(child && child->type == XML_ELEMENT_NODE) {
268  return child;
269  }
270  }
271  return NULL;
272 }
273 
274 void pcmk_free_xml_subtree(xmlNode *xml);
275 void free_xml(xmlNode * child);
276 
277 xmlNode *first_named_child(xmlNode * parent, const char *name);
278 xmlNode *crm_next_same_xml(xmlNode *sibling);
279 
280 xmlNode *sorted_xml(xmlNode * input, xmlNode * parent, gboolean recursive);
281 xmlXPathObjectPtr xpath_search(xmlNode * xml_top, const char *path);
282 void crm_foreach_xpath_result(xmlNode *xml, const char *xpath,
283  void (*helper)(xmlNode*, void*), void *user_data);
284 xmlNode *expand_idref(xmlNode * input, xmlNode * top);
285 
286 void freeXpathObject(xmlXPathObjectPtr xpathObj);
287 xmlNode *getXpathResult(xmlXPathObjectPtr xpathObj, int index);
288 void dedupXpathResults(xmlXPathObjectPtr xpathObj);
289 
290 static inline int numXpathResults(xmlXPathObjectPtr xpathObj)
291 {
292  if(xpathObj == NULL || xpathObj->nodesetval == NULL) {
293  return 0;
294  }
295  return xpathObj->nodesetval->nodeNr;
296 }
297 
298 bool xml_acl_enabled(xmlNode *xml);
299 void xml_acl_disable(xmlNode *xml);
300 bool xml_acl_denied(xmlNode *xml); /* Part or all of a change was rejected */
301 bool xml_acl_filtered_copy(const char *user, xmlNode* acl_source, xmlNode *xml, xmlNode ** result);
302 
303 bool xml_tracking_changes(xmlNode * xml);
304 bool xml_document_dirty(xmlNode *xml);
305 void xml_track_changes(xmlNode * xml, const char *user, xmlNode *acl_source, bool enforce_acls);
306 void xml_calculate_changes(xmlNode * old, xmlNode * new); /* For comparing two documents after the fact */
307 void xml_calculate_significant_changes(xmlNode *old_xml, xmlNode *new_xml);
308 void xml_accept_changes(xmlNode * xml);
309 void xml_log_changes(uint8_t level, const char *function, xmlNode *xml);
310 void xml_log_patchset(uint8_t level, const char *function, xmlNode *xml);
311 bool xml_patch_versions(xmlNode *patchset, int add[3], int del[3]);
312 
313 xmlNode *xml_create_patchset(
314  int format, xmlNode *source, xmlNode *target, bool *config, bool manage_version);
315 int xml_apply_patchset(xmlNode *xml, xmlNode *patchset, bool check_version);
316 
317 void patchset_process_digest(xmlNode *patch, xmlNode *source, xmlNode *target, bool with_digest);
318 
319 void save_xml_to_file(xmlNode * xml, const char *desc, const char *filename);
320 char *xml_get_path(xmlNode *xml);
321 
322 char * crm_xml_escape(const char *text);
323 void crm_xml_sanitize_id(char *id);
324 void crm_xml_set_id(xmlNode *xml, const char *format, ...)
325  __attribute__ ((__format__ (__printf__, 2, 3)));
326 
330 void crm_destroy_xml(gpointer data);
331 
332 #endif
xmlNode * find_xml_node(xmlNode *cib, const char *node_path, gboolean must_find)
Definition: xml.c:1765
xmlNode * get_xpath_object_relative(const char *xpath, xmlNode *xml_obj, int error_level)
Definition: xpath.c:198
void unlink_xml_node(xmlNode *node)
A dumping ground.
xmlNode * get_message_xml(xmlNode *msg, const char *field)
Definition: xml.c:2558
void xml_validate(const xmlNode *root)
void xml_calculate_changes(xmlNode *old, xmlNode *new)
Definition: xml.c:3554
mainloop_io_t * source
Definition: ipcs.h:49
void crm_xml_cleanup(void)
Definition: xml.c:4304
xmlNode * find_entity(xmlNode *parent, const char *node_name, const char *id)
Definition: xml.c:1830
void xml_track_changes(xmlNode *xml, const char *user, xmlNode *acl_source, bool enforce_acls)
Definition: xml.c:314
bool xml_acl_denied(xmlNode *xml)
Definition: acl.c:557
void crm_xml_init(void)
Definition: xml.c:4282
int write_xml_file(xmlNode *xml_node, const char *filename, gboolean compress)
Definition: xml.c:2548
int get_schema_version(const char *name)
Definition: schemas.c:770
void print_xml_diff(FILE *where, xmlNode *diff)
void copy_in_properties(xmlNode *target, xmlNode *src)
Definition: xml.c:1837
void xml_accept_changes(xmlNode *xml)
Definition: xml.c:1033
xmlNode * filename2xml(const char *filename)
Definition: xml.c:2331
void dedupXpathResults(xmlXPathObjectPtr xpathObj)
Definition: xpath.c:107
void purge_diff_markers(xmlNode *a_node)
Definition: xml.c:3260
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
Definition: xpath.c:224
xmlNode * string2xml(const char *input)
Definition: xml.c:2152
void crm_xml_sanitize_id(char *id)
Sanitize a string so it is usable as an XML ID.
Definition: xml.c:2416
char version[256]
Definition: plugin.c:84
gboolean validate_xml(xmlNode *xml_blob, const char *validation, gboolean to_logs)
Definition: schemas.c:654
xmlDoc * getDocPtr(xmlNode *node)
Definition: xml.c:1939
bool xml_acl_enabled(xmlNode *xml)
Definition: acl.c:581
gboolean validate_xml_verbose(xmlNode *xml_blob)
Definition: schemas.c:622
void expand_plus_plus(xmlNode *target, const char *name, const char *value)
Definition: xml.c:1878
bool xml_tracking_changes(xmlNode *xml)
Definition: xml.c:329
xmlNode * copy_xml(xmlNode *src_node)
Definition: xml.c:2114
char * calculate_operation_digest(xmlNode *local_cib, const char *version)
Calculate and return digest of XML operation.
Definition: digest.c:175
xmlNode * stdin2xml(void)
Definition: xml.c:2213
void pcmk_free_xml_subtree(xmlNode *xml)
Definition: xml.c:2041
int xml_apply_patchset(xmlNode *xml, xmlNode *patchset, bool check_version)
Definition: xml.c:1688
gboolean update_xml_child(xmlNode *child, xmlNode *to_update)
Definition: xml.c:4060
enum crm_proc_flag __attribute__
xmlNode * add_node_copy(xmlNode *new_parent, xmlNode *xml_node)
Definition: xml.c:1955
xmlNode * expand_idref(xmlNode *input, xmlNode *top)
Definition: xml.c:4314
bool xml_document_dirty(xmlNode *xml)
Definition: xml.c:340
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition: xml.c:1977
char * dump_xml_formatted(xmlNode *msg)
Definition: xml.c:3210
xmlNode * crm_next_same_xml(xmlNode *sibling)
Get next instance of same XML tag.
Definition: xml.c:4267
void xml_acl_disable(xmlNode *xml)
Definition: acl.c:568
void void crm_destroy_xml(gpointer data)
xmlNode destructor which can be used in glib collections
Definition: xml.c:4354
gboolean add_message_xml(xmlNode *msg, const char *field, xmlNode *xml)
Definition: xml.c:2566
void free_xml(xmlNode *child)
Definition: xml.c:2108
gboolean xml_has_children(const xmlNode *root)
Definition: xml.c:3230
char * calculate_on_disk_digest(xmlNode *local_cib)
Calculate and return digest of XML tree, suitable for storing on disk.
Definition: digest.c:156
xmlNode * sorted_xml(xmlNode *input, xmlNode *parent, gboolean recursive)
Definition: xml.c:4209
const char * xml_latest_schema(void)
Definition: schemas.c:122
void patchset_process_digest(xmlNode *patch, xmlNode *source, xmlNode *target, bool with_digest)
Definition: xml.c:814
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:4094
bool xml_patch_versions(xmlNode *patchset, int add[3], int del[3])
Definition: xml.c:1225
void xml_log_changes(uint8_t level, const char *function, xmlNode *xml)
Definition: xml.c:1002
gboolean apply_xml_diff(xmlNode *old, xmlNode *diff, xmlNode **new)
Definition: xml.c:3291
xmlXPathObjectPtr xpath_search(xmlNode *xml_top, const char *path)
Definition: xpath.c:145
void crm_xml_set_id(xmlNode *xml, const char *format,...) __attribute__((__format__(__printf__
void xml_remove_prop(xmlNode *obj, const char *name)
Definition: xml.c:3239
xmlNode * getXpathResult(xmlXPathObjectPtr xpathObj, int index)
Definition: xpath.c:64
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:192
gboolean can_prune_leaf(xmlNode *xml_node)
Definition: xml.c:3595
char * xml_get_path(xmlNode *xml)
Definition: xml.c:2024
char * dump_xml_unformatted(xmlNode *msg)
Definition: xml.c:3220
bool xml_acl_filtered_copy(const char *user, xmlNode *acl_source, xmlNode *xml, xmlNode **result)
Definition: acl.c:397
char data[0]
Definition: internal.h:86
#define uint8_t
Definition: stdint.in.h:144
void save_xml_to_file(xmlNode *xml, const char *desc, const char *filename)
Definition: xml.c:3273
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:179
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:787
xmlNode * diff_xml_object(xmlNode *left, xmlNode *right, gboolean suppress)
Definition: xml.c:3567
int add_node_nocopy(xmlNode *parent, const char *name, xmlNode *child)
Definition: xml.c:1969
xmlNode * first_named_child(xmlNode *parent, const char *name)
Definition: xml.c:4241
xmlNode * subtract_xml_object(xmlNode *parent, xmlNode *left, xmlNode *right, gboolean full, gboolean *changed, const char *marker)
Definition: xml.c:3755
void xml_log_patchset(uint8_t level, const char *function, xmlNode *xml)
Definition: xml.c:847
void xml_calculate_significant_changes(xmlNode *old_xml, xmlNode *new_xml)
Definition: xml.c:3547
int write_xml_fd(xmlNode *xml_node, const char *filename, int fd, gboolean compress)
Definition: xml.c:2538
char * crm_xml_escape(const char *text)
Definition: xml.c:2592
gboolean cli_config_update(xmlNode **xml, int *best_version, gboolean to_logs)
Definition: schemas.c:930
void fix_plus_plus_recursive(xmlNode *target)
Definition: xml.c:1860
void freeXpathObject(xmlXPathObjectPtr xpathObj)
Definition: xpath.c:45
xmlNode * xml_create_patchset(int format, xmlNode *source, xmlNode *target, bool *config, bool manage_version)
Definition: xml.c:754
char * dump_xml_formatted_with_text(xmlNode *msg)
Definition: xml.c:3200
gboolean replace_xml_child(xmlNode *parent, xmlNode *child, xmlNode *update, gboolean delete_only)
Definition: xml.c:4126
const char * get_schema_name(int version)
Definition: schemas.c:761