pacemaker 2.1.8-2.1.8
Scalable High-Availability cluster resource manager
Loading...
Searching...
No Matches
ipc_internal.h
Go to the documentation of this file.
1/*
2 * Copyright 2013-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__IPC_INTERNAL_H
11#define PCMK__IPC_INTERNAL_H
12
13#ifdef __cplusplus
14extern "C" {
15#endif
16
17#include <stdbool.h> // bool
18#include <stdint.h> // uint32_t, uint64_t, UINT64_C()
19#include <sys/uio.h> // struct iovec
20#include <sys/types.h> // uid_t, gid_t, pid_t, size_t
21
22#ifdef HAVE_GNUTLS_GNUTLS_H
23#include <gnutls/gnutls.h> // gnutls_session_t
24#endif
25
26#include <glib.h> // guint, gpointer, GQueue, ...
27#include <libxml/tree.h> // xmlNode
28#include <qb/qbipcs.h> // qb_ipcs_connection_t, ...
29
30#include <crm_config.h> // HAVE_GETPEEREID
31#include <crm/common/ipc.h>
32#include <crm/common/ipc_controld.h> // pcmk_controld_api_reply
33#include <crm/common/ipc_pacemakerd.h> // pcmk_pacemakerd_{api_reply,state}
34#include <crm/common/mainloop.h> // mainloop_io_t
35
36/*
37 * XML attribute names used only by internal code
38 */
39
40#define PCMK__XA_IPC_PROTO_VERSION "ipc-protocol-version"
41
42/* denotes "non yieldable PID" on FreeBSD, or actual PID1 in scenarios that
43 require a delicate handling anyway (socket-based activation with systemd);
44 we can be reasonably sure that this PID is never possessed by the actual
45 child daemon, as it gets taken either by the proper init, or by pacemakerd
46 itself (i.e. this precludes anything else); note that value of zero
47 is meant to carry "unset" meaning, and better not to bet on/conditionalize
48 over signedness of pid_t */
49#define PCMK__SPECIAL_PID 1
50
51// Timeout (in seconds) to use for IPC client sends, reply waits, etc.
52#define PCMK__IPC_TIMEOUT 120
53
54#if defined(HAVE_GETPEEREID)
55/* on FreeBSD, we don't want to expose "non-yieldable PID" (leading to
56 "IPC liveness check only") as its nominal representation, which could
57 cause confusion -- this is unambiguous as long as there's no
58 socket-based activation like with systemd (very improbable) */
59#define PCMK__SPECIAL_PID_AS_0(p) (((p) == PCMK__SPECIAL_PID) ? 0 : (p))
60#else
61#define PCMK__SPECIAL_PID_AS_0(p) (p)
62#endif
63
96int pcmk__ipc_is_authentic_process_active(const char *name, uid_t refuid,
97 gid_t refgid, pid_t *gotpid);
98
100int pcmk__ipc_fd(crm_ipc_t *ipc, int *fd);
101int pcmk__connect_ipc(pcmk_ipc_api_t *api, enum pcmk_ipc_dispatch dispatch_type,
102 int attempts);
103
104/*
105 * Server-related
106 */
107
109
111 /* Shared */
112 char *buffer;
118 time_t uptime;
120
121 /* CIB-only */
122 char *token;
123
124 /* TLS only */
125#ifdef HAVE_GNUTLS_GNUTLS_H
126 gnutls_session_t *tls_session;
127#endif
128};
129
131 // Lower 32 bits are reserved for server (not library) use
132
133 // Next 8 bits are reserved for client type (sort of a cheap enum)
134
136 pcmk__client_ipc = (UINT64_C(1) << 32),
137
139 pcmk__client_tcp = (UINT64_C(1) << 33),
140
143 pcmk__client_tls = (UINT64_C(1) << 34),
144#endif
145
146 // The rest are client attributes
147
149 pcmk__client_proxied = (UINT64_C(1) << 40),
150
152 pcmk__client_privileged = (UINT64_C(1) << 41),
153
155 pcmk__client_to_proxy = (UINT64_C(1) << 42),
156
162 pcmk__client_authenticated = (UINT64_C(1) << 43),
163
166 pcmk__client_tls_handshake_complete = (UINT64_C(1) << 44),
167#endif
168};
169
170#define PCMK__CLIENT_TYPE(client) ((client)->flags & UINT64_C(0xff00000000))
171
173 unsigned int pid;
174
175 char *id;
176 char *name;
177 char *user;
178 uint64_t flags; // Group of pcmk__client_flags
179
181 void *userdata;
182
184 GQueue *event_queue;
185
186 /* Depending on the client type, only some of the following will be
187 * populated/valid. @TODO Maybe convert to a union.
188 */
189
190 qb_ipcs_connection_t *ipcs; /* IPC */
191
192 struct pcmk__remote_s *remote; /* TCP/TLS */
193
194 unsigned int queue_backlog; /* IPC queue length after last flush */
195 unsigned int queue_max; /* Evict client whose queue grows this big */
196};
197
198#define pcmk__set_client_flags(client, flags_to_set) do { \
199 (client)->flags = pcmk__set_flags_as(__func__, __LINE__, \
200 LOG_TRACE, \
201 "Client", pcmk__client_name(client), \
202 (client)->flags, (flags_to_set), #flags_to_set); \
203 } while (0)
204
205#define pcmk__clear_client_flags(client, flags_to_clear) do { \
206 (client)->flags = pcmk__clear_flags_as(__func__, __LINE__, \
207 LOG_TRACE, \
208 "Client", pcmk__client_name(client), \
209 (client)->flags, (flags_to_clear), #flags_to_clear); \
210 } while (0)
211
212#define pcmk__set_ipc_flags(ipc_flags, ipc_name, flags_to_set) do { \
213 ipc_flags = pcmk__set_flags_as(__func__, __LINE__, LOG_TRACE, \
214 "IPC", (ipc_name), \
215 (ipc_flags), (flags_to_set), \
216 #flags_to_set); \
217 } while (0)
218
219#define pcmk__clear_ipc_flags(ipc_flags, ipc_name, flags_to_clear) do { \
220 ipc_flags = pcmk__clear_flags_as(__func__, __LINE__, LOG_TRACE, \
221 "IPC", (ipc_name), \
222 (ipc_flags), (flags_to_clear), \
223 #flags_to_clear); \
224 } while (0)
225
226guint pcmk__ipc_client_count(void);
227void pcmk__foreach_ipc_client(GHFunc func, gpointer user_data);
228
229void pcmk__client_cleanup(void);
230
231pcmk__client_t *pcmk__find_client(const qb_ipcs_connection_t *c);
233const char *pcmk__client_name(const pcmk__client_t *c);
234const char *pcmk__client_type_str(uint64_t client_type);
235
237pcmk__client_t *pcmk__new_client(qb_ipcs_connection_t *c, uid_t uid, gid_t gid);
239void pcmk__drop_all_clients(qb_ipcs_service_t *s);
240bool pcmk__set_client_queue_max(pcmk__client_t *client, const char *qmax);
241
242xmlNode *pcmk__ipc_create_ack_as(const char *function, int line, uint32_t flags,
243 const char *tag, const char *ver, crm_exit_t status);
244#define pcmk__ipc_create_ack(flags, tag, ver, st) \
245 pcmk__ipc_create_ack_as(__func__, __LINE__, (flags), (tag), (ver), (st))
246
247int pcmk__ipc_send_ack_as(const char *function, int line, pcmk__client_t *c,
248 uint32_t request, uint32_t flags, const char *tag,
249 const char *ver, crm_exit_t status);
250#define pcmk__ipc_send_ack(c, req, flags, tag, ver, st) \
251 pcmk__ipc_send_ack_as(__func__, __LINE__, (c), (req), (flags), (tag), (ver), (st))
252
253int pcmk__ipc_prepare_iov(uint32_t request, const xmlNode *message,
254 uint32_t max_send_size,
255 struct iovec **result, ssize_t *bytes);
256int pcmk__ipc_send_xml(pcmk__client_t *c, uint32_t request,
257 const xmlNode *message, uint32_t flags);
258int pcmk__ipc_send_iov(pcmk__client_t *c, struct iovec *iov, uint32_t flags);
259xmlNode *pcmk__client_data2xml(pcmk__client_t *c, void *data,
260 uint32_t *id, uint32_t *flags);
261
262int pcmk__client_pid(qb_ipcs_connection_t *c);
263
264void pcmk__serve_attrd_ipc(qb_ipcs_service_t **ipcs,
265 struct qb_ipcs_service_handlers *cb);
266void pcmk__serve_fenced_ipc(qb_ipcs_service_t **ipcs,
267 struct qb_ipcs_service_handlers *cb);
268void pcmk__serve_pacemakerd_ipc(qb_ipcs_service_t **ipcs,
269 struct qb_ipcs_service_handlers *cb);
270qb_ipcs_service_t *pcmk__serve_schedulerd_ipc(struct qb_ipcs_service_handlers *cb);
271qb_ipcs_service_t *pcmk__serve_controld_ipc(struct qb_ipcs_service_handlers *cb);
272
273void pcmk__serve_based_ipc(qb_ipcs_service_t **ipcs_ro,
274 qb_ipcs_service_t **ipcs_rw,
275 qb_ipcs_service_t **ipcs_shm,
276 struct qb_ipcs_service_handlers *ro_cb,
277 struct qb_ipcs_service_handlers *rw_cb);
278
279void pcmk__stop_based_ipc(qb_ipcs_service_t *ipcs_ro,
280 qb_ipcs_service_t *ipcs_rw,
281 qb_ipcs_service_t *ipcs_shm);
282
283static inline const char *
284pcmk__ipc_sys_name(const char *ipc_name, const char *fallback)
285{
286 return ipc_name ? ipc_name : ((crm_system_name ? crm_system_name : fallback));
287}
288
290
293
294#ifdef __cplusplus
295}
296#endif
297
298#endif
const char * name
Definition cib.c:26
uint64_t flags
Definition remote.c:3
#define HAVE_GNUTLS_GNUTLS_H
Definition config.h:184
char data[0]
Definition cpg.c:10
char * crm_system_name
Definition utils.c:50
IPC interface to Pacemaker daemons.
pcmk_ipc_dispatch
How IPC replies should be dispatched.
Definition ipc.h:102
struct crm_ipc_s crm_ipc_t
Definition ipc.h:184
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__connect_generic_ipc(crm_ipc_t *ipc)
Definition ipc_client.c:896
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:96
const char * pcmk__pcmkd_state_enum2friendly(enum pcmk_pacemakerd_state state)
xmlNode * pcmk__client_data2xml(pcmk__client_t *c, void *data, uint32_t *id, uint32_t *flags)
Definition ipc_server.c:379
int pcmk__client_pid(qb_ipcs_connection_t *c)
Definition ipc_server.c:358
pcmk__client_flags
@ pcmk__client_proxied
Client IPC is proxied.
@ pcmk__client_ipc
Client uses plain IPC.
@ 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
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:816
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:501
void pcmk__serve_fenced_ipc(qb_ipcs_service_t **ipcs, struct qb_ipcs_service_handlers *cb)
Definition ipc_server.c:935
int pcmk__ipc_send_xml(pcmk__client_t *c, uint32_t request, const xmlNode *message, uint32_t flags)
Definition ipc_server.c:748
qb_ipcs_service_t * pcmk__serve_controld_ipc(struct qb_ipcs_service_handlers *cb)
Definition ipc_server.c:898
void pcmk__stop_based_ipc(qb_ipcs_service_t *ipcs_ro, qb_ipcs_service_t *ipcs_rw, qb_ipcs_service_t *ipcs_shm)
Definition ipc_server.c:880
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)
bool pcmk__set_client_queue_max(pcmk__client_t *client, const char *qmax)
Definition ipc_server.c:343
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)
Definition ipc_server.c:846
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:785
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:669
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)
Definition ipc_server.c:913
qb_ipcs_service_t * pcmk__serve_schedulerd_ipc(struct qb_ipcs_service_handlers *cb)
Definition ipc_server.c:985
void pcmk__serve_pacemakerd_ipc(qb_ipcs_service_t **ipcs, struct qb_ipcs_service_handlers *cb)
Definition ipc_server.c:958
int pcmk__ipc_prepare_iov(uint32_t request, const xmlNode *message, uint32_t max_send_size, struct iovec **result, ssize_t *bytes)
Definition ipc_server.c:575
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:35
pcmk__action_result_t result
Definition pcmk_fence.c:35
enum crm_exit_e crm_exit_t
qb_ipcs_connection_t * ipcs
unsigned int queue_backlog
unsigned int pid
struct pcmk__remote_s * remote
GQueue * event_queue
unsigned int queue_max
mainloop_io_t * source