28 #include <sys/param.h>
29 #include <sys/types.h>
38 cib_process_query(
const char *op,
int options,
const char *section, xmlNode * req, xmlNode * input,
39 xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer)
41 xmlNode *obj_root = NULL;
48 existing_cib, result_cib, answer);
60 if (obj_root == NULL) {
64 const char *tag =
TYPE(obj_root);
74 if (result ==
pcmk_ok && *answer == NULL) {
75 crm_err(
"Error creating query response");
83 cib_process_erase(
const char *op,
int options,
const char *section, xmlNode * req, xmlNode * input,
84 xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer)
101 xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib,
106 int current_version = 0;
112 crm_trace(
"Processing \"%s\" event with max=%s", op, max);
123 if (new_version > current_version) {
134 cib_process_bump(
const char *op,
int options,
const char *section, xmlNode * req, xmlNode * input,
135 xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer)
139 crm_trace(
"Processing \"%s\" event for epoch=%s",
151 char *new_value = NULL;
152 char *old_value = NULL;
158 if (old_value != NULL) {
159 new_value = calloc(1, 128);
160 int_value = atoi(old_value);
161 sprintf(new_value,
"%d", ++int_value);
163 new_value = strdup(
"1");
177 xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib,
180 const char *tag = NULL;
187 existing_cib, result_cib, answer);
196 tag = crm_element_name(input);
210 int replace_updates = 0;
211 int replace_epoch = 0;
212 int replace_admin_epoch = 0;
214 const char *reason = NULL;
225 crm_err(
"Digest mis-match on replace from %s: %s vs. %s (expected)", peer,
226 digest_verify, digest);
227 reason =
"digest mismatch";
230 crm_info(
"Digest matched on replace from %s: %s", peer, digest);
241 if (replace_admin_epoch < admin_epoch) {
244 }
else if (replace_admin_epoch > admin_epoch) {
247 }
else if (replace_epoch < epoch) {
250 }
else if (replace_epoch > epoch) {
253 }
else if (replace_updates < updates) {
257 if (reason != NULL) {
258 crm_info(
"Replacement %d.%d.%d from %s not applied to %d.%d.%d:"
259 " current %s is greater than the replacement",
260 replace_admin_epoch, replace_epoch,
261 replace_updates, peer, admin_epoch, epoch, updates, reason);
264 crm_info(
"Replaced %d.%d.%d with %d.%d.%d from %s",
265 admin_epoch, epoch, updates,
266 replace_admin_epoch, replace_epoch, replace_updates, peer);
273 xmlNode *obj_root = NULL;
279 crm_trace(
"No matching object to replace");
289 xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer)
291 xmlNode *obj_root = NULL;
293 crm_trace(
"Processing \"%s\" event", op);
297 existing_cib, result_cib, answer);
301 crm_err(
"Cannot perform modification with no data");
306 if(
safe_str_eq(crm_element_name(input), section)) {
307 xmlNode *child = NULL;
308 for(child = __xml_first_child(input); child; child = __xml_next(child)) {
310 crm_trace(
"No matching object to delete: %s=%s", child->name,
ID(child));
315 crm_trace(
"No matching object to delete: %s=%s", input->name,
ID(input));
323 xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer)
325 xmlNode *obj_root = NULL;
327 crm_trace(
"Processing \"%s\" event", op);
331 existing_cib, result_cib, answer);
335 crm_err(
"Cannot perform modification with no data");
340 if (obj_root == NULL) {
341 xmlNode *tmp_section = NULL;
355 CRM_CHECK(obj_root != NULL,
return -EINVAL);
367 xmlXPathObjectPtr xpathObj =
xpath_search(*result_cib,
"//@__delete__");
370 max = numXpathResults(xpathObj);
374 for (lpc = 0; lpc < max; lpc++) {
376 xmlChar *match_path = xmlGetNodePath(match);
389 update_cib_object(xmlNode * parent, xmlNode * update)
392 xmlNode *target = NULL;
393 xmlNode *a_child = NULL;
394 const char *replace = NULL;
395 const char *object_id = NULL;
396 const char *object_name = NULL;
398 CRM_CHECK(update != NULL,
return -EINVAL);
399 CRM_CHECK(parent != NULL,
return -EINVAL);
401 object_name = crm_element_name(update);
402 CRM_CHECK(object_name != NULL,
return -EINVAL);
404 object_id =
ID(update);
407 if (object_id == NULL) {
412 target =
find_entity(parent, object_name, object_id);
415 if (target == NULL) {
422 if (replace != NULL) {
423 xmlNode *
remove = NULL;
424 int last = 0, lpc = 0, len = 0;
426 len = strlen(replace);
428 if (replace[lpc] ==
',' || replace[lpc] == 0) {
429 char *replace_item = NULL;
437 replace_item = calloc(1, lpc - last + 1);
438 memcpy(replace_item, replace + last, lpc - last);
441 if (
remove != NULL) {
443 replace_item, crm_element_name(target));
461 for (a_child = __xml_first_child(update); a_child != NULL; a_child = __xml_next(a_child)) {
464 crm_trace(
"Updating child <%s id=%s>", crm_element_name(a_child),
ID(a_child));
466 tmp_result = update_cib_object(target, a_child);
470 crm_err(
"Error updating child <%s id=%s>", crm_element_name(a_child),
ID(a_child));
484 add_cib_object(xmlNode * parent, xmlNode * new_obj)
487 const char *object_name = NULL;
488 const char *object_id = NULL;
489 xmlNode *equiv_node = NULL;
491 if (new_obj != NULL) {
492 object_name = crm_element_name(new_obj);
498 if (new_obj == NULL || object_name == NULL) {
501 }
else if (parent == NULL) {
504 }
else if (object_id == NULL) {
509 equiv_node =
find_entity(parent, object_name, object_id);
515 }
else if (equiv_node != NULL) {
519 result = update_cib_object(parent, new_obj);
527 xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer)
529 xmlNode *failed = NULL;
531 xmlNode *update_section = NULL;
547 crm_err(
"Cannot perform modification with no data");
551 if (section == NULL) {
559 if (
safe_str_eq(crm_element_name(input), section)) {
560 xmlNode *a_child = NULL;
562 for (a_child = __xml_first_child(input); a_child != NULL; a_child = __xml_next(a_child)) {
563 result = add_cib_object(update_section, a_child);
570 result = add_cib_object(update_section, input);
590 cib_process_diff(
const char *op,
int options,
const char *section, xmlNode * req, xmlNode * input,
591 xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer)
593 const char *originator = NULL;
599 crm_trace(
"Processing \"%s\" event from %s %s",
600 op, originator, is_set(options,
cib_force_diff)?
"(global update)":
"");
603 *result_cib =
copy_xml(existing_cib);
610 int lpc = 0, max = 0;
611 gboolean config_changes = FALSE;
612 xmlXPathObject *xpathObj = NULL;
617 if (*diff == NULL && last != NULL && next != NULL) {
630 if (numXpathResults(xpathObj) > 0) {
631 config_changes = TRUE;
642 max = numXpathResults(xpathObj);
644 for (lpc = 0; lpc < max; lpc++) {
648 config_changes = TRUE;
652 config_changes = TRUE;
657 config_changes = TRUE;
661 config_changes = TRUE;
665 config_changes = TRUE;
669 config_changes = TRUE;
676 return config_changes;
680 cib_process_xpath(
const char *op,
int options,
const char *section, xmlNode * req, xmlNode * input,
681 xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer)
688 xmlXPathObjectPtr xpathObj = NULL;
690 crm_trace(
"Processing \"%s\" event", op);
698 max = numXpathResults(xpathObj);
701 crm_debug(
"%s was already removed", section);
703 }
else if (max < 1) {
704 crm_debug(
"%s: %s does not exist", op, section);
707 }
else if (is_query) {
717 for (lpc = 0; lpc < max; lpc++) {
718 xmlChar *path = NULL;
725 path = xmlGetNodePath(match);
726 crm_debug(
"Processing %s op for %s with %s", op, section, path);
730 if (match == *result_cib) {
732 crm_warn(
"Cannot perform %s for %s: The xpath is addressing the whole /cib", op, section);
738 if ((options & cib_multiple) == 0) {
745 }
else if ((options & cib_multiple) == 0) {
756 const char *tag =
TYPE(match);
761 if (*answer == NULL) {
769 xmlNode *parent = match;
771 while (parent && parent->type == XML_ELEMENT_NODE) {
773 char *new_path = NULL;
776 extra += strlen((
const char *)parent->name);
783 new_path = malloc(path_len + 1);
784 if(new_path == NULL) {
788 snprintf(new_path, path_len + 1,
"/%s[@id='%s']%s", parent->name,
id,
791 snprintf(new_path, path_len + 1,
"/%s%s", parent->name, path ? path :
"");
795 parent = parent->parent;
799 if (*answer == NULL) {
806 }
else if (*answer) {
814 xmlNode *parent = match->parent;
821 if ((options & cib_multiple) == 0) {
833 update_results(xmlNode * failed, xmlNode * target,
const char *operation,
int return_code)
835 xmlNode *xml_node = NULL;
836 gboolean was_error = FALSE;
837 const char *error_msg = NULL;
851 crm_warn(
"Action %s failed: %s (cde=%d)", operation, error_msg, return_code);
#define CRM_CHECK(expr, failure_action)
xmlNode * find_xml_node(xmlNode *cib, const char *node_path, gboolean must_find)
gboolean cib_version_details(xmlNode *cib, int *admin_epoch, int *epoch, int *updates)
#define XML_CIB_TAG_SECTION_ALL
gboolean safe_str_neq(const char *a, const char *b)
gboolean update_results(xmlNode *failed, xmlNode *target, const char *operation, int return_code)
#define XML_ATTR_NUMUPDATES
int cib_process_delete(const char *op, int options, const char *section, xmlNode *req, xmlNode *input, xmlNode *existing_cib, xmlNode **result_cib, xmlNode **answer)
const char * pcmk_strerror(int rc)
int cib_process_replace(const char *op, int options, const char *section, xmlNode *req, xmlNode *input, xmlNode *existing_cib, xmlNode **result_cib, xmlNode **answer)
xmlNode * get_object_root(const char *object_type, xmlNode *the_root)
#define pcmk_err_old_data
xmlNode * find_entity(xmlNode *parent, const char *node_name, const char *id)
int cib_process_erase(const char *op, int options, const char *section, xmlNode *req, xmlNode *input, xmlNode *existing_cib, xmlNode **result_cib, xmlNode **answer)
int cib_process_bump(const char *op, int options, const char *section, xmlNode *req, xmlNode *input, xmlNode *existing_cib, xmlNode **result_cib, xmlNode **answer)
char * crm_element_value_copy(xmlNode *data, const char *name)
int get_schema_version(const char *name)
int cib_update_counter(xmlNode *xml_obj, const char *field, gboolean reset)
#define CRM_LOG_ASSERT(expr)
void copy_in_properties(xmlNode *target, xmlNode *src)
int cib_process_xpath(const char *op, int options, const char *section, xmlNode *req, xmlNode *input, xmlNode *existing_cib, xmlNode **result_cib, xmlNode **answer)
void dedupXpathResults(xmlXPathObjectPtr xpathObj)
const char * get_object_parent(const char *object_type)
#define XML_ATTR_GENERATION
xmlNode * copy_xml(xmlNode *src_node)
#define crm_warn(fmt, args...)
#define crm_debug(fmt, args...)
int cib_process_diff(const char *op, int options, const char *section, xmlNode *req, xmlNode *input, xmlNode *existing_cib, xmlNode **result_cib, xmlNode **answer)
gboolean cib_config_changed(xmlNode *last, xmlNode *next, xmlNode **diff)
int xml_apply_patchset(xmlNode *xml, xmlNode *patchset, bool check_version)
gboolean update_xml_child(xmlNode *child, xmlNode *to_update)
#define crm_trace(fmt, args...)
xmlNode * createEmptyCib(int admin_epoch)
xmlNode * add_node_copy(xmlNode *new_parent, xmlNode *xml_node)
Wrappers for and extensions to libxml2.
xmlNode * create_xml_node(xmlNode *parent, const char *name)
int crm_element_value_int(xmlNode *data, const char *name, int *dest)
const char * crm_element_value(xmlNode *data, const char *name)
#define XML_ATTR_VALIDATION
#define XML_FAILCIB_ATTR_OP
void free_xml(xmlNode *child)
gboolean xml_has_children(const xmlNode *root)
#define XML_FAILCIB_ATTR_OBJTYPE
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
int cib_process_query(const char *op, int options, const char *section, xmlNode *req, xmlNode *input, xmlNode *existing_cib, xmlNode **result_cib, xmlNode **answer)
#define crm_log_xml_err(xml, text)
#define crm_err(fmt, args...)
xmlXPathObjectPtr xpath_search(xmlNode *xml_top, const char *path)
#define XML_FAILCIB_ATTR_REASON
void xml_remove_prop(xmlNode *obj, const char *name)
xmlNode * getXpathResult(xmlXPathObjectPtr xpathObj, int index)
char * calculate_xml_versioned_digest(xmlNode *input, gboolean sort, gboolean do_filter, const char *version)
Calculate and return digest of XML tree.
#define XML_ATTR_GENERATION_ADMIN
#define XML_CIB_ATTR_REPLACE
#define XML_ATTR_CRM_VERSION
int update_validation(xmlNode **xml_blob, int *best, int max, gboolean transform, gboolean to_logs)
Update CIB XML to most recent schema version.
xmlNode * diff_xml_object(xmlNode *left, xmlNode *right, gboolean suppress)
#define crm_log_xml_trace(xml, text)
#define XML_TAG_DIFF_REMOVED
#define XML_CIB_TAG_CONFIGURATION
#define XML_FAILCIB_ATTR_ID
#define safe_str_eq(a, b)
void freeXpathObject(xmlXPathObjectPtr xpathObj)
int cib_process_upgrade(const char *op, int options, const char *section, xmlNode *req, xmlNode *input, xmlNode *existing_cib, xmlNode **result_cib, xmlNode **answer)
#define crm_info(fmt, args...)
int cib_process_modify(const char *op, int options, const char *section, xmlNode *req, xmlNode *input, xmlNode *existing_cib, xmlNode **result_cib, xmlNode **answer)
int cib_process_create(const char *op, int options, const char *section, xmlNode *req, xmlNode *input, xmlNode *existing_cib, xmlNode **result_cib, xmlNode **answer)
gboolean replace_xml_child(xmlNode *parent, xmlNode *child, xmlNode *update, gboolean delete_only)