pacemaker  2.0.5-ba59be712
Scalable High-Availability cluster resource manager
ipc_server.c
Go to the documentation of this file.
1 /*
2  * Copyright 2004-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 #include <crm_internal.h>
11 
12 #include <stdio.h>
13 #include <errno.h>
14 #include <bzlib.h>
15 #include <sys/stat.h>
16 #include <sys/types.h>
17 
18 #include <crm/crm.h>
19 #include <crm/msg_xml.h>
20 #include <crm/common/ipc.h>
22 #include "crmcommon_private.h"
23 
24 /* Evict clients whose event queue grows this large (by default) */
25 #define PCMK_IPC_DEFAULT_QUEUE_MAX 500
26 
27 static GHashTable *client_connections = NULL;
28 
35 guint
37 {
38  return client_connections? g_hash_table_size(client_connections) : 0;
39 }
40 
50 void
51 pcmk__foreach_ipc_client(GHFunc func, gpointer user_data)
52 {
53  if ((func != NULL) && (client_connections != NULL)) {
54  g_hash_table_foreach(client_connections, func, user_data);
55  }
56 }
57 
59 pcmk__find_client(qb_ipcs_connection_t *c)
60 {
61  if (client_connections) {
62  return g_hash_table_lookup(client_connections, c);
63  }
64 
65  crm_trace("No client found for %p", c);
66  return NULL;
67 }
68 
70 pcmk__find_client_by_id(const char *id)
71 {
72  gpointer key;
73  pcmk__client_t *client;
74  GHashTableIter iter;
75 
76  if (client_connections && id) {
77  g_hash_table_iter_init(&iter, client_connections);
78  while (g_hash_table_iter_next(&iter, &key, (gpointer *) & client)) {
79  if (strcmp(client->id, id) == 0) {
80  return client;
81  }
82  }
83  }
84 
85  crm_trace("No client found with id=%s", id);
86  return NULL;
87 }
88 
89 const char *
91 {
92  if (c == NULL) {
93  return "null";
94  } else if (c->name == NULL && c->id == NULL) {
95  return "unknown";
96  } else if (c->name == NULL) {
97  return c->id;
98  } else {
99  return c->name;
100  }
101 }
102 
103 void
105 {
106  if (client_connections != NULL) {
107  int active = g_hash_table_size(client_connections);
108 
109  if (active) {
110  crm_err("Exiting with %d active IPC client%s",
111  active, pcmk__plural_s(active));
112  }
113  g_hash_table_destroy(client_connections); client_connections = NULL;
114  }
115 }
116 
117 void
118 pcmk__drop_all_clients(qb_ipcs_service_t *service)
119 {
120  qb_ipcs_connection_t *c = NULL;
121 
122  if (service == NULL) {
123  return;
124  }
125 
126  c = qb_ipcs_connection_first_get(service);
127 
128  while (c != NULL) {
129  qb_ipcs_connection_t *last = c;
130 
131  c = qb_ipcs_connection_next_get(service, last);
132 
133  /* There really shouldn't be anyone connected at this point */
134  crm_notice("Disconnecting client %p, pid=%d...",
135  last, pcmk__client_pid(last));
136  qb_ipcs_disconnect(last);
137  qb_ipcs_connection_unref(last);
138  }
139 }
140 
151 static pcmk__client_t *
152 client_from_connection(qb_ipcs_connection_t *c, void *key, uid_t uid_client)
153 {
154  pcmk__client_t *client = calloc(1, sizeof(pcmk__client_t));
155 
156  if (client == NULL) {
157  crm_perror(LOG_ERR, "Allocating client");
158  return NULL;
159  }
160 
161  if (c) {
162 #if ENABLE_ACL
163  client->user = pcmk__uid2username(uid_client);
164  if (client->user == NULL) {
165  client->user = strdup("#unprivileged");
166  CRM_CHECK(client->user != NULL, free(client); return NULL);
167  crm_err("Unable to enforce ACLs for user ID %d, assuming unprivileged",
168  uid_client);
169  }
170 #endif
171  client->ipcs = c;
173  client->pid = pcmk__client_pid(c);
174  if (key == NULL) {
175  key = c;
176  }
177  }
178 
179  client->id = crm_generate_uuid();
180  if (client->id == NULL) {
181  crm_err("Could not generate UUID for client");
182  free(client->user);
183  free(client);
184  return NULL;
185  }
186  if (key == NULL) {
187  key = client->id;
188  }
189  if (client_connections == NULL) {
190  crm_trace("Creating IPC client table");
191  client_connections = g_hash_table_new(g_direct_hash, g_direct_equal);
192  }
193  g_hash_table_insert(client_connections, key, client);
194  return client;
195 }
196 
206 {
207  pcmk__client_t *client = client_from_connection(NULL, key, 0);
208 
209  CRM_ASSERT(client != NULL);
210  return client;
211 }
212 
214 pcmk__new_client(qb_ipcs_connection_t *c, uid_t uid_client, gid_t gid_client)
215 {
216  gid_t uid_cluster = 0;
217  gid_t gid_cluster = 0;
218 
219  pcmk__client_t *client = NULL;
220 
221  CRM_CHECK(c != NULL, return NULL);
222 
223  if (pcmk_daemon_user(&uid_cluster, &gid_cluster) < 0) {
224  static bool need_log = TRUE;
225 
226  if (need_log) {
227  crm_warn("Could not find user and group IDs for user %s",
229  need_log = FALSE;
230  }
231  }
232 
233  if (uid_client != 0) {
234  crm_trace("Giving group %u access to new IPC connection", gid_cluster);
235  /* Passing -1 to chown(2) means don't change */
236  qb_ipcs_connection_auth_set(c, -1, gid_cluster, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
237  }
238 
239  /* TODO: Do our own auth checking, return NULL if unauthorized */
240  client = client_from_connection(c, NULL, uid_client);
241  if (client == NULL) {
242  return NULL;
243  }
244 
245  if ((uid_client == 0) || (uid_client == uid_cluster)) {
246  /* Remember when a connection came from root or hacluster */
248  }
249 
250  crm_debug("New IPC client %s for PID %u with uid %d and gid %d",
251  client->id, client->pid, uid_client, gid_client);
252  return client;
253 }
254 
255 static struct iovec *
256 pcmk__new_ipc_event(void)
257 {
258  struct iovec *iov = calloc(2, sizeof(struct iovec));
259 
260  CRM_ASSERT(iov != NULL);
261  return iov;
262 }
263 
269 void
270 pcmk_free_ipc_event(struct iovec *event)
271 {
272  if (event != NULL) {
273  free(event[0].iov_base);
274  free(event[1].iov_base);
275  free(event);
276  }
277 }
278 
279 static void
280 free_event(gpointer data)
281 {
282  pcmk_free_ipc_event((struct iovec *) data);
283 }
284 
285 static void
286 add_event(pcmk__client_t *c, struct iovec *iov)
287 {
288  if (c->event_queue == NULL) {
289  c->event_queue = g_queue_new();
290  }
291  g_queue_push_tail(c->event_queue, iov);
292 }
293 
294 void
296 {
297  if (c == NULL) {
298  return;
299  }
300 
301  if (client_connections) {
302  if (c->ipcs) {
303  crm_trace("Destroying %p/%p (%d remaining)",
304  c, c->ipcs, g_hash_table_size(client_connections) - 1);
305  g_hash_table_remove(client_connections, c->ipcs);
306 
307  } else {
308  crm_trace("Destroying remote connection %p (%d remaining)",
309  c, g_hash_table_size(client_connections) - 1);
310  g_hash_table_remove(client_connections, c->id);
311  }
312  }
313 
314  if (c->event_timer) {
315  g_source_remove(c->event_timer);
316  }
317 
318  if (c->event_queue) {
319  crm_debug("Destroying %d events", g_queue_get_length(c->event_queue));
320  g_queue_free_full(c->event_queue, free_event);
321  }
322 
323  free(c->id);
324  free(c->name);
325  free(c->user);
326  if (c->remote) {
327  if (c->remote->auth_timeout) {
328  g_source_remove(c->remote->auth_timeout);
329  }
330  free(c->remote->buffer);
331  free(c->remote);
332  }
333  free(c);
334 }
335 
345 bool
346 pcmk__set_client_queue_max(pcmk__client_t *client, const char *qmax)
347 {
348  if (pcmk_is_set(client->flags, pcmk__client_privileged)) {
349  long long qmax_int;
350 
351  errno = 0;
352  qmax_int = crm_parse_ll(qmax, NULL);
353  if ((errno == 0) && (qmax_int > 0)) {
354  client->queue_max = (unsigned int) qmax_int;
355  return TRUE;
356  }
357  }
358  return FALSE;
359 }
360 
361 int
362 pcmk__client_pid(qb_ipcs_connection_t *c)
363 {
364  struct qb_ipcs_connection_stats stats;
365 
366  stats.client_pid = 0;
367  qb_ipcs_connection_stats_get(c, &stats, 0);
368  return stats.client_pid;
369 }
370 
382 xmlNode *
383 pcmk__client_data2xml(pcmk__client_t *c, void *data, uint32_t *id,
384  uint32_t *flags)
385 {
386  xmlNode *xml = NULL;
387  char *uncompressed = NULL;
388  char *text = ((char *)data) + sizeof(pcmk__ipc_header_t);
389  pcmk__ipc_header_t *header = data;
390 
391  if (!pcmk__valid_ipc_header(header)) {
392  return NULL;
393  }
394 
395  if (id) {
396  *id = ((struct qb_ipc_response_header *)data)->id;
397  }
398  if (flags) {
399  *flags = header->flags;
400  }
401 
402  if (pcmk_is_set(header->flags, crm_ipc_proxied)) {
403  /* Mark this client as being the endpoint of a proxy connection.
404  * Proxy connections responses are sent on the event channel, to avoid
405  * blocking the controller serving as proxy.
406  */
408  }
409 
410  if (header->size_compressed) {
411  int rc = 0;
412  unsigned int size_u = 1 + header->size_uncompressed;
413  uncompressed = calloc(1, size_u);
414 
415  crm_trace("Decompressing message data %u bytes into %u bytes",
416  header->size_compressed, size_u);
417 
418  rc = BZ2_bzBuffToBuffDecompress(uncompressed, &size_u, text, header->size_compressed, 1, 0);
419  text = uncompressed;
420 
421  if (rc != BZ_OK) {
422  crm_err("Decompression failed: %s " CRM_XS " bzerror=%d",
423  bz2_strerror(rc), rc);
424  free(uncompressed);
425  return NULL;
426  }
427  }
428 
429  CRM_ASSERT(text[header->size_uncompressed - 1] == 0);
430 
431  xml = string2xml(text);
432  crm_log_xml_trace(xml, "[IPC received]");
433 
434  free(uncompressed);
435  return xml;
436 }
437 
438 static int crm_ipcs_flush_events(pcmk__client_t *c);
439 
440 static gboolean
441 crm_ipcs_flush_events_cb(gpointer data)
442 {
443  pcmk__client_t *c = data;
444 
445  c->event_timer = 0;
446  crm_ipcs_flush_events(c);
447  return FALSE;
448 }
449 
457 static inline void
458 delay_next_flush(pcmk__client_t *c, unsigned int queue_len)
459 {
460  /* Delay a maximum of 1.5 seconds */
461  guint delay = (queue_len < 5)? (1000 + 100 * queue_len) : 1500;
462 
463  c->event_timer = g_timeout_add(delay, crm_ipcs_flush_events_cb, c);
464 }
465 
474 static int
475 crm_ipcs_flush_events(pcmk__client_t *c)
476 {
477  int rc = pcmk_rc_ok;
478  ssize_t qb_rc = 0;
479  unsigned int sent = 0;
480  unsigned int queue_len = 0;
481 
482  if (c == NULL) {
483  return rc;
484 
485  } else if (c->event_timer) {
486  /* There is already a timer, wait until it goes off */
487  crm_trace("Timer active for %p - %d", c->ipcs, c->event_timer);
488  return rc;
489  }
490 
491  if (c->event_queue) {
492  queue_len = g_queue_get_length(c->event_queue);
493  }
494  while (sent < 100) {
495  pcmk__ipc_header_t *header = NULL;
496  struct iovec *event = NULL;
497 
498  if (c->event_queue) {
499  // We don't pop unless send is successful
500  event = g_queue_peek_head(c->event_queue);
501  }
502  if (event == NULL) { // Queue is empty
503  break;
504  }
505 
506  qb_rc = qb_ipcs_event_sendv(c->ipcs, event, 2);
507  if (qb_rc < 0) {
508  rc = (int) -qb_rc;
509  break;
510  }
511  event = g_queue_pop_head(c->event_queue);
512 
513  sent++;
514  header = event[0].iov_base;
515  if (header->size_compressed) {
516  crm_trace("Event %d to %p[%d] (%lld compressed bytes) sent",
517  header->qb.id, c->ipcs, c->pid, (long long) qb_rc);
518  } else {
519  crm_trace("Event %d to %p[%d] (%lld bytes) sent: %.120s",
520  header->qb.id, c->ipcs, c->pid, (long long) qb_rc,
521  (char *) (event[1].iov_base));
522  }
523  pcmk_free_ipc_event(event);
524  }
525 
526  queue_len -= sent;
527  if (sent > 0 || queue_len) {
528  crm_trace("Sent %d events (%d remaining) for %p[%d]: %s (%lld)",
529  sent, queue_len, c->ipcs, c->pid,
530  pcmk_rc_str(rc), (long long) qb_rc);
531  }
532 
533  if (queue_len) {
534 
535  /* Allow clients to briefly fall behind on processing incoming messages,
536  * but drop completely unresponsive clients so the connection doesn't
537  * consume resources indefinitely.
538  */
539  if (queue_len > QB_MAX(c->queue_max, PCMK_IPC_DEFAULT_QUEUE_MAX)) {
540  if ((c->queue_backlog <= 1) || (queue_len < c->queue_backlog)) {
541  /* Don't evict for a new or shrinking backlog */
542  crm_warn("Client with process ID %u has a backlog of %u messages "
543  CRM_XS " %p", c->pid, queue_len, c->ipcs);
544  } else {
545  crm_err("Evicting client with process ID %u due to backlog of %u messages "
546  CRM_XS " %p", c->pid, queue_len, c->ipcs);
547  c->queue_backlog = 0;
548  qb_ipcs_disconnect(c->ipcs);
549  return rc;
550  }
551  }
552 
553  c->queue_backlog = queue_len;
554  delay_next_flush(c, queue_len);
555 
556  } else {
557  /* Event queue is empty, there is no backlog */
558  c->queue_backlog = 0;
559  }
560 
561  return rc;
562 }
563 
576 int
577 pcmk__ipc_prepare_iov(uint32_t request, xmlNode *message,
578  uint32_t max_send_size, struct iovec **result,
579  ssize_t *bytes)
580 {
581  static unsigned int biggest = 0;
582  struct iovec *iov;
583  unsigned int total = 0;
584  char *compressed = NULL;
585  char *buffer = NULL;
586  pcmk__ipc_header_t *header = NULL;
587 
588  if ((message == NULL) || (result == NULL)) {
589  return EINVAL;
590  }
591 
592  header = calloc(1, sizeof(pcmk__ipc_header_t));
593  if (header == NULL) {
594  return ENOMEM; /* errno mightn't be set by allocator */
595  }
596 
597  buffer = dump_xml_unformatted(message);
598 
599  if (max_send_size == 0) {
600  max_send_size = crm_ipc_default_buffer_size();
601  }
602  CRM_LOG_ASSERT(max_send_size != 0);
603 
604  *result = NULL;
605  iov = pcmk__new_ipc_event();
606  iov[0].iov_len = sizeof(pcmk__ipc_header_t);
607  iov[0].iov_base = header;
608 
609  header->version = PCMK__IPC_VERSION;
610  header->size_uncompressed = 1 + strlen(buffer);
611  total = iov[0].iov_len + header->size_uncompressed;
612 
613  if (total < max_send_size) {
614  iov[1].iov_base = buffer;
615  iov[1].iov_len = header->size_uncompressed;
616 
617  } else {
618  unsigned int new_size = 0;
619 
620  if (pcmk__compress(buffer, (unsigned int) header->size_uncompressed,
621  (unsigned int) max_send_size, &compressed,
622  &new_size) == pcmk_rc_ok) {
623 
624  pcmk__set_ipc_flags(header->flags, "send data", crm_ipc_compressed);
625  header->size_compressed = new_size;
626 
627  iov[1].iov_len = header->size_compressed;
628  iov[1].iov_base = compressed;
629 
630  free(buffer);
631 
632  biggest = QB_MAX(header->size_compressed, biggest);
633 
634  } else {
635  crm_log_xml_trace(message, "EMSGSIZE");
636  biggest = QB_MAX(header->size_uncompressed, biggest);
637 
638  crm_err("Could not compress %u-byte message into less than IPC "
639  "limit of %u bytes; set PCMK_ipc_buffer to higher value "
640  "(%u bytes suggested)",
641  header->size_uncompressed, max_send_size, 4 * biggest);
642 
643  free(compressed);
644  free(buffer);
645  pcmk_free_ipc_event(iov);
646  return EMSGSIZE;
647  }
648  }
649 
650  header->qb.size = iov[0].iov_len + iov[1].iov_len;
651  header->qb.id = (int32_t)request; /* Replying to a specific request */
652 
653  *result = iov;
654  CRM_ASSERT(header->qb.size > 0);
655  if (bytes != NULL) {
656  *bytes = header->qb.size;
657  }
658  return pcmk_rc_ok;
659 }
660 
661 int
662 pcmk__ipc_send_iov(pcmk__client_t *c, struct iovec *iov, uint32_t flags)
663 {
664  int rc = pcmk_rc_ok;
665  static uint32_t id = 1;
666  pcmk__ipc_header_t *header = iov[0].iov_base;
667 
668  if (c->flags & pcmk__client_proxied) {
669  /* _ALL_ replies to proxied connections need to be sent as events */
671  /* The proxied flag lets us know this was originally meant to be a
672  * response, even though we're sending it over the event channel.
673  */
674  pcmk__set_ipc_flags(flags, "server event",
677  }
678  }
679 
680  pcmk__set_ipc_flags(header->flags, "server event", flags);
681  if (flags & crm_ipc_server_event) {
682  header->qb.id = id++; /* We don't really use it, but doesn't hurt to set one */
683 
684  if (flags & crm_ipc_server_free) {
685  crm_trace("Sending the original to %p[%d]", c->ipcs, c->pid);
686  add_event(c, iov);
687 
688  } else {
689  struct iovec *iov_copy = pcmk__new_ipc_event();
690 
691  crm_trace("Sending a copy to %p[%d]", c->ipcs, c->pid);
692  iov_copy[0].iov_len = iov[0].iov_len;
693  iov_copy[0].iov_base = malloc(iov[0].iov_len);
694  memcpy(iov_copy[0].iov_base, iov[0].iov_base, iov[0].iov_len);
695 
696  iov_copy[1].iov_len = iov[1].iov_len;
697  iov_copy[1].iov_base = malloc(iov[1].iov_len);
698  memcpy(iov_copy[1].iov_base, iov[1].iov_base, iov[1].iov_len);
699 
700  add_event(c, iov_copy);
701  }
702 
703  } else {
704  ssize_t qb_rc;
705 
706  CRM_LOG_ASSERT(header->qb.id != 0); /* Replying to a specific request */
707 
708  qb_rc = qb_ipcs_response_sendv(c->ipcs, iov, 2);
709  if (qb_rc < header->qb.size) {
710  if (qb_rc < 0) {
711  rc = (int) -qb_rc;
712  }
713  crm_notice("Response %d to pid %d failed: %s "
714  CRM_XS " bytes=%u rc=%lld ipcs=%p",
715  header->qb.id, c->pid, pcmk_rc_str(rc),
716  header->qb.size, (long long) qb_rc, c->ipcs);
717 
718  } else {
719  crm_trace("Response %d sent, %lld bytes to %p[%d]",
720  header->qb.id, (long long) qb_rc, c->ipcs, c->pid);
721  }
722 
723  if (flags & crm_ipc_server_free) {
724  pcmk_free_ipc_event(iov);
725  }
726  }
727 
728  if (flags & crm_ipc_server_event) {
729  rc = crm_ipcs_flush_events(c);
730  } else {
731  crm_ipcs_flush_events(c);
732  }
733 
734  if ((rc == EPIPE) || (rc == ENOTCONN)) {
735  crm_trace("Client %p disconnected", c->ipcs);
736  }
737  return rc;
738 }
739 
740 int
741 pcmk__ipc_send_xml(pcmk__client_t *c, uint32_t request, xmlNode *message,
742  uint32_t flags)
743 {
744  struct iovec *iov = NULL;
745  int rc = pcmk_rc_ok;
746 
747  if (c == NULL) {
748  return EINVAL;
749  }
751  &iov, NULL);
752  if (rc == pcmk_rc_ok) {
754  rc = pcmk__ipc_send_iov(c, iov, flags);
755  } else {
756  pcmk_free_ipc_event(iov);
757  crm_notice("IPC message to pid %d failed: %s " CRM_XS " rc=%d",
758  c->pid, pcmk_rc_str(rc), rc);
759  }
760  return rc;
761 }
762 
778 int
779 pcmk__ipc_send_ack_as(const char *function, int line, pcmk__client_t *c,
780  uint32_t request, uint32_t flags, const char *tag,
781  crm_exit_t status)
782 {
783  int rc = pcmk_rc_ok;
784 
786  xmlNode *ack = create_xml_node(NULL, tag);
787 
788  crm_trace("Ack'ing IPC message from %s as <%s status=%d>",
789  pcmk__client_name(c), tag, status);
790  c->request_id = 0;
791  crm_xml_add(ack, "function", function);
792  crm_xml_add_int(ack, "line", line);
793  crm_xml_add_int(ack, "status", (int) status);
794  rc = pcmk__ipc_send_xml(c, request, ack, flags);
795  free_xml(ack);
796  }
797  return rc;
798 }
799 
812 void pcmk__serve_based_ipc(qb_ipcs_service_t **ipcs_ro,
813  qb_ipcs_service_t **ipcs_rw,
814  qb_ipcs_service_t **ipcs_shm,
815  struct qb_ipcs_service_handlers *ro_cb,
816  struct qb_ipcs_service_handlers *rw_cb)
817 {
819  QB_IPC_NATIVE, ro_cb);
820 
822  QB_IPC_NATIVE, rw_cb);
823 
825  QB_IPC_SHM, rw_cb);
826 
827  if (*ipcs_ro == NULL || *ipcs_rw == NULL || *ipcs_shm == NULL) {
828  crm_err("Failed to create the CIB manager: exiting and inhibiting respawn");
829  crm_warn("Verify pacemaker and pacemaker_remote are not both enabled");
831  }
832 }
833 
845 void
846 pcmk__stop_based_ipc(qb_ipcs_service_t *ipcs_ro,
847  qb_ipcs_service_t *ipcs_rw,
848  qb_ipcs_service_t *ipcs_shm)
849 {
850  qb_ipcs_destroy(ipcs_ro);
851  qb_ipcs_destroy(ipcs_rw);
852  qb_ipcs_destroy(ipcs_shm);
853 }
854 
863 qb_ipcs_service_t *
864 pcmk__serve_controld_ipc(struct qb_ipcs_service_handlers *cb)
865 {
866  return mainloop_add_ipc_server(CRM_SYSTEM_CRMD, QB_IPC_NATIVE, cb);
867 }
868 
877 void
878 pcmk__serve_attrd_ipc(qb_ipcs_service_t **ipcs,
879  struct qb_ipcs_service_handlers *cb)
880 {
881  *ipcs = mainloop_add_ipc_server(T_ATTRD, QB_IPC_NATIVE, cb);
882 
883  if (*ipcs == NULL) {
884  crm_err("Failed to create pacemaker-attrd server: exiting and inhibiting respawn");
885  crm_warn("Verify pacemaker and pacemaker_remote are not both enabled.");
887  }
888 }
889 
898 void
899 pcmk__serve_fenced_ipc(qb_ipcs_service_t **ipcs,
900  struct qb_ipcs_service_handlers *cb)
901 {
902  *ipcs = mainloop_add_ipc_server_with_prio("stonith-ng", QB_IPC_NATIVE, cb,
903  QB_LOOP_HIGH);
904 
905  if (*ipcs == NULL) {
906  crm_err("Failed to create fencer: exiting and inhibiting respawn.");
907  crm_warn("Verify pacemaker and pacemaker_remote are not both enabled.");
909  }
910 }
911 
922 bool
924 {
926  return (!strcmp(name, CRM_SYSTEM_CRMD)
927  || !strcmp(name, CRM_SYSTEM_STONITHD)
928  || !strcmp(name, "stonith-ng")
929  || !strcmp(name, "attrd")
930  || !strcmp(name, CRM_SYSTEM_CIB)
931  || !strcmp(name, CRM_SYSTEM_MCP)
932  || !strcmp(name, CRM_SYSTEM_DC)
933  || !strcmp(name, CRM_SYSTEM_TENGINE)
934  || !strcmp(name, CRM_SYSTEM_LRMD));
935 }
#define T_ATTRD
Definition: msg_xml.h:46
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:215
#define PCMK__SERVER_BASED_RW
Definition: crm_internal.h:69
const char * pcmk__message_name(const char *name)
Get name to be used as identifier for cluster messages.
Definition: messages.c:182
A dumping ground.
void pcmk__drop_all_clients(qb_ipcs_service_t *service)
Definition: ipc_server.c:118
#define crm_notice(fmt, args...)
Definition: logging.h:349
const char * pcmk__client_name(pcmk__client_t *c)
Definition: ipc_server.c:90
const char * bz2_strerror(int rc)
Definition: results.c:726
char * crm_generate_uuid(void)
Definition: utils.c:498
void pcmk__client_cleanup(void)
Definition: ipc_server.c:104
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
void pcmk__free_client(pcmk__client_t *c)
Definition: ipc_server.c:295
_Noreturn crm_exit_t crm_exit(crm_exit_t rc)
Definition: results.c:759
pcmk__client_t * pcmk__new_client(qb_ipcs_connection_t *c, uid_t uid_client, gid_t gid_client)
Definition: ipc_server.c:214
bool crm_is_daemon_name(const char *name)
Check whether string represents a client name used by cluster daemons.
Definition: ipc_server.c:923
qb_ipcs_service_t * mainloop_add_ipc_server_with_prio(const char *name, enum qb_ipc_type type, struct qb_ipcs_service_handlers *callbacks, enum qb_loop_priority prio)
Start server-side API end-point, hooked into the internal event loop.
Definition: mainloop.c:650
xmlNode * pcmk__client_data2xml(pcmk__client_t *c, void *data, uint32_t *id, uint32_t *flags)
Definition: ipc_server.c:383
int pcmk__client_pid(qb_ipcs_connection_t *c)
Definition: ipc_server.c:362
uint64_t flags
Definition: ipc_internal.h:142
const char * crm_xml_add_int(xmlNode *node, const char *name, int value)
Create an XML attribute with specified name and integer value.
Definition: nvpair.c:425
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
Definition: nvpair.c:317
void pcmk_free_ipc_event(struct iovec *event)
Free an I/O vector created by pcmk__ipc_prepare_iov()
Definition: ipc_server.c:270
enum crm_exit_e crm_exit_t
#define CRM_LOG_ASSERT(expr)
Definition: logging.h:199
guint pcmk__ipc_client_count()
Definition: ipc_server.c:36
int pcmk_daemon_user(uid_t *uid, gid_t *gid)
Get user and group IDs of pacemaker daemon user.
Definition: utils.c:162
struct pcmk__ipc_header_s pcmk__ipc_header_t
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code.
Definition: results.c:420
GQueue * event_queue
Definition: ipc_internal.h:148
void pcmk__foreach_ipc_client(GHFunc func, gpointer user_data)
Definition: ipc_server.c:51
xmlNode * string2xml(const char *input)
Definition: xml.c:835
void pcmk__serve_attrd_ipc(qb_ipcs_service_t **ipcs, struct qb_ipcs_service_handlers *cb)
Definition: ipc_server.c:878
#define CRM_SYSTEM_DC
Definition: crm.h:98
#define CRM_SYSTEM_MCP
Definition: crm.h:107
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
struct qb_ipc_response_header qb
#define pcmk__set_client_flags(client, flags_to_set)
Definition: ipc_internal.h:162
void pcmk__serve_fenced_ipc(qb_ipcs_service_t **ipcs, struct qb_ipcs_service_handlers *cb)
Definition: ipc_server.c:899
#define crm_warn(fmt, args...)
Definition: logging.h:348
pcmk__client_t * pcmk__find_client_by_id(const char *id)
Definition: ipc_server.c:70
#define PCMK__IPC_VERSION
int rc
Definition: pcmk_fence.c:35
#define crm_debug(fmt, args...)
Definition: logging.h:352
#define crm_trace(fmt, args...)
Definition: logging.h:353
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
Definition: util.h:196
G_GNUC_INTERNAL bool pcmk__valid_ipc_header(const pcmk__ipc_header_t *header)
Definition: ipc_common.c:75
int pcmk__ipc_send_xml(pcmk__client_t *c, uint32_t request, xmlNode *message, uint32_t flags)
Definition: ipc_server.c:741
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition: xml.c:663
int pcmk__compress(const char *data, unsigned int length, unsigned int max, char **result, unsigned int *result_len)
Definition: strings.c:663
#define CRM_DAEMON_USER
Definition: config.h:32
unsigned int crm_ipc_default_buffer_size(void)
Return pacemaker's default IPC buffer size.
Definition: ipc_common.c:56
unsigned int pid
Definition: ipc_internal.h:134
void free_xml(xmlNode *child)
Definition: xml.c:790
#define PCMK__SERVER_BASED_RO
Definition: crm_internal.h:68
#define CRM_SYSTEM_CRMD
Definition: crm.h:102
#define CRM_XS
Definition: logging.h:54
qb_ipcs_service_t * pcmk__serve_controld_ipc(struct qb_ipcs_service_handlers *cb)
Definition: ipc_server.c:864
int pcmk__ipc_send_iov(pcmk__client_t *c, struct iovec *iov, uint32_t flags)
Definition: ipc_server.c:662
#define CRM_SYSTEM_STONITHD
Definition: crm.h:106
#define CRM_SYSTEM_CIB
Definition: crm.h:101
#define PCMK_IPC_DEFAULT_QUEUE_MAX
Definition: ipc_server.c:25
long long crm_parse_ll(const char *text, const char *default_text)
Parse a long long integer value from a string.
Definition: strings.c:107
#define CRM_SYSTEM_TENGINE
Definition: crm.h:105
bool pcmk__set_client_queue_max(pcmk__client_t *client, const char *qmax)
Definition: ipc_server.c:346
#define crm_perror(level, fmt, args...)
Send a system error message to both the log and stderr.
Definition: logging.h:298
#define pcmk__set_ipc_flags(ipc_flags, ipc_name, flags_to_set)
Definition: ipc_internal.h:176
#define crm_err(fmt, args...)
Definition: logging.h:347
#define CRM_ASSERT(expr)
Definition: results.h:42
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
int delay
Definition: pcmk_fence.c:34
char * dump_xml_unformatted(xmlNode *msg)
Definition: xml.c:2000
#define CRM_SYSTEM_LRMD
Definition: crm.h:103
char data[0]
Definition: internal.h:90
#define pcmk__plural_s(i)
pcmk__client_t * pcmk__find_client(qb_ipcs_connection_t *c)
Definition: ipc_server.c:59
IPC interface to Pacemaker daemons.
#define crm_log_xml_trace(xml, text)
Definition: logging.h:361
#define PCMK__SERVER_BASED_SHM
Definition: crm_internal.h:70
unsigned int queue_max
Definition: ipc_internal.h:159
struct pcmk__remote_s * remote
Definition: ipc_internal.h:156
char * pcmk__uid2username(uid_t uid)
qb_ipcs_service_t * mainloop_add_ipc_server(const char *name, enum qb_ipc_type type, struct qb_ipcs_service_handlers *callbacks)
Definition: mainloop.c:643
char * name
Definition: pcmk_fence.c:31
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
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
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