pacemaker  3.0.0-d8340737c4
Scalable High-Availability cluster resource manager
corosync.c
Go to the documentation of this file.
1 /*
2  * Copyright 2004-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 #include <crm_internal.h>
11 
12 #include <arpa/inet.h>
13 #include <inttypes.h> // PRIu64, etc.
14 #include <netdb.h>
15 #include <netinet/in.h>
16 #include <stdbool.h>
17 #include <sys/socket.h>
18 #include <sys/utsname.h>
19 
20 #include <bzlib.h>
21 #include <corosync/cfg.h>
22 #include <corosync/cmap.h>
23 #include <corosync/corodefs.h>
24 #include <corosync/corotypes.h>
25 #include <corosync/hdb.h>
26 #include <corosync/quorum.h>
27 #include <qb/qbipcc.h>
28 #include <qb/qbutil.h>
29 
30 #include <crm/cluster/internal.h>
31 #include <crm/common/ipc.h>
32 #include <crm/common/ipc_internal.h> // PCMK__SPECIAL_PID
33 #include <crm/common/mainloop.h>
34 #include <crm/common/xml.h>
35 
36 #include "crmcluster_private.h"
37 
38 static quorum_handle_t pcmk_quorum_handle = 0;
39 
40 static gboolean (*quorum_app_callback)(unsigned long long seq,
41  gboolean quorate) = NULL;
42 
52 char *
54 {
56 
57  if (node != NULL) {
58  if (node->cluster_layer_id > 0) {
59  return crm_strdup_printf("%" PRIu32, node->cluster_layer_id);
60  } else {
61  crm_info("Node %s is not yet known by Corosync", node->name);
62  }
63  }
64  return NULL;
65 }
66 
67 static bool
68 node_name_is_valid(const char *key, const char *name)
69 {
70  int octet;
71 
72  if (name == NULL) {
73  crm_trace("%s is empty", key);
74  return false;
75 
76  } else if (sscanf(name, "%d.%d.%d.%d", &octet, &octet, &octet, &octet) == 4) {
77  crm_trace("%s contains an IPv4 address (%s), ignoring", key, name);
78  return false;
79 
80  } else if (strstr(name, ":") != NULL) {
81  crm_trace("%s contains an IPv6 address (%s), ignoring", key, name);
82  return false;
83  }
84  crm_trace("'%s: %s' is valid", key, name);
85  return true;
86 }
87 
88 /*
89  * \internal
90  * \brief Get Corosync node name corresponding to a node ID
91  *
92  * \param[in] cmap_handle Connection to Corosync CMAP
93  * \param[in] nodeid Node ID to check
94  *
95  * \return Newly allocated string with name or (if no name) IP address
96  * associated with first address assigned to a Corosync node ID (or NULL
97  * if unknown)
98  * \note It is the caller's responsibility to free the result with free().
99  */
100 char *
101 pcmk__corosync_name(uint64_t /*cmap_handle_t */ cmap_handle, uint32_t nodeid)
102 {
103  // Originally based on corosync-quorumtool.c:node_name()
104 
105  int lpc = 0;
106  cs_error_t rc = CS_OK;
107  int retries = 0;
108  char *name = NULL;
109  cmap_handle_t local_handle = 0;
110  int fd = -1;
111  uid_t found_uid = 0;
112  gid_t found_gid = 0;
113  pid_t found_pid = 0;
114  int rv;
115 
116  if (nodeid == 0) {
117  nodeid = pcmk__cpg_local_nodeid(0);
118  }
119 
120  if (cmap_handle == 0 && local_handle == 0) {
121  retries = 0;
122  crm_trace("Initializing CMAP connection");
123  do {
124  rc = pcmk__init_cmap(&local_handle);
125  if (rc != CS_OK) {
126  retries++;
127  crm_debug("API connection setup failed: %s. Retrying in %ds", cs_strerror(rc),
128  retries);
129  sleep(retries);
130  }
131 
132  } while (retries < 5 && rc != CS_OK);
133 
134  if (rc != CS_OK) {
135  crm_warn("Could not connect to Cluster Configuration Database API, error %s",
136  cs_strerror(rc));
137  local_handle = 0;
138  }
139  }
140 
141  if (cmap_handle == 0) {
142  cmap_handle = local_handle;
143 
144  rc = cmap_fd_get(cmap_handle, &fd);
145  if (rc != CS_OK) {
146  crm_err("Could not obtain the CMAP API connection: %s (%d)",
147  cs_strerror(rc), rc);
148  goto bail;
149  }
150 
151  /* CMAP provider run as root (in given user namespace, anyway)? */
152  if (!(rv = crm_ipc_is_authentic_process(fd, (uid_t) 0,(gid_t) 0, &found_pid,
153  &found_uid, &found_gid))) {
154  crm_err("CMAP provider is not authentic:"
155  " process %lld (uid: %lld, gid: %lld)",
156  (long long) PCMK__SPECIAL_PID_AS_0(found_pid),
157  (long long) found_uid, (long long) found_gid);
158  goto bail;
159  } else if (rv < 0) {
160  crm_err("Could not verify authenticity of CMAP provider: %s (%d)",
161  strerror(-rv), -rv);
162  goto bail;
163  }
164  }
165 
166  while (name == NULL && cmap_handle != 0) {
167  uint32_t id = 0;
168  char *key = NULL;
169 
170  key = crm_strdup_printf("nodelist.node.%d.nodeid", lpc);
171  rc = cmap_get_uint32(cmap_handle, key, &id);
172  crm_trace("Checking %u vs %u from %s", nodeid, id, key);
173  free(key);
174 
175  if (rc != CS_OK) {
176  break;
177  }
178 
179  if (nodeid == id) {
180  crm_trace("Searching for node name for %u in nodelist.node.%d %s",
181  nodeid, lpc, pcmk__s(name, "<null>"));
182  if (name == NULL) {
183  key = crm_strdup_printf("nodelist.node.%d.name", lpc);
184  cmap_get_string(cmap_handle, key, &name);
185  crm_trace("%s = %s", key, pcmk__s(name, "<null>"));
186  free(key);
187  }
188  if (name == NULL) {
189  key = crm_strdup_printf("nodelist.node.%d.ring0_addr", lpc);
190  cmap_get_string(cmap_handle, key, &name);
191  crm_trace("%s = %s", key, pcmk__s(name, "<null>"));
192 
193  if (!node_name_is_valid(key, name)) {
194  free(name);
195  name = NULL;
196  }
197  free(key);
198  }
199  break;
200  }
201 
202  lpc++;
203  }
204 
205 bail:
206  if(local_handle) {
207  cmap_finalize(local_handle);
208  }
209 
210  if (name == NULL) {
211  crm_info("Unable to get node name for nodeid %u", nodeid);
212  }
213  return name;
214 }
215 
222 void
224 {
225  pcmk__cpg_disconnect(cluster);
226 
227  if (pcmk_quorum_handle != 0) {
228  quorum_finalize(pcmk_quorum_handle);
229  pcmk_quorum_handle = 0;
230  }
231  crm_notice("Disconnected from Corosync");
232 }
233 
242 static int
243 quorum_dispatch_cb(gpointer user_data)
244 {
245  int rc = quorum_dispatch(pcmk_quorum_handle, CS_DISPATCH_ALL);
246 
247  if (rc < 0) {
248  crm_err("Connection to the Quorum API failed: %d", rc);
249  quorum_finalize(pcmk_quorum_handle);
250  pcmk_quorum_handle = 0;
251  return -1;
252  }
253  return 0;
254 }
255 
266 static void
267 quorum_notification_cb(quorum_handle_t handle, uint32_t quorate,
268  uint64_t ring_id, uint32_t view_list_entries,
269  uint32_t *view_list)
270 {
271  int i;
272  GHashTableIter iter;
273  pcmk__node_status_t *node = NULL;
274  static gboolean init_phase = TRUE;
275 
276  bool is_quorate = (quorate != 0);
277  bool was_quorate = pcmk__cluster_has_quorum();
278 
279  if (is_quorate && !was_quorate) {
280  crm_notice("Quorum acquired " QB_XS " membership=%" PRIu64
281  " members=%" PRIu32,
282  ring_id, view_list_entries);
284 
285  } else if (!is_quorate && was_quorate) {
286  crm_warn("Quorum lost " QB_XS " membership=%" PRIu64 " members=" PRIu32,
287  ring_id, view_list_entries);
289 
290  } else {
291  crm_info("Quorum %s " QB_XS " membership=%" PRIu64 " members=%" PRIu32,
292  (is_quorate? "retained" : "still lost"), ring_id,
293  view_list_entries);
294  }
295 
296  if (view_list_entries == 0 && init_phase) {
297  crm_info("Corosync membership is still forming, ignoring");
298  return;
299  }
300 
301  init_phase = FALSE;
302 
303  /* Reset membership_id for all cached nodes so we can tell which ones aren't
304  * in the view list */
305  g_hash_table_iter_init(&iter, pcmk__peer_cache);
306  while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) {
307  node->membership_id = 0;
308  }
309 
310  /* Update the peer cache for each node in view list */
311  for (i = 0; i < view_list_entries; i++) {
312  uint32_t id = view_list[i];
313 
314  crm_debug("Member[%d] %u ", i, id);
315 
316  /* Get this node's peer cache entry (adding one if not already there) */
317  node = pcmk__get_node(id, NULL, NULL, pcmk__node_search_cluster_member);
318  if (node->name == NULL) {
319  char *name = pcmk__corosync_name(0, id);
320 
321  crm_info("Obtaining name for new node %u", id);
322  node = pcmk__get_node(id, name, NULL,
324  free(name);
325  }
326 
327  // Update the node state (including updating membership_id to ring_id)
328  pcmk__update_peer_state(__func__, node, PCMK_VALUE_MEMBER, ring_id);
329  }
330 
331  /* Remove any peer cache entries we didn't update */
332  pcmk__reap_unseen_nodes(ring_id);
333 
334  if (quorum_app_callback) {
335  quorum_app_callback(ring_id, is_quorate);
336  }
337 }
338 
346 void
347 pcmk__corosync_quorum_connect(gboolean (*dispatch)(unsigned long long,
348  gboolean),
349  void (*destroy)(gpointer))
350 {
351  cs_error_t rc;
352  int fd = 0;
353  int quorate = 0;
354  uint32_t quorum_type = 0;
355  struct mainloop_fd_callbacks quorum_fd_callbacks;
356  uid_t found_uid = 0;
357  gid_t found_gid = 0;
358  pid_t found_pid = 0;
359  int rv;
360 
361  quorum_fd_callbacks.dispatch = quorum_dispatch_cb;
362  quorum_fd_callbacks.destroy = destroy;
363 
364  crm_debug("Configuring Pacemaker to obtain quorum from Corosync");
365 
366  {
367 #if 0
368  // New way but not supported by all Corosync 2 versions
369  quorum_model_v0_data_t quorum_model_data = {
370  .model = QUORUM_MODEL_V0,
371  .quorum_notify_fn = quorum_notification_cb,
372  };
373 
374  rc = quorum_model_initialize(&pcmk_quorum_handle, QUORUM_MODEL_V0,
375  (quorum_model_data_t *) &quorum_model_data,
376  &quorum_type, NULL);
377 #else
378  quorum_callbacks_t quorum_callbacks = {
379  .quorum_notify_fn = quorum_notification_cb,
380  };
381 
382  rc = quorum_initialize(&pcmk_quorum_handle, &quorum_callbacks,
383  &quorum_type);
384 #endif
385  }
386 
387  if (rc != CS_OK) {
388  crm_err("Could not connect to the Quorum API: %s (%d)",
389  cs_strerror(rc), rc);
390  goto bail;
391 
392  } else if (quorum_type != QUORUM_SET) {
393  crm_err("Corosync quorum is not configured");
394  goto bail;
395  }
396 
397  rc = quorum_fd_get(pcmk_quorum_handle, &fd);
398  if (rc != CS_OK) {
399  crm_err("Could not obtain the Quorum API connection: %s (%d)",
400  strerror(rc), rc);
401  goto bail;
402  }
403 
404  /* Quorum provider run as root (in given user namespace, anyway)? */
405  if (!(rv = crm_ipc_is_authentic_process(fd, (uid_t) 0,(gid_t) 0, &found_pid,
406  &found_uid, &found_gid))) {
407  crm_err("Quorum provider is not authentic:"
408  " process %lld (uid: %lld, gid: %lld)",
409  (long long) PCMK__SPECIAL_PID_AS_0(found_pid),
410  (long long) found_uid, (long long) found_gid);
411  rc = CS_ERR_ACCESS;
412  goto bail;
413  } else if (rv < 0) {
414  crm_err("Could not verify authenticity of Quorum provider: %s (%d)",
415  strerror(-rv), -rv);
416  rc = CS_ERR_ACCESS;
417  goto bail;
418  }
419 
420  rc = quorum_getquorate(pcmk_quorum_handle, &quorate);
421  if (rc != CS_OK) {
422  crm_err("Could not obtain the current Quorum API state: %d", rc);
423  goto bail;
424  }
425 
426  if (quorate) {
427  crm_notice("Quorum acquired");
428  } else {
429  crm_warn("No quorum");
430  }
431  quorum_app_callback = dispatch;
432  pcmk__cluster_set_quorum(quorate != 0);
433 
434  rc = quorum_trackstart(pcmk_quorum_handle, CS_TRACK_CHANGES | CS_TRACK_CURRENT);
435  if (rc != CS_OK) {
436  crm_err("Could not setup Quorum API notifications: %d", rc);
437  goto bail;
438  }
439 
440  mainloop_add_fd("quorum", G_PRIORITY_HIGH, fd, dispatch, &quorum_fd_callbacks);
441 
443 
444  bail:
445  if (rc != CS_OK) {
446  quorum_finalize(pcmk_quorum_handle);
447  }
448 }
449 
458 int
460 {
461  const enum pcmk_cluster_layer cluster_layer = pcmk_get_cluster_layer();
462  const char *cluster_layer_s = pcmk_cluster_layer_text(cluster_layer);
463  int rc = pcmk_rc_ok;
464 
466 
467  if (cluster_layer != pcmk_cluster_layer_corosync) {
468  crm_err("Invalid cluster layer: %s " QB_XS " cluster_layer=%d",
469  cluster_layer_s, cluster_layer);
470  return EINVAL;
471  }
472 
473  rc = pcmk__cpg_connect(cluster);
474  if (rc != pcmk_rc_ok) {
475  // Error message was logged by pcmk__cpg_connect()
476  return rc;
477  }
478  crm_info("Connection to %s established", cluster_layer_s);
479 
480  cluster->priv->node_id = pcmk__cpg_local_nodeid(0);
481  if (cluster->priv->node_id == 0) {
482  crm_err("Could not determine local node ID");
483  return ENXIO;
484  }
485 
486  cluster->priv->node_name = pcmk__cluster_node_name(0);
487  if (cluster->priv->node_name == NULL) {
488  crm_err("Could not determine local node name");
489  return ENXIO;
490  }
491 
492  // Ensure local node always exists in peer cache
493  pcmk__get_node(cluster->priv->node_id, cluster->priv->node_name, NULL,
495 
496  return pcmk_rc_ok;
497 }
498 
505 bool
507 {
508  cmap_handle_t handle;
509  int rc = pcmk__init_cmap(&handle);
510 
511  if (rc == CS_OK) {
512  cmap_finalize(handle);
513  return true;
514  }
515 
516  crm_info("Failed to initialize the cmap API: %s (%d)",
517  pcmk__cs_err_str(rc), rc);
518  return false;
519 }
520 
529 bool
531 {
532  if (node == NULL) {
533  crm_trace("Corosync peer inactive: NULL");
534  return false;
535  }
536  if (!pcmk__str_eq(node->state, PCMK_VALUE_MEMBER, pcmk__str_none)) {
537  crm_trace("Corosync peer %s inactive: state=%s",
538  node->name, node->state);
539  return false;
540  }
541  if (!pcmk_is_set(node->processes, crm_proc_cpg)) {
542  crm_trace("Corosync peer %s inactive " QB_XS " processes=%.16" PRIx32,
543  node->name, node->processes);
544  return false;
545  }
546  return true;
547 }
548 
557 bool
558 pcmk__corosync_add_nodes(xmlNode *xml_parent)
559 {
560  int lpc = 0;
561  cs_error_t rc = CS_OK;
562  int retries = 0;
563  bool any = false;
564  cmap_handle_t cmap_handle;
565  int fd = -1;
566  uid_t found_uid = 0;
567  gid_t found_gid = 0;
568  pid_t found_pid = 0;
569  int rv;
570 
571  do {
572  rc = pcmk__init_cmap(&cmap_handle);
573  if (rc != CS_OK) {
574  retries++;
575  crm_debug("API connection setup failed: %s. Retrying in %ds", cs_strerror(rc),
576  retries);
577  sleep(retries);
578  }
579 
580  } while (retries < 5 && rc != CS_OK);
581 
582  if (rc != CS_OK) {
583  crm_warn("Could not connect to Cluster Configuration Database API, error %d", rc);
584  return false;
585  }
586 
587  rc = cmap_fd_get(cmap_handle, &fd);
588  if (rc != CS_OK) {
589  crm_err("Could not obtain the CMAP API connection: %s (%d)",
590  cs_strerror(rc), rc);
591  goto bail;
592  }
593 
594  /* CMAP provider run as root (in given user namespace, anyway)? */
595  if (!(rv = crm_ipc_is_authentic_process(fd, (uid_t) 0,(gid_t) 0, &found_pid,
596  &found_uid, &found_gid))) {
597  crm_err("CMAP provider is not authentic:"
598  " process %lld (uid: %lld, gid: %lld)",
599  (long long) PCMK__SPECIAL_PID_AS_0(found_pid),
600  (long long) found_uid, (long long) found_gid);
601  goto bail;
602  } else if (rv < 0) {
603  crm_err("Could not verify authenticity of CMAP provider: %s (%d)",
604  strerror(-rv), -rv);
605  goto bail;
606  }
607 
609  crm_trace("Initializing Corosync node list");
610  for (lpc = 0; TRUE; lpc++) {
611  uint32_t nodeid = 0;
612  char *name = NULL;
613  char *key = NULL;
614 
615  key = crm_strdup_printf("nodelist.node.%d.nodeid", lpc);
616  rc = cmap_get_uint32(cmap_handle, key, &nodeid);
617  free(key);
618 
619  if (rc != CS_OK) {
620  break;
621  }
622 
623  name = pcmk__corosync_name(cmap_handle, nodeid);
624  if (name != NULL) {
625  GHashTableIter iter;
626  pcmk__node_status_t *node = NULL;
627 
628  g_hash_table_iter_init(&iter, pcmk__peer_cache);
629  while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) {
630  if ((node != NULL)
631  && (node->cluster_layer_id > 0)
632  && (node->cluster_layer_id != nodeid)
633  && pcmk__str_eq(node->name, name, pcmk__str_casei)) {
634 
635  crm_crit("Nodes %" PRIu32 " and %" PRIu32 " share the "
636  "same name '%s': shutting down",
637  node->cluster_layer_id, nodeid, name);
639  }
640  }
641  }
642 
643  if (nodeid > 0 || name != NULL) {
644  crm_trace("Initializing node[%d] %u = %s", lpc, nodeid, name);
646  }
647 
648  if (nodeid > 0 && name != NULL) {
649  any = true;
650 
651  if (xml_parent) {
652  xmlNode *node = pcmk__xe_create(xml_parent, PCMK_XE_NODE);
653 
654  crm_xml_add_ll(node, PCMK_XA_ID, (long long) nodeid);
656  }
657  }
658 
659  free(name);
660  }
661 bail:
662  cmap_finalize(cmap_handle);
663  return any;
664 }
665 
672 char *
674 {
675  cmap_handle_t handle;
676  char *cluster_name = NULL;
677  cs_error_t rc = CS_OK;
678  int fd = -1;
679  uid_t found_uid = 0;
680  gid_t found_gid = 0;
681  pid_t found_pid = 0;
682  int rv;
683 
684  rc = pcmk__init_cmap(&handle);
685  if (rc != CS_OK) {
686  crm_info("Failed to initialize the cmap API: %s (%d)",
687  cs_strerror(rc), rc);
688  return NULL;
689  }
690 
691  rc = cmap_fd_get(handle, &fd);
692  if (rc != CS_OK) {
693  crm_err("Could not obtain the CMAP API connection: %s (%d)",
694  cs_strerror(rc), rc);
695  goto bail;
696  }
697 
698  /* CMAP provider run as root (in given user namespace, anyway)? */
699  if (!(rv = crm_ipc_is_authentic_process(fd, (uid_t) 0,(gid_t) 0, &found_pid,
700  &found_uid, &found_gid))) {
701  crm_err("CMAP provider is not authentic:"
702  " process %lld (uid: %lld, gid: %lld)",
703  (long long) PCMK__SPECIAL_PID_AS_0(found_pid),
704  (long long) found_uid, (long long) found_gid);
705  goto bail;
706  } else if (rv < 0) {
707  crm_err("Could not verify authenticity of CMAP provider: %s (%d)",
708  strerror(-rv), -rv);
709  goto bail;
710  }
711 
712  rc = cmap_get_string(handle, "totem.cluster_name", &cluster_name);
713  if (rc != CS_OK) {
714  crm_info("Cannot get totem.cluster_name: %s (%d)", cs_strerror(rc), rc);
715 
716  } else {
717  crm_debug("cmap totem.cluster_name = '%s'", cluster_name);
718  }
719 
720 bail:
721  cmap_finalize(handle);
722  return cluster_name;
723 }
724 
731 bool
733 {
734  cs_error_t cs_rc = CS_OK;
735  int retries = 0;
736  cmap_handle_t cmap_handle;
737  cmap_iter_handle_t iter_handle;
738  char key_name[CMAP_KEYNAME_MAXLEN + 1];
739  int fd = -1;
740  uid_t found_uid = 0;
741  gid_t found_gid = 0;
742  pid_t found_pid = 0;
743  int rc = pcmk_ok;
744 
745  static bool got_result = false;
746  static bool result = false;
747 
748  if (got_result) {
749  return result;
750  }
751 
752  // Connect to CMAP
753  do {
754  cs_rc = pcmk__init_cmap(&cmap_handle);
755  if (cs_rc != CS_OK) {
756  retries++;
757  crm_debug("CMAP connection failed: %s (rc=%d, retrying in %ds)",
758  cs_strerror(cs_rc), cs_rc, retries);
759  sleep(retries);
760  }
761  } while ((retries < 5) && (cs_rc != CS_OK));
762  if (cs_rc != CS_OK) {
763  crm_warn("Assuming Corosync does not have node list: "
764  "CMAP connection failed (%s) " QB_XS " rc=%d",
765  cs_strerror(cs_rc), cs_rc);
766  return false;
767  }
768 
769  // Get CMAP connection file descriptor
770  cs_rc = cmap_fd_get(cmap_handle, &fd);
771  if (cs_rc != CS_OK) {
772  crm_warn("Assuming Corosync does not have node list: "
773  "CMAP unusable (%s) " QB_XS " rc=%d",
774  cs_strerror(cs_rc), cs_rc);
775  goto bail;
776  }
777 
778  // Check whether CMAP connection is authentic (i.e. provided by root)
779  rc = crm_ipc_is_authentic_process(fd, (uid_t) 0, (gid_t) 0,
780  &found_pid, &found_uid, &found_gid);
781  if (rc == 0) {
782  crm_warn("Assuming Corosync does not have node list: "
783  "CMAP provider is inauthentic "
784  QB_XS " pid=%lld uid=%lld gid=%lld",
785  (long long) PCMK__SPECIAL_PID_AS_0(found_pid),
786  (long long) found_uid, (long long) found_gid);
787  goto bail;
788  } else if (rc < 0) {
789  crm_warn("Assuming Corosync does not have node list: "
790  "Could not verify CMAP authenticity (%s) " QB_XS " rc=%d",
791  pcmk_strerror(rc), rc);
792  goto bail;
793  }
794 
795  // Check whether nodelist section is presetn
796  cs_rc = cmap_iter_init(cmap_handle, "nodelist", &iter_handle);
797  if (cs_rc != CS_OK) {
798  crm_warn("Assuming Corosync does not have node list: "
799  "CMAP not readable (%s) " QB_XS " rc=%d",
800  cs_strerror(cs_rc), cs_rc);
801  goto bail;
802  }
803 
804  cs_rc = cmap_iter_next(cmap_handle, iter_handle, key_name, NULL, NULL);
805  if (cs_rc == CS_OK) {
806  result = true;
807  }
808 
809  cmap_iter_finalize(cmap_handle, iter_handle);
810  got_result = true;
811  crm_debug("Corosync %s node list", (result? "has" : "does not have"));
812 
813 bail:
814  cmap_finalize(cmap_handle);
815  return result;
816 }
pcmk__node_status_t * pcmk__get_node(unsigned int id, const char *uname, const char *xml_id, uint32_t flags)
Definition: membership.c:927
#define crm_notice(fmt, args...)
Definition: logging.h:365
uint32_t pcmk__cpg_local_nodeid(cpg_handle_t handle)
Definition: cpg.c:106
const char * pcmk_strerror(int rc)
Definition: results.c:257
#define crm_crit(fmt, args...)
Definition: logging.h:356
mainloop_io_t * mainloop_add_fd(const char *name, int priority, int fd, void *userdata, struct mainloop_fd_callbacks *callbacks)
Definition: mainloop.c:956
_Noreturn crm_exit_t crm_exit(crm_exit_t rc)
Definition: results.c:1044
Corosync Cluster Engine.
Definition: cluster.h:75
const char * pcmk_cluster_layer_text(enum pcmk_cluster_layer layer)
Get a log-friendly string equivalent of a cluster layer.
Definition: cluster.c:352
void pcmk__reap_unseen_nodes(uint64_t ring_id)
Definition: membership.c:1334
const char * name
Definition: cib.c:26
char * pcmk__corosync_name(uint64_t cmap_handle, uint32_t nodeid)
Definition: corosync.c:101
void(* destroy)(gpointer userdata)
Destroy function for mainloop file descriptor client data.
Definition: mainloop.h:157
Search for cluster nodes from membership cache.
Definition: internal.h:64
void pcmk__corosync_quorum_connect(gboolean(*dispatch)(unsigned long long, gboolean), void(*destroy)(gpointer))
Definition: corosync.c:347
#define PCMK__SPECIAL_PID_AS_0(p)
Definition: ipc_internal.h:53
bool pcmk__corosync_add_nodes(xmlNode *xml_parent)
Definition: corosync.c:558
char * node_name
Local node name at cluster layer.
Definition: internal.h:93
uint32_t cluster_layer_id
Cluster-layer numeric node ID.
Definition: internal.h:166
char * pcmk__corosync_cluster_name(void)
Definition: corosync.c:673
Wrappers for and extensions to glib mainloop.
xmlNode * pcmk__xe_create(xmlNode *parent, const char *name)
Definition: xml_element.c:407
int pcmk__cpg_connect(pcmk_cluster_t *cluster)
Connect to Corosync CPG.
Definition: cpg.c:781
const char * crm_xml_add_ll(xmlNode *node, const char *name, long long value)
Create an XML attribute with specified name and long long int value.
Definition: xml_element.c:1120
G_GNUC_INTERNAL void pcmk__cluster_set_quorum(bool quorate)
Definition: membership.c:108
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
Definition: xml_element.c:1015
int(* dispatch)(gpointer userdata)
Dispatch function for mainloop file descriptor with data ready.
Definition: mainloop.h:150
#define crm_warn(fmt, args...)
Definition: logging.h:362
#define crm_debug(fmt, args...)
Definition: logging.h:370
#define PCMK_XA_UNAME
Definition: xml_names.h:431
bool pcmk__cluster_has_quorum(void)
Definition: membership.c:96
int pcmk__corosync_connect(pcmk_cluster_t *cluster)
Definition: corosync.c:459
#define crm_trace(fmt, args...)
Definition: logging.h:372
#define PCMK_VALUE_MEMBER
Definition: options.h:170
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
Definition: util.h:80
char * pcmk__corosync_uuid(const pcmk__node_status_t *node)
Definition: corosync.c:53
Wrappers for and extensions to libxml2.
uint32_t processes
Definition: internal.h:145
void pcmk__cluster_init_node_caches(void)
Definition: membership.c:562
#define PCMK_XA_ID
Definition: xml_names.h:301
uint32_t node_id
Local node ID at cluster layer.
Definition: internal.h:99
#define pcmk__assert(expr)
bool pcmk__corosync_is_peer_active(const pcmk__node_status_t *node)
Definition: corosync.c:530
#define PCMK_XE_NODE
Definition: xml_names.h:136
pcmk__action_result_t result
Definition: pcmk_fence.c:37
void pcmk__cpg_disconnect(pcmk_cluster_t *cluster)
Definition: cpg.c:890
#define crm_err(fmt, args...)
Definition: logging.h:359
pcmk__node_status_t * pcmk__update_peer_state(const char *source, pcmk__node_status_t *node, const char *state, uint64_t membership)
Update a node&#39;s state and membership information.
Definition: membership.c:1321
GHashTable * pcmk__peer_cache
Definition: membership.c:37
pcmk_cluster_layer
Types of cluster layer.
Definition: cluster.h:72
char * pcmk__cluster_node_name(uint32_t nodeid)
Definition: cluster.c:233
bool pcmk__corosync_has_nodelist(void)
Definition: corosync.c:732
#define pcmk_ok
Definition: results.h:65
IPC interface to Pacemaker daemons.
bool pcmk__corosync_is_active(void)
Definition: corosync.c:506
#define crm_info(fmt, args...)
Definition: logging.h:367
Do not respawn.
Definition: results.h:262
pcmk__cluster_private_t * priv
Definition: cluster.h:36
Node status data (may be a cluster node or a Pacemaker Remote node)
Definition: internal.h:112
enum pcmk_cluster_layer pcmk_get_cluster_layer(void)
Get and validate the local cluster layer.
Definition: cluster.c:379
char * name
Node name as known to cluster layer, or Pacemaker Remote node name.
Definition: internal.h:114
void pcmk__corosync_disconnect(pcmk_cluster_t *cluster)
Definition: corosync.c:223
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
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 (legacy)
Definition: ipc_client.c:1532