pacemaker 3.0.1-16e74fc4da
Scalable High-Availability cluster resource manager
Loading...
Searching...
No Matches
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
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
38static quorum_handle_t pcmk_quorum_handle = 0;
39
40static gboolean (*quorum_app_callback)(unsigned long long seq,
41 gboolean quorate) = NULL;
42
52char *
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
67static bool
68node_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 */
100char *
101pcmk__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
205bail:
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
222void
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
242static int
243quorum_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
266static void
267quorum_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 */
333
334 if (quorum_app_callback) {
335 quorum_app_callback(ring_id, is_quorate);
336 }
337}
338
346void
347pcmk__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
458int
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 pcmk__node_status_t *local_node = NULL;
464 int rc = pcmk_rc_ok;
465
467
468 if (cluster_layer != pcmk_cluster_layer_corosync) {
469 crm_err("Invalid cluster layer: %s " QB_XS " cluster_layer=%d",
470 cluster_layer_s, cluster_layer);
471 return EINVAL;
472 }
473
474 rc = pcmk__cpg_connect(cluster);
475 if (rc != pcmk_rc_ok) {
476 // Error message was logged by pcmk__cpg_connect()
477 return rc;
478 }
479 crm_info("Connection to %s established", cluster_layer_s);
480
481 cluster->priv->node_id = pcmk__cpg_local_nodeid(0);
482 if (cluster->priv->node_id == 0) {
483 crm_err("Could not determine local node ID");
484 return ENXIO;
485 }
486
488 if (cluster->priv->node_name == NULL) {
489 crm_err("Could not determine local node name");
490 return ENXIO;
491 }
492
493 // Ensure local node always exists in peer cache
494 local_node = pcmk__get_node(cluster->priv->node_id,
495 cluster->priv->node_name, NULL,
497
498 cluster->priv->node_xml_id = pcmk__corosync_uuid(local_node);
499 CRM_LOG_ASSERT(cluster->priv->node_xml_id != NULL);
500
501 return pcmk_rc_ok;
502}
503
510bool
512{
513 cmap_handle_t handle;
514 int rc = pcmk__init_cmap(&handle);
515
516 if (rc == CS_OK) {
517 cmap_finalize(handle);
518 return true;
519 }
520
521 crm_info("Failed to initialize the cmap API: %s (%d)",
522 pcmk__cs_err_str(rc), rc);
523 return false;
524}
525
534bool
536{
537 if (node == NULL) {
538 crm_trace("Corosync peer inactive: NULL");
539 return false;
540 }
541 if (!pcmk__str_eq(node->state, PCMK_VALUE_MEMBER, pcmk__str_none)) {
542 crm_trace("Corosync peer %s inactive: state=%s",
543 node->name, node->state);
544 return false;
545 }
546 if (!pcmk_is_set(node->processes, crm_proc_cpg)) {
547 crm_trace("Corosync peer %s inactive " QB_XS " processes=%.16" PRIx32,
548 node->name, node->processes);
549 return false;
550 }
551 return true;
552}
553
562bool
563pcmk__corosync_add_nodes(xmlNode *xml_parent)
564{
565 int lpc = 0;
566 cs_error_t rc = CS_OK;
567 int retries = 0;
568 bool any = false;
569 cmap_handle_t cmap_handle;
570 int fd = -1;
571 uid_t found_uid = 0;
572 gid_t found_gid = 0;
573 pid_t found_pid = 0;
574 int rv;
575
576 do {
577 rc = pcmk__init_cmap(&cmap_handle);
578 if (rc != CS_OK) {
579 retries++;
580 crm_debug("API connection setup failed: %s. Retrying in %ds", cs_strerror(rc),
581 retries);
582 sleep(retries);
583 }
584
585 } while (retries < 5 && rc != CS_OK);
586
587 if (rc != CS_OK) {
588 crm_warn("Could not connect to Cluster Configuration Database API, error %d", rc);
589 return false;
590 }
591
592 rc = cmap_fd_get(cmap_handle, &fd);
593 if (rc != CS_OK) {
594 crm_err("Could not obtain the CMAP API connection: %s (%d)",
595 cs_strerror(rc), rc);
596 goto bail;
597 }
598
599 /* CMAP provider run as root (in given user namespace, anyway)? */
600 if (!(rv = crm_ipc_is_authentic_process(fd, (uid_t) 0,(gid_t) 0, &found_pid,
601 &found_uid, &found_gid))) {
602 crm_err("CMAP provider is not authentic:"
603 " process %lld (uid: %lld, gid: %lld)",
604 (long long) PCMK__SPECIAL_PID_AS_0(found_pid),
605 (long long) found_uid, (long long) found_gid);
606 goto bail;
607 } else if (rv < 0) {
608 crm_err("Could not verify authenticity of CMAP provider: %s (%d)",
609 strerror(-rv), -rv);
610 goto bail;
611 }
612
614 crm_trace("Initializing Corosync node list");
615 for (lpc = 0; TRUE; lpc++) {
616 uint32_t nodeid = 0;
617 char *name = NULL;
618 char *key = NULL;
619
620 key = crm_strdup_printf("nodelist.node.%d.nodeid", lpc);
621 rc = cmap_get_uint32(cmap_handle, key, &nodeid);
622 free(key);
623
624 if (rc != CS_OK) {
625 break;
626 }
627
628 name = pcmk__corosync_name(cmap_handle, nodeid);
629 if (name != NULL) {
630 GHashTableIter iter;
631 pcmk__node_status_t *node = NULL;
632
633 g_hash_table_iter_init(&iter, pcmk__peer_cache);
634 while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) {
635 if ((node != NULL)
636 && (node->cluster_layer_id > 0)
637 && (node->cluster_layer_id != nodeid)
638 && pcmk__str_eq(node->name, name, pcmk__str_casei)) {
639
640 crm_crit("Nodes %" PRIu32 " and %" PRIu32 " share the "
641 "same name '%s': shutting down",
642 node->cluster_layer_id, nodeid, name);
644 }
645 }
646 }
647
648 if (nodeid > 0 || name != NULL) {
649 crm_trace("Initializing node[%d] %u = %s", lpc, nodeid, name);
651 }
652
653 if (nodeid > 0 && name != NULL) {
654 any = true;
655
656 if (xml_parent) {
657 xmlNode *node = pcmk__xe_create(xml_parent, PCMK_XE_NODE);
658
659 crm_xml_add_ll(node, PCMK_XA_ID, (long long) nodeid);
661 }
662 }
663
664 free(name);
665 }
666bail:
667 cmap_finalize(cmap_handle);
668 return any;
669}
670
677char *
679{
680 cmap_handle_t handle;
681 char *cluster_name = NULL;
682 cs_error_t rc = CS_OK;
683 int fd = -1;
684 uid_t found_uid = 0;
685 gid_t found_gid = 0;
686 pid_t found_pid = 0;
687 int rv;
688
689 rc = pcmk__init_cmap(&handle);
690 if (rc != CS_OK) {
691 crm_info("Failed to initialize the cmap API: %s (%d)",
692 cs_strerror(rc), rc);
693 return NULL;
694 }
695
696 rc = cmap_fd_get(handle, &fd);
697 if (rc != CS_OK) {
698 crm_err("Could not obtain the CMAP API connection: %s (%d)",
699 cs_strerror(rc), rc);
700 goto bail;
701 }
702
703 /* CMAP provider run as root (in given user namespace, anyway)? */
704 if (!(rv = crm_ipc_is_authentic_process(fd, (uid_t) 0,(gid_t) 0, &found_pid,
705 &found_uid, &found_gid))) {
706 crm_err("CMAP provider is not authentic:"
707 " process %lld (uid: %lld, gid: %lld)",
708 (long long) PCMK__SPECIAL_PID_AS_0(found_pid),
709 (long long) found_uid, (long long) found_gid);
710 goto bail;
711 } else if (rv < 0) {
712 crm_err("Could not verify authenticity of CMAP provider: %s (%d)",
713 strerror(-rv), -rv);
714 goto bail;
715 }
716
717 rc = cmap_get_string(handle, "totem.cluster_name", &cluster_name);
718 if (rc != CS_OK) {
719 crm_info("Cannot get totem.cluster_name: %s (%d)", cs_strerror(rc), rc);
720
721 } else {
722 crm_debug("cmap totem.cluster_name = '%s'", cluster_name);
723 }
724
725bail:
726 cmap_finalize(handle);
727 return cluster_name;
728}
729
736bool
738{
739 cs_error_t cs_rc = CS_OK;
740 int retries = 0;
741 cmap_handle_t cmap_handle;
742 cmap_iter_handle_t iter_handle;
743 char key_name[CMAP_KEYNAME_MAXLEN + 1];
744 int fd = -1;
745 uid_t found_uid = 0;
746 gid_t found_gid = 0;
747 pid_t found_pid = 0;
748 int rc = pcmk_ok;
749
750 static bool got_result = false;
751 static bool result = false;
752
753 if (got_result) {
754 return result;
755 }
756
757 // Connect to CMAP
758 do {
759 cs_rc = pcmk__init_cmap(&cmap_handle);
760 if (cs_rc != CS_OK) {
761 retries++;
762 crm_debug("CMAP connection failed: %s (rc=%d, retrying in %ds)",
763 cs_strerror(cs_rc), cs_rc, retries);
764 sleep(retries);
765 }
766 } while ((retries < 5) && (cs_rc != CS_OK));
767 if (cs_rc != CS_OK) {
768 crm_warn("Assuming Corosync does not have node list: "
769 "CMAP connection failed (%s) " QB_XS " rc=%d",
770 cs_strerror(cs_rc), cs_rc);
771 return false;
772 }
773
774 // Get CMAP connection file descriptor
775 cs_rc = cmap_fd_get(cmap_handle, &fd);
776 if (cs_rc != CS_OK) {
777 crm_warn("Assuming Corosync does not have node list: "
778 "CMAP unusable (%s) " QB_XS " rc=%d",
779 cs_strerror(cs_rc), cs_rc);
780 goto bail;
781 }
782
783 // Check whether CMAP connection is authentic (i.e. provided by root)
784 rc = crm_ipc_is_authentic_process(fd, (uid_t) 0, (gid_t) 0,
785 &found_pid, &found_uid, &found_gid);
786 if (rc == 0) {
787 crm_warn("Assuming Corosync does not have node list: "
788 "CMAP provider is inauthentic "
789 QB_XS " pid=%lld uid=%lld gid=%lld",
790 (long long) PCMK__SPECIAL_PID_AS_0(found_pid),
791 (long long) found_uid, (long long) found_gid);
792 goto bail;
793 } else if (rc < 0) {
794 crm_warn("Assuming Corosync does not have node list: "
795 "Could not verify CMAP authenticity (%s) " QB_XS " rc=%d",
796 pcmk_strerror(rc), rc);
797 goto bail;
798 }
799
800 // Check whether nodelist section is presetn
801 cs_rc = cmap_iter_init(cmap_handle, "nodelist", &iter_handle);
802 if (cs_rc != CS_OK) {
803 crm_warn("Assuming Corosync does not have node list: "
804 "CMAP not readable (%s) " QB_XS " rc=%d",
805 cs_strerror(cs_rc), cs_rc);
806 goto bail;
807 }
808
809 cs_rc = cmap_iter_next(cmap_handle, iter_handle, key_name, NULL, NULL);
810 if (cs_rc == CS_OK) {
811 result = true;
812 }
813
814 cmap_iter_finalize(cmap_handle, iter_handle);
815 got_result = true;
816 crm_debug("Corosync %s node list", (result? "has" : "does not have"));
817
818bail:
819 cmap_finalize(cmap_handle);
820 return result;
821}
const char * name
Definition cib.c:26
GHashTable * pcmk__peer_cache
Definition membership.c:37
@ pcmk__node_search_cluster_member
Search for cluster nodes from membership cache.
Definition internal.h:63
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's state and membership information.
@ crm_proc_cpg
Definition internal.h:35
pcmk__node_status_t * pcmk__get_node(unsigned int id, const char *uname, const char *xml_id, uint32_t flags)
Definition membership.c:947
bool pcmk__cluster_has_quorum(void)
Definition membership.c:96
void pcmk__cluster_init_node_caches(void)
Definition membership.c:568
char * pcmk__cluster_node_name(uint32_t nodeid)
Definition cluster.c:237
void pcmk__reap_unseen_nodes(uint64_t ring_id)
const char * pcmk_cluster_layer_text(enum pcmk_cluster_layer layer)
Get a log-friendly string equivalent of a cluster layer.
Definition cluster.c:357
enum pcmk_cluster_layer pcmk_get_cluster_layer(void)
Get and validate the local cluster layer.
Definition cluster.c:384
pcmk_cluster_layer
Types of cluster layer.
Definition cluster.h:69
@ pcmk_cluster_layer_corosync
Corosync Cluster Engine.
Definition cluster.h:72
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
Definition util.h:80
bool pcmk__corosync_is_active(void)
Definition corosync.c:511
char * pcmk__corosync_cluster_name(void)
Definition corosync.c:678
char * pcmk__corosync_name(uint64_t cmap_handle, uint32_t nodeid)
Definition corosync.c:101
bool pcmk__corosync_add_nodes(xmlNode *xml_parent)
Definition corosync.c:563
char * pcmk__corosync_uuid(const pcmk__node_status_t *node)
Definition corosync.c:53
int pcmk__corosync_connect(pcmk_cluster_t *cluster)
Definition corosync.c:459
void pcmk__corosync_quorum_connect(gboolean(*dispatch)(unsigned long long, gboolean), void(*destroy)(gpointer))
Definition corosync.c:347
bool pcmk__corosync_has_nodelist(void)
Definition corosync.c:737
void pcmk__corosync_disconnect(pcmk_cluster_t *cluster)
Definition corosync.c:223
bool pcmk__corosync_is_peer_active(const pcmk__node_status_t *node)
Definition corosync.c:535
int pcmk__cpg_connect(pcmk_cluster_t *cluster)
Connect to Corosync CPG.
Definition cpg.c:779
void pcmk__cpg_disconnect(pcmk_cluster_t *cluster)
Definition cpg.c:891
uint32_t pcmk__cpg_local_nodeid(cpg_handle_t handle)
Definition cpg.c:106
G_GNUC_INTERNAL void pcmk__cluster_set_quorum(bool quorate)
Definition membership.c:108
IPC interface to Pacemaker daemons.
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)
#define PCMK__SPECIAL_PID_AS_0(p)
#define crm_info(fmt, args...)
Definition logging.h:365
#define crm_warn(fmt, args...)
Definition logging.h:360
#define crm_crit(fmt, args...)
Definition logging.h:354
#define CRM_LOG_ASSERT(expr)
Definition logging.h:196
#define crm_notice(fmt, args...)
Definition logging.h:363
#define crm_debug(fmt, args...)
Definition logging.h:368
#define crm_err(fmt, args...)
Definition logging.h:357
#define crm_trace(fmt, args...)
Definition logging.h:370
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:962
#define PCMK_VALUE_MEMBER
Definition options.h:171
pcmk__action_result_t result
Definition pcmk_fence.c:37
const char * pcmk_strerror(int rc)
Definition results.c:257
@ CRM_EX_FATAL
Do not respawn.
Definition results.h:264
_Noreturn crm_exit_t crm_exit(crm_exit_t rc)
Definition results.c:1058
@ pcmk_rc_ok
Definition results.h:159
#define pcmk_ok
Definition results.h:65
#define pcmk__assert(expr)
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
@ pcmk__str_none
@ pcmk__str_casei
int(* dispatch)(gpointer userdata)
Dispatch function for mainloop file descriptor with data ready.
Definition mainloop.h:151
void(* destroy)(gpointer userdata)
Destroy function for mainloop file descriptor client data.
Definition mainloop.h:158
char * node_name
Local node name at cluster layer.
Definition internal.h:91
char * node_xml_id
Local node XML ID in CIB.
Definition internal.h:92
uint32_t node_id
Local node ID at cluster layer.
Definition internal.h:98
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:111
uint32_t cluster_layer_id
Cluster-layer numeric node ID.
Definition internal.h:165
uint32_t processes
Definition internal.h:144
char * name
Node name as known to cluster layer, or Pacemaker Remote node name.
Definition internal.h:113
Wrappers for and extensions to libxml2.
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.
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
xmlNode * pcmk__xe_create(xmlNode *parent, const char *name)
#define PCMK_XE_NODE
Definition xml_names.h:136
#define PCMK_XA_ID
Definition xml_names.h:301
#define PCMK_XA_UNAME
Definition xml_names.h:431