pacemaker  3.0.0-d8340737c4
Scalable High-Availability cluster resource manager
messages_internal.h
Go to the documentation of this file.
1 /*
2  * Copyright 2018-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 #ifndef PCMK__CRM_COMMON_MESSAGES_INTERNAL__H
11 #define PCMK__CRM_COMMON_MESSAGES_INTERNAL__H
12 
13 #include <stdint.h> // uint32_t
14 #include <libxml/tree.h> // xmlNode
15 #include <crm/common/ipc_internal.h> // pcmk__client_t
16 #include <crm/common/results_internal.h> // pcmk__action_result_t
17 #include <crm/common/xml_internal.h> // pcmk__xml_copy()
18 
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22 
24  pcmk__request_none = UINT32_C(0),
25 
26  /* It would be nice if we could check for synchronous requests generically,
27  * but each daemon uses its own call options, so the daemons are responsible
28  * for setting this flag when appropriate.
29  */
30  pcmk__request_sync = (UINT32_C(1) << 0),
31 
32  /* Whether reply must use original call options (the library code does not
33  * use this, so it is for internal daemon use)
34  */
35  pcmk__request_reuse_options = (UINT32_C(1) << 1),
36 };
37 
38 // Server request (whether from an IPC client or cluster peer)
39 typedef struct {
40  // If request is from an IPC client
41  pcmk__client_t *ipc_client; // IPC client (NULL if not via IPC)
42  uint32_t ipc_id; // IPC message ID
43  uint32_t ipc_flags; // IPC message flags
44 
45  // If message is from a cluster peer
46  const char *peer; // Peer name (NULL if not via cluster)
47 
48  // Common information regardless of origin
49  xmlNode *xml; // Request XML
50  int call_options; // Call options set on request
51  uint32_t flags; // Flag group of pcmk__request_flags
52  pcmk__action_result_t result; // Where to store operation result
53 
54  /* It would be nice if we could pull the IPC command from the XML
55  * generically, but each daemon uses a different XML attribute for it,
56  * so the daemon is responsible for populating this field.
57  *
58  * This must be a copy of the XML field, and not just a pointer into xml,
59  * because handlers might modify the original XML.
60  *
61  * @TODO Create a per-daemon struct with IPC handlers, IPC endpoints, etc.,
62  * and the name of the XML attribute for IPC commands, then replace this
63  * with a convenience function to copy the command.
64  */
65  char *op; // IPC command name
67 
68 #define pcmk__set_request_flags(request, flags_to_set) do { \
69  (request)->flags = pcmk__set_flags_as(__func__, __LINE__, \
70  LOG_TRACE, "Request", "message", (request)->flags, \
71  (flags_to_set), #flags_to_set); \
72  } while (0)
73 
74 // Type for mapping a server command to a handler
75 typedef struct {
76  const char *command;
77  xmlNode *(*handler)(pcmk__request_t *request);
79 
111 #define pcmk__new_message(server, reply_to, sender_system, \
112  recipient_node, recipient_system, task, data) \
113  pcmk__new_message_as(__func__, (server), (reply_to), \
114  (sender_system), (recipient_node), \
115  (recipient_system), (task), (data))
116 
141 #define pcmk__new_request(server, sender_system, recipient_node, \
142  recipient_system, task, data) \
143  pcmk__new_message_as(__func__, (server), NULL, \
144  (sender_system), (recipient_node), \
145  (recipient_system), (task), (data))
146 
162 #define pcmk__new_reply(original_request, data) \
163  pcmk__new_reply_as(__func__, (original_request), (data))
164 
165 xmlNode *pcmk__new_message_as(const char *origin, enum pcmk_ipc_server server,
166  const char *reply_to, const char *sender_system,
167  const char *recipient_node,
168  const char *recipient_system, const char *task,
169  xmlNode *data);
170 
171 xmlNode *pcmk__new_reply_as(const char *origin, const xmlNode *original_request,
172  xmlNode *data);
173 
174 GHashTable *pcmk__register_handlers(const pcmk__server_command_t handlers[]);
175 xmlNode *pcmk__process_request(pcmk__request_t *request, GHashTable *handlers);
176 void pcmk__reset_request(pcmk__request_t *request);
177 
187 static inline const char *
188 pcmk__request_origin_type(const pcmk__request_t *request)
189 {
190  if ((request != NULL) && (request->ipc_client != NULL)) {
191  return "client";
192  } else if ((request != NULL) && (request->peer != NULL)) {
193  return "peer";
194  } else {
195  return "originator";
196  }
197 }
198 
208 static inline const char *
209 pcmk__request_origin(const pcmk__request_t *request)
210 {
211  if ((request != NULL) && (request->ipc_client != NULL)) {
212  return pcmk__client_name(request->ipc_client);
213  } else if ((request != NULL) && (request->peer != NULL)) {
214  return request->peer;
215  } else {
216  return "(unspecified)";
217  }
218 }
219 
220 #ifdef __cplusplus
221 }
222 #endif
223 
224 #endif // PCMK__CRM_COMMON_MESSAGES_INTERNAL__H
GHashTable * pcmk__register_handlers(const pcmk__server_command_t handlers[])
Definition: messages.c:181
void pcmk__reset_request(pcmk__request_t *request)
Definition: messages.c:244
char data[0]
Definition: cpg.c:58
xmlNode * pcmk__process_request(pcmk__request_t *request, GHashTable *handlers)
Definition: messages.c:210
xmlNode * pcmk__new_reply_as(const char *origin, const xmlNode *original_request, xmlNode *data)
Definition: messages.c:123
pcmk__client_t * ipc_client
pcmk__request_flags
pcmk__action_result_t result
pcmk_ipc_server
Available IPC interfaces.
Definition: ipc.h:48
xmlNode * pcmk__new_message_as(const char *origin, enum pcmk_ipc_server server, const char *reply_to, const char *sender_system, const char *recipient_node, const char *recipient_system, const char *task, xmlNode *data)
Definition: messages.c:58
const char * peer
const char * pcmk__client_name(const pcmk__client_t *c)
Definition: ipc_server.c:98