summaryrefslogtreecommitdiffstats
path: root/include/crm/common/messages_internal.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/crm/common/messages_internal.h')
-rw-r--r--include/crm/common/messages_internal.h122
1 files changed, 122 insertions, 0 deletions
diff --git a/include/crm/common/messages_internal.h b/include/crm/common/messages_internal.h
new file mode 100644
index 0000000..0d1908f
--- /dev/null
+++ b/include/crm/common/messages_internal.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2018-2022 the Pacemaker project contributors
+ *
+ * The version control history for this file may have further details.
+ *
+ * This source code is licensed under the GNU Lesser General Public License
+ * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
+ */
+
+#ifndef PCMK__CRM_COMMON_MESSAGES_INTERNAL__H
+#define PCMK__CRM_COMMON_MESSAGES_INTERNAL__H
+
+#include <stdint.h> // uint32_t
+#include <libxml/tree.h> // xmlNode
+#include <crm/common/ipc_internal.h> // pcmk__client_t
+#include <crm/common/results_internal.h> // pcmk__action_result_t
+
+enum pcmk__request_flags {
+ pcmk__request_none = UINT32_C(0),
+
+ /* It would be nice if we could check for synchronous requests generically,
+ * but each daemon uses its own call options, so the daemons are responsible
+ * for setting this flag when appropriate.
+ */
+ pcmk__request_sync = (UINT32_C(1) << 0),
+
+ /* Whether reply must use original call options (the library code does not
+ * use this, so it is for internal daemon use)
+ */
+ pcmk__request_reuse_options = (UINT32_C(1) << 1),
+};
+
+// Server request (whether from an IPC client or cluster peer)
+typedef struct {
+ // If request is from an IPC client
+ pcmk__client_t *ipc_client; // IPC client (NULL if not via IPC)
+ uint32_t ipc_id; // IPC message ID
+ uint32_t ipc_flags; // IPC message flags
+
+ // If message is from a cluster peer
+ const char *peer; // Peer name (NULL if not via cluster)
+
+ // Common information regardless of origin
+ xmlNode *xml; // Request XML
+ int call_options; // Call options set on request
+ uint32_t flags; // Flag group of pcmk__request_flags
+ pcmk__action_result_t result; // Where to store operation result
+
+ /* It would be nice if we could pull the IPC command from the XML
+ * generically, but each daemon uses a different XML attribute for it,
+ * so the daemon is responsible for populating this field.
+ *
+ * This must be a copy of the XML field, and not just a pointer into xml,
+ * because handlers might modify the original XML.
+ *
+ * @TODO Create a per-daemon struct with IPC handlers, IPC endpoints, etc.,
+ * and the name of the XML attribute for IPC commands, then replace this
+ * with a convenience function to copy the command.
+ */
+ char *op; // IPC command name
+} pcmk__request_t;
+
+#define pcmk__set_request_flags(request, flags_to_set) do { \
+ (request)->flags = pcmk__set_flags_as(__func__, __LINE__, \
+ LOG_TRACE, "Request", "message", (request)->flags, \
+ (flags_to_set), #flags_to_set); \
+ } while (0)
+
+// Type for mapping a server command to a handler
+typedef struct {
+ const char *command;
+ xmlNode *(*handler)(pcmk__request_t *request);
+} pcmk__server_command_t;
+
+const char *pcmk__message_name(const char *name);
+GHashTable *pcmk__register_handlers(const pcmk__server_command_t handlers[]);
+xmlNode *pcmk__process_request(pcmk__request_t *request, GHashTable *handlers);
+void pcmk__reset_request(pcmk__request_t *request);
+
+/*!
+ * \internal
+ * \brief Get a loggable description of a request's origin
+ *
+ * \param[in] request
+ *
+ * \return "peer" if request was via CPG, "client" if via IPC, or "originator"
+ * if unknown
+ */
+static inline const char *
+pcmk__request_origin_type(const pcmk__request_t *request)
+{
+ if ((request != NULL) && (request->ipc_client != NULL)) {
+ return "client";
+ } else if ((request != NULL) && (request->peer != NULL)) {
+ return "peer";
+ } else {
+ return "originator";
+ }
+}
+
+/*!
+ * \internal
+ * \brief Get a loggable name for a request's origin
+ *
+ * \param[in] request
+ *
+ * \return Peer name if request was via CPG, client name if via IPC, or
+ * "(unspecified)" if unknown
+ */
+static inline const char *
+pcmk__request_origin(const pcmk__request_t *request)
+{
+ if ((request != NULL) && (request->ipc_client != NULL)) {
+ return pcmk__client_name(request->ipc_client);
+ } else if ((request != NULL) && (request->peer != NULL)) {
+ return request->peer;
+ } else {
+ return "(unspecified)";
+ }
+}
+
+#endif // PCMK__CRM_COMMON_MESSAGES_INTERNAL__H