19 #include <sys/param.h> 20 #include <sys/types.h> 31 xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer)
33 xmlNode *obj_root = NULL;
37 op, pcmk__s(section,
"unspecified"));
41 existing_cib, result_cib, answer);
53 if (obj_root == NULL) {
57 const char *tag =
TYPE(obj_root);
68 crm_err(
"Error creating query response");
76 update_counter(xmlNode *xml_obj,
const char *field,
bool reset)
78 char *new_value = NULL;
79 char *old_value = NULL;
85 if (old_value != NULL) {
86 int_value = atoi(old_value);
87 new_value = pcmk__itoa(++int_value);
89 new_value = strdup(
"1");
94 field, pcmk__s(old_value,
"unset"), new_value);
105 xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer)
109 crm_trace(
"Processing \"%s\" event", op);
122 xmlNode *
input, xmlNode * existing_cib, xmlNode ** result_cib,
127 int current_version = 0;
133 crm_trace(
"Processing \"%s\" event with max=%s", op, max);
145 if (new_version > current_version) {
157 xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer)
161 crm_trace(
"Processing %s for epoch='%s'", op,
172 xmlNode *
input, xmlNode * existing_cib, xmlNode ** result_cib,
175 const char *tag = NULL;
178 crm_trace(
"Processing %s for %s section",
179 op, pcmk__s(section,
"unspecified"));
183 existing_cib, result_cib, answer);
192 tag = crm_element_name(
input);
206 int replace_updates = 0;
207 int replace_epoch = 0;
208 int replace_admin_epoch = 0;
210 const char *reason = NULL;
221 crm_err(
"Digest mis-match on replace from %s: %s vs. %s (expected)", peer,
222 digest_verify, digest);
223 reason =
"digest mismatch";
226 crm_info(
"Digest matched on replace from %s: %s", peer, digest);
237 if (replace_admin_epoch < admin_epoch) {
240 }
else if (replace_admin_epoch > admin_epoch) {
243 }
else if (replace_epoch < epoch) {
246 }
else if (replace_epoch > epoch) {
249 }
else if (replace_updates < updates) {
253 if (reason != NULL) {
254 crm_info(
"Replacement %d.%d.%d from %s not applied to %d.%d.%d:" 255 " current %s is greater than the replacement",
256 replace_admin_epoch, replace_epoch,
257 replace_updates, peer, admin_epoch, epoch, updates, reason);
260 crm_info(
"Replaced %d.%d.%d with %d.%d.%d from %s",
261 admin_epoch, epoch, updates,
262 replace_admin_epoch, replace_epoch, replace_updates, peer);
269 xmlNode *obj_root = NULL;
275 crm_trace(
"No matching object to replace");
285 xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer)
287 xmlNode *obj_root = NULL;
289 crm_trace(
"Processing \"%s\" event", op);
293 existing_cib, result_cib, answer);
297 crm_err(
"Cannot perform modification with no data");
303 xmlNode *child = NULL;
304 for (child = pcmk__xml_first_child(
input); child;
305 child = pcmk__xml_next(child)) {
307 crm_trace(
"No matching object to delete: %s=%s", child->name,
ID(child));
320 xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer)
322 xmlNode *obj_root = NULL;
324 crm_trace(
"Processing \"%s\" event", op);
328 existing_cib, result_cib, answer);
332 crm_err(
"Cannot perform modification with no data");
337 if (obj_root == NULL) {
338 xmlNode *tmp_section = NULL;
347 NULL, result_cib, answer);
353 CRM_CHECK(obj_root != NULL,
return -EINVAL);
365 xmlXPathObjectPtr xpathObj =
xpath_search(*result_cib,
"//@__delete__");
368 max = numXpathResults(xpathObj);
372 for (lpc = 0; lpc < max; lpc++) {
374 xmlChar *match_path = xmlGetNodePath(match);
387 update_cib_object(xmlNode *
parent, xmlNode * update)
391 xmlNode *a_child = NULL;
392 const char *replace = NULL;
393 const char *object_id = NULL;
394 const char *object_name = NULL;
396 CRM_CHECK(update != NULL,
return -EINVAL);
399 object_name = crm_element_name(update);
400 CRM_CHECK(object_name != NULL,
return -EINVAL);
402 object_id =
ID(update);
403 crm_trace(
"Processing update for <%s%s%s%s>", object_name,
405 pcmk__s(object_id,
""),
406 ((object_id == NULL)?
"" :
"'"));
408 if (object_id == NULL) {
420 crm_trace(
"Found node <%s%s%s%s> to update", object_name,
422 pcmk__s(object_id,
""),
423 ((object_id == NULL)?
"" :
"'"));
427 if (replace != NULL) {
428 xmlNode *
remove = NULL;
429 int last = 0, lpc = 0, len = 0;
431 len = strlen(replace);
433 if (replace[lpc] ==
',' || replace[lpc] == 0) {
434 char *replace_item = NULL;
442 replace_item =
strndup(replace + last, lpc - last);
444 if (
remove != NULL) {
446 replace_item, crm_element_name(
target));
464 pcmk__s(object_name,
"<null>"),
465 pcmk__s(object_id,
"<null>"));
469 crm_trace(
"Processing children of <%s%s%s%s>", object_name,
471 pcmk__s(object_id,
""),
472 ((object_id == NULL)?
"" :
"'"));
474 for (a_child = pcmk__xml_first_child(update); a_child != NULL;
475 a_child = pcmk__xml_next(a_child)) {
478 crm_trace(
"Updating child <%s%s%s%s>", crm_element_name(a_child),
480 pcmk__s(
ID(a_child),
""), ((
ID(a_child) == NULL)?
"" :
"'"));
482 tmp_result = update_cib_object(
target, a_child);
486 crm_err(
"Error updating child <%s%s%s%s>",
487 crm_element_name(a_child),
489 pcmk__s(
ID(a_child),
""),
490 ((
ID(a_child) == NULL)?
"" :
"'"));
498 crm_trace(
"Finished handling update for <%s%s%s%s>", object_name,
500 pcmk__s(object_id,
""),
501 ((object_id == NULL)?
"" :
"'"));
507 add_cib_object(xmlNode *
parent, xmlNode * new_obj)
509 const char *object_name = NULL;
510 const char *object_id = NULL;
511 xmlNode *equiv_node = NULL;
513 if ((
parent == NULL) || (new_obj == NULL)) {
517 object_name = crm_element_name(new_obj);
518 if (object_name == NULL) {
522 object_id =
ID(new_obj);
524 crm_trace(
"Processing creation of <%s%s%s%s>", object_name,
526 pcmk__s(object_id,
""),
527 ((object_id == NULL)?
"" :
"'"));
529 if (object_id == NULL) {
535 if (equiv_node != NULL) {
539 return update_cib_object(
parent, new_obj);
543 update_results(xmlNode *failed, xmlNode *
target,
const char *operation,
546 xmlNode *xml_node = NULL;
547 bool was_error =
false;
548 const char *error_msg = NULL;
562 crm_warn(
"Action %s failed: %s (cde=%d)",
563 operation, error_msg, return_code);
571 xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer)
573 xmlNode *failed = NULL;
575 xmlNode *update_section = NULL;
577 crm_trace(
"Processing %s for %s section",
578 op, pcmk__s(section,
"unspecified"));
592 crm_err(
"Cannot perform modification with no data");
596 if (section == NULL) {
605 xmlNode *a_child = NULL;
607 for (a_child = pcmk__xml_first_child(
input); a_child != NULL;
608 a_child = pcmk__xml_next(a_child)) {
609 result = add_cib_object(update_section, a_child);
610 if (update_results(failed, a_child, op,
result)) {
637 xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer)
639 const char *originator = NULL;
645 crm_trace(
"Processing \"%s\" event from %s%s",
650 *result_cib =
copy_xml(existing_cib);
658 int lpc = 0, max = 0;
659 bool config_changes =
false;
660 xmlXPathObject *xpathObj = NULL;
665 if (*diff == NULL && last != NULL && next != NULL) {
677 if (numXpathResults(xpathObj) > 0) {
678 config_changes =
true;
689 max = numXpathResults(xpathObj);
691 for (lpc = 0; lpc < max; lpc++) {
695 config_changes =
true;
699 config_changes =
true;
704 config_changes =
true;
708 config_changes =
true;
712 config_changes =
true;
716 config_changes =
true;
723 return config_changes;
728 const xmlNode *req, xmlNode *
input, xmlNode *existing_cib,
729 xmlNode **result_cib, xmlNode **answer)
736 xmlXPathObjectPtr xpathObj = NULL;
738 crm_trace(
"Processing \"%s\" event", op);
746 max = numXpathResults(xpathObj);
750 crm_debug(
"%s was already removed", section);
752 }
else if (max < 1) {
753 crm_debug(
"%s: %s does not exist", op, section);
756 }
else if (is_query) {
767 for (lpc = 0; lpc < max; lpc++) {
768 xmlChar *
path = NULL;
775 path = xmlGetNodePath(match);
776 crm_debug(
"Processing %s op for %s with %s", op, section,
path);
780 if (match == *result_cib) {
782 crm_warn(
"Cannot perform %s for %s: The xpath is addressing the whole /cib", op, section);
806 const char *tag =
TYPE(match);
811 if (*answer == NULL) {
821 char *new_path = NULL;
838 if (*answer == NULL) {
845 }
else if (*answer) {
854 xmlNode *
parent = match->parent;
#define pcmk_err_old_data
#define CRM_CHECK(expr, failure_action)
bool cib__config_changed_v1(xmlNode *last, xmlNode *next, xmlNode **diff)
#define crm_notice(fmt, args...)
const char * pcmk_strerror(int rc)
gboolean cib_version_details(xmlNode *cib, int *admin_epoch, int *epoch, int *updates)
#define XML_CIB_TAG_SECTION_ALL
int cib_process_create(const char *op, int options, const char *section, xmlNode *req, xmlNode *input, xmlNode *existing_cib, xmlNode **result_cib, xmlNode **answer)
int cib_process_modify(const char *op, int options, const char *section, xmlNode *req, xmlNode *input, xmlNode *existing_cib, xmlNode **result_cib, xmlNode **answer)
#define XML_ATTR_NUMUPDATES
xmlNode * pcmk__xe_match(const xmlNode *parent, const char *node_name, const char *attr_n, const char *attr_v)
#define PCMK__CIB_REQUEST_CREATE
int cib_process_delete(const char *op, int options, const char *section, xmlNode *req, xmlNode *input, xmlNode *existing_cib, xmlNode **result_cib, xmlNode **answer)
#define PCMK__CIB_REQUEST_QUERY
void copy_in_properties(xmlNode *target, const xmlNode *src)
xmlNode * find_xml_node(const xmlNode *root, const char *search_path, gboolean must_find)
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
int get_schema_version(const char *name)
#define CRM_LOG_ASSERT(expr)
void dedupXpathResults(xmlXPathObjectPtr xpathObj)
int crm_element_value_int(const xmlNode *data, const char *name, int *dest)
Retrieve the integer value of an XML attribute.
char * strndup(const char *str, size_t len)
#define XML_ATTR_GENERATION
int cib_process_diff(const char *op, int options, const char *section, xmlNode *req, xmlNode *input, xmlNode *existing_cib, xmlNode **result_cib, xmlNode **answer)
xmlNode * copy_xml(xmlNode *src_node)
#define crm_warn(fmt, args...)
#define crm_debug(fmt, args...)
int xml_apply_patchset(xmlNode *xml, xmlNode *patchset, bool check_version)
char * crm_element_value_copy(const xmlNode *data, const char *name)
Retrieve a copy of the value of an XML attribute.
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
xmlNode * pcmk_find_cib_element(xmlNode *cib, const char *element_name)
Find an element in the CIB.
int cib_process_upgrade(const char *op, int options, const char *section, xmlNode *req, xmlNode *input, xmlNode *existing_cib, xmlNode **result_cib, xmlNode **answer)
gboolean update_xml_child(xmlNode *child, xmlNode *to_update)
#define crm_trace(fmt, args...)
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
int cib_process_xpath(const char *op, int options, const char *section, const xmlNode *req, xmlNode *input, xmlNode *existing_cib, xmlNode **result_cib, xmlNode **answer)
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
xmlNode * add_node_copy(xmlNode *new_parent, xmlNode *xml_node)
Wrappers for and extensions to libxml2.
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_query(const char *op, int options, const char *section, xmlNode *req, xmlNode *input, xmlNode *existing_cib, xmlNode **result_cib, xmlNode **answer)
xmlNode * create_xml_node(xmlNode *parent, const char *name)
#define XML_ATTR_VALIDATION
const char * pcmk_cib_parent_name_for(const char *element_name)
Get the parent element name of a given CIB element name.
#define XML_FAILCIB_ATTR_OP
void free_xml(xmlNode *child)
gboolean xml_has_children(const xmlNode *root)
#define XML_FAILCIB_ATTR_OBJTYPE
xmlNode * createEmptyCib(int cib_epoch)
Create XML for a new (empty) CIB.
int cib_process_replace(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)
pcmk__action_result_t result
#define crm_err(fmt, args...)
xmlXPathObjectPtr xpath_search(xmlNode *xml_top, const char *path)
#define PCMK__CIB_REQUEST_REPLACE
#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
bool xml_acl_denied(const xmlNode *xml)
Check whether or not an XML node is ACL-denied.
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 PCMK__CIB_REQUEST_MODIFY
#define XML_TAG_DIFF_REMOVED
#define XML_CIB_TAG_CONFIGURATION
#define XML_FAILCIB_ATTR_ID
void freeXpathObject(xmlXPathObjectPtr xpathObj)
#define crm_info(fmt, args...)
int cib_process_bump(const char *op, int options, const char *section, xmlNode *req, xmlNode *input, xmlNode *existing_cib, xmlNode **result_cib, xmlNode **answer)
#define PCMK__CIB_REQUEST_DELETE
gboolean replace_xml_child(xmlNode *parent, xmlNode *child, xmlNode *update, gboolean delete_only)