pacemaker  3.0.0-d8340737c4
Scalable High-Availability cluster resource manager
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__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/common/ipc.h>
26 #include <crm/common/ipc_controld.h> // pcmk_controld_api_reply
27 #include <crm/common/ipc_pacemakerd.h> // pcmk_pacemakerd_{api_reply,state}
28 #include <crm/common/mainloop.h> // mainloop_io_t
29 
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
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(HAVE_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 
88 int pcmk__ipc_is_authentic_process_active(const char *name, uid_t refuid,
89  gid_t refgid, pid_t *gotpid);
90 
92 int pcmk__ipc_fd(crm_ipc_t *ipc, int *fd);
93 int pcmk__connect_ipc(pcmk_ipc_api_t *api, enum pcmk_ipc_dispatch dispatch_type,
94  int attempts);
95 
96 /*
97  * Server-related
98  */
99 
101 
103  /* Shared */
104  char *buffer;
105  size_t buffer_size;
110  time_t uptime;
111  char *start_state;
112 
113  /* CIB-only */
114  char *token;
115 
116  /* TLS only */
117  gnutls_session_t tls_session;
118 };
119 
121  // Lower 32 bits are reserved for server (not library) use
122 
123  // Next 8 bits are reserved for client type (sort of a cheap enum)
124 
126  pcmk__client_ipc = (UINT64_C(1) << 32),
127 
129  pcmk__client_tcp = (UINT64_C(1) << 33),
130 
132  pcmk__client_tls = (UINT64_C(1) << 34),
133 
134  // The rest are client attributes
135 
137  pcmk__client_proxied = (UINT64_C(1) << 40),
138 
140  pcmk__client_privileged = (UINT64_C(1) << 41),
141 
143  pcmk__client_to_proxy = (UINT64_C(1) << 42),
144 
150  pcmk__client_authenticated = (UINT64_C(1) << 43),
151 
153  pcmk__client_tls_handshake_complete = (UINT64_C(1) << 44),
154 };
155 
156 #define PCMK__CLIENT_TYPE(client) ((client)->flags & UINT64_C(0xff00000000))
157 
159  unsigned int pid;
160 
161  char *id;
162  char *name;
163  char *user;
164  uint64_t flags; // Group of pcmk__client_flags
165 
167  void *userdata;
168 
170  GQueue *event_queue;
171 
172  /* Depending on the client type, only some of the following will be
173  * populated/valid. @TODO Maybe convert to a union.
174  */
175 
176  qb_ipcs_connection_t *ipcs; /* IPC */
177 
178  struct pcmk__remote_s *remote; /* TCP/TLS */
179 
180  unsigned int queue_backlog; /* IPC queue length after last flush */
181  unsigned int queue_max; /* Evict client whose queue grows this big */
182 };
183 
184 #define pcmk__set_client_flags(client, flags_to_set) do { \
185  (client)->flags = pcmk__set_flags_as(__func__, __LINE__, \
186  LOG_TRACE, \
187  "Client", pcmk__client_name(client), \
188  (client)->flags, (flags_to_set), #flags_to_set); \
189  } while (0)
190 
191 #define pcmk__clear_client_flags(client, flags_to_clear) do { \
192  (client)->flags = pcmk__clear_flags_as(__func__, __LINE__, \
193  LOG_TRACE, \
194  "Client", pcmk__client_name(client), \
195  (client)->flags, (flags_to_clear), #flags_to_clear); \
196  } while (0)
197 
198 #define pcmk__set_ipc_flags(ipc_flags, ipc_name, flags_to_set) do { \
199  ipc_flags = pcmk__set_flags_as(__func__, __LINE__, LOG_TRACE, \
200  "IPC", (ipc_name), \
201  (ipc_flags), (flags_to_set), \
202  #flags_to_set); \
203  } while (0)
204 
205 #define pcmk__clear_ipc_flags(ipc_flags, ipc_name, flags_to_clear) do { \
206  ipc_flags = pcmk__clear_flags_as(__func__, __LINE__, LOG_TRACE, \
207  "IPC", (ipc_name), \
208  (ipc_flags), (flags_to_clear), \
209  #flags_to_clear); \
210  } while (0)
211 
212 guint pcmk__ipc_client_count(void);
213 void pcmk__foreach_ipc_client(GHFunc func, gpointer user_data);
214 
215 void pcmk__client_cleanup(void);
216 
217 pcmk__client_t *pcmk__find_client(const qb_ipcs_connection_t *c);
218 pcmk__client_t *pcmk__find_client_by_id(const char *id);
219 const char *pcmk__client_name(const pcmk__client_t *c);
220 const char *pcmk__client_type_str(uint64_t client_type);
221 
223 pcmk__client_t *pcmk__new_client(qb_ipcs_connection_t *c, uid_t uid, gid_t gid);
225 void pcmk__drop_all_clients(qb_ipcs_service_t *s);
226 void pcmk__set_client_queue_max(pcmk__client_t *client, const char *qmax);
227 
228 xmlNode *pcmk__ipc_create_ack_as(const char *function, int line, uint32_t flags,
229  const char *tag, const char *ver, crm_exit_t status);
230 #define pcmk__ipc_create_ack(flags, tag, ver, st) \
231  pcmk__ipc_create_ack_as(__func__, __LINE__, (flags), (tag), (ver), (st))
232 
233 int pcmk__ipc_send_ack_as(const char *function, int line, pcmk__client_t *c,
234  uint32_t request, uint32_t flags, const char *tag,
235  const char *ver, crm_exit_t status);
236 #define pcmk__ipc_send_ack(c, req, flags, tag, ver, st) \
237  pcmk__ipc_send_ack_as(__func__, __LINE__, (c), (req), (flags), (tag), (ver), (st))
238 
239 int pcmk__ipc_prepare_iov(uint32_t request, const xmlNode *message,
240  uint32_t max_send_size,
241  struct iovec **result, ssize_t *bytes);
242 int pcmk__ipc_send_xml(pcmk__client_t *c, uint32_t request,
243  const xmlNode *message, uint32_t flags);
244 int pcmk__ipc_send_iov(pcmk__client_t *c, struct iovec *iov, uint32_t flags);
245 xmlNode *pcmk__client_data2xml(pcmk__client_t *c, void *data,
246  uint32_t *id, uint32_t *flags);
247 
248 int pcmk__client_pid(qb_ipcs_connection_t *c);
249 
250 void pcmk__serve_attrd_ipc(qb_ipcs_service_t **ipcs,
251  struct qb_ipcs_service_handlers *cb);
252 void pcmk__serve_fenced_ipc(qb_ipcs_service_t **ipcs,
253  struct qb_ipcs_service_handlers *cb);
254 void pcmk__serve_pacemakerd_ipc(qb_ipcs_service_t **ipcs,
255  struct qb_ipcs_service_handlers *cb);
256 qb_ipcs_service_t *pcmk__serve_schedulerd_ipc(struct qb_ipcs_service_handlers *cb);
257 qb_ipcs_service_t *pcmk__serve_controld_ipc(struct qb_ipcs_service_handlers *cb);
258 
259 void pcmk__serve_based_ipc(qb_ipcs_service_t **ipcs_ro,
260  qb_ipcs_service_t **ipcs_rw,
261  qb_ipcs_service_t **ipcs_shm,
262  struct qb_ipcs_service_handlers *ro_cb,
263  struct qb_ipcs_service_handlers *rw_cb);
264 
265 void pcmk__stop_based_ipc(qb_ipcs_service_t *ipcs_ro,
266  qb_ipcs_service_t *ipcs_rw,
267  qb_ipcs_service_t *ipcs_shm);
268 
269 static inline const char *
270 pcmk__ipc_sys_name(const char *ipc_name, const char *fallback)
271 {
272  return ipc_name ? ipc_name : ((crm_system_name ? crm_system_name : fallback));
273 }
274 
276 
279 
280 #ifdef __cplusplus
281 }
282 #endif
283 
284 #endif // PCMK__CRM_COMMON_IPC_INTERNAL__H
Client uses TCP connection.
Definition: ipc_internal.h:129
xmlNode * pcmk__client_data2xml(pcmk__client_t *c, void *data, uint32_t *id, uint32_t *flags)
Definition: ipc_server.c:396
pcmk__client_t * pcmk__new_client(qb_ipcs_connection_t *c, uid_t uid, gid_t gid)
Definition: ipc_server.c:209
char data[0]
Definition: cpg.c:58
const char * pcmk__pcmkd_api_reply2str(enum pcmk_pacemakerd_api_reply reply)
const char * name
Definition: cib.c:26
const char * pcmk__controld_api_reply2str(enum pcmk_controld_api_reply reply)
Definition: ipc_controld.c:45
void pcmk__set_client_queue_max(pcmk__client_t *client, const char *qmax)
Definition: ipc_server.c:339
size_t buffer_offset
Definition: ipc_internal.h:106
uint64_t flags
Definition: ipc_internal.h:164
qb_ipcs_service_t * pcmk__serve_controld_ipc(struct qb_ipcs_service_handlers *cb)
Definition: ipc_server.c:919
int pcmk__ipc_send_xml(pcmk__client_t *c, uint32_t request, const xmlNode *message, uint32_t flags)
Definition: ipc_server.c:765
struct mainloop_io_s mainloop_io_t
Definition: mainloop.h:41
Client TLS handshake is complete.
Definition: ipc_internal.h:153
char * crm_system_name
Definition: utils.c:44
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:592
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:901
pcmk_pacemakerd_api_reply
Possible types of pacemakerd replies.
void pcmk__client_cleanup(void)
Definition: ipc_server.c:115
int pcmk__connect_ipc(pcmk_ipc_api_t *api, enum pcmk_ipc_dispatch dispatch_type, int attempts)
Definition: ipc_client.c:491
GQueue * event_queue
Definition: ipc_internal.h:170
Wrappers for and extensions to glib mainloop.
int pcmk__client_pid(qb_ipcs_connection_t *c)
Definition: ipc_server.c:375
Client is run by root or cluster user.
Definition: ipc_internal.h:140
int pcmk__connect_generic_ipc(crm_ipc_t *ipc)
Definition: ipc_client.c:890
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:835
pcmk__client_t * pcmk__find_client(const qb_ipcs_connection_t *c)
Definition: ipc_server.c:59
struct crm_ipc_s crm_ipc_t
Definition: ipc.h:151
char * start_state
Definition: ipc_internal.h:111
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:804
size_t buffer_size
Definition: ipc_internal.h:105
int pcmk__ipc_send_iov(pcmk__client_t *c, struct iovec *iov, uint32_t flags)
Definition: ipc_server.c:686
unsigned int pid
Definition: ipc_internal.h:159
IPC commands for Pacemakerd.
Client uses TCP with TLS.
Definition: ipc_internal.h:132
IPC commands for Pacemaker controller.
Client IPC connection accepted.
Definition: ipc_internal.h:150
mainloop_io_t * source
Definition: ipc_internal.h:109
pcmk_pacemakerd_state
pcmk_ipc_dispatch
How IPC replies should be dispatched.
Definition: ipc.h:74
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:37
int pcmk__ipc_fd(crm_ipc_t *ipc, int *fd)
Definition: ipc_client.c:1001
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:867
const char * pcmk__pcmkd_state_enum2friendly(enum pcmk_pacemakerd_state state)
gnutls_session_t tls_session
Definition: ipc_internal.h:117
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:126
const char * pcmk__client_type_str(uint64_t client_type)
Definition: ipc_common.c:122
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
Local client to be proxied.
Definition: ipc_internal.h:143
pcmk__client_flags
Definition: ipc_internal.h:120
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:957
unsigned int queue_max
Definition: ipc_internal.h:181
struct pcmk__remote_s * remote
Definition: ipc_internal.h:178
Client IPC is proxied.
Definition: ipc_internal.h:137
void pcmk__serve_attrd_ipc(qb_ipcs_service_t **ipcs, struct qb_ipcs_service_handlers *cb)
Definition: ipc_server.c:934
void pcmk__serve_pacemakerd_ipc(qb_ipcs_service_t **ipcs, struct qb_ipcs_service_handlers *cb)
Definition: ipc_server.c:980
int pcmk__ipc_is_authentic_process_active(const char *name, uid_t refuid, gid_t refgid, pid_t *gotpid)
Definition: ipc_client.c:1549
unsigned int queue_backlog
Definition: ipc_internal.h:180
qb_ipcs_connection_t * ipcs
Definition: ipc_internal.h:176
uint64_t flags
Definition: remote.c:211
qb_ipcs_service_t * pcmk__serve_schedulerd_ipc(struct qb_ipcs_service_handlers *cb)
Definition: ipc_server.c:1007
void pcmk__free_client(pcmk__client_t *c)
Definition: ipc_server.c:284
pcmk_controld_api_reply
Possible types of controller replies.
Definition: ipc_controld.h:31