19 #include <sys/param.h>
20 #include <sys/types.h>
30 cib_process_query(
const char *op,
int options,
const char *section, xmlNode * req, xmlNode * input,
31 xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer)
33 xmlNode *obj_root = NULL;
40 existing_cib, result_cib, answer);
52 if (obj_root == NULL) {
56 const char *tag =
TYPE(obj_root);
66 if (result ==
pcmk_ok && *answer == NULL) {
67 crm_err(
"Error creating query response");
75 cib_process_erase(
const char *op,
int options,
const char *section, xmlNode * req, xmlNode * input,
76 xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer)
93 xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib,
98 int current_version = 0;
104 crm_trace(
"Processing \"%s\" event with max=%s", op, max);
116 if (new_version > current_version) {
127 cib_process_bump(
const char *op,
int options,
const char *section, xmlNode * req, xmlNode * input,
128 xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer)
132 crm_trace(
"Processing \"%s\" event for epoch=%s",
144 char *new_value = NULL;
145 char *old_value = NULL;
151 if (old_value != NULL) {
152 int_value = atoi(old_value);
153 new_value = crm_itoa(++int_value);
155 new_value = strdup(
"1");
169 xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib,
172 const char *tag = NULL;
179 existing_cib, result_cib, answer);
188 tag = crm_element_name(input);
202 int replace_updates = 0;
203 int replace_epoch = 0;
204 int replace_admin_epoch = 0;
206 const char *reason = NULL;
217 crm_err(
"Digest mis-match on replace from %s: %s vs. %s (expected)", peer,
218 digest_verify, digest);
219 reason =
"digest mismatch";
222 crm_info(
"Digest matched on replace from %s: %s", peer, digest);
233 if (replace_admin_epoch < admin_epoch) {
236 }
else if (replace_admin_epoch > admin_epoch) {
239 }
else if (replace_epoch < epoch) {
242 }
else if (replace_epoch > epoch) {
245 }
else if (replace_updates < updates) {
249 if (reason != NULL) {
250 crm_info(
"Replacement %d.%d.%d from %s not applied to %d.%d.%d:"
251 " current %s is greater than the replacement",
252 replace_admin_epoch, replace_epoch,
253 replace_updates, peer, admin_epoch, epoch, updates, reason);
256 crm_info(
"Replaced %d.%d.%d with %d.%d.%d from %s",
257 admin_epoch, epoch, updates,
258 replace_admin_epoch, replace_epoch, replace_updates, peer);
265 xmlNode *obj_root = NULL;
271 crm_trace(
"No matching object to replace");
281 xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer)
283 xmlNode *obj_root = NULL;
285 crm_trace(
"Processing \"%s\" event", op);
289 existing_cib, result_cib, answer);
293 crm_err(
"Cannot perform modification with no data");
299 xmlNode *child = NULL;
300 for (child = pcmk__xml_first_child(input); child;
301 child = pcmk__xml_next(child)) {
303 crm_trace(
"No matching object to delete: %s=%s", child->name,
ID(child));
308 crm_trace(
"No matching object to delete: %s=%s", input->name,
ID(input));
316 xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer)
318 xmlNode *obj_root = NULL;
320 crm_trace(
"Processing \"%s\" event", op);
324 existing_cib, result_cib, answer);
328 crm_err(
"Cannot perform modification with no data");
333 if (obj_root == NULL) {
334 xmlNode *tmp_section = NULL;
348 CRM_CHECK(obj_root != NULL,
return -EINVAL);
360 xmlXPathObjectPtr xpathObj =
xpath_search(*result_cib,
"//@__delete__");
363 max = numXpathResults(xpathObj);
367 for (lpc = 0; lpc < max; lpc++) {
369 xmlChar *match_path = xmlGetNodePath(match);
382 update_cib_object(xmlNode * parent, xmlNode * update)
386 xmlNode *a_child = NULL;
387 const char *replace = NULL;
388 const char *object_id = NULL;
389 const char *object_name = NULL;
391 CRM_CHECK(update != NULL,
return -EINVAL);
392 CRM_CHECK(parent != NULL,
return -EINVAL);
394 object_name = crm_element_name(update);
395 CRM_CHECK(object_name != NULL,
return -EINVAL);
397 object_id =
ID(update);
400 if (object_id == NULL) {
415 if (replace != NULL) {
416 xmlNode *remove = NULL;
417 int last = 0, lpc = 0, len = 0;
419 len = strlen(replace);
421 if (replace[lpc] ==
',' || replace[lpc] == 0) {
422 char *replace_item = NULL;
430 replace_item =
strndup(replace + last, lpc - last);
432 if (remove != NULL) {
434 replace_item, crm_element_name(
target));
452 for (a_child = pcmk__xml_first_child(update); a_child != NULL;
453 a_child = pcmk__xml_next(a_child)) {
456 crm_trace(
"Updating child <%s id=%s>", crm_element_name(a_child),
ID(a_child));
458 tmp_result = update_cib_object(
target, a_child);
462 crm_err(
"Error updating child <%s id=%s>", crm_element_name(a_child),
ID(a_child));
476 add_cib_object(xmlNode * parent, xmlNode * new_obj)
479 const char *object_name = NULL;
480 const char *object_id = NULL;
481 xmlNode *equiv_node = NULL;
483 if (new_obj != NULL) {
484 object_name = crm_element_name(new_obj);
490 if (new_obj == NULL || object_name == NULL) {
493 }
else if (parent == NULL) {
496 }
else if (object_id == NULL) {
508 }
else if (equiv_node != NULL) {
512 result = update_cib_object(parent, new_obj);
520 xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer)
522 xmlNode *failed = NULL;
524 xmlNode *update_section = NULL;
540 crm_err(
"Cannot perform modification with no data");
544 if (section == NULL) {
553 xmlNode *a_child = NULL;
555 for (a_child = pcmk__xml_first_child(input); a_child != NULL;
556 a_child = pcmk__xml_next(a_child)) {
557 result = add_cib_object(update_section, a_child);
564 result = add_cib_object(update_section, input);
584 cib_process_diff(
const char *op,
int options,
const char *section, xmlNode * req, xmlNode * input,
585 xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer)
587 const char *originator = NULL;
593 crm_trace(
"Processing \"%s\" event from %s%s",
598 *result_cib =
copy_xml(existing_cib);
605 int lpc = 0, max = 0;
606 gboolean config_changes = FALSE;
607 xmlXPathObject *xpathObj = NULL;
612 if (*diff == NULL && last != NULL && next != NULL) {
625 if (numXpathResults(xpathObj) > 0) {
626 config_changes = TRUE;
637 max = numXpathResults(xpathObj);
639 for (lpc = 0; lpc < max; lpc++) {
643 config_changes = TRUE;
647 config_changes = TRUE;
652 config_changes = TRUE;
656 config_changes = TRUE;
660 config_changes = TRUE;
664 config_changes = TRUE;
671 return config_changes;
675 cib_process_xpath(
const char *op,
int options,
const char *section, xmlNode * req, xmlNode * input,
676 xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer)
683 xmlXPathObjectPtr xpathObj = NULL;
685 crm_trace(
"Processing \"%s\" event", op);
693 max = numXpathResults(xpathObj);
696 crm_debug(
"%s was already removed", section);
698 }
else if (max < 1) {
699 crm_debug(
"%s: %s does not exist", op, section);
702 }
else if (is_query) {
712 for (lpc = 0; lpc < max; lpc++) {
713 xmlChar *path = NULL;
720 path = xmlGetNodePath(match);
721 crm_debug(
"Processing %s op for %s with %s", op, section, path);
725 if (match == *result_cib) {
727 crm_warn(
"Cannot perform %s for %s: The xpath is addressing the whole /cib", op, section);
751 const char *tag =
TYPE(match);
756 if (*answer == NULL) {
762 xmlNode *parent = match;
764 while (parent && parent->type == XML_ELEMENT_NODE) {
766 char *new_path = NULL;
778 parent = parent->parent;
782 if (*answer == NULL) {
789 }
else if (*answer) {
797 xmlNode *parent = match->parent;
818 xmlNode *xml_node = NULL;
819 gboolean was_error = FALSE;
820 const char *error_msg = NULL;
834 crm_warn(
"Action %s failed: %s (cde=%d)", operation, error_msg, return_code);