pacemaker  2.1.8-3980678f03
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, PRIx32
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->id > 0) {
59  return crm_strdup_printf("%u", node->id);
60  } else {
61  crm_info("Node %s is not yet known by Corosync", node->uname);
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  crm_node_t *node = NULL;
274  static gboolean init_phase = TRUE;
275 
276  if (quorate != crm_have_quorum) {
277  if (quorate) {
278  crm_notice("Quorum acquired " CRM_XS " membership=%" PRIu64 " members=%lu",
279  ring_id, (long unsigned int)view_list_entries);
280  } else {
281  crm_warn("Quorum lost " CRM_XS " membership=%" PRIu64 " members=%lu",
282  ring_id, (long unsigned int)view_list_entries);
283  }
284  crm_have_quorum = quorate;
285 
286  } else {
287  crm_info("Quorum %s " CRM_XS " membership=%" PRIu64 " members=%lu",
288  (quorate? "retained" : "still lost"), ring_id,
289  (long unsigned int)view_list_entries);
290  }
291 
292  if (view_list_entries == 0 && init_phase) {
293  crm_info("Corosync membership is still forming, ignoring");
294  return;
295  }
296 
297  init_phase = FALSE;
298 
299  /* Reset last_seen for all cached nodes so we can tell which ones aren't
300  * in the view list */
301  g_hash_table_iter_init(&iter, crm_peer_cache);
302  while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) {
303  node->last_seen = 0;
304  }
305 
306  /* Update the peer cache for each node in view list */
307  for (i = 0; i < view_list_entries; i++) {
308  uint32_t id = view_list[i];
309 
310  crm_debug("Member[%d] %u ", i, id);
311 
312  /* Get this node's peer cache entry (adding one if not already there) */
313  node = pcmk__get_node(id, NULL, NULL, pcmk__node_search_cluster_member);
314  if (node->uname == NULL) {
315  char *name = pcmk__corosync_name(0, id);
316 
317  crm_info("Obtaining name for new node %u", id);
318  node = pcmk__get_node(id, name, NULL,
320  free(name);
321  }
322 
323  /* Update the node state (including updating last_seen to ring_id) */
324  pcmk__update_peer_state(__func__, node, CRM_NODE_MEMBER, ring_id);
325  }
326 
327  /* Remove any peer cache entries we didn't update */
328  pcmk__reap_unseen_nodes(ring_id);
329 
330  if (quorum_app_callback) {
331  quorum_app_callback(ring_id, quorate);
332  }
333 }
334 
342 void
343 pcmk__corosync_quorum_connect(gboolean (*dispatch)(unsigned long long,
344  gboolean),
345  void (*destroy)(gpointer))
346 {
347  cs_error_t rc;
348  int fd = 0;
349  int quorate = 0;
350  uint32_t quorum_type = 0;
351  struct mainloop_fd_callbacks quorum_fd_callbacks;
352  uid_t found_uid = 0;
353  gid_t found_gid = 0;
354  pid_t found_pid = 0;
355  int rv;
356 
357  quorum_fd_callbacks.dispatch = quorum_dispatch_cb;
358  quorum_fd_callbacks.destroy = destroy;
359 
360  crm_debug("Configuring Pacemaker to obtain quorum from Corosync");
361 
362  {
363 #if 0
364  // New way but not supported by all Corosync 2 versions
365  quorum_model_v0_data_t quorum_model_data = {
366  .model = QUORUM_MODEL_V0,
367  .quorum_notify_fn = quorum_notification_cb,
368  };
369 
370  rc = quorum_model_initialize(&pcmk_quorum_handle, QUORUM_MODEL_V0,
371  (quorum_model_data_t *) &quorum_model_data,
372  &quorum_type, NULL);
373 #else
374  quorum_callbacks_t quorum_callbacks = {
375  .quorum_notify_fn = quorum_notification_cb,
376  };
377 
378  rc = quorum_initialize(&pcmk_quorum_handle, &quorum_callbacks,
379  &quorum_type);
380 #endif
381  }
382 
383  if (rc != CS_OK) {
384  crm_err("Could not connect to the Quorum API: %s (%d)",
385  cs_strerror(rc), rc);
386  goto bail;
387 
388  } else if (quorum_type != QUORUM_SET) {
389  crm_err("Corosync quorum is not configured");
390  goto bail;
391  }
392 
393  rc = quorum_fd_get(pcmk_quorum_handle, &fd);
394  if (rc != CS_OK) {
395  crm_err("Could not obtain the Quorum API connection: %s (%d)",
396  strerror(rc), rc);
397  goto bail;
398  }
399 
400  /* Quorum provider run as root (in given user namespace, anyway)? */
401  if (!(rv = crm_ipc_is_authentic_process(fd, (uid_t) 0,(gid_t) 0, &found_pid,
402  &found_uid, &found_gid))) {
403  crm_err("Quorum provider is not authentic:"
404  " process %lld (uid: %lld, gid: %lld)",
405  (long long) PCMK__SPECIAL_PID_AS_0(found_pid),
406  (long long) found_uid, (long long) found_gid);
407  rc = CS_ERR_ACCESS;
408  goto bail;
409  } else if (rv < 0) {
410  crm_err("Could not verify authenticity of Quorum provider: %s (%d)",
411  strerror(-rv), -rv);
412  rc = CS_ERR_ACCESS;
413  goto bail;
414  }
415 
416  rc = quorum_getquorate(pcmk_quorum_handle, &quorate);
417  if (rc != CS_OK) {
418  crm_err("Could not obtain the current Quorum API state: %d", rc);
419  goto bail;
420  }
421 
422  if (quorate) {
423  crm_notice("Quorum acquired");
424  } else {
425  crm_warn("No quorum");
426  }
427  quorum_app_callback = dispatch;
428  crm_have_quorum = quorate;
429 
430  rc = quorum_trackstart(pcmk_quorum_handle, CS_TRACK_CHANGES | CS_TRACK_CURRENT);
431  if (rc != CS_OK) {
432  crm_err("Could not setup Quorum API notifications: %d", rc);
433  goto bail;
434  }
435 
436  mainloop_add_fd("quorum", G_PRIORITY_HIGH, fd, dispatch, &quorum_fd_callbacks);
437 
439 
440  bail:
441  if (rc != CS_OK) {
442  quorum_finalize(pcmk_quorum_handle);
443  }
444 }
445 
454 int
456 {
457  crm_node_t *peer = NULL;
458  const enum pcmk_cluster_layer cluster_layer = pcmk_get_cluster_layer();
459  const char *cluster_layer_s = pcmk_cluster_layer_text(cluster_layer);
460  int rc = pcmk_rc_ok;
461 
463 
464  if (cluster_layer != pcmk_cluster_layer_corosync) {
465  crm_err("Invalid cluster layer: %s " CRM_XS " cluster_layer=%d",
466  cluster_layer_s, cluster_layer);
467  return EINVAL;
468  }
469 
470  rc = pcmk__cpg_connect(cluster);
471  if (rc != pcmk_rc_ok) {
472  // Error message was logged by pcmk__cpg_connect()
473  return rc;
474  }
475  crm_info("Connection to %s established", cluster_layer_s);
476 
477  cluster->nodeid = pcmk__cpg_local_nodeid(0);
478  if (cluster->nodeid == 0) {
479  crm_err("Could not determine local node ID");
480  return ENXIO;
481  }
482 
483  cluster->uname = pcmk__cluster_node_name(0);
484  if (cluster->uname == NULL) {
485  crm_err("Could not determine local node name");
486  return ENXIO;
487  }
488 
489  // Ensure local node always exists in peer cache
490  peer = pcmk__get_node(cluster->nodeid, cluster->uname, NULL,
492  cluster->uuid = pcmk__corosync_uuid(peer);
493 
494  return pcmk_rc_ok;
495 }
496 
503 bool
505 {
506  cmap_handle_t handle;
507  int rc = pcmk__init_cmap(&handle);
508 
509  if (rc == CS_OK) {
510  cmap_finalize(handle);
511  return true;
512  }
513 
514  crm_info("Failed to initialize the cmap API: %s (%d)",
515  pcmk__cs_err_str(rc), rc);
516  return false;
517 }
518 
527 bool
529 {
530  if (node == NULL) {
531  crm_trace("Corosync peer inactive: NULL");
532  return false;
533  }
534  if (!pcmk__str_eq(node->state, CRM_NODE_MEMBER, pcmk__str_none)) {
535  crm_trace("Corosync peer %s inactive: state=%s",
536  node->uname, node->state);
537  return false;
538  }
539  if (!pcmk_is_set(node->processes, crm_proc_cpg)) {
540  crm_trace("Corosync peer %s inactive " CRM_XS " processes=%.16" PRIx32,
541  node->uname, node->processes);
542  return false;
543  }
544  return true;
545 }
546 
555 bool
556 pcmk__corosync_add_nodes(xmlNode *xml_parent)
557 {
558  int lpc = 0;
559  cs_error_t rc = CS_OK;
560  int retries = 0;
561  bool any = false;
562  cmap_handle_t cmap_handle;
563  int fd = -1;
564  uid_t found_uid = 0;
565  gid_t found_gid = 0;
566  pid_t found_pid = 0;
567  int rv;
568 
569  do {
570  rc = pcmk__init_cmap(&cmap_handle);
571  if (rc != CS_OK) {
572  retries++;
573  crm_debug("API connection setup failed: %s. Retrying in %ds", cs_strerror(rc),
574  retries);
575  sleep(retries);
576  }
577 
578  } while (retries < 5 && rc != CS_OK);
579 
580  if (rc != CS_OK) {
581  crm_warn("Could not connect to Cluster Configuration Database API, error %d", rc);
582  return false;
583  }
584 
585  rc = cmap_fd_get(cmap_handle, &fd);
586  if (rc != CS_OK) {
587  crm_err("Could not obtain the CMAP API connection: %s (%d)",
588  cs_strerror(rc), rc);
589  goto bail;
590  }
591 
592  /* CMAP provider run as root (in given user namespace, anyway)? */
593  if (!(rv = crm_ipc_is_authentic_process(fd, (uid_t) 0,(gid_t) 0, &found_pid,
594  &found_uid, &found_gid))) {
595  crm_err("CMAP provider is not authentic:"
596  " process %lld (uid: %lld, gid: %lld)",
597  (long long) PCMK__SPECIAL_PID_AS_0(found_pid),
598  (long long) found_uid, (long long) found_gid);
599  goto bail;
600  } else if (rv < 0) {
601  crm_err("Could not verify authenticity of CMAP provider: %s (%d)",
602  strerror(-rv), -rv);
603  goto bail;
604  }
605 
607  crm_trace("Initializing Corosync node list");
608  for (lpc = 0; TRUE; lpc++) {
609  uint32_t nodeid = 0;
610  char *name = NULL;
611  char *key = NULL;
612 
613  key = crm_strdup_printf("nodelist.node.%d.nodeid", lpc);
614  rc = cmap_get_uint32(cmap_handle, key, &nodeid);
615  free(key);
616 
617  if (rc != CS_OK) {
618  break;
619  }
620 
621  name = pcmk__corosync_name(cmap_handle, nodeid);
622  if (name != NULL) {
623  GHashTableIter iter;
624  crm_node_t *node = NULL;
625 
626  g_hash_table_iter_init(&iter, crm_peer_cache);
627  while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) {
628  if(node && node->uname && strcasecmp(node->uname, name) == 0) {
629  if (node->id && node->id != nodeid) {
630  crm_crit("Nodes %u and %u share the same name '%s': shutting down", node->id,
631  nodeid, name);
633  }
634  }
635  }
636  }
637 
638  if (nodeid > 0 || name != NULL) {
639  crm_trace("Initializing node[%d] %u = %s", lpc, nodeid, name);
641  }
642 
643  if (nodeid > 0 && name != NULL) {
644  any = true;
645 
646  if (xml_parent) {
647  xmlNode *node = pcmk__xe_create(xml_parent, PCMK_XE_NODE);
648 
649  crm_xml_add_ll(node, PCMK_XA_ID, (long long) nodeid);
651  }
652  }
653 
654  free(name);
655  }
656 bail:
657  cmap_finalize(cmap_handle);
658  return any;
659 }
660 
667 char *
669 {
670  cmap_handle_t handle;
671  char *cluster_name = NULL;
672  cs_error_t rc = CS_OK;
673  int fd = -1;
674  uid_t found_uid = 0;
675  gid_t found_gid = 0;
676  pid_t found_pid = 0;
677  int rv;
678 
679  rc = pcmk__init_cmap(&handle);
680  if (rc != CS_OK) {
681  crm_info("Failed to initialize the cmap API: %s (%d)",
682  cs_strerror(rc), rc);
683  return NULL;
684  }
685 
686  rc = cmap_fd_get(handle, &fd);
687  if (rc != CS_OK) {
688  crm_err("Could not obtain the CMAP API connection: %s (%d)",
689  cs_strerror(rc), rc);
690  goto bail;
691  }
692 
693  /* CMAP provider run as root (in given user namespace, anyway)? */
694  if (!(rv = crm_ipc_is_authentic_process(fd, (uid_t) 0,(gid_t) 0, &found_pid,
695  &found_uid, &found_gid))) {
696  crm_err("CMAP provider is not authentic:"
697  " process %lld (uid: %lld, gid: %lld)",
698  (long long) PCMK__SPECIAL_PID_AS_0(found_pid),
699  (long long) found_uid, (long long) found_gid);
700  goto bail;
701  } else if (rv < 0) {
702  crm_err("Could not verify authenticity of CMAP provider: %s (%d)",
703  strerror(-rv), -rv);
704  goto bail;
705  }
706 
707  rc = cmap_get_string(handle, "totem.cluster_name", &cluster_name);
708  if (rc != CS_OK) {
709  crm_info("Cannot get totem.cluster_name: %s (%d)", cs_strerror(rc), rc);
710 
711  } else {
712  crm_debug("cmap totem.cluster_name = '%s'", cluster_name);
713  }
714 
715 bail:
716  cmap_finalize(handle);
717  return cluster_name;
718 }
719 
726 bool
728 {
729  cs_error_t cs_rc = CS_OK;
730  int retries = 0;
731  cmap_handle_t cmap_handle;
732  cmap_iter_handle_t iter_handle;
733  char key_name[CMAP_KEYNAME_MAXLEN + 1];
734  int fd = -1;
735  uid_t found_uid = 0;
736  gid_t found_gid = 0;
737  pid_t found_pid = 0;
738  int rc = pcmk_ok;
739 
740  static bool got_result = false;
741  static bool result = false;
742 
743  if (got_result) {
744  return result;
745  }
746 
747  // Connect to CMAP
748  do {
749  cs_rc = pcmk__init_cmap(&cmap_handle);
750  if (cs_rc != CS_OK) {
751  retries++;
752  crm_debug("CMAP connection failed: %s (rc=%d, retrying in %ds)",
753  cs_strerror(cs_rc), cs_rc, retries);
754  sleep(retries);
755  }
756  } while ((retries < 5) && (cs_rc != CS_OK));
757  if (cs_rc != CS_OK) {
758  crm_warn("Assuming Corosync does not have node list: "
759  "CMAP connection failed (%s) " CRM_XS " rc=%d",
760  cs_strerror(cs_rc), cs_rc);
761  return false;
762  }
763 
764  // Get CMAP connection file descriptor
765  cs_rc = cmap_fd_get(cmap_handle, &fd);
766  if (cs_rc != CS_OK) {
767  crm_warn("Assuming Corosync does not have node list: "
768  "CMAP unusable (%s) " CRM_XS " rc=%d",
769  cs_strerror(cs_rc), cs_rc);
770  goto bail;
771  }
772 
773  // Check whether CMAP connection is authentic (i.e. provided by root)
774  rc = crm_ipc_is_authentic_process(fd, (uid_t) 0, (gid_t) 0,
775  &found_pid, &found_uid, &found_gid);
776  if (rc == 0) {
777  crm_warn("Assuming Corosync does not have node list: "
778  "CMAP provider is inauthentic "
779  CRM_XS " pid=%lld uid=%lld gid=%lld",
780  (long long) PCMK__SPECIAL_PID_AS_0(found_pid),
781  (long long) found_uid, (long long) found_gid);
782  goto bail;
783  } else if (rc < 0) {
784  crm_warn("Assuming Corosync does not have node list: "
785  "Could not verify CMAP authenticity (%s) " CRM_XS " rc=%d",
786  pcmk_strerror(rc), rc);
787  goto bail;
788  }
789 
790  // Check whether nodelist section is presetn
791  cs_rc = cmap_iter_init(cmap_handle, "nodelist", &iter_handle);
792  if (cs_rc != CS_OK) {
793  crm_warn("Assuming Corosync does not have node list: "
794  "CMAP not readable (%s) " CRM_XS " rc=%d",
795  cs_strerror(cs_rc), cs_rc);
796  goto bail;
797  }
798 
799  cs_rc = cmap_iter_next(cmap_handle, iter_handle, key_name, NULL, NULL);
800  if (cs_rc == CS_OK) {
801  result = true;
802  }
803 
804  cmap_iter_finalize(cmap_handle, iter_handle);
805  got_result = true;
806  crm_debug("Corosync %s node list", (result? "has" : "does not have"));
807 
808 bail:
809  cmap_finalize(cmap_handle);
810  return result;
811 }
812 
813 // Deprecated functions kept only for backward API compatibility
814 // LCOV_EXCL_START
815 
816 #include <crm/cluster/compat.h>
817 
818 gboolean
820 {
821  return pcmk__corosync_is_peer_active(node);
822 }
823 
824 // LCOV_EXCL_STOP
825 // End deprecated API
#define crm_notice(fmt, args...)
Definition: logging.h:397
uint32_t pcmk__cpg_local_nodeid(cpg_handle_t handle)
Definition: cpg.c:101
const char * pcmk_strerror(int rc)
Definition: results.c:149
crm_node_t * pcmk__get_node(unsigned int id, const char *uname, const char *uuid, uint32_t flags)
Definition: membership.c:890
#define crm_crit(fmt, args...)
Definition: logging.h:388
mainloop_io_t * mainloop_add_fd(const char *name, int priority, int fd, void *userdata, struct mainloop_fd_callbacks *callbacks)
Definition: mainloop.c:958
uint32_t nodeid
Definition: cluster.h:142
_Noreturn crm_exit_t crm_exit(crm_exit_t rc)
Definition: results.c:936
bool pcmk__corosync_is_peer_active(const crm_node_t *node)
Definition: corosync.c:528
Corosync Cluster Engine.
Definition: cluster.h:228
const char * pcmk_cluster_layer_text(enum pcmk_cluster_layer layer)
Get a log-friendly string equivalent of a cluster layer.
Definition: cluster.c:388
void pcmk__reap_unseen_nodes(uint64_t ring_id)
Definition: membership.c:1291
const char * name
Definition: cib.c:26
uint32_t id
Definition: cluster.h:120
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:155
gboolean crm_have_quorum
Definition: membership.c:68
Search for cluster nodes from membership cache.
Definition: internal.h:37
void pcmk__corosync_quorum_connect(gboolean(*dispatch)(unsigned long long, gboolean), void(*destroy)(gpointer))
Definition: corosync.c:343
#define PCMK__SPECIAL_PID_AS_0(p)
Definition: ipc_internal.h:61
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:301
bool pcmk__corosync_add_nodes(xmlNode *xml_parent)
Definition: corosync.c:556
char * uuid
Definition: cluster.h:140
char * pcmk__corosync_cluster_name(void)
Definition: corosync.c:668
Wrappers for and extensions to glib mainloop.
int pcmk__cpg_connect(pcmk_cluster_t *cluster)
Connect to Corosync CPG.
Definition: cpg.c:829
gboolean crm_is_corosync_peer_active(const crm_node_t *node)
Definition: corosync.c:819
int(* dispatch)(gpointer userdata)
Dispatch function for mainloop file descriptor with data ready.
Definition: mainloop.h:148
#define crm_warn(fmt, args...)
Definition: logging.h:394
crm_node_t * pcmk__update_peer_state(const char *source, crm_node_t *node, const char *state, uint64_t membership)
Update a node&#39;s state and membership information.
Definition: membership.c:1278
uint32_t processes
Definition: cluster.h:112
#define crm_debug(fmt, args...)
Definition: logging.h:402
#define PCMK_XA_UNAME
Definition: xml_names.h:426
int pcmk__corosync_connect(pcmk_cluster_t *cluster)
Definition: corosync.c:455
#define crm_trace(fmt, args...)
Definition: logging.h:404
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
Definition: util.h:98
Wrappers for and extensions to libxml2.
void pcmk__cluster_init_node_caches(void)
Definition: membership.c:537
#define CRM_NODE_MEMBER
Definition: cluster.h:49
#define PCMK_XA_ID
Definition: xml_names.h:296
Deprecated Pacemaker cluster API.
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: nvpair.c:398
#define CRM_XS
Definition: logging.h:56
char * uname
Definition: cluster.h:141
#define PCMK_XE_NODE
Definition: xml_names.h:133
pcmk__action_result_t result
Definition: pcmk_fence.c:35
void pcmk__cpg_disconnect(pcmk_cluster_t *cluster)
Definition: cpg.c:933
#define crm_err(fmt, args...)
Definition: logging.h:391
#define CRM_ASSERT(expr)
Definition: results.h:42
pcmk_cluster_layer
Types of cluster layer.
Definition: cluster.h:225
char * pcmk__cluster_node_name(uint32_t nodeid)
Definition: cluster.c:269
char * state
Definition: cluster.h:109
bool pcmk__corosync_has_nodelist(void)
Definition: corosync.c:727
#define pcmk_ok
Definition: results.h:69
IPC interface to Pacemaker daemons.
char * uname
Definition: cluster.h:88
char * pcmk__corosync_uuid(const crm_node_t *node)
Definition: corosync.c:53
bool pcmk__corosync_is_active(void)
Definition: corosync.c:504
xmlNode * pcmk__xe_create(xmlNode *parent, const char *name)
Definition: xml.c:720
GHashTable * crm_peer_cache
Definition: membership.c:40
#define crm_info(fmt, args...)
Definition: logging.h:399
Do not respawn.
Definition: results.h:286
enum pcmk_cluster_layer pcmk_get_cluster_layer(void)
Get and validate the local cluster layer.
Definition: cluster.c:415
void pcmk__corosync_disconnect(pcmk_cluster_t *cluster)
Definition: corosync.c:223
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:1580