pacemaker  2.0.4-2deceaa
Scalable High-Availability cluster resource manager
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
xml.h
Go to the documentation of this file.
1 /*
2  * Copyright 2004-2020 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 CRM_COMMON_XML__H
11 # define CRM_COMMON_XML__H
12 
13 #ifdef __cplusplus
14 extern "C" {
15 #endif
16 
23 # include <stdio.h>
24 # include <sys/types.h>
25 # include <unistd.h>
26 
27 # include <stdlib.h>
28 # include <errno.h>
29 # include <fcntl.h>
30 
31 # include <libxml/tree.h>
32 # include <libxml/xpath.h>
33 
34 # include <crm/crm.h>
35 # include <crm/common/nvpair.h>
36 
37 /* Define compression parameters for IPC messages
38  *
39  * Compression costs a LOT, so we don't want to do it unless we're hitting
40  * message limits. Currently, we use 128KB as the threshold, because higher
41  * values don't play well with the heartbeat stack. With an earlier limit of
42  * 10KB, compressing 184 of 1071 messages accounted for 23% of the total CPU
43  * used by the cib.
44  */
45 # define CRM_BZ2_BLOCKS 4
46 # define CRM_BZ2_WORK 20
47 # define CRM_BZ2_THRESHOLD 128 * 1024
48 
49 # define XML_PARANOIA_CHECKS 0
50 
51 typedef const xmlChar *pcmkXmlStr;
52 
53 gboolean add_message_xml(xmlNode * msg, const char *field, xmlNode * xml);
54 xmlNode *get_message_xml(xmlNode * msg, const char *field);
55 
56 xmlDoc *getDocPtr(xmlNode * node);
57 
58 /*
59  * Replacement function for xmlCopyPropList which at the very least,
60  * doesn't work the way *I* would expect it to.
61  *
62  * Copy all the attributes/properties from src into target.
63  *
64  * Not recursive, does not return anything.
65  *
66  */
67 void copy_in_properties(xmlNode * target, xmlNode * src);
68 void expand_plus_plus(xmlNode * target, const char *name, const char *value);
69 void fix_plus_plus_recursive(xmlNode * target);
70 
71 /*
72  * Create a node named "name" as a child of "parent"
73  * If parent is NULL, creates an unconnected node.
74  *
75  * Returns the created node
76  *
77  */
78 xmlNode *create_xml_node(xmlNode * parent, const char *name);
79 
80 /*
81  * Create a node named "name" as a child of "parent", giving it the provided
82  * text content.
83  * If parent is NULL, creates an unconnected node.
84  *
85  * Returns the created node
86  *
87  */
88 xmlNode *pcmk_create_xml_text_node(xmlNode * parent, const char *name, const char *content);
89 
90 /*
91  * Create a new HTML node named "element_name" as a child of "parent", giving it the
92  * provided text content. Optionally, apply a CSS #id and #class.
93  *
94  * Returns the created node.
95  */
96 xmlNode *pcmk_create_html_node(xmlNode * parent, const char *element_name, const char *id,
97  const char *class_name, const char *text);
98 
99 /*
100  *
101  */
102 void purge_diff_markers(xmlNode * a_node);
103 
104 /*
105  * Returns a deep copy of src_node
106  *
107  */
108 xmlNode *copy_xml(xmlNode * src_node);
109 
110 /*
111  * Add a copy of xml_node to new_parent
112  */
113 xmlNode *add_node_copy(xmlNode * new_parent, xmlNode * xml_node);
114 
115 int add_node_nocopy(xmlNode * parent, const char *name, xmlNode * child);
116 
117 /*
118  * XML I/O Functions
119  *
120  * Whitespace between tags is discarded.
121  */
122 xmlNode *filename2xml(const char *filename);
123 
124 xmlNode *stdin2xml(void);
125 
126 xmlNode *string2xml(const char *input);
127 
128 int write_xml_fd(xmlNode * xml_node, const char *filename, int fd, gboolean compress);
129 int write_xml_file(xmlNode * xml_node, const char *filename, gboolean compress);
130 
131 char *dump_xml_formatted(xmlNode * msg);
132 /* Also dump the text node with xml_log_option_text enabled */
133 char *dump_xml_formatted_with_text(xmlNode * msg);
134 
135 char *dump_xml_unformatted(xmlNode * msg);
136 
137 /*
138  * Diff related Functions
139  */
140 xmlNode *diff_xml_object(xmlNode * left, xmlNode * right, gboolean suppress);
141 
142 xmlNode *subtract_xml_object(xmlNode * parent, xmlNode * left, xmlNode * right,
143  gboolean full, gboolean * changed, const char *marker);
144 
145 gboolean can_prune_leaf(xmlNode * xml_node);
146 
147 gboolean apply_xml_diff(xmlNode *old_xml, xmlNode *diff, xmlNode **new_xml);
148 
149 /*
150  * Searching & Modifying
151  */
152 xmlNode *find_xml_node(xmlNode * cib, const char *node_path, gboolean must_find);
153 
154 xmlNode *find_entity(xmlNode * parent, const char *node_name, const char *id);
155 
156 void xml_remove_prop(xmlNode * obj, const char *name);
157 
158 gboolean replace_xml_child(xmlNode * parent, xmlNode * child, xmlNode * update,
159  gboolean delete_only);
160 
161 gboolean update_xml_child(xmlNode * child, xmlNode * to_update);
162 
163 int find_xml_children(xmlNode ** children, xmlNode * root,
164  const char *tag, const char *field, const char *value,
165  gboolean search_matches);
166 
167 xmlNode *get_xpath_object(const char *xpath, xmlNode * xml_obj, int error_level);
168 xmlNode *get_xpath_object_relative(const char *xpath, xmlNode * xml_obj, int error_level);
169 
170 static inline const char *
171 crm_element_name(const xmlNode *xml)
172 {
173  return xml? (const char *)(xml->name) : NULL;
174 }
175 
176 static inline const char *
177 crm_map_element_name(const xmlNode *xml)
178 {
179  const char *name = crm_element_name(xml);
180 
181  if (crm_str_eq(name, "master", TRUE)) {
182  return "clone";
183  } else {
184  return name;
185  }
186 }
187 
188 gboolean xml_has_children(const xmlNode * root);
189 
190 char *calculate_on_disk_digest(xmlNode * local_cib);
191 char *calculate_operation_digest(xmlNode * local_cib, const char *version);
192 char *calculate_xml_versioned_digest(xmlNode * input, gboolean sort, gboolean do_filter,
193  const char *version);
194 
195 /* schema-related functions (from schemas.c) */
196 gboolean validate_xml(xmlNode * xml_blob, const char *validation, gboolean to_logs);
197 gboolean validate_xml_verbose(xmlNode * xml_blob);
198 
236 int update_validation(xmlNode **xml_blob, int *best, int max,
237  gboolean transform, gboolean to_logs);
238 
239 int get_schema_version(const char *name);
240 const char *get_schema_name(int version);
241 const char *xml_latest_schema(void);
242 gboolean cli_config_update(xmlNode ** xml, int *best_version, gboolean to_logs);
243 
244 void crm_xml_init(void);
245 void crm_xml_cleanup(void);
246 
247 static inline xmlNode *
248 __xml_first_child(const xmlNode *parent)
249 {
250  xmlNode *child = parent? parent->children : NULL;
251 
252  while (child && (child->type == XML_TEXT_NODE)) {
253  child = child->next;
254  }
255  return child;
256 }
257 
258 static inline xmlNode *
259 __xml_next(const xmlNode *child)
260 {
261  xmlNode *next = child? child->next : NULL;
262 
263  while (next && (next->type == XML_TEXT_NODE)) {
264  next = next->next;
265  }
266  return next;
267 }
268 
269 static inline xmlNode *
270 __xml_first_child_element(const xmlNode *parent)
271 {
272  xmlNode *child = parent? parent->children : NULL;
273 
274  while (child && (child->type != XML_ELEMENT_NODE)) {
275  child = child->next;
276  }
277  return child;
278 }
279 
280 static inline xmlNode *
281 __xml_next_element(const xmlNode *child)
282 {
283  xmlNode *next = child? child->next : NULL;
284 
285  while (next && (next->type != XML_ELEMENT_NODE)) {
286  next = next->next;
287  }
288  return next;
289 }
290 
291 void pcmk_free_xml_subtree(xmlNode *xml);
292 void free_xml(xmlNode * child);
293 
294 xmlNode *first_named_child(const xmlNode *parent, const char *name);
295 xmlNode *crm_next_same_xml(const xmlNode *sibling);
296 
297 xmlNode *sorted_xml(xmlNode * input, xmlNode * parent, gboolean recursive);
298 xmlXPathObjectPtr xpath_search(xmlNode * xml_top, const char *path);
299 void crm_foreach_xpath_result(xmlNode *xml, const char *xpath,
300  void (*helper)(xmlNode*, void*), void *user_data);
301 xmlNode *expand_idref(xmlNode * input, xmlNode * top);
302 
303 void freeXpathObject(xmlXPathObjectPtr xpathObj);
304 xmlNode *getXpathResult(xmlXPathObjectPtr xpathObj, int index);
305 void dedupXpathResults(xmlXPathObjectPtr xpathObj);
306 
307 static inline int numXpathResults(xmlXPathObjectPtr xpathObj)
308 {
309  if(xpathObj == NULL || xpathObj->nodesetval == NULL) {
310  return 0;
311  }
312  return xpathObj->nodesetval->nodeNr;
313 }
314 
315 bool xml_tracking_changes(xmlNode * xml);
316 bool xml_document_dirty(xmlNode *xml);
317 void xml_track_changes(xmlNode * xml, const char *user, xmlNode *acl_source, bool enforce_acls);
318 void xml_calculate_changes(xmlNode *old_xml, xmlNode *new_xml);
319 void xml_calculate_significant_changes(xmlNode *old_xml, xmlNode *new_xml);
320 void xml_accept_changes(xmlNode * xml);
321 void xml_log_changes(uint8_t level, const char *function, xmlNode *xml);
322 void xml_log_patchset(uint8_t level, const char *function, xmlNode *xml);
323 bool xml_patch_versions(xmlNode *patchset, int add[3], int del[3]);
324 
325 xmlNode *xml_create_patchset(
326  int format, xmlNode *source, xmlNode *target, bool *config, bool manage_version);
327 int xml_apply_patchset(xmlNode *xml, xmlNode *patchset, bool check_version);
328 
329 void patchset_process_digest(xmlNode *patch, xmlNode *source, xmlNode *target, bool with_digest);
330 
331 void save_xml_to_file(xmlNode * xml, const char *desc, const char *filename);
332 char *xml_get_path(xmlNode *xml);
333 
334 char * crm_xml_escape(const char *text);
335 void crm_xml_sanitize_id(char *id);
336 void crm_xml_set_id(xmlNode *xml, const char *format, ...)
337  __attribute__ ((__format__ (__printf__, 2, 3)));
338 
342 void crm_destroy_xml(gpointer data);
343 
344 #ifdef __cplusplus
345 }
346 #endif
347 
348 #endif
xmlNode * find_xml_node(xmlNode *cib, const char *node_path, gboolean must_find)
Definition: xml.c:1764
xmlNode * get_xpath_object_relative(const char *xpath, xmlNode *xml_obj, int error_level)
Definition: xpath.c:189
A dumping ground.
xmlNode * get_message_xml(xmlNode *msg, const char *field)
Definition: xml.c:2619
xmlNode * first_named_child(const xmlNode *parent, const char *name)
Definition: xml.c:4399
void crm_xml_cleanup(void)
Definition: xml.c:4462
xmlNode * pcmk_create_html_node(xmlNode *parent, const char *element_name, const char *id, const char *class_name, const char *text)
Definition: xml.c:2013
xmlNode * find_entity(xmlNode *parent, const char *node_name, const char *id)
Definition: xml.c:1829
void xml_track_changes(xmlNode *xml, const char *user, xmlNode *acl_source, bool enforce_acls)
Definition: xml.c:309
void crm_xml_init(void)
Definition: xml.c:4440
int write_xml_file(xmlNode *xml_node, const char *filename, gboolean compress)
Write XML to a file.
Definition: xml.c:2606
int get_schema_version(const char *name)
Definition: schemas.c:1030
void copy_in_properties(xmlNode *target, xmlNode *src)
Definition: xml.c:1836
void xml_accept_changes(xmlNode *xml)
Definition: xml.c:1016
xmlNode * filename2xml(const char *filename)
Definition: xml.c:2356
void dedupXpathResults(xmlXPathObjectPtr xpathObj)
Definition: xpath.c:98
void purge_diff_markers(xmlNode *a_node)
Definition: xml.c:3361
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
Definition: xpath.c:211
xmlNode * string2xml(const char *input)
Definition: xml.c:2180
void crm_xml_sanitize_id(char *id)
Sanitize a string so it is usable as an XML ID.
Definition: xml.c:2440
gboolean validate_xml(xmlNode *xml_blob, const char *validation, gboolean to_logs)
Definition: schemas.c:700
xmlDoc * getDocPtr(xmlNode *node)
Definition: xml.c:1938
gboolean validate_xml_verbose(xmlNode *xml_blob)
Definition: schemas.c:672
void expand_plus_plus(xmlNode *target, const char *name, const char *value)
Definition: xml.c:1877
bool xml_tracking_changes(xmlNode *xml)
Definition: xml.c:324
xmlNode * copy_xml(xmlNode *src_node)
Definition: xml.c:2142
char * calculate_operation_digest(xmlNode *local_cib, const char *version)
Calculate and return digest of XML operation.
Definition: digest.c:167
xmlNode * stdin2xml(void)
Definition: xml.c:2241
void pcmk_free_xml_subtree(xmlNode *xml)
Definition: xml.c:2069
int xml_apply_patchset(xmlNode *xml, xmlNode *patchset, bool check_version)
Definition: xml.c:1687
gboolean update_xml_child(xmlNode *child, xmlNode *to_update)
Definition: xml.c:4218
xmlNode * pcmk_create_xml_text_node(xmlNode *parent, const char *name, const char *content)
Definition: xml.c:2001
xmlNode * add_node_copy(xmlNode *new_parent, xmlNode *xml_node)
Definition: xml.c:1954
xmlNode * expand_idref(xmlNode *input, xmlNode *top)
Definition: xml.c:4472
gboolean apply_xml_diff(xmlNode *old_xml, xmlNode *diff, xmlNode **new_xml)
Definition: xml.c:3392
bool xml_document_dirty(xmlNode *xml)
Definition: xml.c:335
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition: xml.c:1976
char * dump_xml_formatted(xmlNode *msg)
Definition: xml.c:3311
void void crm_destroy_xml(gpointer data)
xmlNode destructor which can be used in glib collections
Definition: xml.c:4505
gboolean add_message_xml(xmlNode *msg, const char *field, xmlNode *xml)
Definition: xml.c:2627
void free_xml(xmlNode *child)
Definition: xml.c:2136
gboolean xml_has_children(const xmlNode *root)
Definition: xml.c:3331
gboolean crm_str_eq(const char *a, const char *b, gboolean use_case)
Definition: strings.c:326
char * calculate_on_disk_digest(xmlNode *local_cib)
Calculate and return digest of XML tree, suitable for storing on disk.
Definition: digest.c:148
xmlNode * sorted_xml(xmlNode *input, xmlNode *parent, gboolean recursive)
Definition: xml.c:4367
const char * xml_latest_schema(void)
Definition: schemas.c:115
void patchset_process_digest(xmlNode *patch, xmlNode *source, xmlNode *target, bool with_digest)
Definition: xml.c:791
mainloop_io_t * source
Definition: ipcs_internal.h:44
const xmlChar * pcmkXmlStr
Definition: xml.h:51
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:4252
const char * target
Definition: pcmk_fence.c:28
bool xml_patch_versions(xmlNode *patchset, int add[3], int del[3])
Definition: xml.c:1208
void xml_log_changes(uint8_t level, const char *function, xmlNode *xml)
Definition: xml.c:981
xmlXPathObjectPtr xpath_search(xmlNode *xml_top, const char *path)
Definition: xpath.c:136
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:3340
xmlNode * getXpathResult(xmlXPathObjectPtr xpathObj, int index)
Definition: xpath.c:55
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:184
gboolean can_prune_leaf(xmlNode *xml_node)
Definition: xml.c:3819
char * xml_get_path(xmlNode *xml)
Definition: xml.c:2052
char * dump_xml_unformatted(xmlNode *msg)
Definition: xml.c:3321
char data[0]
Definition: internal.h:90
void save_xml_to_file(xmlNode *xml, const char *desc, const char *filename)
Definition: xml.c:3374
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:170
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:1047
xmlNode * diff_xml_object(xmlNode *left, xmlNode *right, gboolean suppress)
Definition: xml.c:3791
int add_node_nocopy(xmlNode *parent, const char *name, xmlNode *child)
Definition: xml.c:1968
xmlNode * subtract_xml_object(xmlNode *parent, xmlNode *left, xmlNode *right, gboolean full, gboolean *changed, const char *marker)
Definition: xml.c:3914
void xml_log_patchset(uint8_t level, const char *function, xmlNode *xml)
Definition: xml.c:824
void xml_calculate_significant_changes(xmlNode *old_xml, xmlNode *new_xml)
Definition: xml.c:3769
int write_xml_fd(xmlNode *xml_node, const char *filename, int fd, gboolean compress)
Write XML to a file descriptor.
Definition: xml.c:2584
char * crm_xml_escape(const char *text)
Definition: xml.c:2653
gboolean cli_config_update(xmlNode **xml, int *best_version, gboolean to_logs)
Definition: schemas.c:1196
char * name
Definition: pcmk_fence.c:30
void fix_plus_plus_recursive(xmlNode *target)
Definition: xml.c:1859
void freeXpathObject(xmlXPathObjectPtr xpathObj)
Definition: xpath.c:36
xmlNode * xml_create_patchset(int format, xmlNode *source, xmlNode *target, bool *config, bool manage_version)
Definition: xml.c:734
void xml_calculate_changes(xmlNode *old_xml, xmlNode *new_xml)
Definition: xml.c:3776
char * dump_xml_formatted_with_text(xmlNode *msg)
Definition: xml.c:3299
uint32_t version
Definition: remote.c:147
enum crm_proc_flag __attribute__
gboolean replace_xml_child(xmlNode *parent, xmlNode *child, xmlNode *update, gboolean delete_only)
Definition: xml.c:4284
const char * get_schema_name(int version)
Definition: schemas.c:1021
xmlNode * crm_next_same_xml(const xmlNode *sibling)
Get next instance of same XML tag.
Definition: xml.c:4425