pacemaker 2.1.8-2.1.8
Scalable High-Availability cluster resource manager
Loading...
Searching...
No Matches
messages.c
Go to the documentation of this file.
1/*
2 * Copyright 2004-2024 the Pacemaker project contributors
3 *
4 * The version control history for this file may have further details.
5 *
6 * This source code is licensed under the GNU Lesser General Public License
7 * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
8 */
9
10#include <crm_internal.h>
11
12#include <stdio.h>
13#include <sys/types.h>
14
15#include <glib.h>
16#include <libxml/tree.h>
17
18#include <crm/common/xml.h>
20
39xmlNode *
40create_request_adv(const char *task, xmlNode *msg_data,
41 const char *host_to, const char *sys_to,
42 const char *sys_from, const char *uuid_from,
43 const char *origin)
44{
45 static uint ref_counter = 0;
46
47 char *true_from = NULL;
48 xmlNode *request = NULL;
49 char *reference = crm_strdup_printf("%s-%s-%lld-%u",
50 (task? task : "_empty_"),
51 (sys_from? sys_from : "_empty_"),
52 (long long) time(NULL), ref_counter++);
53
54 if (uuid_from != NULL) {
55 true_from = crm_strdup_printf("%s_%s", uuid_from,
56 (sys_from? sys_from : "none"));
57 } else if (sys_from != NULL) {
58 true_from = strdup(sys_from);
59 } else {
60 crm_err("Cannot create IPC request: No originating system specified");
61 }
62
63 // host_from will get set for us if necessary by the controller when routed
64 request = pcmk__xe_create(NULL, __func__);
65 crm_xml_add(request, PCMK_XA_ORIGIN, origin);
69 crm_xml_add(request, PCMK_XA_REFERENCE, reference);
70 crm_xml_add(request, PCMK__XA_CRM_TASK, task);
71 crm_xml_add(request, PCMK__XA_CRM_SYS_TO, sys_to);
72 crm_xml_add(request, PCMK__XA_CRM_SYS_FROM, true_from);
73
74 /* HOSTTO will be ignored if it is to the DC anyway. */
75 if (host_to != NULL && strlen(host_to) > 0) {
76 crm_xml_add(request, PCMK__XA_CRM_HOST_TO, host_to);
77 }
78
79 if (msg_data != NULL) {
80 xmlNode *wrapper = pcmk__xe_create(request, PCMK__XE_CRM_XML);
81
82 pcmk__xml_copy(wrapper, msg_data);
83 }
84 free(reference);
85 free(true_from);
86
87 return request;
88}
89
103xmlNode *
104create_reply_adv(const xmlNode *original_request, xmlNode *xml_response_data,
105 const char *origin)
106{
107 xmlNode *reply = NULL;
108
109 const char *host_from = crm_element_value(original_request, PCMK__XA_SRC);
110 const char *sys_from = crm_element_value(original_request,
112 const char *sys_to = crm_element_value(original_request,
114 const char *type = crm_element_value(original_request, PCMK__XA_SUBT);
115 const char *operation = crm_element_value(original_request,
117 const char *crm_msg_reference = crm_element_value(original_request,
119
120 if (type == NULL) {
121 crm_err("Cannot create new_message, no message type in original message");
122 CRM_ASSERT(type != NULL);
123 return NULL;
124 }
125
126 if (strcmp(type, PCMK__VALUE_REQUEST) != 0) {
127 /* Replies should only be generated for request messages, but it's possible
128 * we expect replies to other messages right now so this can't be enforced.
129 */
130 crm_trace("Creating a reply for a non-request original message");
131 }
132
133 reply = pcmk__xe_create(NULL, __func__);
134 crm_xml_add(reply, PCMK_XA_ORIGIN, origin);
138 crm_xml_add(reply, PCMK_XA_REFERENCE, crm_msg_reference);
139 crm_xml_add(reply, PCMK__XA_CRM_TASK, operation);
140
141 /* since this is a reply, we reverse the from and to */
142 crm_xml_add(reply, PCMK__XA_CRM_SYS_TO, sys_from);
143 crm_xml_add(reply, PCMK__XA_CRM_SYS_FROM, sys_to);
144
145 /* HOSTTO will be ignored if it is to the DC anyway. */
146 if (host_from != NULL && strlen(host_from) > 0) {
147 crm_xml_add(reply, PCMK__XA_CRM_HOST_TO, host_from);
148 }
149
150 if (xml_response_data != NULL) {
151 xmlNode *wrapper = pcmk__xe_create(reply, PCMK__XE_CRM_XML);
152
153 pcmk__xml_copy(wrapper, xml_response_data);
154 }
155
156 return reply;
157}
158
170const char *
172{
173 if (name == NULL) {
174 return "unknown";
175
176 } else if (!strcmp(name, "pacemaker-attrd")) {
177 return "attrd";
178
179 } else if (!strcmp(name, "pacemaker-based")) {
180 return CRM_SYSTEM_CIB;
181
182 } else if (!strcmp(name, "pacemaker-controld")) {
183 return CRM_SYSTEM_CRMD;
184
185 } else if (!strcmp(name, "pacemaker-execd")) {
186 return CRM_SYSTEM_LRMD;
187
188 } else if (!strcmp(name, "pacemaker-fenced")) {
189 return "stonith-ng";
190
191 } else if (!strcmp(name, "pacemaker-schedulerd")) {
192 return CRM_SYSTEM_PENGINE;
193
194 } else {
195 return name;
196 }
197}
198
212GHashTable *
214{
215 GHashTable *commands = g_hash_table_new(g_str_hash, g_str_equal);
216
217 if (handlers != NULL) {
218 int i;
219
220 for (i = 0; handlers[i].command != NULL; ++i) {
221 g_hash_table_insert(commands, (gpointer) handlers[i].command,
222 handlers[i].handler);
223 }
224 if (handlers[i].handler != NULL) {
225 // g_str_hash() can't handle NULL, so use empty string for default
226 g_hash_table_insert(commands, (gpointer) "", handlers[i].handler);
227 }
228 }
229 return commands;
230}
231
241xmlNode *
242pcmk__process_request(pcmk__request_t *request, GHashTable *handlers)
243{
244 xmlNode *(*handler)(pcmk__request_t *request) = NULL;
245
246 CRM_CHECK((request != NULL) && (request->op != NULL) && (handlers != NULL),
247 return NULL);
248
250 && (request->ipc_client != NULL)) {
251 CRM_CHECK(request->ipc_client->request_id == request->ipc_id,
252 return NULL);
253 }
254
255 handler = g_hash_table_lookup(handlers, request->op);
256 if (handler == NULL) {
257 handler = g_hash_table_lookup(handlers, ""); // Default handler
258 if (handler == NULL) {
259 crm_info("Ignoring %s request from %s %s with no handler",
260 request->op, pcmk__request_origin_type(request),
261 pcmk__request_origin(request));
262 return NULL;
263 }
264 }
265
266 return (*handler)(request);
267}
268
275void
277{
278 free(request->op);
279 request->op = NULL;
280
281 pcmk__reset_result(&(request->result));
282}
283
284// Deprecated functions kept only for backward API compatibility
285// LCOV_EXCL_START
286
288
289gboolean
290add_message_xml(xmlNode *msg, const char *field, xmlNode *xml)
291{
292 xmlNode *holder = pcmk__xe_create(msg, field);
293
294 pcmk__xml_copy(holder, xml);
295 return TRUE;
296}
297
298xmlNode *
299get_message_xml(const xmlNode *msg, const char *field)
300{
301 xmlNode *child = pcmk__xe_first_child(msg, field, NULL, NULL);
302
303 return pcmk__xe_first_child(child, NULL, NULL, NULL);
304}
305
306// LCOV_EXCL_STOP
307// End deprecated API
const char * name
Definition cib.c:26
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
Definition util.h:98
enum crm_ais_msg_types type
Definition cpg.c:3
#define CRM_SYSTEM_CIB
Definition crm.h:89
#define CRM_SYSTEM_CRMD
Definition crm.h:90
#define CRM_FEATURE_SET
Definition crm.h:72
#define CRM_SYSTEM_LRMD
Definition crm.h:91
#define CRM_SYSTEM_PENGINE
Definition crm.h:92
#define crm_info(fmt, args...)
Definition logging.h:397
#define CRM_CHECK(expr, failure_action)
Definition logging.h:245
#define crm_err(fmt, args...)
Definition logging.h:389
#define crm_trace(fmt, args...)
Definition logging.h:402
const char * pcmk__message_name(const char *name)
Get name to be used as identifier for cluster messages.
Definition messages.c:171
GHashTable * pcmk__register_handlers(const pcmk__server_command_t handlers[])
Definition messages.c:213
xmlNode * create_reply_adv(const xmlNode *original_request, xmlNode *xml_response_data, const char *origin)
Create a Pacemaker reply (for IPC or cluster layer)
Definition messages.c:104
gboolean add_message_xml(xmlNode *msg, const char *field, xmlNode *xml)
Definition messages.c:290
void pcmk__reset_request(pcmk__request_t *request)
Definition messages.c:276
xmlNode * create_request_adv(const char *task, xmlNode *msg_data, const char *host_to, const char *sys_to, const char *sys_from, const char *uuid_from, const char *origin)
Create a Pacemaker request (for IPC or cluster layer)
Definition messages.c:40
xmlNode * get_message_xml(const xmlNode *msg, const char *field)
Definition messages.c:299
xmlNode * pcmk__process_request(pcmk__request_t *request, GHashTable *handlers)
Definition messages.c:242
@ pcmk__request_sync
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
Definition nvpair.c:446
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
Definition nvpair.c:301
#define PCMK__VALUE_RESPONSE
#define PCMK__VALUE_REQUEST
#define PCMK__VALUE_CRMD
#define CRM_ASSERT(expr)
Definition results.h:42
void pcmk__reset_result(pcmk__action_result_t *result)
Definition results.c:1065
pcmk__action_result_t result
pcmk__client_t * ipc_client
Wrappers for and extensions to libxml2.
Deprecated Pacemaker XML API.
xmlNode * pcmk__xml_copy(xmlNode *parent, xmlNode *src)
Definition xml.c:883
xmlNode * pcmk__xe_first_child(const xmlNode *parent, const char *node_name, const char *attr_n, const char *attr_v)
Definition xml.c:440
xmlNode * pcmk__xe_create(xmlNode *parent, const char *name)
Definition xml.c:720
#define PCMK_XA_ORIGIN
Definition xml_names.h:346
#define PCMK_XA_VERSION
Definition xml_names.h:439
#define PCMK_XA_REFERENCE
Definition xml_names.h:367
#define PCMK__XA_CRM_TASK
#define PCMK__XA_CRM_SYS_TO
#define PCMK__XA_T
#define PCMK__XA_SUBT
#define PCMK__XA_CRM_HOST_TO
#define PCMK__XA_CRM_SYS_FROM
#define PCMK__XE_CRM_XML
#define PCMK__XA_SRC