summaryrefslogtreecommitdiffstats
path: root/daemons/based/based_messages.c
diff options
context:
space:
mode:
Diffstat (limited to 'daemons/based/based_messages.c')
-rw-r--r--daemons/based/based_messages.c125
1 files changed, 89 insertions, 36 deletions
diff --git a/daemons/based/based_messages.c b/daemons/based/based_messages.c
index d46456c..35d639a 100644
--- a/daemons/based/based_messages.c
+++ b/daemons/based/based_messages.c
@@ -19,6 +19,9 @@
#include <sys/param.h>
#include <sys/types.h>
+#include <glib.h>
+#include <libxml/tree.h>
+
#include <crm/crm.h>
#include <crm/cib/internal.h>
#include <crm/msg_xml.h>
@@ -61,25 +64,15 @@ cib_process_shutdown_req(const char *op, int options, const char *section, xmlNo
return pcmk_ok;
}
+// @COMPAT: Remove when PCMK__CIB_REQUEST_NOOP is removed
int
-cib_process_default(const char *op, int options, const char *section, xmlNode * req,
- xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib,
- xmlNode ** answer)
+cib_process_noop(const char *op, int options, const char *section, xmlNode *req,
+ xmlNode *input, xmlNode *existing_cib, xmlNode **result_cib,
+ xmlNode **answer)
{
- int result = pcmk_ok;
-
crm_trace("Processing \"%s\" event", op);
*answer = NULL;
-
- if (op == NULL) {
- result = -EINVAL;
- crm_err("No operation specified");
-
- } else if (strcmp(PCMK__CIB_REQUEST_NOOP, op) != 0) {
- result = -EPROTONOSUPPORT;
- crm_err("Action [%s] is not supported by the CIB manager", op);
- }
- return result;
+ return pcmk_ok;
}
int
@@ -158,10 +151,10 @@ cib_process_ping(const char *op, int options, const char *section, xmlNode * req
// Append additional detail so the receiver can log the differences
add_message_xml(*answer, F_CIB_CALLDATA, the_cib);
},
- {
+ if (the_cib != NULL) {
// Always include at least the version details
- const char *tag = TYPE(the_cib);
- xmlNode *shallow = create_xml_node(NULL, tag);
+ xmlNode *shallow = create_xml_node(NULL,
+ (const char *) the_cib->name);
copy_in_properties(shallow, the_cib);
add_message_xml(*answer, F_CIB_CALLDATA, shallow);
@@ -250,7 +243,7 @@ cib_process_upgrade_server(const char *op, int options, const char *section, xml
if (rc != pcmk_ok) {
// Notify originating peer so it can notify its local clients
- crm_node_t *origin = pcmk__search_cluster_node_cache(0, host);
+ crm_node_t *origin = pcmk__search_cluster_node_cache(0, host, NULL);
crm_info("Rejecting upgrade request from %s: %s "
CRM_XS " rc=%d peer=%s", host, pcmk_strerror(rc), rc,
@@ -341,8 +334,7 @@ cib_server_process_diff(const char *op, int options, const char *section, xmlNod
crm_warn("Requesting full CIB refresh because update failed: %s"
CRM_XS " rc=%d", pcmk_strerror(rc), rc);
- pcmk__output_set_log_level(logger_out, LOG_INFO);
- logger_out->message(logger_out, "xml-patchset", input);
+ pcmk__log_xml_patchset(LOG_INFO, input);
free_xml(*result_cib);
*result_cib = NULL;
send_sync_request(NULL);
@@ -356,15 +348,16 @@ cib_process_replace_svr(const char *op, int options, const char *section, xmlNod
xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib,
xmlNode ** answer)
{
- const char *tag = crm_element_name(input);
int rc =
cib_process_replace(op, options, section, req, input, existing_cib, result_cib, answer);
- if (rc == pcmk_ok && pcmk__str_eq(tag, XML_TAG_CIB, pcmk__str_casei)) {
+
+ if ((rc == pcmk_ok) && pcmk__xe_is(input, XML_TAG_CIB)) {
sync_in_progress = 0;
}
return rc;
}
+// @COMPAT: Remove when PCMK__CIB_REQUEST_ABS_DELETE is removed
int
cib_process_delete_absolute(const char *op, int options, const char *section, xmlNode * req,
xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib,
@@ -373,6 +366,49 @@ cib_process_delete_absolute(const char *op, int options, const char *section, xm
return -EINVAL;
}
+static xmlNode *
+cib_msg_copy(xmlNode *msg)
+{
+ static const char *field_list[] = {
+ F_XML_TAGNAME,
+ F_TYPE,
+ F_CIB_CLIENTID,
+ F_CIB_CALLOPTS,
+ F_CIB_CALLID,
+ F_CIB_OPERATION,
+ F_CIB_ISREPLY,
+ F_CIB_SECTION,
+ F_CIB_HOST,
+ F_CIB_RC,
+ F_CIB_DELEGATED,
+ F_CIB_OBJID,
+ F_CIB_OBJTYPE,
+ F_CIB_EXISTING,
+ F_CIB_SEENCOUNT,
+ F_CIB_TIMEOUT,
+ F_CIB_GLOBAL_UPDATE,
+ F_CIB_CLIENTNAME,
+ F_CIB_USER,
+ F_CIB_NOTIFY_TYPE,
+ F_CIB_NOTIFY_ACTIVATE
+ };
+
+ xmlNode *copy = create_xml_node(NULL, "copy");
+
+ CRM_ASSERT(copy != NULL);
+
+ for (int lpc = 0; lpc < PCMK__NELEM(field_list); lpc++) {
+ const char *field = field_list[lpc];
+ const char *value = crm_element_value(msg, field);
+
+ if (value != NULL) {
+ crm_xml_add(copy, field, value);
+ }
+ }
+
+ return copy;
+}
+
int
sync_our_cib(xmlNode * request, gboolean all)
{
@@ -384,22 +420,12 @@ sync_our_cib(xmlNode * request, gboolean all)
xmlNode *replace_request = NULL;
CRM_CHECK(the_cib != NULL, return -EINVAL);
-
- replace_request = cib_msg_copy(request, FALSE);
- CRM_CHECK(replace_request != NULL, return -EINVAL);
+ CRM_CHECK(all || (host != NULL), return -EINVAL);
crm_debug("Syncing CIB to %s", all ? "all peers" : host);
- if (all == FALSE && host == NULL) {
- crm_log_xml_err(request, "bad sync");
- }
- /* remove the "all == FALSE" condition
- *
- * sync_from was failing, the local client wasn't being notified
- * because it didn't know it was a reply
- * setting this does not prevent the other nodes from applying it
- * if all == TRUE
- */
+ replace_request = cib_msg_copy(request);
+
if (host != NULL) {
crm_xml_add(replace_request, F_CIB_ISREPLY, host);
}
@@ -425,3 +451,30 @@ sync_our_cib(xmlNode * request, gboolean all)
free(digest);
return result;
}
+
+int
+cib_process_commit_transaction(const char *op, int options, const char *section,
+ xmlNode *req, xmlNode *input,
+ xmlNode *existing_cib, xmlNode **result_cib,
+ xmlNode **answer)
+{
+ /* On success, our caller will activate *result_cib locally, trigger a
+ * replace notification if appropriate, and sync *result_cib to all nodes.
+ * On failure, our caller will free *result_cib.
+ */
+ int rc = pcmk_rc_ok;
+ const char *client_id = crm_element_value(req, F_CIB_CLIENTID);
+ const char *origin = crm_element_value(req, F_ORIG);
+ pcmk__client_t *client = pcmk__find_client_by_id(client_id);
+
+ rc = based_commit_transaction(input, client, origin, result_cib);
+
+ if (rc != pcmk_rc_ok) {
+ char *source = based_transaction_source_str(client, origin);
+
+ crm_err("Could not commit transaction for %s: %s",
+ source, pcmk_rc_str(rc));
+ free(source);
+ }
+ return pcmk_rc2legacy(rc);
+}