pacemaker  2.0.5-ba59be712
Scalable High-Availability cluster resource manager
ipc_internal.h
Go to the documentation of this file.
1 /*
2  * Copyright 2013-2020 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 #if defined(US_AUTH_GETPEEREID)
44 /* on FreeBSD, we don't want to expose "non-yieldable PID" (leading to
45  "IPC liveness check only") as its nominal representation, which could
46  cause confusion -- this is unambiguous as long as there's no
47  socket-based activation like with systemd (very improbable) */
48 #define PCMK__SPECIAL_PID_AS_0(p) (((p) == PCMK__SPECIAL_PID) ? 0 : (p))
49 #else
50 #define PCMK__SPECIAL_PID_AS_0(p) (p)
51 #endif
52 
85 int pcmk__ipc_is_authentic_process_active(const char *name, uid_t refuid,
86  gid_t refgid, pid_t *gotpid);
87 
88 
89 /*
90  * Server-related
91  */
92 
94 
96  /* Shared */
97  char *buffer;
98  size_t buffer_size;
99  size_t buffer_offset;
103 
104  /* CIB-only */
106  char *token;
107 
108  /* TLS only */
109 # ifdef HAVE_GNUTLS_GNUTLS_H
110  gnutls_session_t *tls_session;
111  bool tls_handshake_complete;
112 # endif
113 };
114 
116  // Lower 32 bits are reserved for server (not library) use
117 
118  // Next 8 bits are reserved for client type (sort of a cheap enum)
119  pcmk__client_ipc = (UINT64_C(1) << 32), // Client uses plain IPC
120  pcmk__client_tcp = (UINT64_C(1) << 33), // Client uses TCP connection
121 # ifdef HAVE_GNUTLS_GNUTLS_H
122  pcmk__client_tls = (UINT64_C(1) << 34), // Client uses TCP with TLS
123 # endif
124 
125  // The rest are client attributes
126  pcmk__client_proxied = (UINT64_C(1) << 40), // Client IPC is proxied
127  pcmk__client_privileged = (UINT64_C(1) << 41), // root or cluster user
128  pcmk__client_to_proxy = (UINT64_C(1) << 42), // Local client to be proxied
129 };
130 
131 #define PCMK__CLIENT_TYPE(client) ((client)->flags & UINT64_C(0xff00000000))
132 
134  unsigned int pid;
135 
136  uid_t uid;
137  gid_t gid;
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", ((client)->name? (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", ((client)->name? (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 qb_ipcs_service_t *pcmk__serve_controld_ipc(struct qb_ipcs_service_handlers *cb);
228 
229 void pcmk__serve_based_ipc(qb_ipcs_service_t **ipcs_ro,
230  qb_ipcs_service_t **ipcs_rw,
231  qb_ipcs_service_t **ipcs_shm,
232  struct qb_ipcs_service_handlers *ro_cb,
233  struct qb_ipcs_service_handlers *rw_cb);
234 
235 void pcmk__stop_based_ipc(qb_ipcs_service_t *ipcs_ro,
236  qb_ipcs_service_t *ipcs_rw,
237  qb_ipcs_service_t *ipcs_shm);
238 
239 #ifdef __cplusplus
240 }
241 #endif
242 
243 #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:577
xmlNode * pcmk__client_data2xml(pcmk__client_t *c, void *data, uint32_t *id, uint32_t *flags)
Definition: ipc_server.c:383
pcmk__client_t * pcmk__new_client(qb_ipcs_connection_t *c, uid_t uid, gid_t gid)
Definition: ipc_server.c:214
pcmk__client_t * pcmk__find_client(qb_ipcs_connection_t *c)
Definition: ipc_server.c:59
size_t buffer_offset
Definition: ipc_internal.h:99
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:864
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:846
void pcmk__client_cleanup(void)
Definition: ipc_server.c:104
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:362
int pcmk__ipc_send_xml(pcmk__client_t *c, uint32_t request, xmlNode *message, uint32_t flags)
Definition: ipc_server.c:741
void gnutls_session_t
Definition: cib_remote.c:44
size_t buffer_size
Definition: ipc_internal.h:98
int pcmk__ipc_send_iov(pcmk__client_t *c, struct iovec *iov, uint32_t flags)
Definition: ipc_server.c:662
unsigned int pid
Definition: ipc_internal.h:134
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:779
bool pcmk__set_client_queue_max(pcmk__client_t *client, const char *qmax)
Definition: ipc_server.c:346
#define HAVE_GNUTLS_GNUTLS_H
Definition: config.h:179
mainloop_io_t * source
Definition: ipc_internal.h:102
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
char data[0]
Definition: internal.h:90
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:812
IPC interface to Pacemaker daemons.
const char * pcmk__client_type_str(uint64_t client_type)
Definition: ipc_common.c:90
pcmk__client_t * pcmk__new_unauth_client(void *key)
Allocate a new pcmk__client_t object and generate its ID.
Definition: ipc_server.c:205
const char * pcmk__client_name(pcmk__client_t *c)
Definition: ipc_server.c:90
pcmk__client_flags
Definition: ipc_internal.h:115
void pcmk__drop_all_clients(qb_ipcs_service_t *s)
Definition: ipc_server.c:118
void pcmk__serve_fenced_ipc(qb_ipcs_service_t **ipcs, struct qb_ipcs_service_handlers *cb)
Definition: ipc_server.c:899
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:878
int pcmk__ipc_is_authentic_process_active(const char *name, uid_t refuid, gid_t refgid, pid_t *gotpid)
Definition: ipc_client.c:1356
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:295