pacemaker 2.1.4-dc6eb4362e
Scalable High-Availability cluster resource manager
ipc_internal.h
Go to the documentation of this file.
1/*
2 * Copyright 2013-2022 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> // US_AUTH_GETPEEREID
31#include <crm/common/ipc.h>
32#include <crm/common/mainloop.h> // mainloop_io_t
33
34/* denotes "non yieldable PID" on FreeBSD, or actual PID1 in scenarios that
35 require a delicate handling anyway (socket-based activation with systemd);
36 we can be reasonably sure that this PID is never possessed by the actual
37 child daemon, as it gets taken either by the proper init, or by pacemakerd
38 itself (i.e. this precludes anything else); note that value of zero
39 is meant to carry "unset" meaning, and better not to bet on/conditionalize
40 over signedness of pid_t */
41#define PCMK__SPECIAL_PID 1
42
43// Timeout (in seconds) to use for IPC client sends, reply waits, etc.
44#define PCMK__IPC_TIMEOUT 120
45
46#if defined(US_AUTH_GETPEEREID)
47/* on FreeBSD, we don't want to expose "non-yieldable PID" (leading to
48 "IPC liveness check only") as its nominal representation, which could
49 cause confusion -- this is unambiguous as long as there's no
50 socket-based activation like with systemd (very improbable) */
51#define PCMK__SPECIAL_PID_AS_0(p) (((p) == PCMK__SPECIAL_PID) ? 0 : (p))
52#else
53#define PCMK__SPECIAL_PID_AS_0(p) (p)
54#endif
55
88int pcmk__ipc_is_authentic_process_active(const char *name, uid_t refuid,
89 gid_t refgid, pid_t *gotpid);
90
91
92/*
93 * Server-related
94 */
95
97
99 /* Shared */
100 char *buffer;
106
107 /* CIB-only */
109 char *token;
110
111 /* TLS only */
112# ifdef HAVE_GNUTLS_GNUTLS_H
113 gnutls_session_t *tls_session;
114 bool tls_handshake_complete;
115# endif
116};
117
119 // Lower 32 bits are reserved for server (not library) use
120
121 // Next 8 bits are reserved for client type (sort of a cheap enum)
122 pcmk__client_ipc = (UINT64_C(1) << 32), // Client uses plain IPC
123 pcmk__client_tcp = (UINT64_C(1) << 33), // Client uses TCP connection
125 pcmk__client_tls = (UINT64_C(1) << 34), // Client uses TCP with TLS
126# endif
127
128 // The rest are client attributes
129 pcmk__client_proxied = (UINT64_C(1) << 40), // Client IPC is proxied
130 pcmk__client_privileged = (UINT64_C(1) << 41), // root or cluster user
131 pcmk__client_to_proxy = (UINT64_C(1) << 42), // Local client to be proxied
132};
133
134#define PCMK__CLIENT_TYPE(client) ((client)->flags & UINT64_C(0xff00000000))
135
137 unsigned int pid;
138
139 char *id;
140 char *name;
141 char *user;
142 uint64_t flags; // Group of pcmk__client_flags
143
145 void *userdata;
146
148 GQueue *event_queue;
149
150 /* Depending on the client type, only some of the following will be
151 * populated/valid. @TODO Maybe convert to a union.
152 */
153
154 qb_ipcs_connection_t *ipcs; /* IPC */
155
156 struct pcmk__remote_s *remote; /* TCP/TLS */
157
158 unsigned int queue_backlog; /* IPC queue length after last flush */
159 unsigned int queue_max; /* Evict client whose queue grows this big */
160};
161
162#define pcmk__set_client_flags(client, flags_to_set) do { \
163 (client)->flags = pcmk__set_flags_as(__func__, __LINE__, \
164 LOG_TRACE, \
165 "Client", pcmk__client_name(client), \
166 (client)->flags, (flags_to_set), #flags_to_set); \
167 } while (0)
168
169#define pcmk__clear_client_flags(client, flags_to_clear) do { \
170 (client)->flags = pcmk__clear_flags_as(__func__, __LINE__, \
171 LOG_TRACE, \
172 "Client", pcmk__client_name(client), \
173 (client)->flags, (flags_to_clear), #flags_to_clear); \
174 } while (0)
175
176#define pcmk__set_ipc_flags(ipc_flags, ipc_name, flags_to_set) do { \
177 ipc_flags = pcmk__set_flags_as(__func__, __LINE__, LOG_TRACE, \
178 "IPC", (ipc_name), \
179 (ipc_flags), (flags_to_set), \
180 #flags_to_set); \
181 } while (0)
182
183#define pcmk__clear_ipc_flags(ipc_flags, ipc_name, flags_to_clear) do { \
184 ipc_flags = pcmk__clear_flags_as(__func__, __LINE__, LOG_TRACE, \
185 "IPC", (ipc_name), \
186 (ipc_flags), (flags_to_clear), \
187 #flags_to_clear); \
188 } while (0)
189
190guint pcmk__ipc_client_count(void);
191void pcmk__foreach_ipc_client(GHFunc func, gpointer user_data);
192
193void pcmk__client_cleanup(void);
194
195pcmk__client_t *pcmk__find_client(qb_ipcs_connection_t *c);
197const char *pcmk__client_name(pcmk__client_t *c);
198const char *pcmk__client_type_str(uint64_t client_type);
199
201pcmk__client_t *pcmk__new_client(qb_ipcs_connection_t *c, uid_t uid, gid_t gid);
203void pcmk__drop_all_clients(qb_ipcs_service_t *s);
204bool pcmk__set_client_queue_max(pcmk__client_t *client, const char *qmax);
205
206xmlNode *pcmk__ipc_create_ack_as(const char *function, int line, uint32_t flags,
207 const char *tag, crm_exit_t status);
208#define pcmk__ipc_create_ack(flags, tag, st) \
209 pcmk__ipc_create_ack_as(__func__, __LINE__, (flags), (tag), (st))
210
211int pcmk__ipc_send_ack_as(const char *function, int line, pcmk__client_t *c,
212 uint32_t request, uint32_t flags, const char *tag,
213 crm_exit_t status);
214#define pcmk__ipc_send_ack(c, req, flags, tag, st) \
215 pcmk__ipc_send_ack_as(__func__, __LINE__, (c), (req), (flags), (tag), (st))
216
217int pcmk__ipc_prepare_iov(uint32_t request, xmlNode *message,
218 uint32_t max_send_size,
219 struct iovec **result, ssize_t *bytes);
220int pcmk__ipc_send_xml(pcmk__client_t *c, uint32_t request, xmlNode *message,
221 uint32_t flags);
222int pcmk__ipc_send_iov(pcmk__client_t *c, struct iovec *iov, uint32_t flags);
223xmlNode *pcmk__client_data2xml(pcmk__client_t *c, void *data,
224 uint32_t *id, uint32_t *flags);
225
226int pcmk__client_pid(qb_ipcs_connection_t *c);
227
228void pcmk__serve_attrd_ipc(qb_ipcs_service_t **ipcs,
229 struct qb_ipcs_service_handlers *cb);
230void pcmk__serve_fenced_ipc(qb_ipcs_service_t **ipcs,
231 struct qb_ipcs_service_handlers *cb);
232void pcmk__serve_pacemakerd_ipc(qb_ipcs_service_t **ipcs,
233 struct qb_ipcs_service_handlers *cb);
234qb_ipcs_service_t *pcmk__serve_schedulerd_ipc(struct qb_ipcs_service_handlers *cb);
235qb_ipcs_service_t *pcmk__serve_controld_ipc(struct qb_ipcs_service_handlers *cb);
236
237void pcmk__serve_based_ipc(qb_ipcs_service_t **ipcs_ro,
238 qb_ipcs_service_t **ipcs_rw,
239 qb_ipcs_service_t **ipcs_shm,
240 struct qb_ipcs_service_handlers *ro_cb,
241 struct qb_ipcs_service_handlers *rw_cb);
242
243void pcmk__stop_based_ipc(qb_ipcs_service_t *ipcs_ro,
244 qb_ipcs_service_t *ipcs_rw,
245 qb_ipcs_service_t *ipcs_shm);
246
247static inline const char *
248pcmk__ipc_sys_name(const char *ipc_name, const char *fallback)
249{
250 return ipc_name ? ipc_name : ((crm_system_name ? crm_system_name : fallback));
251}
252
253#ifdef __cplusplus
254}
255#endif
256
257#endif
const char * name
Definition: cib.c:24
void gnutls_session_t
Definition: cib_remote.c:42
uint64_t flags
Definition: remote.c:3
#define HAVE_GNUTLS_GNUTLS_H
Definition: config.h:191
char data[0]
Definition: cpg.c:10
char * crm_system_name
Definition: utils.c:54
IPC interface to Pacemaker daemons.
const char * pcmk__client_name(pcmk__client_t *c)
Definition: ipc_server.c:99
pcmk__client_t * pcmk__new_client(qb_ipcs_connection_t *c, uid_t uid, gid_t gid)
Definition: ipc_server.c:224
pcmk__client_t * pcmk__find_client_by_id(const char *id)
Definition: ipc_server.c:70
const char * pcmk__client_type_str(uint64_t client_type)
Definition: ipc_common.c:96
xmlNode * pcmk__client_data2xml(pcmk__client_t *c, void *data, uint32_t *id, uint32_t *flags)
Definition: ipc_server.c:392
int pcmk__client_pid(qb_ipcs_connection_t *c)
Definition: ipc_server.c:371
pcmk__client_flags
Definition: ipc_internal.h:118
@ pcmk__client_proxied
Definition: ipc_internal.h:129
@ pcmk__client_ipc
Definition: ipc_internal.h:122
@ pcmk__client_privileged
Definition: ipc_internal.h:130
@ pcmk__client_to_proxy
Definition: ipc_internal.h:131
@ pcmk__client_tcp
Definition: ipc_internal.h:123
int pcmk__ipc_send_xml(pcmk__client_t *c, uint32_t request, xmlNode *message, uint32_t flags)
Definition: ipc_server.c:750
pcmk__client_t * pcmk__new_unauth_client(void *key)
Allocate a new pcmk__client_t object and generate its ID.
Definition: ipc_server.c:215
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
void pcmk__serve_fenced_ipc(qb_ipcs_service_t **ipcs, struct qb_ipcs_service_handlers *cb)
Definition: ipc_server.c:931
qb_ipcs_service_t * pcmk__serve_controld_ipc(struct qb_ipcs_service_handlers *cb)
Definition: ipc_server.c:896
int pcmk__ipc_send_ack_as(const char *function, int line, pcmk__client_t *c, uint32_t request, uint32_t flags, const char *tag, crm_exit_t status)
Definition: ipc_server.c:815
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:878
void pcmk__free_client(pcmk__client_t *c)
Definition: ipc_server.c:305
int pcmk__ipc_is_authentic_process_active(const char *name, uid_t refuid, gid_t refgid, pid_t *gotpid)
Definition: ipc_client.c:1458
bool pcmk__set_client_queue_max(pcmk__client_t *client, const char *qmax)
Definition: ipc_server.c:356
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:844
void pcmk__client_cleanup(void)
Definition: ipc_server.c:116
int pcmk__ipc_prepare_iov(uint32_t request, xmlNode *message, uint32_t max_send_size, struct iovec **result, ssize_t *bytes)
Definition: ipc_server.c:586
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:671
xmlNode * pcmk__ipc_create_ack_as(const char *function, int line, uint32_t flags, const char *tag, crm_exit_t status)
Definition: ipc_server.c:786
void pcmk__serve_attrd_ipc(qb_ipcs_service_t **ipcs, struct qb_ipcs_service_handlers *cb)
Definition: ipc_server.c:910
pcmk__client_t * pcmk__find_client(qb_ipcs_connection_t *c)
Definition: ipc_server.c:59
qb_ipcs_service_t * pcmk__serve_schedulerd_ipc(struct qb_ipcs_service_handlers *cb)
Definition: ipc_server.c:979
void pcmk__serve_pacemakerd_ipc(qb_ipcs_service_t **ipcs, struct qb_ipcs_service_handlers *cb)
Definition: ipc_server.c:953
Wrappers for and extensions to glib mainloop.
struct mainloop_io_s mainloop_io_t
Definition: mainloop.h:33
pcmk__action_result_t result
Definition: pcmk_fence.c:34
enum crm_exit_e crm_exit_t
qb_ipcs_connection_t * ipcs
Definition: ipc_internal.h:154
unsigned int queue_backlog
Definition: ipc_internal.h:158
unsigned int pid
Definition: ipc_internal.h:137
struct pcmk__remote_s * remote
Definition: ipc_internal.h:156
GQueue * event_queue
Definition: ipc_internal.h:148
unsigned int queue_max
Definition: ipc_internal.h:159
uint64_t flags
Definition: ipc_internal.h:142
size_t buffer_offset
Definition: ipc_internal.h:102
mainloop_io_t * source
Definition: ipc_internal.h:105
size_t buffer_size
Definition: ipc_internal.h:101