pacemaker  2.1.0-7c3f660
Scalable High-Availability cluster resource manager
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ipc_internal.h
Go to the documentation of this file.
1 /*
2  * Copyright 2013-2021 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> // 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 
88 int 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;
101  size_t buffer_size;
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
124 # ifdef HAVE_GNUTLS_GNUTLS_H
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 
190 guint pcmk__ipc_client_count(void);
191 void pcmk__foreach_ipc_client(GHFunc func, gpointer user_data);
192 
193 void pcmk__client_cleanup(void);
194 
195 pcmk__client_t *pcmk__find_client(qb_ipcs_connection_t *c);
196 pcmk__client_t *pcmk__find_client_by_id(const char *id);
197 const char *pcmk__client_name(pcmk__client_t *c);
198 const char *pcmk__client_type_str(uint64_t client_type);
199 
201 pcmk__client_t *pcmk__new_client(qb_ipcs_connection_t *c, uid_t uid, gid_t gid);
203 void pcmk__drop_all_clients(qb_ipcs_service_t *s);
204 bool pcmk__set_client_queue_max(pcmk__client_t *client, const char *qmax);
205 
206 int pcmk__ipc_send_ack_as(const char *function, int line, pcmk__client_t *c,
207  uint32_t request, uint32_t flags, const char *tag,
208  crm_exit_t status);
209 #define pcmk__ipc_send_ack(c, req, flags, tag, st) \
210  pcmk__ipc_send_ack_as(__func__, __LINE__, (c), (req), (flags), (tag), (st))
211 
212 int pcmk__ipc_prepare_iov(uint32_t request, xmlNode *message,
213  uint32_t max_send_size,
214  struct iovec **result, ssize_t *bytes);
215 int pcmk__ipc_send_xml(pcmk__client_t *c, uint32_t request, xmlNode *message,
216  uint32_t flags);
217 int pcmk__ipc_send_iov(pcmk__client_t *c, struct iovec *iov, uint32_t flags);
218 xmlNode *pcmk__client_data2xml(pcmk__client_t *c, void *data,
219  uint32_t *id, uint32_t *flags);
220 
221 int pcmk__client_pid(qb_ipcs_connection_t *c);
222 
223 void pcmk__serve_attrd_ipc(qb_ipcs_service_t **ipcs,
224  struct qb_ipcs_service_handlers *cb);
225 void pcmk__serve_fenced_ipc(qb_ipcs_service_t **ipcs,
226  struct qb_ipcs_service_handlers *cb);
227 void pcmk__serve_pacemakerd_ipc(qb_ipcs_service_t **ipcs,
228  struct qb_ipcs_service_handlers *cb);
229 qb_ipcs_service_t *pcmk__serve_controld_ipc(struct qb_ipcs_service_handlers *cb);
230 
231 void pcmk__serve_based_ipc(qb_ipcs_service_t **ipcs_ro,
232  qb_ipcs_service_t **ipcs_rw,
233  qb_ipcs_service_t **ipcs_shm,
234  struct qb_ipcs_service_handlers *ro_cb,
235  struct qb_ipcs_service_handlers *rw_cb);
236 
237 void pcmk__stop_based_ipc(qb_ipcs_service_t *ipcs_ro,
238  qb_ipcs_service_t *ipcs_rw,
239  qb_ipcs_service_t *ipcs_shm);
240 
241 #ifdef __cplusplus
242 }
243 #endif
244 
245 #endif
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
xmlNode * pcmk__client_data2xml(pcmk__client_t *c, void *data, uint32_t *id, uint32_t *flags)
Definition: ipc_server.c:392
pcmk__client_t * pcmk__new_client(qb_ipcs_connection_t *c, uid_t uid, gid_t gid)
Definition: ipc_server.c:224
char data[0]
Definition: cpg.c:55
pcmk__client_t * pcmk__find_client(qb_ipcs_connection_t *c)
Definition: ipc_server.c:59
size_t buffer_offset
Definition: ipc_internal.h:102
uint64_t flags
Definition: ipc_internal.h:142
qb_ipcs_service_t * pcmk__serve_controld_ipc(struct qb_ipcs_service_handlers *cb)
Definition: ipc_server.c:873
struct mainloop_io_s mainloop_io_t
Definition: mainloop.h:32
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:855
void pcmk__client_cleanup(void)
Definition: ipc_server.c:116
GQueue * event_queue
Definition: ipc_internal.h:148
Wrappers for and extensions to glib mainloop.
int pcmk__client_pid(qb_ipcs_connection_t *c)
Definition: ipc_server.c:371
int pcmk__ipc_send_xml(pcmk__client_t *c, uint32_t request, xmlNode *message, uint32_t flags)
Definition: ipc_server.c:750
void gnutls_session_t
Definition: cib_remote.c:45
size_t buffer_size
Definition: ipc_internal.h:101
int pcmk__ipc_send_iov(pcmk__client_t *c, struct iovec *iov, uint32_t flags)
Definition: ipc_server.c:671
unsigned int pid
Definition: ipc_internal.h:137
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:788
bool pcmk__set_client_queue_max(pcmk__client_t *client, const char *qmax)
Definition: ipc_server.c:356
#define HAVE_GNUTLS_GNUTLS_H
Definition: config.h:170
mainloop_io_t * source
Definition: ipc_internal.h:105
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__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:821
IPC interface to Pacemaker daemons.
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:215
const char * pcmk__client_name(pcmk__client_t *c)
Definition: ipc_server.c:99
pcmk__client_flags
Definition: ipc_internal.h:118
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:908
unsigned int queue_max
Definition: ipc_internal.h:159
struct pcmk__remote_s * remote
Definition: ipc_internal.h:156
char * name
Definition: pcmk_fence.c:31
void pcmk__serve_attrd_ipc(qb_ipcs_service_t **ipcs, struct qb_ipcs_service_handlers *cb)
Definition: ipc_server.c:887
void pcmk__serve_pacemakerd_ipc(qb_ipcs_service_t **ipcs, struct qb_ipcs_service_handlers *cb)
Definition: ipc_server.c:930
int pcmk__ipc_is_authentic_process_active(const char *name, uid_t refuid, gid_t refgid, pid_t *gotpid)
Definition: ipc_client.c:1399
unsigned int queue_backlog
Definition: ipc_internal.h:158
qb_ipcs_connection_t * ipcs
Definition: ipc_internal.h:154
uint64_t flags
Definition: remote.c:149
void pcmk__free_client(pcmk__client_t *c)
Definition: ipc_server.c:305