This source file includes following definitions.
- get_corosync_uuid
- corosync_node_name
- terminate_cs_connection
- pcmk_quorum_dispatch
- pcmk_quorum_notification
- cluster_connect_quorum
- init_cs_connection
- init_cs_connection_once
- check_message_sanity
- find_corosync_variant
- crm_is_corosync_peer_active
- corosync_initialize_nodelist
- corosync_cluster_name
- corosync_cmap_has_config
1
2
3
4
5
6
7
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>
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>
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 *
44 get_corosync_uuid(crm_node_t *node)
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
58
59
60 char *
61 corosync_node_name(uint64_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
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
174 terminate_cs_connection(crm_cluster_t *cluster)
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
233
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
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
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
256 crm_update_peer_state(__func__, node, CRM_NODE_MEMBER, ring_id);
257 }
258
259
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
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 }
335 quorum_app_callback = dispatch;
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
357 init_cs_connection(crm_cluster_t * cluster)
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 case CS_ERR_TRY_AGAIN:
370 case CS_ERR_QUEUE_FULL:
371 sleep(retries);
372 break;
373 default:
374 return FALSE;
375 }
376 }
377
378 crm_err("Could not connect to corosync after %d retries", retries);
379 return FALSE;
380 }
381
382 gboolean
383 init_cs_connection_once(crm_cluster_t * cluster)
384 {
385 crm_node_t *peer = NULL;
386 enum cluster_type_e stack = get_cluster_type();
387
388 crm_peer_init();
389
390
391 if (stack != pcmk_cluster_corosync) {
392 crm_err("Invalid cluster type: %s (%d)", name_for_cluster_type(stack), stack);
393 return FALSE;
394 }
395
396 if (cluster_connect_cpg(cluster) == FALSE) {
397 return FALSE;
398 }
399 crm_info("Connection to '%s': established", name_for_cluster_type(stack));
400
401 cluster->nodeid = get_local_nodeid(0);
402 if(cluster->nodeid == 0) {
403 crm_err("Could not establish local nodeid");
404 return FALSE;
405 }
406
407 cluster->uname = get_node_name(0);
408 if(cluster->uname == NULL) {
409 crm_err("Could not establish local node name");
410 return FALSE;
411 }
412
413
414 peer = crm_get_peer(cluster->nodeid, cluster->uname);
415 cluster->uuid = get_corosync_uuid(peer);
416
417 return TRUE;
418 }
419
420 gboolean
421 check_message_sanity(const AIS_Message * msg, const char *data)
422 {
423 gboolean sane = TRUE;
424 int dest = msg->host.type;
425 int tmp_size = msg->header.size - sizeof(AIS_Message);
426
427 if (sane && msg->header.size == 0) {
428 crm_warn("Message with no size");
429 sane = FALSE;
430 }
431
432 if (sane && msg->header.error != CS_OK) {
433 crm_warn("Message header contains an error: %d", msg->header.error);
434 sane = FALSE;
435 }
436
437 if (sane && ais_data_len(msg) != tmp_size) {
438 crm_warn("Message payload size is incorrect: expected %d, got %d", ais_data_len(msg),
439 tmp_size);
440 sane = TRUE;
441 }
442
443 if (sane && ais_data_len(msg) == 0) {
444 crm_warn("Message with no payload");
445 sane = FALSE;
446 }
447
448 if (sane && data && msg->is_compressed == FALSE) {
449 int str_size = strlen(data) + 1;
450
451 if (ais_data_len(msg) != str_size) {
452 int lpc = 0;
453
454 crm_warn("Message payload is corrupted: expected %d bytes, got %d",
455 ais_data_len(msg), str_size);
456 sane = FALSE;
457 for (lpc = (str_size - 10); lpc < msg->size; lpc++) {
458 if (lpc < 0) {
459 lpc = 0;
460 }
461 crm_debug("bad_data[%d]: %d / '%c'", lpc, data[lpc], data[lpc]);
462 }
463 }
464 }
465
466 if (sane == FALSE) {
467 crm_err("Invalid message %d: (dest=%s:%s, from=%s:%s.%u, compressed=%d, size=%d, total=%d)",
468 msg->id, ais_dest(&(msg->host)), msg_type2text(dest),
469 ais_dest(&(msg->sender)), msg_type2text(msg->sender.type),
470 msg->sender.pid, msg->is_compressed, ais_data_len(msg), msg->header.size);
471
472 } else {
473 crm_trace
474 ("Verified message %d: (dest=%s:%s, from=%s:%s.%u, compressed=%d, size=%d, total=%d)",
475 msg->id, ais_dest(&(msg->host)), msg_type2text(dest), ais_dest(&(msg->sender)),
476 msg_type2text(msg->sender.type), msg->sender.pid, msg->is_compressed,
477 ais_data_len(msg), msg->header.size);
478 }
479
480 return sane;
481 }
482
483 enum cluster_type_e
484 find_corosync_variant(void)
485 {
486 int rc = CS_OK;
487 cmap_handle_t handle;
488
489 rc = cmap_initialize(&handle);
490
491 switch(rc) {
492 case CS_OK:
493 break;
494 case CS_ERR_SECURITY:
495 crm_debug("Failed to initialize the cmap API: Permission denied (%d)", rc);
496
497
498
499 return pcmk_cluster_corosync;
500
501 default:
502 crm_info("Failed to initialize the cmap API: %s (%d)",
503 ais_error2text(rc), rc);
504 return pcmk_cluster_unknown;
505 }
506
507 cmap_finalize(handle);
508 return pcmk_cluster_corosync;
509 }
510
511 gboolean
512 crm_is_corosync_peer_active(const crm_node_t * node)
513 {
514 if (node == NULL) {
515 crm_trace("NULL");
516 return FALSE;
517
518 } else if (!pcmk__str_eq(node->state, CRM_NODE_MEMBER, pcmk__str_casei)) {
519 crm_trace("%s: state=%s", node->uname, node->state);
520 return FALSE;
521
522 } else if ((node->processes & crm_proc_cpg) == 0) {
523 crm_trace("%s: processes=%.16x", node->uname, node->processes);
524 return FALSE;
525 }
526 return TRUE;
527 }
528
529 gboolean
530 corosync_initialize_nodelist(void *cluster, gboolean force_member, xmlNode * xml_parent)
531 {
532 int lpc = 0;
533 cs_error_t rc = CS_OK;
534 int retries = 0;
535 gboolean any = FALSE;
536 cmap_handle_t cmap_handle;
537 int fd = -1;
538 uid_t found_uid = 0;
539 gid_t found_gid = 0;
540 pid_t found_pid = 0;
541 int rv;
542
543 do {
544 rc = cmap_initialize(&cmap_handle);
545 if (rc != CS_OK) {
546 retries++;
547 crm_debug("API connection setup failed: %s. Retrying in %ds", cs_strerror(rc),
548 retries);
549 sleep(retries);
550 }
551
552 } while (retries < 5 && rc != CS_OK);
553
554 if (rc != CS_OK) {
555 crm_warn("Could not connect to Cluster Configuration Database API, error %d", rc);
556 return FALSE;
557 }
558
559 rc = cmap_fd_get(cmap_handle, &fd);
560 if (rc != CS_OK) {
561 crm_err("Could not obtain the CMAP API connection: %s (%d)",
562 cs_strerror(rc), rc);
563 goto bail;
564 }
565
566
567 if (!(rv = crm_ipc_is_authentic_process(fd, (uid_t) 0,(gid_t) 0, &found_pid,
568 &found_uid, &found_gid))) {
569 crm_err("CMAP provider is not authentic:"
570 " process %lld (uid: %lld, gid: %lld)",
571 (long long) PCMK__SPECIAL_PID_AS_0(found_pid),
572 (long long) found_uid, (long long) found_gid);
573 goto bail;
574 } else if (rv < 0) {
575 crm_err("Could not verify authenticity of CMAP provider: %s (%d)",
576 strerror(-rv), -rv);
577 goto bail;
578 }
579
580 crm_peer_init();
581 crm_trace("Initializing corosync nodelist");
582 for (lpc = 0; TRUE; lpc++) {
583 uint32_t nodeid = 0;
584 char *name = NULL;
585 char *key = NULL;
586
587 key = crm_strdup_printf("nodelist.node.%d.nodeid", lpc);
588 rc = cmap_get_uint32(cmap_handle, key, &nodeid);
589 free(key);
590
591 if (rc != CS_OK) {
592 break;
593 }
594
595 name = corosync_node_name(cmap_handle, nodeid);
596 if (name != NULL) {
597 GHashTableIter iter;
598 crm_node_t *node = NULL;
599
600 g_hash_table_iter_init(&iter, crm_peer_cache);
601 while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) {
602 if(node && node->uname && strcasecmp(node->uname, name) == 0) {
603 if (node->id && node->id != nodeid) {
604 crm_crit("Nodes %u and %u share the same name '%s': shutting down", node->id,
605 nodeid, name);
606 crm_exit(CRM_EX_FATAL);
607 }
608 }
609 }
610 }
611
612 if (nodeid > 0 || name != NULL) {
613 crm_trace("Initializing node[%d] %u = %s", lpc, nodeid, name);
614 crm_get_peer(nodeid, name);
615 }
616
617 if (nodeid > 0 && name != NULL) {
618 any = TRUE;
619
620 if (xml_parent) {
621 xmlNode *node = create_xml_node(xml_parent, XML_CIB_TAG_NODE);
622
623 crm_xml_set_id(node, "%u", nodeid);
624 crm_xml_add(node, XML_ATTR_UNAME, name);
625 if (force_member) {
626 crm_xml_add(node, XML_ATTR_TYPE, CRM_NODE_MEMBER);
627 }
628 }
629 }
630
631 free(name);
632 }
633 bail:
634 cmap_finalize(cmap_handle);
635 return any;
636 }
637
638 char *
639 corosync_cluster_name(void)
640 {
641 cmap_handle_t handle;
642 char *cluster_name = NULL;
643 cs_error_t rc = CS_OK;
644 int fd = -1;
645 uid_t found_uid = 0;
646 gid_t found_gid = 0;
647 pid_t found_pid = 0;
648 int rv;
649
650 rc = cmap_initialize(&handle);
651 if (rc != CS_OK) {
652 crm_info("Failed to initialize the cmap API: %s (%d)",
653 cs_strerror(rc), rc);
654 return NULL;
655 }
656
657 rc = cmap_fd_get(handle, &fd);
658 if (rc != CS_OK) {
659 crm_err("Could not obtain the CMAP API connection: %s (%d)",
660 cs_strerror(rc), rc);
661 goto bail;
662 }
663
664
665 if (!(rv = crm_ipc_is_authentic_process(fd, (uid_t) 0,(gid_t) 0, &found_pid,
666 &found_uid, &found_gid))) {
667 crm_err("CMAP provider is not authentic:"
668 " process %lld (uid: %lld, gid: %lld)",
669 (long long) PCMK__SPECIAL_PID_AS_0(found_pid),
670 (long long) found_uid, (long long) found_gid);
671 goto bail;
672 } else if (rv < 0) {
673 crm_err("Could not verify authenticity of CMAP provider: %s (%d)",
674 strerror(-rv), -rv);
675 goto bail;
676 }
677
678 rc = cmap_get_string(handle, "totem.cluster_name", &cluster_name);
679 if (rc != CS_OK) {
680 crm_info("Cannot get totem.cluster_name: %s (%d)", cs_strerror(rc), rc);
681
682 } else {
683 crm_debug("cmap totem.cluster_name = '%s'", cluster_name);
684 }
685
686 bail:
687 cmap_finalize(handle);
688 return cluster_name;
689 }
690
691
692
693
694
695
696
697
698
699
700
701
702
703 int
704 corosync_cmap_has_config(const char *prefix)
705 {
706 cs_error_t rc = CS_OK;
707 int retries = 0;
708 static int found = -1;
709 cmap_handle_t cmap_handle;
710 cmap_iter_handle_t iter_handle;
711 char key_name[CMAP_KEYNAME_MAXLEN + 1];
712 int fd = -1;
713 uid_t found_uid = 0;
714 gid_t found_gid = 0;
715 pid_t found_pid = 0;
716 int rv;
717
718 if(found != -1) {
719 return found;
720 }
721
722 do {
723 rc = cmap_initialize(&cmap_handle);
724 if (rc != CS_OK) {
725 retries++;
726 crm_debug("API connection setup failed: %s. Retrying in %ds", cs_strerror(rc),
727 retries);
728 sleep(retries);
729 }
730
731 } while (retries < 5 && rc != CS_OK);
732
733 if (rc != CS_OK) {
734 crm_warn("Could not connect to Cluster Configuration Database API: %s (rc=%d)",
735 cs_strerror(rc), rc);
736 return -1;
737 }
738
739 rc = cmap_fd_get(cmap_handle, &fd);
740 if (rc != CS_OK) {
741 crm_err("Could not obtain the CMAP API connection: %s (%d)",
742 cs_strerror(rc), rc);
743 goto bail;
744 }
745
746
747 if (!(rv = crm_ipc_is_authentic_process(fd, (uid_t) 0,(gid_t) 0, &found_pid,
748 &found_uid, &found_gid))) {
749 crm_err("CMAP provider is not authentic:"
750 " process %lld (uid: %lld, gid: %lld)",
751 (long long) PCMK__SPECIAL_PID_AS_0(found_pid),
752 (long long) found_uid, (long long) found_gid);
753 goto bail;
754 } else if (rv < 0) {
755 crm_err("Could not verify authenticity of CMAP provider: %s (%d)",
756 strerror(-rv), -rv);
757 goto bail;
758 }
759
760 rc = cmap_iter_init(cmap_handle, prefix, &iter_handle);
761 if (rc != CS_OK) {
762 crm_warn("Failed to initialize iteration for corosync cmap '%s': %s (rc=%d)",
763 prefix, cs_strerror(rc), rc);
764 goto bail;
765 }
766
767 found = 0;
768 if (cmap_iter_next(cmap_handle, iter_handle, key_name, NULL, NULL) == CS_OK) {
769 crm_trace("'%s' is configured in corosync cmap: %s", prefix, key_name);
770 found = 1;
771 }
772 cmap_iter_finalize(cmap_handle, iter_handle);
773
774 bail:
775 cmap_finalize(cmap_handle);
776
777 return found;
778 }