pacemaker  2.1.6-802a72226b
Scalable High-Availability cluster resource manager
ipc_internal.h
Go to the documentation of this file.
1 /*
2  * Copyright 2013-2023 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
14 extern "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 
96 int pcmk__ipc_is_authentic_process_active(const char *name, uid_t refuid,
97  gid_t refgid, pid_t *gotpid);
98 
99 
100 /*
101  * Server-related
102  */
103 
105 
107  /* Shared */
108  char *buffer;
109  size_t buffer_size;
114  time_t uptime;
115 
116  /* CIB-only */
117  char *token;
118 
119  /* TLS only */
120 # ifdef HAVE_GNUTLS_GNUTLS_H
121  gnutls_session_t *tls_session;
122 # endif
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 
136 # ifdef HAVE_GNUTLS_GNUTLS_H
138  pcmk__client_tls = (UINT64_C(1) << 34),
139 # endif
140 
141  // The rest are client attributes
142 
144  pcmk__client_proxied = (UINT64_C(1) << 40),
145 
147  pcmk__client_privileged = (UINT64_C(1) << 41),
148 
150  pcmk__client_to_proxy = (UINT64_C(1) << 42),
151 
157  pcmk__client_authenticated = (UINT64_C(1) << 43),
158 
159 # ifdef HAVE_GNUTLS_GNUTLS_H
161  pcmk__client_tls_handshake_complete = (UINT64_C(1) << 44),
162 # endif
163 };
164 
165 #define PCMK__CLIENT_TYPE(client) ((client)->flags & UINT64_C(0xff00000000))
166 
168  unsigned int pid;
169 
170  char *id;
171  char *name;
172  char *user;
173  uint64_t flags; // Group of pcmk__client_flags
174 
176  void *userdata;
177 
179  GQueue *event_queue;
180 
181  /* Depending on the client type, only some of the following will be
182  * populated/valid. @TODO Maybe convert to a union.
183  */
184 
185  qb_ipcs_connection_t *ipcs; /* IPC */
186 
187  struct pcmk__remote_s *remote; /* TCP/TLS */
188 
189  unsigned int queue_backlog; /* IPC queue length after last flush */
190  unsigned int queue_max; /* Evict client whose queue grows this big */
191 };
192 
193 #define pcmk__set_client_flags(client, flags_to_set) do { \
194  (client)->flags = pcmk__set_flags_as(__func__, __LINE__, \
195  LOG_TRACE, \
196  "Client", pcmk__client_name(client), \
197  (client)->flags, (flags_to_set), #flags_to_set); \
198  } while (0)
199 
200 #define pcmk__clear_client_flags(client, flags_to_clear) do { \
201  (client)->flags = pcmk__clear_flags_as(__func__, __LINE__, \
202  LOG_TRACE, \
203  "Client", pcmk__client_name(client), \
204  (client)->flags, (flags_to_clear), #flags_to_clear); \
205  } while (0)
206 
207 #define pcmk__set_ipc_flags(ipc_flags, ipc_name, flags_to_set) do { \
208  ipc_flags = pcmk__set_flags_as(__func__, __LINE__, LOG_TRACE, \
209  "IPC", (ipc_name), \
210  (ipc_flags), (flags_to_set), \
211  #flags_to_set); \
212  } while (0)
213 
214 #define pcmk__clear_ipc_flags(ipc_flags, ipc_name, flags_to_clear) do { \
215  ipc_flags = pcmk__clear_flags_as(__func__, __LINE__, LOG_TRACE, \
216  "IPC", (ipc_name), \
217  (ipc_flags), (flags_to_clear), \
218  #flags_to_clear); \
219  } while (0)
220 
221 guint pcmk__ipc_client_count(void);
222 void pcmk__foreach_ipc_client(GHFunc func, gpointer user_data);
223 
224 void pcmk__client_cleanup(void);
225 
226 pcmk__client_t *pcmk__find_client(const qb_ipcs_connection_t *c);
227 pcmk__client_t *pcmk__find_client_by_id(const char *id);
228 const char *pcmk__client_name(const pcmk__client_t *c);
229 const char *pcmk__client_type_str(uint64_t client_type);
230 
232 pcmk__client_t *pcmk__new_client(qb_ipcs_connection_t *c, uid_t uid, gid_t gid);
234 void pcmk__drop_all_clients(qb_ipcs_service_t *s);
235 bool pcmk__set_client_queue_max(pcmk__client_t *client, const char *qmax);
236 
237 xmlNode *pcmk__ipc_create_ack_as(const char *function, int line, uint32_t flags,
238  const char *tag, const char *ver, crm_exit_t status);
239 #define pcmk__ipc_create_ack(flags, tag, ver, st) \
240  pcmk__ipc_create_ack_as(__func__, __LINE__, (flags), (tag), (ver), (st))
241 
242 int pcmk__ipc_send_ack_as(const char *function, int line, pcmk__client_t *c,
243  uint32_t request, uint32_t flags, const char *tag,
244  const char *ver, crm_exit_t status);
245 #define pcmk__ipc_send_ack(c, req, flags, tag, ver, st) \
246  pcmk__ipc_send_ack_as(__func__, __LINE__, (c), (req), (flags), (tag), (ver), (st))
247 
248 int pcmk__ipc_prepare_iov(uint32_t request, xmlNode *message,
249  uint32_t max_send_size,
250  struct iovec **result, ssize_t *bytes);
251 int pcmk__ipc_send_xml(pcmk__client_t *c, uint32_t request, xmlNode *message,
252  uint32_t flags);
253 int pcmk__ipc_send_iov(pcmk__client_t *c, struct iovec *iov, uint32_t flags);
254 xmlNode *pcmk__client_data2xml(pcmk__client_t *c, void *data,
255  uint32_t *id, uint32_t *flags);
256 
257 int pcmk__client_pid(qb_ipcs_connection_t *c);
258 
259 void pcmk__serve_attrd_ipc(qb_ipcs_service_t **ipcs,
260  struct qb_ipcs_service_handlers *cb);
261 void pcmk__serve_fenced_ipc(qb_ipcs_service_t **ipcs,
262  struct qb_ipcs_service_handlers *cb);
263 void pcmk__serve_pacemakerd_ipc(qb_ipcs_service_t **ipcs,
264  struct qb_ipcs_service_handlers *cb);
265 qb_ipcs_service_t *pcmk__serve_schedulerd_ipc(struct qb_ipcs_service_handlers *cb);
266 qb_ipcs_service_t *pcmk__serve_controld_ipc(struct qb_ipcs_service_handlers *cb);
267 
268 void pcmk__serve_based_ipc(qb_ipcs_service_t **ipcs_ro,
269  qb_ipcs_service_t **ipcs_rw,
270  qb_ipcs_service_t **ipcs_shm,
271  struct qb_ipcs_service_handlers *ro_cb,
272  struct qb_ipcs_service_handlers *rw_cb);
273 
274 void pcmk__stop_based_ipc(qb_ipcs_service_t *ipcs_ro,
275  qb_ipcs_service_t *ipcs_rw,
276  qb_ipcs_service_t *ipcs_shm);
277 
278 static inline const char *
279 pcmk__ipc_sys_name(const char *ipc_name, const char *fallback)
280 {
281  return ipc_name ? ipc_name : ((crm_system_name ? crm_system_name : fallback));
282 }
283 
285 
288 
289 #ifdef __cplusplus
290 }
291 #endif
292 
293 #endif
Client uses TCP connection.
Definition: ipc_internal.h:134
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:580
xmlNode * pcmk__client_data2xml(pcmk__client_t *c, void *data, uint32_t *id, uint32_t *flags)
Definition: ipc_server.c:386
pcmk__client_t * pcmk__new_client(qb_ipcs_connection_t *c, uid_t uid, gid_t gid)
Definition: ipc_server.c:218
char data[0]
Definition: cpg.c:55
const char * pcmk__pcmkd_api_reply2str(enum pcmk_pacemakerd_api_reply reply)
const char * name
Definition: cib.c:24
const char * pcmk__controld_api_reply2str(enum pcmk_controld_api_reply reply)
Definition: ipc_controld.c:39
size_t buffer_offset
Definition: ipc_internal.h:110
uint64_t flags
Definition: ipc_internal.h:173
qb_ipcs_service_t * pcmk__serve_controld_ipc(struct qb_ipcs_service_handlers *cb)
Definition: ipc_server.c:893
struct mainloop_io_s mainloop_io_t
Definition: mainloop.h:33
char * crm_system_name
Definition: utils.c:51
enum crm_exit_e crm_exit_t
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:875
pcmk_pacemakerd_api_reply
Possible types of pacemakerd replies.
void pcmk__client_cleanup(void)
Definition: ipc_server.c:115
GQueue * event_queue
Definition: ipc_internal.h:179
Wrappers for and extensions to glib mainloop.
int pcmk__client_pid(qb_ipcs_connection_t *c)
Definition: ipc_server.c:365
Client is run by root or cluster user.
Definition: ipc_internal.h:147
int pcmk__ipc_send_xml(pcmk__client_t *c, uint32_t request, xmlNode *message, uint32_t flags)
Definition: ipc_server.c:744
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:812
pcmk__client_t * pcmk__find_client(const qb_ipcs_connection_t *c)
Definition: ipc_server.c:59
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:781
size_t buffer_size
Definition: ipc_internal.h:109
int pcmk__ipc_send_iov(pcmk__client_t *c, struct iovec *iov, uint32_t flags)
Definition: ipc_server.c:665
unsigned int pid
Definition: ipc_internal.h:168
IPC commands for Pacemakerd.
IPC commands for Pacemaker controller.
bool pcmk__set_client_queue_max(pcmk__client_t *client, const char *qmax)
Definition: ipc_server.c:350
Client IPC connection accepted.
Definition: ipc_internal.h:157
#define HAVE_GNUTLS_GNUTLS_H
Definition: config.h:178
mainloop_io_t * source
Definition: ipc_internal.h:113
pcmk_pacemakerd_state
void pcmk__foreach_ipc_client(GHFunc func, gpointer user_data)
Definition: ipc_server.c:51
guint pcmk__ipc_client_count(void)
Definition: ipc_server.c:36
pcmk__action_result_t result
Definition: pcmk_fence.c:35
pcmk__client_t * pcmk__find_client_by_id(const char *id)
Definition: ipc_server.c:70
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:841
const char * pcmk__pcmkd_state_enum2friendly(enum pcmk_pacemakerd_state state)
IPC interface to Pacemaker daemons.
const char * pcmk__client_name(const pcmk__client_t *c)
Definition: ipc_server.c:98
Client uses plain IPC.
Definition: ipc_internal.h:131
const char * pcmk__client_type_str(uint64_t client_type)
Definition: ipc_common.c:96
pcmk__client_t * pcmk__new_unauth_client(void *key)
Allocate a new pcmk__client_t object and generate its ID.
Definition: ipc_server.c:209
Local client to be proxied.
Definition: ipc_internal.h:150
pcmk__client_flags
Definition: ipc_internal.h:125
void pcmk__drop_all_clients(qb_ipcs_service_t *s)
Definition: ipc_server.c:130
void pcmk__serve_fenced_ipc(qb_ipcs_service_t **ipcs, struct qb_ipcs_service_handlers *cb)
Definition: ipc_server.c:930
unsigned int queue_max
Definition: ipc_internal.h:190
struct pcmk__remote_s * remote
Definition: ipc_internal.h:187
Client IPC is proxied.
Definition: ipc_internal.h:144
void pcmk__serve_attrd_ipc(qb_ipcs_service_t **ipcs, struct qb_ipcs_service_handlers *cb)
Definition: ipc_server.c:908
void pcmk__serve_pacemakerd_ipc(qb_ipcs_service_t **ipcs, struct qb_ipcs_service_handlers *cb)
Definition: ipc_server.c:953
int pcmk__ipc_is_authentic_process_active(const char *name, uid_t refuid, gid_t refgid, pid_t *gotpid)
Definition: ipc_client.c:1483
unsigned int queue_backlog
Definition: ipc_internal.h:189
qb_ipcs_connection_t * ipcs
Definition: ipc_internal.h:185
uint64_t flags
Definition: remote.c:215
qb_ipcs_service_t * pcmk__serve_schedulerd_ipc(struct qb_ipcs_service_handlers *cb)
Definition: ipc_server.c:980
void pcmk__free_client(pcmk__client_t *c)
Definition: ipc_server.c:299
pcmk_controld_api_reply
Possible types of controller replies.
Definition: ipc_controld.h:31