pacemaker 3.0.1-16e74fc4da
Scalable High-Availability cluster resource manager
Loading...
Searching...
No Matches
ipc_internal.h
Go to the documentation of this file.
1/*
2 * Copyright 2013-2025 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_IPC_INTERNAL__H
11#define PCMK__CRM_COMMON_IPC_INTERNAL__H
12
13#include <stdbool.h> // bool
14#include <stdint.h> // uint32_t, uint64_t, UINT64_C()
15#include <sys/uio.h> // struct iovec
16#include <sys/types.h> // uid_t, gid_t, pid_t, size_t
17
18#include <gnutls/gnutls.h> // gnutls_session_t
19
20#include <glib.h> // guint, gpointer, GQueue, ...
21#include <libxml/tree.h> // xmlNode
22#include <qb/qbipcs.h> // qb_ipcs_connection_t, ...
23
24#include <crm_config.h> // HAVE_GETPEEREID
25#include <crm/crm.h> // crm_system_name
26#include <crm/common/ipc.h>
27#include <crm/common/ipc_controld.h> // pcmk_controld_api_reply
28#include <crm/common/ipc_pacemakerd.h> // pcmk_pacemakerd_{api_reply,state}
29#include <crm/common/mainloop.h> // mainloop_io_t
30
31#ifdef __cplusplus
32extern "C" {
33#endif
34
35/* denotes "non yieldable PID" on FreeBSD, or actual PID1 in scenarios that
36 require a delicate handling anyway (socket-based activation with systemd);
37 we can be reasonably sure that this PID is never possessed by the actual
38 child daemon, as it gets taken either by the proper init, or by pacemakerd
39 itself (i.e. this precludes anything else); note that value of zero
40 is meant to carry "unset" meaning, and better not to bet on/conditionalize
41 over signedness of pid_t */
42#define PCMK__SPECIAL_PID 1
43
44// Timeout (in seconds) to use for IPC client sends, reply waits, etc.
45#define PCMK__IPC_TIMEOUT 120
46
47#if defined(HAVE_GETPEEREID)
48/* on FreeBSD, we don't want to expose "non-yieldable PID" (leading to
49 "IPC liveness check only") as its nominal representation, which could
50 cause confusion -- this is unambiguous as long as there's no
51 socket-based activation like with systemd (very improbable) */
52#define PCMK__SPECIAL_PID_AS_0(p) (((p) == PCMK__SPECIAL_PID) ? 0 : (p))
53#else
54#define PCMK__SPECIAL_PID_AS_0(p) (p)
55#endif
56
89int pcmk__ipc_is_authentic_process_active(const char *name, uid_t refuid,
90 gid_t refgid, pid_t *gotpid);
91
93int pcmk__ipc_fd(crm_ipc_t *ipc, int *fd);
94int pcmk__connect_ipc(pcmk_ipc_api_t *api, enum pcmk_ipc_dispatch dispatch_type,
95 int attempts);
97 enum pcmk_ipc_dispatch dispatch_type,
98 int attempts);
99/*
100 * Server-related
101 */
102
104
106 /* Shared */
107 char *buffer;
113 time_t uptime;
115
116 /* CIB-only */
117 char *token;
118
119 /* TLS only */
120
121 // Must be created by pcmk__new_tls_session()
122 gnutls_session_t tls_session;
123};
124
126 // Lower 32 bits are reserved for server (not library) use
127
128 // Next 8 bits are reserved for client type (sort of a cheap enum)
129
131 pcmk__client_ipc = (UINT64_C(1) << 32),
132
134 pcmk__client_tcp = (UINT64_C(1) << 33),
135
137 pcmk__client_tls = (UINT64_C(1) << 34),
138
139 // The rest are client attributes
140
142 pcmk__client_proxied = (UINT64_C(1) << 40),
143
145 pcmk__client_privileged = (UINT64_C(1) << 41),
146
148 pcmk__client_to_proxy = (UINT64_C(1) << 42),
149
155 pcmk__client_authenticated = (UINT64_C(1) << 43),
156
159};
160
161#define PCMK__CLIENT_TYPE(client) ((client)->flags & UINT64_C(0xff00000000))
162
164 unsigned int pid;
165
166 char *id;
167 char *name;
168 char *user;
169 uint64_t flags; // Group of pcmk__client_flags
170
172 void *userdata;
173
175 GQueue *event_queue;
176
177 /* Buffer used to store a multipart IPC message when we are building it
178 * up over multiple reads.
179 */
180 GByteArray *buffer;
181
182 /* Depending on the client type, only some of the following will be
183 * populated/valid. @TODO Maybe convert to a union.
184 */
185
186 qb_ipcs_connection_t *ipcs; /* IPC */
187
188 struct pcmk__remote_s *remote; /* TCP/TLS */
189
190 unsigned int queue_backlog; /* IPC queue length after last flush */
191 unsigned int queue_max; /* Evict client whose queue grows this big */
192};
193
194#define pcmk__set_client_flags(client, flags_to_set) do { \
195 (client)->flags = pcmk__set_flags_as(__func__, __LINE__, \
196 LOG_TRACE, \
197 "Client", pcmk__client_name(client), \
198 (client)->flags, (flags_to_set), #flags_to_set); \
199 } while (0)
200
201#define pcmk__clear_client_flags(client, flags_to_clear) do { \
202 (client)->flags = pcmk__clear_flags_as(__func__, __LINE__, \
203 LOG_TRACE, \
204 "Client", pcmk__client_name(client), \
205 (client)->flags, (flags_to_clear), #flags_to_clear); \
206 } while (0)
207
208#define pcmk__set_ipc_flags(ipc_flags, ipc_name, flags_to_set) do { \
209 ipc_flags = pcmk__set_flags_as(__func__, __LINE__, LOG_TRACE, \
210 "IPC", (ipc_name), \
211 (ipc_flags), (flags_to_set), \
212 #flags_to_set); \
213 } while (0)
214
215#define pcmk__clear_ipc_flags(ipc_flags, ipc_name, flags_to_clear) do { \
216 ipc_flags = pcmk__clear_flags_as(__func__, __LINE__, LOG_TRACE, \
217 "IPC", (ipc_name), \
218 (ipc_flags), (flags_to_clear), \
219 #flags_to_clear); \
220 } while (0)
221
222guint pcmk__ipc_client_count(void);
223void pcmk__foreach_ipc_client(GHFunc func, gpointer user_data);
224
225void pcmk__client_cleanup(void);
226
227pcmk__client_t *pcmk__find_client(const qb_ipcs_connection_t *c);
229const char *pcmk__client_name(const pcmk__client_t *c);
230const char *pcmk__client_type_str(uint64_t client_type);
231
233pcmk__client_t *pcmk__new_client(qb_ipcs_connection_t *c, uid_t uid, gid_t gid);
235void pcmk__drop_all_clients(qb_ipcs_service_t *s);
236void pcmk__set_client_queue_max(pcmk__client_t *client, const char *qmax);
237
238xmlNode *pcmk__ipc_create_ack_as(const char *function, int line, uint32_t flags,
239 const char *tag, const char *ver, crm_exit_t status);
240#define pcmk__ipc_create_ack(flags, tag, ver, st) \
241 pcmk__ipc_create_ack_as(__func__, __LINE__, (flags), (tag), (ver), (st))
242
243int pcmk__ipc_send_ack_as(const char *function, int line, pcmk__client_t *c,
244 uint32_t request, uint32_t flags, const char *tag,
245 const char *ver, crm_exit_t status);
246#define pcmk__ipc_send_ack(c, req, flags, tag, ver, st) \
247 pcmk__ipc_send_ack_as(__func__, __LINE__, (c), (req), (flags), (tag), (ver), (st))
248
249int pcmk__ipc_prepare_iov(uint32_t request, const GString *message,
250 uint16_t index, struct iovec **result, ssize_t *bytes);
251int pcmk__ipc_send_xml(pcmk__client_t *c, uint32_t request,
252 const xmlNode *message, uint32_t flags);
253int pcmk__ipc_send_iov(pcmk__client_t *c, struct iovec *iov, uint32_t flags);
255int pcmk__ipc_msg_append(GByteArray **buffer, guint8 *data);
256xmlNode *pcmk__client_data2xml(pcmk__client_t *c, uint32_t *id, uint32_t *flags);
257
258int pcmk__client_pid(qb_ipcs_connection_t *c);
259
260void pcmk__serve_attrd_ipc(qb_ipcs_service_t **ipcs,
261 struct qb_ipcs_service_handlers *cb);
262void pcmk__serve_fenced_ipc(qb_ipcs_service_t **ipcs,
263 struct qb_ipcs_service_handlers *cb);
264void pcmk__serve_pacemakerd_ipc(qb_ipcs_service_t **ipcs,
265 struct qb_ipcs_service_handlers *cb);
266qb_ipcs_service_t *pcmk__serve_schedulerd_ipc(struct qb_ipcs_service_handlers *cb);
267qb_ipcs_service_t *pcmk__serve_controld_ipc(struct qb_ipcs_service_handlers *cb);
268
269void pcmk__serve_based_ipc(qb_ipcs_service_t **ipcs_ro,
270 qb_ipcs_service_t **ipcs_rw,
271 qb_ipcs_service_t **ipcs_shm,
272 struct qb_ipcs_service_handlers *ro_cb,
273 struct qb_ipcs_service_handlers *rw_cb);
274
275void pcmk__stop_based_ipc(qb_ipcs_service_t *ipcs_ro,
276 qb_ipcs_service_t *ipcs_rw,
277 qb_ipcs_service_t *ipcs_shm);
278
279static inline const char *
280pcmk__ipc_sys_name(const char *ipc_name, const char *fallback)
281{
282 return ipc_name ? ipc_name : ((crm_system_name ? crm_system_name : fallback));
283}
284
286
289
290#ifdef __cplusplus
291}
292#endif
293
294#endif // PCMK__CRM_COMMON_IPC_INTERNAL__H
const char * name
Definition cib.c:26
uint64_t flags
Definition remote.c:3
char data[0]
Definition cpg.c:10
A dumping ground.
char * crm_system_name
Definition utils.c:45
IPC interface to Pacemaker daemons.
pcmk_ipc_dispatch
How IPC replies should be dispatched.
Definition ipc.h:74
struct crm_ipc_s crm_ipc_t
Definition ipc.h:159
IPC commands for Pacemaker controller.
pcmk_controld_api_reply
Possible types of controller replies.
pcmk__client_t * pcmk__new_client(qb_ipcs_connection_t *c, uid_t uid, gid_t gid)
Definition ipc_server.c:209
int pcmk__ipc_msg_append(GByteArray **buffer, guint8 *data)
Definition ipc_common.c:99
int pcmk__connect_generic_ipc(crm_ipc_t *ipc)
Definition ipc_client.c:912
int pcmk__ipc_fd(crm_ipc_t *ipc, int *fd)
pcmk__client_t * pcmk__find_client_by_id(const char *id)
Definition ipc_server.c:70
const char * pcmk__client_name(const pcmk__client_t *c)
Definition ipc_server.c:98
const char * pcmk__client_type_str(uint64_t client_type)
Definition ipc_common.c:60
const char * pcmk__pcmkd_state_enum2friendly(enum pcmk_pacemakerd_state state)
int pcmk__ipc_prepare_iov(uint32_t request, const GString *message, uint16_t index, struct iovec **result, ssize_t *bytes)
Definition ipc_server.c:595
int pcmk__client_pid(qb_ipcs_connection_t *c)
Definition ipc_server.c:381
pcmk__client_flags
@ pcmk__client_proxied
Client IPC is proxied.
@ pcmk__client_ipc
Client uses plain IPC.
@ pcmk__client_tls
Client uses TCP with TLS.
@ pcmk__client_tls_handshake_complete
Client TLS handshake is complete.
@ pcmk__client_privileged
Client is run by root or cluster user.
@ pcmk__client_to_proxy
Local client to be proxied.
@ pcmk__client_tcp
Client uses TCP connection.
@ pcmk__client_authenticated
Client IPC connection accepted.
const char * pcmk__pcmkd_api_reply2str(enum pcmk_pacemakerd_api_reply reply)
pcmk__client_t * pcmk__find_client(const qb_ipcs_connection_t *c)
Definition ipc_server.c:59
void pcmk__ipc_free_client_buffer(crm_ipc_t *client)
int pcmk__ipc_send_ack_as(const char *function, int line, pcmk__client_t *c, uint32_t request, uint32_t flags, const char *tag, const char *ver, crm_exit_t status)
Definition ipc_server.c:983
pcmk__client_t * pcmk__new_unauth_client(void *key)
Allocate a new pcmk__client_t object and generate its ID.
Definition ipc_server.c:203
void pcmk__drop_all_clients(qb_ipcs_service_t *s)
Definition ipc_server.c:130
guint pcmk__ipc_client_count(void)
Definition ipc_server.c:36
int pcmk__connect_ipc(pcmk_ipc_api_t *api, enum pcmk_ipc_dispatch dispatch_type, int attempts)
Definition ipc_client.c:517
void pcmk__serve_fenced_ipc(qb_ipcs_service_t **ipcs, struct qb_ipcs_service_handlers *cb)
int pcmk__ipc_send_xml(pcmk__client_t *c, uint32_t request, const xmlNode *message, uint32_t flags)
Definition ipc_server.c:822
void pcmk__set_client_queue_max(pcmk__client_t *client, const char *qmax)
Definition ipc_server.c:345
qb_ipcs_service_t * pcmk__serve_controld_ipc(struct qb_ipcs_service_handlers *cb)
void pcmk__stop_based_ipc(qb_ipcs_service_t *ipcs_ro, qb_ipcs_service_t *ipcs_rw, qb_ipcs_service_t *ipcs_shm)
void pcmk__free_client(pcmk__client_t *c)
Definition ipc_server.c:284
int pcmk__ipc_is_authentic_process_active(const char *name, uid_t refuid, gid_t refgid, pid_t *gotpid)
xmlNode * pcmk__client_data2xml(pcmk__client_t *c, uint32_t *id, uint32_t *flags)
Definition ipc_server.c:401
int pcmk__connect_ipc_retry_conrefused(pcmk_ipc_api_t *api, enum pcmk_ipc_dispatch dispatch_type, int attempts)
Definition ipc_client.c:487
void pcmk__serve_based_ipc(qb_ipcs_service_t **ipcs_ro, qb_ipcs_service_t **ipcs_rw, qb_ipcs_service_t **ipcs_shm, struct qb_ipcs_service_handlers *ro_cb, struct qb_ipcs_service_handlers *rw_cb)
xmlNode * pcmk__ipc_create_ack_as(const char *function, int line, uint32_t flags, const char *tag, const char *ver, crm_exit_t status)
Definition ipc_server.c:952
void pcmk__client_cleanup(void)
Definition ipc_server.c:115
void pcmk__foreach_ipc_client(GHFunc func, gpointer user_data)
Definition ipc_server.c:51
int pcmk__ipc_send_iov(pcmk__client_t *c, struct iovec *iov, uint32_t flags)
Definition ipc_server.c:720
const char * pcmk__controld_api_reply2str(enum pcmk_controld_api_reply reply)
void pcmk__serve_attrd_ipc(qb_ipcs_service_t **ipcs, struct qb_ipcs_service_handlers *cb)
qb_ipcs_service_t * pcmk__serve_schedulerd_ipc(struct qb_ipcs_service_handlers *cb)
void pcmk__serve_pacemakerd_ipc(qb_ipcs_service_t **ipcs, struct qb_ipcs_service_handlers *cb)
IPC commands for Pacemakerd.
pcmk_pacemakerd_api_reply
Possible types of pacemakerd replies.
pcmk_pacemakerd_state
Wrappers for and extensions to glib mainloop.
struct mainloop_io_s mainloop_io_t
Definition mainloop.h:41
pcmk__action_result_t result
Definition pcmk_fence.c:37
enum crm_exit_e crm_exit_t
Exit status codes for tools and daemons.
qb_ipcs_connection_t * ipcs
GByteArray * buffer
unsigned int queue_backlog
unsigned int pid
struct pcmk__remote_s * remote
GQueue * event_queue
unsigned int queue_max
gnutls_session_t tls_session
mainloop_io_t * source