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");
77 xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer)
94 xmlNode *
input, xmlNode * existing_cib, xmlNode ** result_cib,
99 int current_version = 0;
105 crm_trace(
"Processing \"%s\" event with max=%s", op, max);
117 if (new_version > current_version) {
129 xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer)
133 crm_trace(
"Processing %s for epoch='%s'", op,
145 char *new_value = NULL;
146 char *old_value = NULL;
152 if (old_value != NULL) {
153 int_value = atoi(old_value);
154 new_value = pcmk__itoa(++int_value);
156 new_value = strdup(
"1");
161 field, pcmk__s(old_value,
"unset"), new_value);
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,
404 ((object_id == NULL)?
"" :
" id='"), pcmk__s(object_id,
""),
405 ((object_id == NULL)?
"" :
"'"));
407 if (object_id == NULL) {
419 crm_trace(
"Found node <%s%s%s%s> to update", object_name,
420 ((object_id == NULL)?
"" :
" id='"), pcmk__s(object_id,
""),
421 ((object_id == NULL)?
"" :
"'"));
424 if (replace != NULL) {
425 xmlNode *
remove = NULL;
426 int last = 0, lpc = 0, len = 0;
428 len = strlen(replace);
430 if (replace[lpc] ==
',' || replace[lpc] == 0) {
431 char *replace_item = NULL;
439 replace_item =
strndup(replace + last, lpc - last);
441 if (
remove != NULL) {
443 replace_item, crm_element_name(
target));
460 crm_notice(
"Cannot update <%s id=%s>", pcmk__s(object_name,
"<null>"), pcmk__s(object_id,
"<null>"));
464 crm_trace(
"Processing children of <%s%s%s%s>", object_name,
465 ((object_id == NULL)?
"" :
" id='"), pcmk__s(object_id,
""),
466 ((object_id == NULL)?
"" :
"'"));
468 for (a_child = pcmk__xml_first_child(update); a_child != NULL;
469 a_child = pcmk__xml_next(a_child)) {
472 crm_trace(
"Updating child <%s%s%s%s>", crm_element_name(a_child),
473 ((
ID(a_child) == NULL)?
"" :
" id='"),
474 pcmk__s(
ID(a_child),
""), ((
ID(a_child) == NULL)?
"" :
"'"));
476 tmp_result = update_cib_object(
target, a_child);
480 crm_err(
"Error updating child <%s%s%s%s>",
481 crm_element_name(a_child),
482 ((
ID(a_child) == NULL)?
"" :
" id='"),
483 pcmk__s(
ID(a_child),
""),
484 ((
ID(a_child) == NULL)?
"" :
"'"));
492 crm_trace(
"Finished handling update for <%s%s%s%s>", object_name,
493 ((object_id == NULL)?
"" :
" id='"), pcmk__s(object_id,
""),
494 ((object_id == NULL)?
"" :
"'"));
500 add_cib_object(xmlNode *
parent, xmlNode * new_obj)
502 const char *object_name = NULL;
503 const char *object_id = NULL;
504 xmlNode *equiv_node = NULL;
506 if ((
parent == NULL) || (new_obj == NULL)) {
510 object_name = crm_element_name(new_obj);
511 if (object_name == NULL) {
515 object_id =
ID(new_obj);
517 crm_trace(
"Processing creation of <%s%s%s%s>", object_name,
518 ((object_id == NULL)?
"" :
" id='"), pcmk__s(object_id,
""),
519 ((object_id == NULL)?
"" :
"'"));
521 if (object_id == NULL) {
527 if (equiv_node != NULL) {
531 return update_cib_object(
parent, new_obj);
536 xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer)
538 xmlNode *failed = NULL;
540 xmlNode *update_section = NULL;
542 crm_trace(
"Processing %s for %s section",
543 op, pcmk__s(section,
"unspecified"));
557 crm_err(
"Cannot perform modification with no data");
561 if (section == NULL) {
570 xmlNode *a_child = NULL;
572 for (a_child = pcmk__xml_first_child(
input); a_child != NULL;
573 a_child = pcmk__xml_next(a_child)) {
574 result = add_cib_object(update_section, a_child);
602 xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer)
604 const char *originator = NULL;
610 crm_trace(
"Processing \"%s\" event from %s%s",
615 *result_cib =
copy_xml(existing_cib);
622 int lpc = 0, max = 0;
623 gboolean config_changes = FALSE;
624 xmlXPathObject *xpathObj = NULL;
629 if (*diff == NULL && last != NULL && next != NULL) {
642 if (numXpathResults(xpathObj) > 0) {
643 config_changes = TRUE;
654 max = numXpathResults(xpathObj);
656 for (lpc = 0; lpc < max; lpc++) {
660 config_changes = TRUE;
664 config_changes = TRUE;
669 config_changes = TRUE;
673 config_changes = TRUE;
677 config_changes = TRUE;
681 config_changes = TRUE;
688 return config_changes;
693 const xmlNode *req, xmlNode *
input, xmlNode *existing_cib,
694 xmlNode **result_cib, xmlNode **answer)
701 xmlXPathObjectPtr xpathObj = NULL;
703 crm_trace(
"Processing \"%s\" event", op);
711 max = numXpathResults(xpathObj);
715 crm_debug(
"%s was already removed", section);
717 }
else if (max < 1) {
718 crm_debug(
"%s: %s does not exist", op, section);
721 }
else if (is_query) {
732 for (lpc = 0; lpc < max; lpc++) {
733 xmlChar *
path = NULL;
740 path = xmlGetNodePath(match);
741 crm_debug(
"Processing %s op for %s with %s", op, section,
path);
745 if (match == *result_cib) {
747 crm_warn(
"Cannot perform %s for %s: The xpath is addressing the whole /cib", op, section);
771 const char *tag =
TYPE(match);
776 if (*answer == NULL) {
786 char *new_path = NULL;
802 if (*answer == NULL) {
809 }
else if (*answer) {
818 xmlNode *
parent = match->parent;
839 xmlNode *xml_node = NULL;
840 gboolean was_error = FALSE;
841 const char *error_msg = NULL;
855 crm_warn(
"Action %s failed: %s (cde=%d)", operation, error_msg, return_code);
#define pcmk_err_old_data
#define CRM_CHECK(expr, failure_action)
#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
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 copy_in_properties(xmlNode *target, xmlNode *src)
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)
int cib_update_counter(xmlNode *xml_obj, const char *field, gboolean reset)
#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.
gboolean cib_config_changed(xmlNode *last, xmlNode *next, xmlNode **diff)
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)
gboolean update_results(xmlNode *failed, xmlNode *target, const char *operation, int return_code)
#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)