pacemaker  2.0.1-57cc9c14bf
Scalable High-Availability cluster resource manager
xml.h
Go to the documentation of this file.
1 /*
2  * Copyright 2004-2018 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 
11 #ifdef __cplusplus
12 extern "C" {
13 #endif
14 
21 # include <stdio.h>
22 # include <sys/types.h>
23 # include <unistd.h>
24 
25 # include <stdlib.h>
26 # include <errno.h>
27 # include <fcntl.h>
28 
29 # include <crm/crm.h>
30 
31 # include <libxml/tree.h>
32 # include <libxml/xpath.h>
33 
34 /* Define compression parameters for IPC messages
35  *
36  * Compression costs a LOT, so we don't want to do it unless we're hitting
37  * message limits. Currently, we use 128KB as the threshold, because higher
38  * values don't play well with the heartbeat stack. With an earlier limit of
39  * 10KB, compressing 184 of 1071 messages accounted for 23% of the total CPU
40  * used by the cib.
41  */
42 # define CRM_BZ2_BLOCKS 4
43 # define CRM_BZ2_WORK 20
44 # define CRM_BZ2_THRESHOLD 128 * 1024
45 
46 # define XML_PARANOIA_CHECKS 0
47 
48 gboolean add_message_xml(xmlNode * msg, const char *field, xmlNode * xml);
49 xmlNode *get_message_xml(xmlNode * msg, const char *field);
50 GHashTable *xml2list(xmlNode * parent);
51 
52 xmlNode *crm_create_nvpair_xml(xmlNode *parent, const char *id,
53  const char *name, const char *value);
54 
55 void hash2nvpair(gpointer key, gpointer value, gpointer user_data);
56 void hash2field(gpointer key, gpointer value, gpointer user_data);
57 void hash2metafield(gpointer key, gpointer value, gpointer user_data);
58 void hash2smartfield(gpointer key, gpointer value, gpointer user_data);
59 
60 xmlDoc *getDocPtr(xmlNode * node);
61 
62 /*
63  * Replacement function for xmlCopyPropList which at the very least,
64  * doesn't work the way *I* would expect it to.
65  *
66  * Copy all the attributes/properties from src into target.
67  *
68  * Not recursive, does not return anything.
69  *
70  */
71 void copy_in_properties(xmlNode * target, xmlNode * src);
72 void expand_plus_plus(xmlNode * target, const char *name, const char *value);
73 void fix_plus_plus_recursive(xmlNode * target);
74 
75 /*
76  * Create a node named "name" as a child of "parent"
77  * If parent is NULL, creates an unconnected node.
78  *
79  * Returns the created node
80  *
81  */
82 xmlNode *create_xml_node(xmlNode * parent, const char *name);
83 
84 /*
85  * Make a copy of name and value and use the copied memory to create
86  * an attribute for node.
87  *
88  * If node, name or value are NULL, nothing is done.
89  *
90  * If name or value are an empty string, nothing is done.
91  *
92  * Returns FALSE on failure and TRUE on success.
93  *
94  */
95 const char *crm_xml_add(xmlNode * node, const char *name, const char *value);
96 
97 const char *crm_xml_replace(xmlNode * node, const char *name, const char *value);
98 
99 const char *crm_xml_add_int(xmlNode * node, const char *name, int value);
100 const char *crm_xml_add_ms(xmlNode *node, const char *name, guint ms);
101 
102 
115 static inline const char *
116 crm_xml_add_boolean(xmlNode *node, const char *name, gboolean value)
117 {
118  return crm_xml_add(node, name, (value? "true" : "false"));
119 }
120 
121 /*
122  *
123  */
124 void purge_diff_markers(xmlNode * a_node);
125 
126 /*
127  * Returns a deep copy of src_node
128  *
129  */
130 xmlNode *copy_xml(xmlNode * src_node);
131 
132 /*
133  * Add a copy of xml_node to new_parent
134  */
135 xmlNode *add_node_copy(xmlNode * new_parent, xmlNode * xml_node);
136 
137 int add_node_nocopy(xmlNode * parent, const char *name, xmlNode * child);
138 
139 /*
140  * XML I/O Functions
141  *
142  * Whitespace between tags is discarded.
143  */
144 xmlNode *filename2xml(const char *filename);
145 
146 xmlNode *stdin2xml(void);
147 
148 xmlNode *string2xml(const char *input);
149 
150 int write_xml_fd(xmlNode * xml_node, const char *filename, int fd, gboolean compress);
151 int write_xml_file(xmlNode * xml_node, const char *filename, gboolean compress);
152 
153 char *dump_xml_formatted(xmlNode * msg);
154 /* Also dump the text node with xml_log_option_text enabled */
155 char *dump_xml_formatted_with_text(xmlNode * msg);
156 
157 char *dump_xml_unformatted(xmlNode * msg);
158 
159 /*
160  * Diff related Functions
161  */
162 xmlNode *diff_xml_object(xmlNode * left, xmlNode * right, gboolean suppress);
163 
164 xmlNode *subtract_xml_object(xmlNode * parent, xmlNode * left, xmlNode * right,
165  gboolean full, gboolean * changed, const char *marker);
166 
167 gboolean can_prune_leaf(xmlNode * xml_node);
168 
169 gboolean apply_xml_diff(xmlNode *old_xml, xmlNode *diff, xmlNode **new_xml);
170 
171 /*
172  * Searching & Modifying
173  */
174 xmlNode *find_xml_node(xmlNode * cib, const char *node_path, gboolean must_find);
175 
176 xmlNode *find_entity(xmlNode * parent, const char *node_name, const char *id);
177 
178 void xml_remove_prop(xmlNode * obj, const char *name);
179 
180 gboolean replace_xml_child(xmlNode * parent, xmlNode * child, xmlNode * update,
181  gboolean delete_only);
182 
183 gboolean update_xml_child(xmlNode * child, xmlNode * to_update);
184 
185 int find_xml_children(xmlNode ** children, xmlNode * root,
186  const char *tag, const char *field, const char *value,
187  gboolean search_matches);
188 
189 int crm_element_value_int(const xmlNode *data, const char *name, int *dest);
190 int crm_element_value_ms(const xmlNode *data, const char *name, guint *dest);
191 int crm_element_value_timeval(const xmlNode *data, const char *name_sec,
192  const char *name_usec, struct timeval *dest);
193 char *crm_element_value_copy(const xmlNode *data, const char *name);
194 xmlNode *get_xpath_object(const char *xpath, xmlNode * xml_obj, int error_level);
195 xmlNode *get_xpath_object_relative(const char *xpath, xmlNode * xml_obj, int error_level);
196 
197 static inline const char *
198 crm_element_name(const xmlNode *xml)
199 {
200  return xml? (const char *)(xml->name) : NULL;
201 }
202 
203 const char *crm_element_value(const xmlNode *data, const char *name);
204 
214 static inline const char *
215 crm_copy_xml_element(xmlNode *obj1, xmlNode *obj2, const char *element)
216 {
217  const char *value = crm_element_value(obj1, element);
218 
219  crm_xml_add(obj2, element, value);
220  return value;
221 }
222 
223 gboolean xml_has_children(const xmlNode * root);
224 
225 char *calculate_on_disk_digest(xmlNode * local_cib);
226 char *calculate_operation_digest(xmlNode * local_cib, const char *version);
227 char *calculate_xml_versioned_digest(xmlNode * input, gboolean sort, gboolean do_filter,
228  const char *version);
229 
230 /* schema-related functions (from schemas.c) */
231 gboolean validate_xml(xmlNode * xml_blob, const char *validation, gboolean to_logs);
232 gboolean validate_xml_verbose(xmlNode * xml_blob);
233 
271 int update_validation(xmlNode **xml_blob, int *best, int max,
272  gboolean transform, gboolean to_logs);
273 
274 int get_schema_version(const char *name);
275 const char *get_schema_name(int version);
276 const char *xml_latest_schema(void);
277 gboolean cli_config_update(xmlNode ** xml, int *best_version, gboolean to_logs);
278 
279 void crm_xml_init(void);
280 void crm_xml_cleanup(void);
281 
282 static inline xmlNode *
283 __xml_first_child(const xmlNode *parent)
284 {
285  xmlNode *child = parent? parent->children : NULL;
286 
287  while (child && (child->type == XML_TEXT_NODE)) {
288  child = child->next;
289  }
290  return child;
291 }
292 
293 static inline xmlNode *
294 __xml_next(const xmlNode *child)
295 {
296  xmlNode *next = child? child->next : NULL;
297 
298  while (next && (next->type == XML_TEXT_NODE)) {
299  next = next->next;
300  }
301  return next;
302 }
303 
304 static inline xmlNode *
305 __xml_first_child_element(const xmlNode *parent)
306 {
307  xmlNode *child = parent? parent->children : NULL;
308 
309  while (child && (child->type != XML_ELEMENT_NODE)) {
310  child = child->next;
311  }
312  return child;
313 }
314 
315 static inline xmlNode *
316 __xml_next_element(const xmlNode *child)
317 {
318  xmlNode *next = child? child->next : NULL;
319 
320  while (next && (next->type != XML_ELEMENT_NODE)) {
321  next = next->next;
322  }
323  return next;
324 }
325 
326 void free_xml(xmlNode * child);
327 
328 xmlNode *first_named_child(const xmlNode *parent, const char *name);
329 xmlNode *crm_next_same_xml(const xmlNode *sibling);
330 
331 xmlNode *sorted_xml(xmlNode * input, xmlNode * parent, gboolean recursive);
332 xmlXPathObjectPtr xpath_search(xmlNode * xml_top, const char *path);
333 void crm_foreach_xpath_result(xmlNode *xml, const char *xpath,
334  void (*helper)(xmlNode*, void*), void *user_data);
335 xmlNode *expand_idref(xmlNode * input, xmlNode * top);
336 
337 void freeXpathObject(xmlXPathObjectPtr xpathObj);
338 xmlNode *getXpathResult(xmlXPathObjectPtr xpathObj, int index);
339 void dedupXpathResults(xmlXPathObjectPtr xpathObj);
340 
341 static inline int numXpathResults(xmlXPathObjectPtr xpathObj)
342 {
343  if(xpathObj == NULL || xpathObj->nodesetval == NULL) {
344  return 0;
345  }
346  return xpathObj->nodesetval->nodeNr;
347 }
348 
349 bool xml_acl_enabled(xmlNode *xml);
350 void xml_acl_disable(xmlNode *xml);
351 bool xml_acl_denied(xmlNode *xml); /* Part or all of a change was rejected */
352 bool xml_acl_filtered_copy(const char *user, xmlNode* acl_source, xmlNode *xml, xmlNode ** result);
353 
354 bool xml_tracking_changes(xmlNode * xml);
355 bool xml_document_dirty(xmlNode *xml);
356 void xml_track_changes(xmlNode * xml, const char *user, xmlNode *acl_source, bool enforce_acls);
357 void xml_calculate_changes(xmlNode *old_xml, xmlNode *new_xml);
358 void xml_calculate_significant_changes(xmlNode *old_xml, xmlNode *new_xml);
359 void xml_accept_changes(xmlNode * xml);
360 void xml_log_changes(uint8_t level, const char *function, xmlNode *xml);
361 void xml_log_patchset(uint8_t level, const char *function, xmlNode *xml);
362 bool xml_patch_versions(xmlNode *patchset, int add[3], int del[3]);
363 
364 xmlNode *xml_create_patchset(
365  int format, xmlNode *source, xmlNode *target, bool *config, bool manage_version);
366 int xml_apply_patchset(xmlNode *xml, xmlNode *patchset, bool check_version);
367 
368 void patchset_process_digest(xmlNode *patch, xmlNode *source, xmlNode *target, bool with_digest);
369 
370 void save_xml_to_file(xmlNode * xml, const char *desc, const char *filename);
371 char *xml_get_path(xmlNode *xml);
372 
373 char * crm_xml_escape(const char *text);
374 void crm_xml_sanitize_id(char *id);
375 void crm_xml_set_id(xmlNode *xml, const char *format, ...)
376  __attribute__ ((__format__ (__printf__, 2, 3)));
377 
381 void crm_destroy_xml(gpointer data);
382 
383 #ifdef __cplusplus
384 }
385 #endif
386 
387 #endif
xmlNode * find_xml_node(xmlNode *cib, const char *node_path, gboolean must_find)
Definition: xml.c:1695
xmlNode * get_xpath_object_relative(const char *xpath, xmlNode *xml_obj, int error_level)
Definition: xpath.c:198
A dumping ground.
xmlNode * get_message_xml(xmlNode *msg, const char *field)
Definition: xml.c:2629
GHashTable * xml2list(xmlNode *parent)
Definition: xml.c:4414
int crm_element_value_ms(const xmlNode *data, const char *name, guint *dest)
Definition: xml.c:3324
mainloop_io_t * source
Definition: ipcs.h:42
xmlNode * first_named_child(const xmlNode *parent, const char *name)
Definition: xml.c:4536
void crm_xml_cleanup(void)
Definition: xml.c:4598
xmlNode * find_entity(xmlNode *parent, const char *node_name, const char *id)
Definition: xml.c:1760
void xml_track_changes(xmlNode *xml, const char *user, xmlNode *acl_source, bool enforce_acls)
Definition: xml.c:316
bool xml_acl_denied(xmlNode *xml)
Definition: acl.c:522
void crm_xml_init(void)
Definition: xml.c:4576
int write_xml_file(xmlNode *xml_node, const char *filename, gboolean compress)
Write XML to a file.
Definition: xml.c:2616
int get_schema_version(const char *name)
Definition: schemas.c:1023
void copy_in_properties(xmlNode *target, xmlNode *src)
Definition: xml.c:1767
void xml_accept_changes(xmlNode *xml)
Definition: xml.c:1017
xmlNode * filename2xml(const char *filename)
Definition: xml.c:2362
void dedupXpathResults(xmlXPathObjectPtr xpathObj)
Definition: xpath.c:107
void purge_diff_markers(xmlNode *a_node)
Definition: xml.c:3416
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
Definition: xpath.c:220
xmlNode * string2xml(const char *input)
Definition: xml.c:2183
void crm_xml_sanitize_id(char *id)
Sanitize a string so it is usable as an XML ID.
Definition: xml.c:2450
gboolean validate_xml(xmlNode *xml_blob, const char *validation, gboolean to_logs)
Definition: schemas.c:694
xmlDoc * getDocPtr(xmlNode *node)
Definition: xml.c:1869
bool xml_acl_enabled(xmlNode *xml)
Definition: acl.c:546
const char * crm_xml_replace(xmlNode *node, const char *name, const char *value)
Definition: xml.c:1953
gboolean validate_xml_verbose(xmlNode *xml_blob)
Definition: schemas.c:666
void expand_plus_plus(xmlNode *target, const char *name, const char *value)
Definition: xml.c:1808
bool xml_tracking_changes(xmlNode *xml)
Definition: xml.c:331
void hash2smartfield(gpointer key, gpointer value, gpointer user_data)
Definition: xml.c:4352
xmlNode * copy_xml(xmlNode *src_node)
Definition: xml.c:2145
void hash2field(gpointer key, gpointer value, gpointer user_data)
Definition: xml.c:4375
char * calculate_operation_digest(xmlNode *local_cib, const char *version)
Calculate and return digest of XML operation.
Definition: digest.c:176
xmlNode * stdin2xml(void)
Definition: xml.c:2248
int xml_apply_patchset(xmlNode *xml, xmlNode *patchset, bool check_version)
Definition: xml.c:1618
gboolean update_xml_child(xmlNode *child, xmlNode *to_update)
Definition: xml.c:4155
xmlNode * add_node_copy(xmlNode *new_parent, xmlNode *xml_node)
Definition: xml.c:1885
xmlNode * expand_idref(xmlNode *input, xmlNode *top)
Definition: xml.c:4608
gboolean apply_xml_diff(xmlNode *old_xml, xmlNode *diff, xmlNode **new_xml)
Definition: xml.c:3447
bool xml_document_dirty(xmlNode *xml)
Definition: xml.c:342
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition: xml.c:2015
char * dump_xml_formatted(xmlNode *msg)
Definition: xml.c:3281
void xml_acl_disable(xmlNode *xml)
Definition: acl.c:533
void void crm_destroy_xml(gpointer data)
xmlNode destructor which can be used in glib collections
Definition: xml.c:4666
char * crm_element_value_copy(const xmlNode *data, const char *name)
Definition: xml.c:3383
const char * crm_xml_add_ms(xmlNode *node, const char *name, guint ms)
Definition: xml.c:2005
gboolean add_message_xml(xmlNode *msg, const char *field, xmlNode *xml)
Definition: xml.c:2637
void free_xml(xmlNode *child)
Definition: xml.c:2139
gboolean xml_has_children(const xmlNode *root)
Definition: xml.c:3301
const char * crm_element_value(const xmlNode *data, const char *name)
Definition: xml.c:4641
int crm_element_value_timeval(const xmlNode *data, const char *name_sec, const char *name_usec, struct timeval *dest)
Parse a time value from XML.
Definition: xml.c:3346
char * calculate_on_disk_digest(xmlNode *local_cib)
Calculate and return digest of XML tree, suitable for storing on disk.
Definition: digest.c:157
xmlNode * sorted_xml(xmlNode *input, xmlNode *parent, gboolean recursive)
Definition: xml.c:4492
const char * xml_latest_schema(void)
Definition: schemas.c:113
void patchset_process_digest(xmlNode *patch, xmlNode *source, xmlNode *target, bool with_digest)
Definition: xml.c:798
void hash2metafield(gpointer key, gpointer value, gpointer user_data)
Definition: xml.c:4391
int find_xml_children(xmlNode **children, xmlNode *root, const char *tag, const char *field, const char *value, gboolean search_matches)
Definition: xml.c:4189
bool xml_patch_versions(xmlNode *patchset, int add[3], int del[3])
Definition: xml.c:1209
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Definition: xml.c:1907
void xml_log_changes(uint8_t level, const char *function, xmlNode *xml)
Definition: xml.c:986
const char * crm_xml_add_int(xmlNode *node, const char *name, int value)
Definition: xml.c:1995
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:3395
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:193
gboolean can_prune_leaf(xmlNode *xml_node)
Definition: xml.c:3755
xmlNode * crm_create_nvpair_xml(xmlNode *parent, const char *id, const char *name, const char *value)
Create an XML name/value pair.
Definition: xml.c:4314
char * xml_get_path(xmlNode *xml)
Definition: xml.c:2062
char * dump_xml_unformatted(xmlNode *msg)
Definition: xml.c:3291
bool xml_acl_filtered_copy(const char *user, xmlNode *acl_source, xmlNode *xml, xmlNode **result)
Definition: acl.c:395
int crm_element_value_int(const xmlNode *data, const char *name, int *dest)
Definition: xml.c:3310
char data[0]
Definition: internal.h:90
#define uint8_t
Definition: stdint.in.h:144
void save_xml_to_file(xmlNode *xml, const char *desc, const char *filename)
Definition: xml.c:3429
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:1040
xmlNode * diff_xml_object(xmlNode *left, xmlNode *right, gboolean suppress)
Definition: xml.c:3727
int add_node_nocopy(xmlNode *parent, const char *name, xmlNode *child)
Definition: xml.c:1899
xmlNode * subtract_xml_object(xmlNode *parent, xmlNode *left, xmlNode *right, gboolean full, gboolean *changed, const char *marker)
Definition: xml.c:3850
void xml_log_patchset(uint8_t level, const char *function, xmlNode *xml)
Definition: xml.c:831
void xml_calculate_significant_changes(xmlNode *old_xml, xmlNode *new_xml)
Definition: xml.c:3705
int write_xml_fd(xmlNode *xml_node, const char *filename, int fd, gboolean compress)
Write XML to a file descriptor.
Definition: xml.c:2594
char * crm_xml_escape(const char *text)
Definition: xml.c:2663
gboolean cli_config_update(xmlNode **xml, int *best_version, gboolean to_logs)
Definition: schemas.c:1189
void hash2nvpair(gpointer key, gpointer value, gpointer user_data)
Definition: xml.c:4341
void fix_plus_plus_recursive(xmlNode *target)
Definition: xml.c:1790
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:741
void xml_calculate_changes(xmlNode *old_xml, xmlNode *new_xml)
Definition: xml.c:3712
char * dump_xml_formatted_with_text(xmlNode *msg)
Definition: xml.c:3271
uint32_t version
Definition: remote.c:146
enum crm_proc_flag __attribute__
gboolean replace_xml_child(xmlNode *parent, xmlNode *child, xmlNode *update, gboolean delete_only)
Definition: xml.c:4221
const char * get_schema_name(int version)
Definition: schemas.c:1014
xmlNode * crm_next_same_xml(const xmlNode *sibling)
Get next instance of same XML tag.
Definition: xml.c:4561