pacemaker  1.1.18-7fdfbbe
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 (C) 2004 Andrew Beekhof <andrew@beekhof.net>
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This software is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 #ifndef CRM_COMMON_XML__H
19 # define CRM_COMMON_XML__H
20 
27 # include <stdio.h>
28 # include <sys/types.h>
29 # include <unistd.h>
30 
31 # include <stdlib.h>
32 # include <errno.h>
33 # include <fcntl.h>
34 
35 # include <crm/crm.h>
36 
37 # include <libxml/tree.h>
38 # include <libxml/xpath.h>
39 
40 /* Define compression parameters for IPC messages
41  *
42  * Compression costs a LOT, so we don't want to do it unless we're hitting
43  * message limits. Currently, we use 128KB as the threshold, because higher
44  * values don't play well with the heartbeat stack. With an earlier limit of
45  * 10KB, compressing 184 of 1071 messages accounted for 23% of the total CPU
46  * used by the cib.
47  */
48 # define CRM_BZ2_BLOCKS 4
49 # define CRM_BZ2_WORK 20
50 # define CRM_BZ2_THRESHOLD 128 * 1024
51 
52 # define XML_PARANOIA_CHECKS 0
53 
54 gboolean add_message_xml(xmlNode * msg, const char *field, xmlNode * xml);
55 xmlNode *get_message_xml(xmlNode * msg, const char *field);
56 GHashTable *xml2list(xmlNode * parent);
57 
58 xmlNode *crm_create_nvpair_xml(xmlNode *parent, const char *id,
59  const char *name, const char *value);
60 
61 void hash2nvpair(gpointer key, gpointer value, gpointer user_data);
62 void hash2field(gpointer key, gpointer value, gpointer user_data);
63 void hash2metafield(gpointer key, gpointer value, gpointer user_data);
64 void hash2smartfield(gpointer key, gpointer value, gpointer user_data);
65 
66 xmlDoc *getDocPtr(xmlNode * node);
67 
68 /*
69  * Replacement function for xmlCopyPropList which at the very least,
70  * doesn't work the way *I* would expect it to.
71  *
72  * Copy all the attributes/properties from src into target.
73  *
74  * Not recursive, does not return anything.
75  *
76  */
77 void copy_in_properties(xmlNode * target, xmlNode * src);
78 void expand_plus_plus(xmlNode * target, const char *name, const char *value);
79 void fix_plus_plus_recursive(xmlNode * target);
80 
81 /*
82  * Create a node named "name" as a child of "parent"
83  * If parent is NULL, creates an unconnected node.
84  *
85  * Returns the created node
86  *
87  */
88 xmlNode *create_xml_node(xmlNode * parent, const char *name);
89 
90 /*
91  * Make a copy of name and value and use the copied memory to create
92  * an attribute for node.
93  *
94  * If node, name or value are NULL, nothing is done.
95  *
96  * If name or value are an empty string, nothing is done.
97  *
98  * Returns FALSE on failure and TRUE on success.
99  *
100  */
101 const char *crm_xml_add(xmlNode * node, const char *name, const char *value);
102 
103 const char *crm_xml_replace(xmlNode * node, const char *name, const char *value);
104 
105 const char *crm_xml_add_int(xmlNode * node, const char *name, int value);
106 
119 static inline const char *
120 crm_xml_add_boolean(xmlNode *node, const char *name, gboolean value)
121 {
122  return crm_xml_add(node, name, (value? "true" : "false"));
123 }
124 
125 /*
126  * Unlink the node and set its doc pointer to NULL so free_xml()
127  * will act appropriately
128  */
129 void unlink_xml_node(xmlNode * node);
130 
131 /*
132  *
133  */
134 void purge_diff_markers(xmlNode * a_node);
135 
136 /*
137  * Returns a deep copy of src_node
138  *
139  */
140 xmlNode *copy_xml(xmlNode * src_node);
141 
142 /*
143  * Add a copy of xml_node to new_parent
144  */
145 xmlNode *add_node_copy(xmlNode * new_parent, xmlNode * xml_node);
146 
147 int add_node_nocopy(xmlNode * parent, const char *name, xmlNode * child);
148 
149 /*
150  * XML I/O Functions
151  *
152  * Whitespace between tags is discarded.
153  */
154 xmlNode *filename2xml(const char *filename);
155 
156 xmlNode *stdin2xml(void);
157 
158 xmlNode *string2xml(const char *input);
159 
160 int write_xml_fd(xmlNode * xml_node, const char *filename, int fd, gboolean compress);
161 int write_xml_file(xmlNode * xml_node, const char *filename, gboolean compress);
162 
163 char *dump_xml_formatted(xmlNode * msg);
164 /* Also dump the text node with xml_log_option_text enabled */
165 char *dump_xml_formatted_with_text(xmlNode * msg);
166 
167 char *dump_xml_unformatted(xmlNode * msg);
168 
169 /*
170  * Diff related Functions
171  */
172 xmlNode *diff_xml_object(xmlNode * left, xmlNode * right, gboolean suppress);
173 
174 xmlNode *subtract_xml_object(xmlNode * parent, xmlNode * left, xmlNode * right,
175  gboolean full, gboolean * changed, const char *marker);
176 
177 gboolean can_prune_leaf(xmlNode * xml_node);
178 
179 void print_xml_diff(FILE * where, xmlNode * diff);
180 
181 gboolean apply_xml_diff(xmlNode * old, xmlNode * diff, xmlNode ** new);
182 
183 /*
184  * Searching & Modifying
185  */
186 xmlNode *find_xml_node(xmlNode * cib, const char *node_path, gboolean must_find);
187 
188 xmlNode *find_entity(xmlNode * parent, const char *node_name, const char *id);
189 
190 void xml_remove_prop(xmlNode * obj, const char *name);
191 
192 gboolean replace_xml_child(xmlNode * parent, xmlNode * child, xmlNode * update,
193  gboolean delete_only);
194 
195 gboolean update_xml_child(xmlNode * child, xmlNode * to_update);
196 
197 int find_xml_children(xmlNode ** children, xmlNode * root,
198  const char *tag, const char *field, const char *value,
199  gboolean search_matches);
200 
201 int crm_element_value_int(xmlNode * data, const char *name, int *dest);
202 char *crm_element_value_copy(xmlNode * data, const char *name);
203 int crm_element_value_const_int(const xmlNode * data, const char *name, int *dest);
204 const char *crm_element_value_const(const xmlNode * data, const char *name);
205 xmlNode *get_xpath_object(const char *xpath, xmlNode * xml_obj, int error_level);
206 xmlNode *get_xpath_object_relative(const char *xpath, xmlNode * xml_obj, int error_level);
207 
208 static inline const char *
209 crm_element_name(xmlNode *xml)
210 {
211  return xml? (const char *)(xml->name) : NULL;
212 }
213 
214 const char *crm_element_value(xmlNode * data, const char *name);
215 
225 static inline const char *
226 crm_copy_xml_element(xmlNode *obj1, xmlNode *obj2, const char *element)
227 {
228  const char *value = crm_element_value(obj1, element);
229 
230  crm_xml_add(obj2, element, value);
231  return value;
232 }
233 
234 void xml_validate(const xmlNode * root);
235 
236 gboolean xml_has_children(const xmlNode * root);
237 
238 char *calculate_on_disk_digest(xmlNode * local_cib);
239 char *calculate_operation_digest(xmlNode * local_cib, const char *version);
240 char *calculate_xml_versioned_digest(xmlNode * input, gboolean sort, gboolean do_filter,
241  const char *version);
242 
243 /* schema-related functions (from schemas.c) */
244 gboolean validate_xml(xmlNode * xml_blob, const char *validation, gboolean to_logs);
245 gboolean validate_xml_verbose(xmlNode * xml_blob);
246 
284 int update_validation(xmlNode **xml_blob, int *best, int max,
285  gboolean transform, gboolean to_logs);
286 
287 int get_schema_version(const char *name);
288 const char *get_schema_name(int version);
289 const char *xml_latest_schema(void);
290 gboolean cli_config_update(xmlNode ** xml, int *best_version, gboolean to_logs);
291 
292 void crm_xml_init(void);
293 void crm_xml_cleanup(void);
294 
295 static inline xmlNode *
296 __xml_first_child(xmlNode * parent)
297 {
298  xmlNode *child = NULL;
299 
300  if (parent) {
301  child = parent->children;
302  while (child && child->type == XML_TEXT_NODE) {
303  child = child->next;
304  }
305  }
306  return child;
307 }
308 
309 static inline xmlNode *
310 __xml_next(xmlNode * child)
311 {
312  if (child) {
313  child = child->next;
314  while (child && child->type == XML_TEXT_NODE) {
315  child = child->next;
316  }
317  }
318  return child;
319 }
320 
321 static inline xmlNode *
322 __xml_first_child_element(xmlNode * parent)
323 {
324  xmlNode *child = NULL;
325 
326  if (parent) {
327  child = parent->children;
328  }
329 
330  while (child) {
331  if(child->type == XML_ELEMENT_NODE) {
332  return child;
333  }
334  child = child->next;
335  }
336  return NULL;
337 }
338 
339 static inline xmlNode *
340 __xml_next_element(xmlNode * child)
341 {
342  while (child) {
343  child = child->next;
344  if(child && child->type == XML_ELEMENT_NODE) {
345  return child;
346  }
347  }
348  return NULL;
349 }
350 
351 void free_xml(xmlNode * child);
352 
353 xmlNode *first_named_child(xmlNode * parent, const char *name);
354 xmlNode *crm_next_same_xml(xmlNode *sibling);
355 
356 xmlNode *sorted_xml(xmlNode * input, xmlNode * parent, gboolean recursive);
357 xmlXPathObjectPtr xpath_search(xmlNode * xml_top, const char *path);
358 void crm_foreach_xpath_result(xmlNode *xml, const char *xpath,
359  void (*helper)(xmlNode*, void*), void *user_data);
360 xmlNode *expand_idref(xmlNode * input, xmlNode * top);
361 
362 void freeXpathObject(xmlXPathObjectPtr xpathObj);
363 xmlNode *getXpathResult(xmlXPathObjectPtr xpathObj, int index);
364 void dedupXpathResults(xmlXPathObjectPtr xpathObj);
365 
366 static inline int numXpathResults(xmlXPathObjectPtr xpathObj)
367 {
368  if(xpathObj == NULL || xpathObj->nodesetval == NULL) {
369  return 0;
370  }
371  return xpathObj->nodesetval->nodeNr;
372 }
373 
374 bool xml_acl_enabled(xmlNode *xml);
375 void xml_acl_disable(xmlNode *xml);
376 bool xml_acl_denied(xmlNode *xml); /* Part or all of a change was rejected */
377 bool xml_acl_filtered_copy(const char *user, xmlNode* acl_source, xmlNode *xml, xmlNode ** result);
378 
379 bool xml_tracking_changes(xmlNode * xml);
380 bool xml_document_dirty(xmlNode *xml);
381 void xml_track_changes(xmlNode * xml, const char *user, xmlNode *acl_source, bool enforce_acls);
382 void xml_calculate_changes(xmlNode * old, xmlNode * new); /* For comparing two documents after the fact */
383 void xml_accept_changes(xmlNode * xml);
384 void xml_log_changes(uint8_t level, const char *function, xmlNode *xml);
385 void xml_log_patchset(uint8_t level, const char *function, xmlNode *xml);
386 bool xml_patch_versions(xmlNode *patchset, int add[3], int del[3]);
387 
388 xmlNode *xml_create_patchset(
389  int format, xmlNode *source, xmlNode *target, bool *config, bool manage_version);
390 int xml_apply_patchset(xmlNode *xml, xmlNode *patchset, bool check_version);
391 
392 void patchset_process_digest(xmlNode *patch, xmlNode *source, xmlNode *target, bool with_digest);
393 
394 void save_xml_to_file(xmlNode * xml, const char *desc, const char *filename);
395 char *xml_get_path(xmlNode *xml);
396 
397 char * crm_xml_escape(const char *text);
398 void crm_xml_sanitize_id(char *id);
399 void crm_xml_set_id(xmlNode *xml, const char *format, ...)
400  __attribute__ ((__format__ (__printf__, 2, 3)));
401 
405 void crm_destroy_xml(gpointer data);
406 
407 #endif
xmlNode * find_xml_node(xmlNode *cib, const char *node_path, gboolean must_find)
Definition: xml.c:2235
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:3163
GHashTable * xml2list(xmlNode *parent)
Definition: xml.c:4931
void xml_validate(const xmlNode *root)
int crm_element_value_const_int(const xmlNode *data, const char *name, int *dest)
Definition: xml.c:3857
void xml_calculate_changes(xmlNode *old, xmlNode *new)
Definition: xml.c:4187
void crm_xml_cleanup(void)
Definition: xml.c:5115
xmlNode * find_entity(xmlNode *parent, const char *node_name, const char *id)
Definition: xml.c:2268
void xml_track_changes(xmlNode *xml, const char *user, xmlNode *acl_source, bool enforce_acls)
Definition: xml.c:857
bool xml_acl_denied(xmlNode *xml)
Definition: xml.c:822
void crm_xml_init(void)
Definition: xml.c:5093
int write_xml_file(xmlNode *xml_node, const char *filename, gboolean compress)
Definition: xml.c:3153
char * crm_element_value_copy(xmlNode *data, const char *name)
Definition: xml.c:3869
int get_schema_version(const char *name)
Definition: schemas.c:766
void print_xml_diff(FILE *where, xmlNode *diff)
void copy_in_properties(xmlNode *target, xmlNode *src)
Definition: xml.c:2287
void xml_accept_changes(xmlNode *xml)
Definition: xml.c:1573
xmlNode * filename2xml(const char *filename)
Definition: xml.c:2934
void dedupXpathResults(xmlXPathObjectPtr xpathObj)
Definition: xpath.c:107
void purge_diff_markers(xmlNode *a_node)
Definition: xml.c:3902
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:2750
void crm_xml_sanitize_id(char *id)
Sanitize a string so it is usable as an XML ID.
Definition: xml.c:3021
char version[256]
Definition: plugin.c:84
gboolean validate_xml(xmlNode *xml_blob, const char *validation, gboolean to_logs)
Definition: schemas.c:650
xmlDoc * getDocPtr(xmlNode *node)
Definition: xml.c:2389
bool xml_acl_enabled(xmlNode *xml)
Definition: xml.c:846
const char * crm_xml_replace(xmlNode *node, const char *name, const char *value)
Definition: xml.c:2536
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:2328
bool xml_tracking_changes(xmlNode *xml)
Definition: xml.c:872
void hash2smartfield(gpointer key, gpointer value, gpointer user_data)
Definition: xml.c:4869
xmlNode * copy_xml(xmlNode *src_node)
Definition: xml.c:2712
void hash2field(gpointer key, gpointer value, gpointer user_data)
Definition: xml.c:4892
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:2815
int xml_apply_patchset(xmlNode *xml, xmlNode *patchset, bool check_version)
Definition: xml.c:2158
gboolean update_xml_child(xmlNode *child, xmlNode *to_update)
Definition: xml.c:4672
enum crm_proc_flag __attribute__
xmlNode * add_node_copy(xmlNode *new_parent, xmlNode *xml_node)
Definition: xml.c:2405
const char * crm_element_value_const(const xmlNode *data, const char *name)
Definition: xml.c:3863
xmlNode * expand_idref(xmlNode *input, xmlNode *top)
Definition: xml.c:5125
bool xml_document_dirty(xmlNode *xml)
Definition: xml.c:883
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition: xml.c:2588
int crm_element_value_int(xmlNode *data, const char *name, int *dest)
Definition: xml.c:3844
char * dump_xml_formatted(xmlNode *msg)
Definition: xml.c:3815
const char * crm_element_value(xmlNode *data, const char *name)
Definition: xml.c:5165
xmlNode * crm_next_same_xml(xmlNode *sibling)
Get next instance of same XML tag.
Definition: xml.c:5078
void xml_acl_disable(xmlNode *xml)
Definition: xml.c:833
void void crm_destroy_xml(gpointer data)
xmlNode destructor which can be used in glib collections
Definition: xml.c:5187
gboolean add_message_xml(xmlNode *msg, const char *field, xmlNode *xml)
Definition: xml.c:3171
void free_xml(xmlNode *child)
Definition: xml.c:2706
gboolean xml_has_children(const xmlNode *root)
Definition: xml.c:3835
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:5009
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:1354
void hash2metafield(gpointer key, gpointer value, gpointer user_data)
Definition: xml.c:4908
int find_xml_children(xmlNode **children, xmlNode *root, const char *tag, const char *field, const char *value, gboolean search_matches)
Definition: xml.c:4706
bool xml_patch_versions(xmlNode *patchset, int add[3], int del[3])
Definition: xml.c:1765
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Definition: xml.c:2490
void xml_log_changes(uint8_t level, const char *function, xmlNode *xml)
Definition: xml.c:1542
const char * crm_xml_add_int(xmlNode *node, const char *name, int value)
Definition: xml.c:2578
gboolean apply_xml_diff(xmlNode *old, xmlNode *diff, xmlNode **new)
Definition: xml.c:3933
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:3881
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:4228
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:4831
char * xml_get_path(xmlNode *xml)
Definition: xml.c:2631
char * dump_xml_unformatted(xmlNode *msg)
Definition: xml.c:3825
bool xml_acl_filtered_copy(const char *user, xmlNode *acl_source, xmlNode *xml, xmlNode **result)
Definition: xml.c:701
char data[0]
Definition: internal.h:58
#define uint8_t
Definition: stdint.in.h:144
void save_xml_to_file(xmlNode *xml, const char *desc, const char *filename)
Definition: xml.c:3915
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:783
xmlNode * diff_xml_object(xmlNode *left, xmlNode *right, gboolean suppress)
Definition: xml.c:4200
int add_node_nocopy(xmlNode *parent, const char *name, xmlNode *child)
Definition: xml.c:2419
xmlNode * first_named_child(xmlNode *parent, const char *name)
Definition: xml.c:5053
xmlNode * subtract_xml_object(xmlNode *parent, xmlNode *left, xmlNode *right, gboolean full, gboolean *changed, const char *marker)
Definition: xml.c:4386
void xml_log_patchset(uint8_t level, const char *function, xmlNode *xml)
Definition: xml.c:1387
int write_xml_fd(xmlNode *xml_node, const char *filename, int fd, gboolean compress)
Definition: xml.c:3143
char * crm_xml_escape(const char *text)
Definition: xml.c:3197
gboolean cli_config_update(xmlNode **xml, int *best_version, gboolean to_logs)
Definition: schemas.c:926
void hash2nvpair(gpointer key, gpointer value, gpointer user_data)
Definition: xml.c:4858
void fix_plus_plus_recursive(xmlNode *target)
Definition: xml.c:2310
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:1294
char * dump_xml_formatted_with_text(xmlNode *msg)
Definition: xml.c:3805
gboolean replace_xml_child(xmlNode *parent, xmlNode *child, xmlNode *update, gboolean delete_only)
Definition: xml.c:4738
const char * get_schema_name(int version)
Definition: schemas.c:757