pacemaker  2.1.5-b7adf64e51
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
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_pacemakerd.h> // enum pcmk_pacemakerd_state
33 #include <crm/common/mainloop.h> // mainloop_io_t
34 
35 /*
36  * XML attribute names used only by internal code
37  */
38 
39 #define PCMK__XA_IPC_PROTO_VERSION "ipc-protocol-version"
40 
41 /* denotes "non yieldable PID" on FreeBSD, or actual PID1 in scenarios that
42  require a delicate handling anyway (socket-based activation with systemd);
43  we can be reasonably sure that this PID is never possessed by the actual
44  child daemon, as it gets taken either by the proper init, or by pacemakerd
45  itself (i.e. this precludes anything else); note that value of zero
46  is meant to carry "unset" meaning, and better not to bet on/conditionalize
47  over signedness of pid_t */
48 #define PCMK__SPECIAL_PID 1
49 
50 // Timeout (in seconds) to use for IPC client sends, reply waits, etc.
51 #define PCMK__IPC_TIMEOUT 120
52 
53 #if defined(HAVE_GETPEEREID)
54 /* on FreeBSD, we don't want to expose "non-yieldable PID" (leading to
55  "IPC liveness check only") as its nominal representation, which could
56  cause confusion -- this is unambiguous as long as there's no
57  socket-based activation like with systemd (very improbable) */
58 #define PCMK__SPECIAL_PID_AS_0(p) (((p) == PCMK__SPECIAL_PID) ? 0 : (p))
59 #else
60 #define PCMK__SPECIAL_PID_AS_0(p) (p)
61 #endif
62 
95 int pcmk__ipc_is_authentic_process_active(const char *name, uid_t refuid,
96  gid_t refgid, pid_t *gotpid);
97 
98 
99 /*
100  * Server-related
101  */
102 
104 
106  /* Shared */
107  char *buffer;
108  size_t buffer_size;
113 
114  /* CIB-only */
115  char *token;
116 
117  /* TLS only */
118 # ifdef HAVE_GNUTLS_GNUTLS_H
119  gnutls_session_t *tls_session;
120 # endif
121 };
122 
124  // Lower 32 bits are reserved for server (not library) use
125 
126  // Next 8 bits are reserved for client type (sort of a cheap enum)
127 
129  pcmk__client_ipc = (UINT64_C(1) << 32),
130 
132  pcmk__client_tcp = (UINT64_C(1) << 33),
133 
134 # ifdef HAVE_GNUTLS_GNUTLS_H
136  pcmk__client_tls = (UINT64_C(1) << 34),
137 # endif
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 
157 # ifdef HAVE_GNUTLS_GNUTLS_H
159  pcmk__client_tls_handshake_complete = (UINT64_C(1) << 44),
160 # endif
161 };
162 
163 #define PCMK__CLIENT_TYPE(client) ((client)->flags & UINT64_C(0xff00000000))
164 
166  unsigned int pid;
167 
168  char *id;
169  char *name;
170  char *user;
171  uint64_t flags; // Group of pcmk__client_flags
172 
174  void *userdata;
175 
177  GQueue *event_queue;
178 
179  /* Depending on the client type, only some of the following will be
180  * populated/valid. @TODO Maybe convert to a union.
181  */
182 
183  qb_ipcs_connection_t *ipcs; /* IPC */
184 
185  struct pcmk__remote_s *remote; /* TCP/TLS */
186 
187  unsigned int queue_backlog; /* IPC queue length after last flush */
188  unsigned int queue_max; /* Evict client whose queue grows this big */
189 };
190 
191 #define pcmk__set_client_flags(client, flags_to_set) do { \
192  (client)->flags = pcmk__set_flags_as(__func__, __LINE__, \
193  LOG_TRACE, \
194  "Client", pcmk__client_name(client), \
195  (client)->flags, (flags_to_set), #flags_to_set); \
196  } while (0)
197 
198 #define pcmk__clear_client_flags(client, flags_to_clear) do { \
199  (client)->flags = pcmk__clear_flags_as(__func__, __LINE__, \
200  LOG_TRACE, \
201  "Client", pcmk__client_name(client), \
202  (client)->flags, (flags_to_clear), #flags_to_clear); \
203  } while (0)
204 
205 #define pcmk__set_ipc_flags(ipc_flags, ipc_name, flags_to_set) do { \
206  ipc_flags = pcmk__set_flags_as(__func__, __LINE__, LOG_TRACE, \
207  "IPC", (ipc_name), \
208  (ipc_flags), (flags_to_set), \
209  #flags_to_set); \
210  } while (0)
211 
212 #define pcmk__clear_ipc_flags(ipc_flags, ipc_name, flags_to_clear) do { \
213  ipc_flags = pcmk__clear_flags_as(__func__, __LINE__, LOG_TRACE, \
214  "IPC", (ipc_name), \
215  (ipc_flags), (flags_to_clear), \
216  #flags_to_clear); \
217  } while (0)
218 
219 guint pcmk__ipc_client_count(void);
220 void pcmk__foreach_ipc_client(GHFunc func, gpointer user_data);
221 
222 void pcmk__client_cleanup(void);
223 
224 pcmk__client_t *pcmk__find_client(const qb_ipcs_connection_t *c);
225 pcmk__client_t *pcmk__find_client_by_id(const char *id);
226 const char *pcmk__client_name(const pcmk__client_t *c);
227 const char *pcmk__client_type_str(uint64_t client_type);
228 
230 pcmk__client_t *pcmk__new_client(qb_ipcs_connection_t *c, uid_t uid, gid_t gid);
232 void pcmk__drop_all_clients(qb_ipcs_service_t *s);
233 bool pcmk__set_client_queue_max(pcmk__client_t *client, const char *qmax);
234 
235 xmlNode *pcmk__ipc_create_ack_as(const char *function, int line, uint32_t flags,
236  const char *tag, const char *ver, crm_exit_t status);
237 #define pcmk__ipc_create_ack(flags, tag, ver, st) \
238  pcmk__ipc_create_ack_as(__func__, __LINE__, (flags), (tag), (ver), (st))
239 
240 int pcmk__ipc_send_ack_as(const char *function, int line, pcmk__client_t *c,
241  uint32_t request, uint32_t flags, const char *tag,
242  const char *ver, crm_exit_t status);
243 #define pcmk__ipc_send_ack(c, req, flags, tag, ver, st) \
244  pcmk__ipc_send_ack_as(__func__, __LINE__, (c), (req), (flags), (tag), (ver), (st))
245 
246 int pcmk__ipc_prepare_iov(uint32_t request, xmlNode *message,
247  uint32_t max_send_size,
248  struct iovec **result, ssize_t *bytes);
249 int pcmk__ipc_send_xml(pcmk__client_t *c, uint32_t request, xmlNode *message,
250  uint32_t flags);
251 int pcmk__ipc_send_iov(pcmk__client_t *c, struct iovec *iov, uint32_t flags);
252 xmlNode *pcmk__client_data2xml(pcmk__client_t *c, void *data,
253  uint32_t *id, uint32_t *flags);
254 
255 int pcmk__client_pid(qb_ipcs_connection_t *c);
256 
257 void pcmk__serve_attrd_ipc(qb_ipcs_service_t **ipcs,
258  struct qb_ipcs_service_handlers *cb);
259 void pcmk__serve_fenced_ipc(qb_ipcs_service_t **ipcs,
260  struct qb_ipcs_service_handlers *cb);
261 void pcmk__serve_pacemakerd_ipc(qb_ipcs_service_t **ipcs,
262  struct qb_ipcs_service_handlers *cb);
263 qb_ipcs_service_t *pcmk__serve_schedulerd_ipc(struct qb_ipcs_service_handlers *cb);
264 qb_ipcs_service_t *pcmk__serve_controld_ipc(struct qb_ipcs_service_handlers *cb);
265 
266 void pcmk__serve_based_ipc(qb_ipcs_service_t **ipcs_ro,
267  qb_ipcs_service_t **ipcs_rw,
268  qb_ipcs_service_t **ipcs_shm,
269  struct qb_ipcs_service_handlers *ro_cb,
270  struct qb_ipcs_service_handlers *rw_cb);
271 
272 void pcmk__stop_based_ipc(qb_ipcs_service_t *ipcs_ro,
273  qb_ipcs_service_t *ipcs_rw,
274  qb_ipcs_service_t *ipcs_shm);
275 
276 static inline const char *
277 pcmk__ipc_sys_name(const char *ipc_name, const char *fallback)
278 {
279  return ipc_name ? ipc_name : ((crm_system_name ? crm_system_name : fallback));
280 }
281 
283 
284 #ifdef __cplusplus
285 }
286 #endif
287 
288 #endif
Client uses TCP connection.
Definition: ipc_internal.h:132
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 * name
Definition: cib.c:24
size_t buffer_offset
Definition: ipc_internal.h:109
uint64_t flags
Definition: ipc_internal.h:171
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
void pcmk__client_cleanup(void)
Definition: ipc_server.c:115
GQueue * event_queue
Definition: ipc_internal.h:177
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:145
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
void gnutls_session_t
Definition: cib_remote.c:42
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:108
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:166
IPC commands for Pacemakerd.
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:155
#define HAVE_GNUTLS_GNUTLS_H
Definition: config.h:181
mainloop_io_t * source
Definition: ipc_internal.h:112
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:129
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:148
pcmk__client_flags
Definition: ipc_internal.h:123
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:188
struct pcmk__remote_s * remote
Definition: ipc_internal.h:185
Client IPC is proxied.
Definition: ipc_internal.h:142
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:1458
unsigned int queue_backlog
Definition: ipc_internal.h:187
qb_ipcs_connection_t * ipcs
Definition: ipc_internal.h:183
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