pacemaker  2.0.1-9e909a5bdd
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 
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 <libxml/tree.h>
30 # include <libxml/xpath.h>
31 
32 # include <crm/crm.h>
33 # include <crm/common/nvpair.h>
34 
35 /* Define compression parameters for IPC messages
36  *
37  * Compression costs a LOT, so we don't want to do it unless we're hitting
38  * message limits. Currently, we use 128KB as the threshold, because higher
39  * values don't play well with the heartbeat stack. With an earlier limit of
40  * 10KB, compressing 184 of 1071 messages accounted for 23% of the total CPU
41  * used by the cib.
42  */
43 # define CRM_BZ2_BLOCKS 4
44 # define CRM_BZ2_WORK 20
45 # define CRM_BZ2_THRESHOLD 128 * 1024
46 
47 # define XML_PARANOIA_CHECKS 0
48 
49 gboolean add_message_xml(xmlNode * msg, const char *field, xmlNode * xml);
50 xmlNode *get_message_xml(xmlNode * msg, const char *field);
51 
52 xmlDoc *getDocPtr(xmlNode * node);
53 
54 /*
55  * Replacement function for xmlCopyPropList which at the very least,
56  * doesn't work the way *I* would expect it to.
57  *
58  * Copy all the attributes/properties from src into target.
59  *
60  * Not recursive, does not return anything.
61  *
62  */
63 void copy_in_properties(xmlNode * target, xmlNode * src);
64 void expand_plus_plus(xmlNode * target, const char *name, const char *value);
65 void fix_plus_plus_recursive(xmlNode * target);
66 
67 /*
68  * Create a node named "name" as a child of "parent"
69  * If parent is NULL, creates an unconnected node.
70  *
71  * Returns the created node
72  *
73  */
74 xmlNode *create_xml_node(xmlNode * parent, const char *name);
75 
76 /*
77  *
78  */
79 void purge_diff_markers(xmlNode * a_node);
80 
81 /*
82  * Returns a deep copy of src_node
83  *
84  */
85 xmlNode *copy_xml(xmlNode * src_node);
86 
87 /*
88  * Add a copy of xml_node to new_parent
89  */
90 xmlNode *add_node_copy(xmlNode * new_parent, xmlNode * xml_node);
91 
92 int add_node_nocopy(xmlNode * parent, const char *name, xmlNode * child);
93 
94 /*
95  * XML I/O Functions
96  *
97  * Whitespace between tags is discarded.
98  */
99 xmlNode *filename2xml(const char *filename);
100 
101 xmlNode *stdin2xml(void);
102 
103 xmlNode *string2xml(const char *input);
104 
105 int write_xml_fd(xmlNode * xml_node, const char *filename, int fd, gboolean compress);
106 int write_xml_file(xmlNode * xml_node, const char *filename, gboolean compress);
107 
108 char *dump_xml_formatted(xmlNode * msg);
109 /* Also dump the text node with xml_log_option_text enabled */
110 char *dump_xml_formatted_with_text(xmlNode * msg);
111 
112 char *dump_xml_unformatted(xmlNode * msg);
113 
114 /*
115  * Diff related Functions
116  */
117 xmlNode *diff_xml_object(xmlNode * left, xmlNode * right, gboolean suppress);
118 
119 xmlNode *subtract_xml_object(xmlNode * parent, xmlNode * left, xmlNode * right,
120  gboolean full, gboolean * changed, const char *marker);
121 
122 gboolean can_prune_leaf(xmlNode * xml_node);
123 
124 gboolean apply_xml_diff(xmlNode *old_xml, xmlNode *diff, xmlNode **new_xml);
125 
126 /*
127  * Searching & Modifying
128  */
129 xmlNode *find_xml_node(xmlNode * cib, const char *node_path, gboolean must_find);
130 
131 xmlNode *find_entity(xmlNode * parent, const char *node_name, const char *id);
132 
133 void xml_remove_prop(xmlNode * obj, const char *name);
134 
135 gboolean replace_xml_child(xmlNode * parent, xmlNode * child, xmlNode * update,
136  gboolean delete_only);
137 
138 gboolean update_xml_child(xmlNode * child, xmlNode * to_update);
139 
140 int find_xml_children(xmlNode ** children, xmlNode * root,
141  const char *tag, const char *field, const char *value,
142  gboolean search_matches);
143 
144 xmlNode *get_xpath_object(const char *xpath, xmlNode * xml_obj, int error_level);
145 xmlNode *get_xpath_object_relative(const char *xpath, xmlNode * xml_obj, int error_level);
146 
147 static inline const char *
148 crm_element_name(const xmlNode *xml)
149 {
150  return xml? (const char *)(xml->name) : NULL;
151 }
152 
153 gboolean xml_has_children(const xmlNode * root);
154 
155 char *calculate_on_disk_digest(xmlNode * local_cib);
156 char *calculate_operation_digest(xmlNode * local_cib, const char *version);
157 char *calculate_xml_versioned_digest(xmlNode * input, gboolean sort, gboolean do_filter,
158  const char *version);
159 
160 /* schema-related functions (from schemas.c) */
161 gboolean validate_xml(xmlNode * xml_blob, const char *validation, gboolean to_logs);
162 gboolean validate_xml_verbose(xmlNode * xml_blob);
163 
201 int update_validation(xmlNode **xml_blob, int *best, int max,
202  gboolean transform, gboolean to_logs);
203 
204 int get_schema_version(const char *name);
205 const char *get_schema_name(int version);
206 const char *xml_latest_schema(void);
207 gboolean cli_config_update(xmlNode ** xml, int *best_version, gboolean to_logs);
208 
209 void crm_xml_init(void);
210 void crm_xml_cleanup(void);
211 
212 static inline xmlNode *
213 __xml_first_child(const xmlNode *parent)
214 {
215  xmlNode *child = parent? parent->children : NULL;
216 
217  while (child && (child->type == XML_TEXT_NODE)) {
218  child = child->next;
219  }
220  return child;
221 }
222 
223 static inline xmlNode *
224 __xml_next(const xmlNode *child)
225 {
226  xmlNode *next = child? child->next : NULL;
227 
228  while (next && (next->type == XML_TEXT_NODE)) {
229  next = next->next;
230  }
231  return next;
232 }
233 
234 static inline xmlNode *
235 __xml_first_child_element(const xmlNode *parent)
236 {
237  xmlNode *child = parent? parent->children : NULL;
238 
239  while (child && (child->type != XML_ELEMENT_NODE)) {
240  child = child->next;
241  }
242  return child;
243 }
244 
245 static inline xmlNode *
246 __xml_next_element(const xmlNode *child)
247 {
248  xmlNode *next = child? child->next : NULL;
249 
250  while (next && (next->type != XML_ELEMENT_NODE)) {
251  next = next->next;
252  }
253  return next;
254 }
255 
256 void free_xml(xmlNode * child);
257 
258 xmlNode *first_named_child(const xmlNode *parent, const char *name);
259 xmlNode *crm_next_same_xml(const xmlNode *sibling);
260 
261 xmlNode *sorted_xml(xmlNode * input, xmlNode * parent, gboolean recursive);
262 xmlXPathObjectPtr xpath_search(xmlNode * xml_top, const char *path);
263 void crm_foreach_xpath_result(xmlNode *xml, const char *xpath,
264  void (*helper)(xmlNode*, void*), void *user_data);
265 xmlNode *expand_idref(xmlNode * input, xmlNode * top);
266 
267 void freeXpathObject(xmlXPathObjectPtr xpathObj);
268 xmlNode *getXpathResult(xmlXPathObjectPtr xpathObj, int index);
269 void dedupXpathResults(xmlXPathObjectPtr xpathObj);
270 
271 static inline int numXpathResults(xmlXPathObjectPtr xpathObj)
272 {
273  if(xpathObj == NULL || xpathObj->nodesetval == NULL) {
274  return 0;
275  }
276  return xpathObj->nodesetval->nodeNr;
277 }
278 
279 bool xml_acl_enabled(xmlNode *xml);
280 void xml_acl_disable(xmlNode *xml);
281 bool xml_acl_denied(xmlNode *xml); /* Part or all of a change was rejected */
282 bool xml_acl_filtered_copy(const char *user, xmlNode* acl_source, xmlNode *xml, xmlNode ** result);
283 
284 bool xml_tracking_changes(xmlNode * xml);
285 bool xml_document_dirty(xmlNode *xml);
286 void xml_track_changes(xmlNode * xml, const char *user, xmlNode *acl_source, bool enforce_acls);
287 void xml_calculate_changes(xmlNode *old_xml, xmlNode *new_xml);
288 void xml_calculate_significant_changes(xmlNode *old_xml, xmlNode *new_xml);
289 void xml_accept_changes(xmlNode * xml);
290 void xml_log_changes(uint8_t level, const char *function, xmlNode *xml);
291 void xml_log_patchset(uint8_t level, const char *function, xmlNode *xml);
292 bool xml_patch_versions(xmlNode *patchset, int add[3], int del[3]);
293 
294 xmlNode *xml_create_patchset(
295  int format, xmlNode *source, xmlNode *target, bool *config, bool manage_version);
296 int xml_apply_patchset(xmlNode *xml, xmlNode *patchset, bool check_version);
297 
298 void patchset_process_digest(xmlNode *patch, xmlNode *source, xmlNode *target, bool with_digest);
299 
300 void save_xml_to_file(xmlNode * xml, const char *desc, const char *filename);
301 char *xml_get_path(xmlNode *xml);
302 
303 char * crm_xml_escape(const char *text);
304 void crm_xml_sanitize_id(char *id);
305 void crm_xml_set_id(xmlNode *xml, const char *format, ...)
306  __attribute__ ((__format__ (__printf__, 2, 3)));
307 
311 void crm_destroy_xml(gpointer data);
312 
313 #ifdef __cplusplus
314 }
315 #endif
316 
317 #endif
calculate_operation_digest
char * calculate_operation_digest(xmlNode *local_cib, const char *version)
Calculate and return digest of XML operation.
Definition: digest.c:176
replace_xml_child
gboolean replace_xml_child(xmlNode *parent, xmlNode *child, xmlNode *update, gboolean delete_only)
Definition: xml.c:4009
find_xml_children
int find_xml_children(xmlNode **children, xmlNode *root, const char *tag, const char *field, const char *value, gboolean search_matches)
Definition: xml.c:3977
dump_xml_unformatted
char * dump_xml_unformatted(xmlNode *msg)
Definition: xml.c:3164
save_xml_to_file
void save_xml_to_file(xmlNode *xml, const char *desc, const char *filename)
Definition: xml.c:3217
xml_log_changes
void xml_log_changes(uint8_t level, const char *function, xmlNode *xml)
Definition: xml.c:967
xml_apply_patchset
int xml_apply_patchset(xmlNode *xml, xmlNode *patchset, bool check_version)
Definition: xml.c:1599
get_schema_version
int get_schema_version(const char *name)
Definition: schemas.c:1023
add_node_nocopy
int add_node_nocopy(xmlNode *parent, const char *name, xmlNode *child)
Definition: xml.c:1880
xml_patch_versions
bool xml_patch_versions(xmlNode *patchset, int add[3], int del[3])
Definition: xml.c:1190
diff_xml_object
xmlNode * diff_xml_object(xmlNode *left, xmlNode *right, gboolean suppress)
Definition: xml.c:3515
data
char data[0]
Definition: internal.h:10
xml_calculate_significant_changes
void xml_calculate_significant_changes(xmlNode *old_xml, xmlNode *new_xml)
Definition: xml.c:3493
getDocPtr
xmlDoc * getDocPtr(xmlNode *node)
Definition: xml.c:1850
create_xml_node
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition: xml.c:1888
expand_plus_plus
void expand_plus_plus(xmlNode *target, const char *name, const char *value)
Definition: xml.c:1789
get_xpath_object
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
Definition: xpath.c:220
xml_document_dirty
bool xml_document_dirty(xmlNode *xml)
Definition: xml.c:323
copy_xml
xmlNode * copy_xml(xmlNode *src_node)
Definition: xml.c:2018
patchset_process_digest
void patchset_process_digest(xmlNode *patch, xmlNode *source, xmlNode *target, bool with_digest)
Definition: xml.c:779
filename2xml
xmlNode * filename2xml(const char *filename)
Definition: xml.c:2235
write_xml_file
int write_xml_file(xmlNode *xml_node, const char *filename, gboolean compress)
Write XML to a file.
Definition: xml.c:2489
free_xml
void free_xml(xmlNode *child)
Definition: xml.c:2012
xpath_search
xmlXPathObjectPtr xpath_search(xmlNode *xml_top, const char *path)
Definition: xpath.c:145
update_xml_child
gboolean update_xml_child(xmlNode *child, xmlNode *to_update)
Definition: xml.c:3943
xml_has_children
gboolean xml_has_children(const xmlNode *root)
Definition: xml.c:3174
xml_acl_disable
void xml_acl_disable(xmlNode *xml)
Definition: acl.c:533
write_xml_fd
int write_xml_fd(xmlNode *xml_node, const char *filename, int fd, gboolean compress)
Write XML to a file descriptor.
Definition: xml.c:2467
add_message_xml
gboolean add_message_xml(xmlNode *msg, const char *field, xmlNode *xml)
Definition: xml.c:2510
xml_calculate_changes
void xml_calculate_changes(xmlNode *old_xml, xmlNode *new_xml)
Definition: xml.c:3500
sorted_xml
xmlNode * sorted_xml(xmlNode *input, xmlNode *parent, gboolean recursive)
Definition: xml.c:4092
crm_xml_escape
char * crm_xml_escape(const char *text)
Definition: xml.c:2536
first_named_child
xmlNode * first_named_child(const xmlNode *parent, const char *name)
Definition: xml.c:4124
find_entity
xmlNode * find_entity(xmlNode *parent, const char *node_name, const char *id)
Definition: xml.c:1741
purge_diff_markers
void purge_diff_markers(xmlNode *a_node)
Definition: xml.c:3204
crm_xml_set_id
void crm_xml_set_id(xmlNode *xml, const char *format,...) __attribute__((__format__(__printf__
update_validation
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
stdin2xml
xmlNode * stdin2xml(void)
Definition: xml.c:2121
xml_create_patchset
xmlNode * xml_create_patchset(int format, xmlNode *source, xmlNode *target, bool *config, bool manage_version)
Definition: xml.c:722
uint8_t
#define uint8_t
Definition: stdint.in.h:142
string2xml
xmlNode * string2xml(const char *input)
Definition: xml.c:2056
expand_idref
xmlNode * expand_idref(xmlNode *input, xmlNode *top)
Definition: xml.c:4196
calculate_xml_versioned_digest
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
dedupXpathResults
void dedupXpathResults(xmlXPathObjectPtr xpathObj)
Definition: xpath.c:107
get_message_xml
xmlNode * get_message_xml(xmlNode *msg, const char *field)
Definition: xml.c:2502
getXpathResult
xmlNode * getXpathResult(xmlXPathObjectPtr xpathObj, int index)
Definition: xpath.c:64
xml_acl_enabled
bool xml_acl_enabled(xmlNode *xml)
Definition: acl.c:546
xml_track_changes
void xml_track_changes(xmlNode *xml, const char *user, xmlNode *acl_source, bool enforce_acls)
Definition: xml.c:297
subtract_xml_object
xmlNode * subtract_xml_object(xmlNode *parent, xmlNode *left, xmlNode *right, gboolean full, gboolean *changed, const char *marker)
Definition: xml.c:3638
validate_xml
gboolean validate_xml(xmlNode *xml_blob, const char *validation, gboolean to_logs)
Definition: schemas.c:694
xml_accept_changes
void xml_accept_changes(xmlNode *xml)
Definition: xml.c:998
dump_xml_formatted_with_text
char * dump_xml_formatted_with_text(xmlNode *msg)
Definition: xml.c:3144
xml_acl_denied
bool xml_acl_denied(xmlNode *xml)
Definition: acl.c:522
fix_plus_plus_recursive
void fix_plus_plus_recursive(xmlNode *target)
Definition: xml.c:1771
crm_xml_init
void crm_xml_init(void)
Definition: xml.c:4164
xml_remove_prop
void xml_remove_prop(xmlNode *obj, const char *name)
Definition: xml.c:3183
xml_get_path
char * xml_get_path(xmlNode *xml)
Definition: xml.c:1935
xml_acl_filtered_copy
bool xml_acl_filtered_copy(const char *user, xmlNode *acl_source, xmlNode *xml, xmlNode **result)
Definition: acl.c:395
nvpair.h
Functionality for manipulating name/value pairs.
__attribute__
Definition: crm_internal.h:221
get_xpath_object_relative
xmlNode * get_xpath_object_relative(const char *xpath, xmlNode *xml_obj, int error_level)
Definition: xpath.c:198
crm_xml_cleanup
void crm_xml_cleanup(void)
Definition: xml.c:4186
apply_xml_diff
gboolean apply_xml_diff(xmlNode *old_xml, xmlNode *diff, xmlNode **new_xml)
Definition: xml.c:3235
find_xml_node
xmlNode * find_xml_node(xmlNode *cib, const char *node_path, gboolean must_find)
Definition: xml.c:1676
xml_latest_schema
const char * xml_latest_schema(void)
Definition: schemas.c:113
crm_next_same_xml
xmlNode * crm_next_same_xml(const xmlNode *sibling)
Get next instance of same XML tag.
Definition: xml.c:4149
validate_xml_verbose
gboolean validate_xml_verbose(xmlNode *xml_blob)
Definition: schemas.c:666
version
uint32_t version
Definition: remote.c:1
copy_in_properties
void copy_in_properties(xmlNode *target, xmlNode *src)
Definition: xml.c:1748
xml_log_patchset
void xml_log_patchset(uint8_t level, const char *function, xmlNode *xml)
Definition: xml.c:812
can_prune_leaf
gboolean can_prune_leaf(xmlNode *xml_node)
Definition: xml.c:3543
cli_config_update
gboolean cli_config_update(xmlNode **xml, int *best_version, gboolean to_logs)
Definition: schemas.c:1189
dump_xml_formatted
char * dump_xml_formatted(xmlNode *msg)
Definition: xml.c:3154
get_schema_name
const char * get_schema_name(int version)
Definition: schemas.c:1014
add_node_copy
xmlNode * add_node_copy(xmlNode *new_parent, xmlNode *xml_node)
Definition: xml.c:1866
xml_tracking_changes
bool xml_tracking_changes(xmlNode *xml)
Definition: xml.c:312
crm_destroy_xml
void void crm_destroy_xml(gpointer data)
xmlNode destructor which can be used in glib collections
Definition: xml.c:4229
freeXpathObject
void freeXpathObject(xmlXPathObjectPtr xpathObj)
Definition: xpath.c:45
crm.h
A dumping ground.
crm_remote_s::source
mainloop_io_t * source
Definition: ipcs.h:42
calculate_on_disk_digest
char * calculate_on_disk_digest(xmlNode *local_cib)
Calculate and return digest of XML tree, suitable for storing on disk.
Definition: digest.c:157
crm_xml_sanitize_id
void crm_xml_sanitize_id(char *id)
Sanitize a string so it is usable as an XML ID.
Definition: xml.c:2323
crm_foreach_xpath_result
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