pacemaker  2.0.4-2deceaa3ae
Scalable High-Availability cluster resource manager
corosync.c
Go to the documentation of this file.
1 /*
2  * Copyright 2004-2019 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 <sys/socket.h>
13 #include <netinet/in.h>
14 #include <arpa/inet.h>
15 #include <netdb.h>
16 #include <inttypes.h> /* U64T ~ PRIu64 */
17 
18 #include <bzlib.h>
19 
20 #include <crm/common/ipc.h>
21 #include <crm/cluster/internal.h>
22 #include <crm/common/mainloop.h>
23 #include <sys/utsname.h>
24 
25 #include <qb/qbipcc.h>
26 #include <qb/qbutil.h>
27 
28 #include <corosync/corodefs.h>
29 #include <corosync/corotypes.h>
30 #include <corosync/hdb.h>
31 #include <corosync/cfg.h>
32 #include <corosync/cmap.h>
33 #include <corosync/quorum.h>
34 
35 #include <crm/msg_xml.h>
36 
37 #include <crm/common/ipc_internal.h> /* PCMK__SPECIAL_PID* */
38 
39 quorum_handle_t pcmk_quorum_handle = 0;
40 
41 gboolean(*quorum_app_callback) (unsigned long long seq, gboolean quorate) = NULL;
42 
43 char *
45 {
46  if (node && is_corosync_cluster()) {
47  if (node->id > 0) {
48  return crm_strdup_printf("%u", node->id);
49  } else {
50  crm_info("Node %s is not yet known by corosync", node->uname);
51  }
52  }
53  return NULL;
54 }
55 
56 /*
57  * CFG functionality stolen from node_name() in corosync-quorumtool.c
58  * This resolves the first address assigned to a node and returns the name or IP address.
59  */
60 char *
61 corosync_node_name(uint64_t /*cmap_handle_t */ cmap_handle, uint32_t nodeid)
62 {
63  int lpc = 0;
64  cs_error_t rc = CS_OK;
65  int retries = 0;
66  char *name = NULL;
67  cmap_handle_t local_handle = 0;
68  int fd = -1;
69  uid_t found_uid = 0;
70  gid_t found_gid = 0;
71  pid_t found_pid = 0;
72  int rv;
73 
74  if (nodeid == 0) {
75  nodeid = get_local_nodeid(0);
76  }
77 
78  if (cmap_handle == 0 && local_handle == 0) {
79  retries = 0;
80  crm_trace("Initializing CMAP connection");
81  do {
82  rc = cmap_initialize(&local_handle);
83  if (rc != CS_OK) {
84  retries++;
85  crm_debug("API connection setup failed: %s. Retrying in %ds", cs_strerror(rc),
86  retries);
87  sleep(retries);
88  }
89 
90  } while (retries < 5 && rc != CS_OK);
91 
92  if (rc != CS_OK) {
93  crm_warn("Could not connect to Cluster Configuration Database API, error %s",
94  cs_strerror(rc));
95  local_handle = 0;
96  }
97  }
98 
99  if (cmap_handle == 0) {
100  cmap_handle = local_handle;
101 
102  rc = cmap_fd_get(cmap_handle, &fd);
103  if (rc != CS_OK) {
104  crm_err("Could not obtain the CMAP API connection: %s (%d)",
105  cs_strerror(rc), rc);
106  goto bail;
107  }
108 
109  /* CMAP provider run as root (in given user namespace, anyway)? */
110  if (!(rv = crm_ipc_is_authentic_process(fd, (uid_t) 0,(gid_t) 0, &found_pid,
111  &found_uid, &found_gid))) {
112  crm_err("CMAP provider is not authentic:"
113  " process %lld (uid: %lld, gid: %lld)",
114  (long long) PCMK__SPECIAL_PID_AS_0(found_pid),
115  (long long) found_uid, (long long) found_gid);
116  goto bail;
117  } else if (rv < 0) {
118  crm_err("Could not verify authenticity of CMAP provider: %s (%d)",
119  strerror(-rv), -rv);
120  goto bail;
121  }
122  }
123 
124  while (name == NULL && cmap_handle != 0) {
125  uint32_t id = 0;
126  char *key = NULL;
127 
128  key = crm_strdup_printf("nodelist.node.%d.nodeid", lpc);
129  rc = cmap_get_uint32(cmap_handle, key, &id);
130  crm_trace("Checking %u vs %u from %s", nodeid, id, key);
131  free(key);
132 
133  if (rc != CS_OK) {
134  break;
135  }
136 
137  if (nodeid == id) {
138  crm_trace("Searching for node name for %u in nodelist.node.%d %s", nodeid, lpc, name);
139  if (name == NULL) {
140  key = crm_strdup_printf("nodelist.node.%d.name", lpc);
141  cmap_get_string(cmap_handle, key, &name);
142  crm_trace("%s = %s", key, name);
143  free(key);
144  }
145  if (name == NULL) {
146  key = crm_strdup_printf("nodelist.node.%d.ring0_addr", lpc);
147  cmap_get_string(cmap_handle, key, &name);
148  crm_trace("%s = %s", key, name);
149 
150  if (node_name_is_valid(key, name) == FALSE) {
151  free(name);
152  name = NULL;
153  }
154  free(key);
155  }
156  break;
157  }
158 
159  lpc++;
160  }
161 
162 bail:
163  if(local_handle) {
164  cmap_finalize(local_handle);
165  }
166 
167  if (name == NULL) {
168  crm_info("Unable to get node name for nodeid %u", nodeid);
169  }
170  return name;
171 }
172 
173 void
175 {
176  cluster_disconnect_cpg(cluster);
177  if (pcmk_quorum_handle) {
178  quorum_finalize(pcmk_quorum_handle);
179  pcmk_quorum_handle = 0;
180  }
181  crm_notice("Disconnected from Corosync");
182 }
183 
184 static int
185 pcmk_quorum_dispatch(gpointer user_data)
186 {
187  int rc = 0;
188 
189  rc = quorum_dispatch(pcmk_quorum_handle, CS_DISPATCH_ALL);
190  if (rc < 0) {
191  crm_err("Connection to the Quorum API failed: %d", rc);
192  quorum_finalize(pcmk_quorum_handle);
193  pcmk_quorum_handle = 0;
194  return -1;
195  }
196  return 0;
197 }
198 
199 static void
200 pcmk_quorum_notification(quorum_handle_t handle,
201  uint32_t quorate,
202  uint64_t ring_id, uint32_t view_list_entries, uint32_t * view_list)
203 {
204  int i;
205  GHashTableIter iter;
206  crm_node_t *node = NULL;
207  static gboolean init_phase = TRUE;
208 
209  if (quorate != crm_have_quorum) {
210  if (quorate) {
211  crm_notice("Quorum acquired " CRM_XS " membership=%" U64T " members=%lu",
212  ring_id, (long unsigned int)view_list_entries);
213  } else {
214  crm_warn("Quorum lost " CRM_XS " membership=%" U64T " members=%lu",
215  ring_id, (long unsigned int)view_list_entries);
216  }
217  crm_have_quorum = quorate;
218 
219  } else {
220  crm_info("Quorum %s " CRM_XS " membership=%" U64T " members=%lu",
221  (quorate? "retained" : "still lost"), ring_id,
222  (long unsigned int)view_list_entries);
223  }
224 
225  if (view_list_entries == 0 && init_phase) {
226  crm_info("Corosync membership is still forming, ignoring");
227  return;
228  }
229 
230  init_phase = FALSE;
231 
232  /* Reset last_seen for all cached nodes so we can tell which ones aren't
233  * in the view list */
234  g_hash_table_iter_init(&iter, crm_peer_cache);
235  while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) {
236  node->last_seen = 0;
237  }
238 
239  /* Update the peer cache for each node in view list */
240  for (i = 0; i < view_list_entries; i++) {
241  uint32_t id = view_list[i];
242 
243  crm_debug("Member[%d] %u ", i, id);
244 
245  /* Get this node's peer cache entry (adding one if not already there) */
246  node = crm_get_peer(id, NULL);
247  if (node->uname == NULL) {
248  char *name = corosync_node_name(0, id);
249 
250  crm_info("Obtaining name for new node %u", id);
251  node = crm_get_peer(id, name);
252  free(name);
253  }
254 
255  /* Update the node state (including updating last_seen to ring_id) */
256  crm_update_peer_state(__FUNCTION__, node, CRM_NODE_MEMBER, ring_id);
257  }
258 
259  /* Remove any peer cache entries we didn't update */
260  crm_reap_unseen_nodes(ring_id);
261 
262  if (quorum_app_callback) {
263  quorum_app_callback(ring_id, quorate);
264  }
265 }
266 
267 quorum_callbacks_t quorum_callbacks = {
268  .quorum_notify_fn = pcmk_quorum_notification,
269 };
270 
271 gboolean
272 cluster_connect_quorum(gboolean(*dispatch) (unsigned long long, gboolean),
273  void (*destroy) (gpointer))
274 {
275  cs_error_t rc;
276  int fd = 0;
277  int quorate = 0;
278  uint32_t quorum_type = 0;
279  struct mainloop_fd_callbacks quorum_fd_callbacks;
280  uid_t found_uid = 0;
281  gid_t found_gid = 0;
282  pid_t found_pid = 0;
283  int rv;
284 
285  quorum_fd_callbacks.dispatch = pcmk_quorum_dispatch;
286  quorum_fd_callbacks.destroy = destroy;
287 
288  crm_debug("Configuring Pacemaker to obtain quorum from Corosync");
289 
290  rc = quorum_initialize(&pcmk_quorum_handle, &quorum_callbacks, &quorum_type);
291  if (rc != CS_OK) {
292  crm_err("Could not connect to the Quorum API: %s (%d)",
293  cs_strerror(rc), rc);
294  goto bail;
295 
296  } else if (quorum_type != QUORUM_SET) {
297  crm_err("Corosync quorum is not configured");
298  goto bail;
299  }
300 
301  rc = quorum_fd_get(pcmk_quorum_handle, &fd);
302  if (rc != CS_OK) {
303  crm_err("Could not obtain the Quorum API connection: %s (%d)",
304  strerror(rc), rc);
305  goto bail;
306  }
307 
308  /* Quorum provider run as root (in given user namespace, anyway)? */
309  if (!(rv = crm_ipc_is_authentic_process(fd, (uid_t) 0,(gid_t) 0, &found_pid,
310  &found_uid, &found_gid))) {
311  crm_err("Quorum provider is not authentic:"
312  " process %lld (uid: %lld, gid: %lld)",
313  (long long) PCMK__SPECIAL_PID_AS_0(found_pid),
314  (long long) found_uid, (long long) found_gid);
315  rc = CS_ERR_ACCESS;
316  goto bail;
317  } else if (rv < 0) {
318  crm_err("Could not verify authenticity of Quorum provider: %s (%d)",
319  strerror(-rv), -rv);
320  rc = CS_ERR_ACCESS;
321  goto bail;
322  }
323 
324  rc = quorum_getquorate(pcmk_quorum_handle, &quorate);
325  if (rc != CS_OK) {
326  crm_err("Could not obtain the current Quorum API state: %d", rc);
327  goto bail;
328  }
329 
330  if (quorate) {
331  crm_notice("Quorum acquired");
332  } else {
333  crm_warn("Quorum lost");
334  }
336  crm_have_quorum = quorate;
337 
338  rc = quorum_trackstart(pcmk_quorum_handle, CS_TRACK_CHANGES | CS_TRACK_CURRENT);
339  if (rc != CS_OK) {
340  crm_err("Could not setup Quorum API notifications: %d", rc);
341  goto bail;
342  }
343 
344  mainloop_add_fd("quorum", G_PRIORITY_HIGH, fd, dispatch, &quorum_fd_callbacks);
345 
346  corosync_initialize_nodelist(NULL, FALSE, NULL);
347 
348  bail:
349  if (rc != CS_OK) {
350  quorum_finalize(pcmk_quorum_handle);
351  return FALSE;
352  }
353  return TRUE;
354 }
355 
356 gboolean
358 {
359  int retries = 0;
360 
361  while (retries < 5) {
362  int rc = init_cs_connection_once(cluster);
363 
364  retries++;
365 
366  switch (rc) {
367  case CS_OK:
368  return TRUE;
369  break;
370  case CS_ERR_TRY_AGAIN:
371  case CS_ERR_QUEUE_FULL:
372  sleep(retries);
373  break;
374  default:
375  return FALSE;
376  }
377  }
378 
379  crm_err("Could not connect to corosync after %d retries", retries);
380  return FALSE;
381 }
382 
383 gboolean
385 {
386  crm_node_t *peer = NULL;
387  enum cluster_type_e stack = get_cluster_type();
388 
389  crm_peer_init();
390 
391  /* Here we just initialize comms */
392  if (stack != pcmk_cluster_corosync) {
393  crm_err("Invalid cluster type: %s (%d)", name_for_cluster_type(stack), stack);
394  return FALSE;
395  }
396 
397  if (cluster_connect_cpg(cluster) == FALSE) {
398  return FALSE;
399  }
400  crm_info("Connection to '%s': established", name_for_cluster_type(stack));
401 
402  cluster->nodeid = get_local_nodeid(0);
403  if(cluster->nodeid == 0) {
404  crm_err("Could not establish local nodeid");
405  return FALSE;
406  }
407 
408  cluster->uname = get_node_name(0);
409  if(cluster->uname == NULL) {
410  crm_err("Could not establish local node name");
411  return FALSE;
412  }
413 
414  /* Ensure the local node always exists */
415  peer = crm_get_peer(cluster->nodeid, cluster->uname);
416  cluster->uuid = get_corosync_uuid(peer);
417 
418  return TRUE;
419 }
420 
421 gboolean
422 check_message_sanity(const AIS_Message * msg, const char *data)
423 {
424  gboolean sane = TRUE;
425  int dest = msg->host.type;
426  int tmp_size = msg->header.size - sizeof(AIS_Message);
427 
428  if (sane && msg->header.size == 0) {
429  crm_warn("Message with no size");
430  sane = FALSE;
431  }
432 
433  if (sane && msg->header.error != CS_OK) {
434  crm_warn("Message header contains an error: %d", msg->header.error);
435  sane = FALSE;
436  }
437 
438  if (sane && ais_data_len(msg) != tmp_size) {
439  crm_warn("Message payload size is incorrect: expected %d, got %d", ais_data_len(msg),
440  tmp_size);
441  sane = TRUE;
442  }
443 
444  if (sane && ais_data_len(msg) == 0) {
445  crm_warn("Message with no payload");
446  sane = FALSE;
447  }
448 
449  if (sane && data && msg->is_compressed == FALSE) {
450  int str_size = strlen(data) + 1;
451 
452  if (ais_data_len(msg) != str_size) {
453  int lpc = 0;
454 
455  crm_warn("Message payload is corrupted: expected %d bytes, got %d",
456  ais_data_len(msg), str_size);
457  sane = FALSE;
458  for (lpc = (str_size - 10); lpc < msg->size; lpc++) {
459  if (lpc < 0) {
460  lpc = 0;
461  }
462  crm_debug("bad_data[%d]: %d / '%c'", lpc, data[lpc], data[lpc]);
463  }
464  }
465  }
466 
467  if (sane == FALSE) {
468  crm_err("Invalid message %d: (dest=%s:%s, from=%s:%s.%u, compressed=%d, size=%d, total=%d)",
469  msg->id, ais_dest(&(msg->host)), msg_type2text(dest),
470  ais_dest(&(msg->sender)), msg_type2text(msg->sender.type),
471  msg->sender.pid, msg->is_compressed, ais_data_len(msg), msg->header.size);
472 
473  } else {
474  crm_trace
475  ("Verified message %d: (dest=%s:%s, from=%s:%s.%u, compressed=%d, size=%d, total=%d)",
476  msg->id, ais_dest(&(msg->host)), msg_type2text(dest), ais_dest(&(msg->sender)),
477  msg_type2text(msg->sender.type), msg->sender.pid, msg->is_compressed,
478  ais_data_len(msg), msg->header.size);
479  }
480 
481  return sane;
482 }
483 
484 enum cluster_type_e
486 {
487  int rc = CS_OK;
488  cmap_handle_t handle;
489 
490  rc = cmap_initialize(&handle);
491 
492  switch(rc) {
493  case CS_OK:
494  break;
495  case CS_ERR_SECURITY:
496  crm_debug("Failed to initialize the cmap API: Permission denied (%d)", rc);
497  /* It's there, we just can't talk to it.
498  * Good enough for us to identify as 'corosync'
499  */
500  return pcmk_cluster_corosync;
501 
502  default:
503  crm_info("Failed to initialize the cmap API: %s (%d)",
504  ais_error2text(rc), rc);
505  return pcmk_cluster_unknown;
506  }
507 
508  cmap_finalize(handle);
509  return pcmk_cluster_corosync;
510 }
511 
512 gboolean
514 {
515  if (node == NULL) {
516  crm_trace("NULL");
517  return FALSE;
518 
519  } else if (safe_str_neq(node->state, CRM_NODE_MEMBER)) {
520  crm_trace("%s: state=%s", node->uname, node->state);
521  return FALSE;
522 
523  } else if ((node->processes & crm_proc_cpg) == 0) {
524  crm_trace("%s: processes=%.16x", node->uname, node->processes);
525  return FALSE;
526  }
527  return TRUE;
528 }
529 
530 gboolean
531 corosync_initialize_nodelist(void *cluster, gboolean force_member, xmlNode * xml_parent)
532 {
533  int lpc = 0;
534  cs_error_t rc = CS_OK;
535  int retries = 0;
536  gboolean any = FALSE;
537  cmap_handle_t cmap_handle;
538  int fd = -1;
539  uid_t found_uid = 0;
540  gid_t found_gid = 0;
541  pid_t found_pid = 0;
542  int rv;
543 
544  do {
545  rc = cmap_initialize(&cmap_handle);
546  if (rc != CS_OK) {
547  retries++;
548  crm_debug("API connection setup failed: %s. Retrying in %ds", cs_strerror(rc),
549  retries);
550  sleep(retries);
551  }
552 
553  } while (retries < 5 && rc != CS_OK);
554 
555  if (rc != CS_OK) {
556  crm_warn("Could not connect to Cluster Configuration Database API, error %d", rc);
557  return FALSE;
558  }
559 
560  rc = cmap_fd_get(cmap_handle, &fd);
561  if (rc != CS_OK) {
562  crm_err("Could not obtain the CMAP API connection: %s (%d)",
563  cs_strerror(rc), rc);
564  goto bail;
565  }
566 
567  /* CMAP provider run as root (in given user namespace, anyway)? */
568  if (!(rv = crm_ipc_is_authentic_process(fd, (uid_t) 0,(gid_t) 0, &found_pid,
569  &found_uid, &found_gid))) {
570  crm_err("CMAP provider is not authentic:"
571  " process %lld (uid: %lld, gid: %lld)",
572  (long long) PCMK__SPECIAL_PID_AS_0(found_pid),
573  (long long) found_uid, (long long) found_gid);
574  goto bail;
575  } else if (rv < 0) {
576  crm_err("Could not verify authenticity of CMAP provider: %s (%d)",
577  strerror(-rv), -rv);
578  goto bail;
579  }
580 
581  crm_peer_init();
582  crm_trace("Initializing corosync nodelist");
583  for (lpc = 0; TRUE; lpc++) {
584  uint32_t nodeid = 0;
585  char *name = NULL;
586  char *key = NULL;
587 
588  key = crm_strdup_printf("nodelist.node.%d.nodeid", lpc);
589  rc = cmap_get_uint32(cmap_handle, key, &nodeid);
590  free(key);
591 
592  if (rc != CS_OK) {
593  break;
594  }
595 
596  name = corosync_node_name(cmap_handle, nodeid);
597  if (name != NULL) {
598  GHashTableIter iter;
599  crm_node_t *node = NULL;
600 
601  g_hash_table_iter_init(&iter, crm_peer_cache);
602  while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) {
603  if(node && node->uname && strcasecmp(node->uname, name) == 0) {
604  if (node->id && node->id != nodeid) {
605  crm_crit("Nodes %u and %u share the same name '%s': shutting down", node->id,
606  nodeid, name);
608  }
609  }
610  }
611  }
612 
613  if (nodeid > 0 || name != NULL) {
614  crm_trace("Initializing node[%d] %u = %s", lpc, nodeid, name);
615  crm_get_peer(nodeid, name);
616  }
617 
618  if (nodeid > 0 && name != NULL) {
619  any = TRUE;
620 
621  if (xml_parent) {
622  xmlNode *node = create_xml_node(xml_parent, XML_CIB_TAG_NODE);
623 
624  crm_xml_set_id(node, "%u", nodeid);
626  if (force_member) {
628  }
629  }
630  }
631 
632  free(name);
633  }
634 bail:
635  cmap_finalize(cmap_handle);
636  return any;
637 }
638 
639 char *
641 {
642  cmap_handle_t handle;
643  char *cluster_name = NULL;
644  cs_error_t rc = CS_OK;
645  int fd = -1;
646  uid_t found_uid = 0;
647  gid_t found_gid = 0;
648  pid_t found_pid = 0;
649  int rv;
650 
651  rc = cmap_initialize(&handle);
652  if (rc != CS_OK) {
653  crm_info("Failed to initialize the cmap API: %s (%d)",
654  cs_strerror(rc), rc);
655  return NULL;
656  }
657 
658  rc = cmap_fd_get(handle, &fd);
659  if (rc != CS_OK) {
660  crm_err("Could not obtain the CMAP API connection: %s (%d)",
661  cs_strerror(rc), rc);
662  goto bail;
663  }
664 
665  /* CMAP provider run as root (in given user namespace, anyway)? */
666  if (!(rv = crm_ipc_is_authentic_process(fd, (uid_t) 0,(gid_t) 0, &found_pid,
667  &found_uid, &found_gid))) {
668  crm_err("CMAP provider is not authentic:"
669  " process %lld (uid: %lld, gid: %lld)",
670  (long long) PCMK__SPECIAL_PID_AS_0(found_pid),
671  (long long) found_uid, (long long) found_gid);
672  goto bail;
673  } else if (rv < 0) {
674  crm_err("Could not verify authenticity of CMAP provider: %s (%d)",
675  strerror(-rv), -rv);
676  goto bail;
677  }
678 
679  rc = cmap_get_string(handle, "totem.cluster_name", &cluster_name);
680  if (rc != CS_OK) {
681  crm_info("Cannot get totem.cluster_name: %s (%d)", cs_strerror(rc), rc);
682 
683  } else {
684  crm_debug("cmap totem.cluster_name = '%s'", cluster_name);
685  }
686 
687 bail:
688  cmap_finalize(handle);
689  return cluster_name;
690 }
691 
692 int
693 corosync_cmap_has_config(const char *prefix)
694 {
695  cs_error_t rc = CS_OK;
696  int retries = 0;
697  static int found = -1;
698  cmap_handle_t cmap_handle;
699  cmap_iter_handle_t iter_handle;
700  char key_name[CMAP_KEYNAME_MAXLEN + 1];
701  int fd = -1;
702  uid_t found_uid = 0;
703  gid_t found_gid = 0;
704  pid_t found_pid = 0;
705  int rv;
706 
707  if(found != -1) {
708  return found;
709  }
710 
711  do {
712  rc = cmap_initialize(&cmap_handle);
713  if (rc != CS_OK) {
714  retries++;
715  crm_debug("API connection setup failed: %s. Retrying in %ds", cs_strerror(rc),
716  retries);
717  sleep(retries);
718  }
719 
720  } while (retries < 5 && rc != CS_OK);
721 
722  if (rc != CS_OK) {
723  crm_warn("Could not connect to Cluster Configuration Database API: %s (rc=%d)",
724  cs_strerror(rc), rc);
725  return -1;
726  }
727 
728  rc = cmap_fd_get(cmap_handle, &fd);
729  if (rc != CS_OK) {
730  crm_err("Could not obtain the CMAP API connection: %s (%d)",
731  cs_strerror(rc), rc);
732  goto bail;
733  }
734 
735  /* CMAP provider run as root (in given user namespace, anyway)? */
736  if (!(rv = crm_ipc_is_authentic_process(fd, (uid_t) 0,(gid_t) 0, &found_pid,
737  &found_uid, &found_gid))) {
738  crm_err("CMAP provider is not authentic:"
739  " process %lld (uid: %lld, gid: %lld)",
740  (long long) PCMK__SPECIAL_PID_AS_0(found_pid),
741  (long long) found_uid, (long long) found_gid);
742  goto bail;
743  } else if (rv < 0) {
744  crm_err("Could not verify authenticity of CMAP provider: %s (%d)",
745  strerror(-rv), -rv);
746  goto bail;
747  }
748 
749  rc = cmap_iter_init(cmap_handle, prefix, &iter_handle);
750  if (rc != CS_OK) {
751  crm_warn("Failed to initialize iteration for corosync cmap '%s': %s (rc=%d)",
752  prefix, cs_strerror(rc), rc);
753  goto bail;
754  }
755 
756  found = 0;
757  while ((rc = cmap_iter_next(cmap_handle, iter_handle, key_name, NULL, NULL)) == CS_OK) {
758  crm_trace("'%s' is configured in corosync cmap: %s", prefix, key_name);
759  found++;
760  break;
761  }
762  cmap_iter_finalize(cmap_handle, iter_handle);
763 
764 bail:
765  cmap_finalize(cmap_handle);
766 
767  return found;
768 }
gboolean node_name_is_valid(const char *key, const char *name)
Definition: cluster.c:336
crm_node_t * crm_update_peer_state(const char *source, crm_node_t *node, const char *state, uint64_t membership)
Update a node's state and membership information.
Definition: membership.c:965
void crm_reap_unseen_nodes(uint64_t ring_id)
Definition: membership.c:977
#define ais_data_len(msg)
Definition: internal.h:125
@ crm_proc_cpg
Definition: internal.h:48
struct crm_ais_msg_s AIS_Message
Definition: internal.h:16
char data[0]
Definition: internal.h:10
gboolean crm_have_quorum
Definition: membership.c:56
gboolean is_corosync_cluster(void)
Definition: cluster.c:330
GHashTable * crm_peer_cache
Definition: membership.c:34
enum cluster_type_e get_cluster_type(void)
Definition: cluster.c:275
const char * name_for_cluster_type(enum cluster_type_e type)
Definition: cluster.c:236
#define CRM_NODE_MEMBER
Definition: cluster.h:34
crm_node_t * crm_get_peer(unsigned int id, const char *uname)
Definition: membership.c:653
char * get_node_name(uint32_t nodeid)
Definition: cluster.c:132
cluster_type_e
Definition: cluster.h:178
@ pcmk_cluster_unknown
Definition: cluster.h:179
@ pcmk_cluster_corosync
Definition: cluster.h:183
void crm_peer_init(void)
Definition: membership.c:390
char * crm_strdup_printf(char const *format,...) __attribute__((__format__(__printf__
gboolean safe_str_neq(const char *a, const char *b)
Definition: strings.c:263
#define U64T
Definition: config.h:598
gboolean corosync_initialize_nodelist(void *cluster, gboolean force_member, xmlNode *xml_parent)
Definition: corosync.c:531
quorum_handle_t pcmk_quorum_handle
Definition: corosync.c:39
void terminate_cs_connection(crm_cluster_t *cluster)
Definition: corosync.c:174
char * get_corosync_uuid(crm_node_t *node)
Definition: corosync.c:44
gboolean crm_is_corosync_peer_active(const crm_node_t *node)
Definition: corosync.c:513
char * corosync_node_name(uint64_t cmap_handle, uint32_t nodeid)
Definition: corosync.c:61
gboolean cluster_connect_quorum(gboolean(*dispatch)(unsigned long long, gboolean), void(*destroy)(gpointer))
Definition: corosync.c:272
int corosync_cmap_has_config(const char *prefix)
Definition: corosync.c:693
char * corosync_cluster_name(void)
Definition: corosync.c:640
gboolean check_message_sanity(const AIS_Message *msg, const char *data)
Definition: corosync.c:422
gboolean(* quorum_app_callback)(unsigned long long seq, gboolean quorate)
Definition: corosync.c:41
enum cluster_type_e find_corosync_variant(void)
Definition: corosync.c:485
quorum_callbacks_t quorum_callbacks
Definition: corosync.c:267
gboolean init_cs_connection(crm_cluster_t *cluster)
Definition: corosync.c:357
gboolean init_cs_connection_once(crm_cluster_t *cluster)
Definition: corosync.c:384
void cluster_disconnect_cpg(crm_cluster_t *cluster)
Definition: cpg.c:51
uint32_t get_local_nodeid(cpg_handle_t handle)
Definition: cpg.c:65
gboolean cluster_connect_cpg(crm_cluster_t *cluster)
Definition: cpg.c:538
Wrappers for and extensions to libqb IPC.
int crm_ipc_is_authentic_process(int sock, uid_t refuid, gid_t refgid, pid_t *gotpid, uid_t *gotuid, gid_t *gotgid)
Check the authenticity of the IPC socket peer process.
Definition: ipc.c:1672
#define PCMK__SPECIAL_PID_AS_0(p)
Definition: ipc_internal.h:34
#define crm_info(fmt, args...)
Definition: logging.h:366
#define crm_warn(fmt, args...)
Definition: logging.h:364
#define CRM_XS
Definition: logging.h:54
#define crm_crit(fmt, args...)
Definition: logging.h:362
#define crm_notice(fmt, args...)
Definition: logging.h:365
#define crm_debug(fmt, args...)
Definition: logging.h:368
#define crm_err(fmt, args...)
Definition: logging.h:363
#define crm_trace(fmt, args...)
Definition: logging.h:369
Wrappers for and extensions to glib mainloop.
mainloop_io_t * mainloop_add_fd(const char *name, int priority, int fd, void *userdata, struct mainloop_fd_callbacks *callbacks)
Definition: mainloop.c:881
#define XML_ATTR_UNAME
Definition: msg_xml.h:118
#define XML_ATTR_TYPE
Definition: msg_xml.h:99
#define XML_CIB_TAG_NODE
Definition: msg_xml.h:159
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:316
char * name
Definition: pcmk_fence.c:30
int rc
Definition: pcmk_fence.c:34
char * strerror(int errnum)
@ CRM_EX_FATAL
Definition: results.h:202
_Noreturn crm_exit_t crm_exit(crm_exit_t rc)
Definition: results.c:751
uint32_t pid
Definition: internal.h:20
enum crm_ais_msg_types type
Definition: internal.h:22
uint32_t size
Definition: internal.h:36
AIS_Host sender
Definition: internal.h:34
gboolean is_compressed
Definition: internal.h:31
AIS_Host host
Definition: internal.h:33
uint32_t id
Definition: internal.h:30
uint32_t nodeid
Definition: cluster.h:79
char * uuid
Definition: cluster.h:77
char * uname
Definition: cluster.h:78
uint32_t processes
Definition: cluster.h:62
char * uname
Definition: cluster.h:57
uint32_t id
Definition: cluster.h:65
char * state
Definition: cluster.h:59
int(* dispatch)(gpointer userdata)
Definition: mainloop.h:115
void(* destroy)(gpointer userdata)
Definition: mainloop.h:116
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition: xml.c:1976
void crm_xml_set_id(xmlNode *xml, const char *format,...) __attribute__((__format__(__printf__