corosync 3.1.10
vsf_quorum.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2008-2020 Red Hat, Inc.
3 *
4 * All rights reserved.
5 *
6 * Author: Christine Caulfield (ccaulfie@redhat.com)
7 *
8 * This software licensed under BSD license, the text of which follows:
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are met:
12 *
13 * - Redistributions of source code must retain the above copyright notice,
14 * this list of conditions and the following disclaimer.
15 * - Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 * - Neither the name of Red Hat Inc. nor the names of its
19 * contributors may be used to endorse or promote products derived from this
20 * software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32 * THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35#include <config.h>
36
37#ifdef HAVE_ALLOCA_H
38#include <alloca.h>
39#endif
40
41#include <pwd.h>
42#include <grp.h>
43#include <sys/types.h>
44#include <sys/poll.h>
45#include <sys/uio.h>
46#include <sys/mman.h>
47#include <sys/socket.h>
48#include <sys/un.h>
49#include <sys/time.h>
50#include <sys/resource.h>
51#include <netinet/in.h>
52#include <arpa/inet.h>
53#include <unistd.h>
54#include <fcntl.h>
55#include <stdlib.h>
56#include <stdio.h>
57#include <errno.h>
58#include <sched.h>
59#include <time.h>
60
61#include "quorum.h"
62#include <corosync/corotypes.h>
63#include <qb/qbipc_common.h>
64#include <corosync/corodefs.h>
65#include <corosync/swab.h>
66#include <qb/qblist.h>
67#include <corosync/mar_gen.h>
68#include <corosync/ipc_quorum.h>
69#include <corosync/coroapi.h>
70#include <corosync/logsys.h>
71#include <corosync/icmap.h>
72
73#include "service.h"
74#include "votequorum.h"
75#include "vsf_ykd.h"
76
78
79struct quorum_pd {
80 unsigned char track_flags;
82 struct qb_list_head list;
83 void *conn;
85};
86
88 struct qb_list_head list;
90 void *context;
91};
92
93static void quorum_sync_init (
94 const unsigned int *trans_list,
95 size_t trans_list_entries,
96 const unsigned int *member_list,
97 size_t member_list_entries,
98 const struct memb_ring_id *ring_id);
99
100static int quorum_sync_process (void);
101
102static void quorum_sync_activate (void);
103
104static void quorum_sync_abort (void);
105
106static void message_handler_req_lib_quorum_getquorate (void *conn,
107 const void *msg);
108static void message_handler_req_lib_quorum_trackstart (void *conn,
109 const void *msg);
110static void message_handler_req_lib_quorum_trackstop (void *conn,
111 const void *msg);
112static void message_handler_req_lib_quorum_gettype (void *conn,
113 const void *msg);
114static void message_handler_req_lib_quorum_model_gettype (void *conn,
115 const void *msg);
116static void send_library_notification(void *conn);
117static void send_internal_notification(void);
118static void send_nodelist_library_notification(void *conn, int send_joined_left_list);
119static char *quorum_exec_init_fn (struct corosync_api_v1 *api);
120static int quorum_lib_init_fn (void *conn);
121static int quorum_lib_exit_fn (void *conn);
122
123static int primary_designated = 0;
124static int quorum_type = 0;
125static struct corosync_api_v1 *corosync_api;
126static struct qb_list_head lib_trackers_list;
127static struct qb_list_head internal_trackers_list;
128static struct memb_ring_id quorum_ring_id;
129static struct memb_ring_id last_sync_ring_id;
130static size_t quorum_view_list_entries = 0;
131static int quorum_view_list[PROCESSOR_COUNT_MAX];
132struct quorum_services_api_ver1 *quorum_iface = NULL;
133
134static char view_buf[64];
135
136static unsigned int my_member_list[PROCESSOR_COUNT_MAX];
137static size_t my_member_list_entries;
138static unsigned int my_old_member_list[PROCESSOR_COUNT_MAX];
139static size_t my_old_member_list_entries = 0;
140static unsigned int my_left_list[PROCESSOR_COUNT_MAX];
141static size_t my_left_list_entries;
142static unsigned int my_joined_list[PROCESSOR_COUNT_MAX];
143static size_t my_joined_list_entries;
144
145static void log_view_list(const unsigned int *view_list, size_t view_list_entries,
146 const char *view_list_type_str)
147{
148 int total = (int)view_list_entries;
149 int len, pos, ret;
150 int i = 0;
151
152 while (1) {
153 len = sizeof(view_buf);
154 pos = 0;
155 memset(view_buf, 0, len);
156
157 for (; i < total; i++) {
158 ret = snprintf(view_buf + pos, len - pos, " " CS_PRI_NODE_ID, view_list[i]);
159 if (ret >= len - pos)
160 break;
161 pos += ret;
162 }
163 log_printf (LOGSYS_LEVEL_NOTICE, "%s[%d]:%s%s",
164 view_list_type_str, total, view_buf, i < total ? "\\" : "");
165
166 if (i == total)
167 break;
168 }
169}
170
171/* Internal quorum API function */
172static void quorum_api_set_quorum(const unsigned int *view_list,
173 size_t view_list_entries,
174 int quorum, struct memb_ring_id *ring_id)
175{
176 int old_quorum = primary_designated;
177 primary_designated = quorum;
178
179 if (primary_designated && !old_quorum) {
180 log_printf (LOGSYS_LEVEL_NOTICE, "This node is within the primary component and will provide service.");
181 } else if (!primary_designated && old_quorum) {
182 log_printf (LOGSYS_LEVEL_NOTICE, "This node is within the non-primary component and will NOT provide any services.");
183 }
184
185 quorum_view_list_entries = view_list_entries;
186 memcpy(&quorum_ring_id, ring_id, sizeof (quorum_ring_id));
187 memcpy(quorum_view_list, view_list, sizeof(unsigned int)*view_list_entries);
188
189 log_view_list(view_list, view_list_entries, "Members");
190
191 /* Tell internal listeners */
192 send_internal_notification();
193
194 /* Tell IPC listeners */
195 send_library_notification(NULL);
196}
197
198static struct corosync_lib_handler quorum_lib_service[] =
199{
200 { /* 0 */
201 .lib_handler_fn = message_handler_req_lib_quorum_getquorate,
203 },
204 { /* 1 */
205 .lib_handler_fn = message_handler_req_lib_quorum_trackstart,
207 },
208 { /* 2 */
209 .lib_handler_fn = message_handler_req_lib_quorum_trackstop,
211 },
212 { /* 3 */
213 .lib_handler_fn = message_handler_req_lib_quorum_gettype,
215 },
216 { /* 4 */
217 .lib_handler_fn = message_handler_req_lib_quorum_model_gettype,
219 }
220};
221
222static struct corosync_service_engine quorum_service_handler = {
223 .name = "corosync cluster quorum service v0.1",
224 .id = QUORUM_SERVICE,
225 .priority = 1,
226 .private_data_size = sizeof (struct quorum_pd),
227 .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED,
228 .allow_inquorate = CS_LIB_ALLOW_INQUORATE,
229 .lib_init_fn = quorum_lib_init_fn,
230 .lib_exit_fn = quorum_lib_exit_fn,
231 .lib_engine = quorum_lib_service,
232 .exec_init_fn = quorum_exec_init_fn,
233 .sync_init = quorum_sync_init,
234 .sync_process = quorum_sync_process,
235 .sync_activate = quorum_sync_activate,
236 .sync_abort = quorum_sync_abort,
237 .lib_engine_count = sizeof (quorum_lib_service) / sizeof (struct corosync_lib_handler)
238};
239
241{
242 return (&quorum_service_handler);
243}
244
245/* -------------------------------------------------- */
246
247
248/*
249 * Internal API functions for corosync
250 */
251
252static int quorum_quorate(void)
253{
254 return primary_designated;
255}
256
257
258static int quorum_register_callback(quorum_callback_fn_t function, void *context)
259{
260 struct internal_callback_pd *pd = malloc(sizeof(struct internal_callback_pd));
261 if (!pd)
262 return -1;
263
264 pd->context = context;
265 pd->callback = function;
266 qb_list_add (&pd->list, &internal_trackers_list);
267
268 return 0;
269}
270
271static int quorum_unregister_callback(quorum_callback_fn_t function, void *context)
272{
273 struct internal_callback_pd *pd;
274 struct qb_list_head *tmp, *tmp_iter;
275
276 qb_list_for_each_safe(tmp, tmp_iter, &internal_trackers_list) {
277 pd = qb_list_entry(tmp, struct internal_callback_pd, list);
278 if (pd->callback == function && pd->context == context) {
279 qb_list_del(&pd->list);
280 free(pd);
281 return 0;
282 }
283 }
284 return -1;
285}
286
287static struct quorum_callin_functions callins = {
288 .quorate = quorum_quorate,
289 .register_callback = quorum_register_callback,
290 .unregister_callback = quorum_unregister_callback
291};
292
293/* --------------------------------------------------------------------- */
294
295static void quorum_sync_init (
296 const unsigned int *trans_list,
297 size_t trans_list_entries,
298 const unsigned int *member_list,
299 size_t member_list_entries,
300 const struct memb_ring_id *ring_id)
301{
302 int found;
303 int i, j;
304 int entries;
305 int node_joined;
306
307 memcpy (my_member_list, member_list, member_list_entries *
308 sizeof (unsigned int));
309 my_member_list_entries = member_list_entries;
310
311 last_sync_ring_id = *ring_id;
312
313 /*
314 * Determine left list of nodeids
315 */
316 entries = 0;
317 for (i = 0; i < my_old_member_list_entries; i++) {
318 found = 0;
319 for (j = 0; j < trans_list_entries; j++) {
320 if (my_old_member_list[i] == trans_list[j]) {
321 found = 1;
322 break;
323 }
324 }
325
326 if (found == 0) {
327 my_left_list[entries++] = my_old_member_list[i];
328 } else {
329 /*
330 * Check it is really in new membership
331 */
332 found = 0;
333
334 for (j = 0; j < my_member_list_entries; j++) {
335 if (my_old_member_list[i] == my_member_list[j]) {
336 found = 1;
337 break;
338 }
339 }
340
341 /*
342 * Node is in both old_member_list and trans list but not in my_member_list.
343 * (This shouldn't really happen).
344 */
345 if (!found) {
346 my_left_list[entries++] = my_old_member_list[i];
347 }
348 }
349 }
350 my_left_list_entries = entries;
351
352 /*
353 * Determine joined list of nodeids
354 */
355 entries = 0;
356 for (i = 0; i < my_member_list_entries; i++) {
357 node_joined = 1;
358 for (j = 0; j < my_old_member_list_entries; j++) {
359 if (my_member_list[i] == my_old_member_list[j]) {
360 /*
361 * Node is in member list and also in my_old_member list -> check
362 * if it is in left_list.
363 */
364 node_joined = 0;
365 break;
366 }
367 }
368
369 if (!node_joined) {
370 /*
371 * Check if node is in left list.
372 */
373 for (j = 0; j < my_left_list_entries; j++) {
374 if (my_member_list[i] == my_left_list[j]) {
375 /*
376 * Node is both in left and also in member list -> joined
377 */
378 node_joined = 1;
379 break;
380 }
381 }
382 }
383
384 if (node_joined) {
385 my_joined_list[entries++] = my_member_list[i];
386 }
387 }
388 my_joined_list_entries = entries;
389
390 log_view_list(my_member_list, my_member_list_entries, "Sync members");
391
392 if (my_joined_list_entries > 0) {
393 log_view_list(my_joined_list, my_joined_list_entries, "Sync joined");
394 }
395
396 if (my_left_list_entries > 0) {
397 log_view_list(my_left_list, my_left_list_entries, "Sync left");
398 }
399}
400
401static int quorum_sync_process (void)
402{
403
404 return (0);
405}
406
407static void quorum_sync_activate (void)
408{
409
410 memcpy (my_old_member_list, my_member_list,
411 my_member_list_entries * sizeof (unsigned int));
412 my_old_member_list_entries = my_member_list_entries;
413
414 /* Tell IPC listeners */
415 send_nodelist_library_notification(NULL, 1);
416}
417
418static void quorum_sync_abort (void)
419{
420
421}
422
423static char *quorum_exec_init_fn (struct corosync_api_v1 *api)
424{
425 char *quorum_module = NULL;
426 char *error;
427
428 corosync_api = api;
429 qb_list_init (&lib_trackers_list);
430 qb_list_init (&internal_trackers_list);
431
432 /*
433 * Tell corosync we have a quorum engine.
434 */
435 api->quorum_initialize(&callins);
436
437 /*
438 * Look for a quorum provider
439 */
440 if (icmap_get_string("quorum.provider", &quorum_module) == CS_OK) {
442 "Using quorum provider %s", quorum_module);
443
444 error = (char *)"Invalid quorum provider";
445
446 if (strcmp (quorum_module, "corosync_votequorum") == 0) {
447 error = votequorum_init (api, quorum_api_set_quorum);
448 quorum_type = 1;
449 }
450 if (strcmp (quorum_module, "corosync_ykd") == 0) {
451 error = ykd_init (api, quorum_api_set_quorum);
452 quorum_type = 1;
453 }
454 if (error) {
456 "Quorum provider: %s failed to initialize.",
457 quorum_module);
458 free(quorum_module);
459 return (error);
460 }
461 }
462
463 if (quorum_module) {
464 free(quorum_module);
465 quorum_module = NULL;
466 }
467
468 /*
469 * setting quorum_type and primary_designated in the right order is important
470 * always try to lookup/init a quorum module, then revert back to be quorate
471 */
472
473 if (quorum_type == 0) {
474 primary_designated = 1;
475 }
476
477 return (NULL);
478}
479
480static int quorum_lib_init_fn (void *conn)
481{
482 struct quorum_pd *pd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn);
483
484 log_printf(LOGSYS_LEVEL_DEBUG, "lib_init_fn: conn=%p", conn);
485
486 qb_list_init (&pd->list);
487 pd->conn = conn;
489
490 return (0);
491}
492
493static int quorum_lib_exit_fn (void *conn)
494{
495 struct quorum_pd *quorum_pd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn);
496
497 log_printf(LOGSYS_LEVEL_DEBUG, "lib_exit_fn: conn=%p", conn);
498
500 qb_list_del (&quorum_pd->list);
501 qb_list_init (&quorum_pd->list);
502 }
503 return (0);
504}
505
506
507static void send_internal_notification(void)
508{
509 struct qb_list_head *tmp;
510 struct internal_callback_pd *pd;
511
512 qb_list_for_each(tmp, &internal_trackers_list) {
513 pd = qb_list_entry(tmp, struct internal_callback_pd, list);
514
515 pd->callback(primary_designated, pd->context);
516 }
517}
518
519static void prepare_library_notification_v0(char *buf, size_t size)
520{
522 int i;
523
524 res_lib_quorum_notification->quorate = primary_designated;
526 res_lib_quorum_notification->view_list_entries = quorum_view_list_entries;
527 for (i=0; i<quorum_view_list_entries; i++) {
528 res_lib_quorum_notification->view_list[i] = quorum_view_list[i];
529 }
530
532 res_lib_quorum_notification->header.size = size;
533 res_lib_quorum_notification->header.error = CS_OK;
534}
535
536static void prepare_library_notification_v1(char *buf, size_t size)
537{
540 int i;
541
542 res_lib_quorum_v1_quorum_notification->quorate = primary_designated;
545 res_lib_quorum_v1_quorum_notification->view_list_entries = quorum_view_list_entries;
546 for (i=0; i<quorum_view_list_entries; i++) {
547 res_lib_quorum_v1_quorum_notification->view_list[i] = quorum_view_list[i];
548 }
549
551 res_lib_quorum_v1_quorum_notification->header.size = size;
553}
554
555static void send_library_notification(void *conn)
556{
557 int size_v0 = sizeof(struct res_lib_quorum_notification) +
558 sizeof(mar_uint32_t) * quorum_view_list_entries;
559 int size_v1 = sizeof(struct res_lib_quorum_v1_quorum_notification) +
560 sizeof(mar_uint32_t)*quorum_view_list_entries;
561
562 char buf_v0[size_v0];
563 char buf_v1[size_v1];
564
566 (struct res_lib_quorum_notification *)buf_v0;
569
570 struct quorum_pd *qpd;
571 struct qb_list_head *tmp;
572
573 log_printf(LOGSYS_LEVEL_DEBUG, "sending quorum notification to %p, length = %u/%u", conn, size_v0, size_v1);
574
575 prepare_library_notification_v0(buf_v0, size_v0);
576 prepare_library_notification_v1(buf_v1, size_v1);
577
578 /* Send it to all interested parties */
579 if (conn) {
580 qpd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn);
581
582 if (qpd->model == LIB_QUORUM_MODEL_V0) {
583 corosync_api->ipc_dispatch_send(conn, res_lib_quorum_notification, size_v0);
584 } else if (qpd->model == LIB_QUORUM_MODEL_V1) {
585 corosync_api->ipc_dispatch_send(conn, res_lib_quorum_v1_quorum_notification, size_v1);
586 }
587 }
588 else {
589 qb_list_for_each(tmp, &lib_trackers_list) {
590 qpd = qb_list_entry(tmp, struct quorum_pd, list);
591
592 if (qpd->model == LIB_QUORUM_MODEL_V0) {
593 corosync_api->ipc_dispatch_send(qpd->conn,
595 } else if (qpd->model == LIB_QUORUM_MODEL_V1) {
596 corosync_api->ipc_dispatch_send(qpd->conn,
598 }
599 }
600 }
601 return;
602}
603
604static void send_nodelist_library_notification(void *conn, int send_joined_left_list)
605{
606 int size = sizeof(struct res_lib_quorum_v1_nodelist_notification) +
607 sizeof(mar_uint32_t) * my_member_list_entries;
608 char *buf;
610 struct quorum_pd *qpd;
611 struct qb_list_head *tmp;
612 mar_uint32_t *ptr;
613 int i;
614
615 if (send_joined_left_list) {
616 size += sizeof(mar_uint32_t) * my_joined_list_entries;
617 size += sizeof(mar_uint32_t) * my_left_list_entries;
618 }
619
620 buf = alloca(size);
621 memset(buf, 0, size);
622
624
625 res_lib_quorum_v1_nodelist_notification->ring_id.nodeid = last_sync_ring_id.nodeid;
626 res_lib_quorum_v1_nodelist_notification->ring_id.seq = last_sync_ring_id.seq;
627 res_lib_quorum_v1_nodelist_notification->member_list_entries = my_member_list_entries;
628
629 if (send_joined_left_list) {
630 res_lib_quorum_v1_nodelist_notification->joined_list_entries = my_joined_list_entries;
631 res_lib_quorum_v1_nodelist_notification->left_list_entries = my_left_list_entries;
632 }
633
635
636 for (i=0; i<my_member_list_entries; i++, ptr++) {
637 *ptr = my_member_list[i];
638 }
639
640 if (send_joined_left_list) {
641 for (i=0; i<my_joined_list_entries; i++, ptr++) {
642 *ptr = my_joined_list[i];
643 }
644
645 for (i=0; i<my_left_list_entries; i++, ptr++) {
646 *ptr = my_left_list[i];
647 }
648 }
649
651 res_lib_quorum_v1_nodelist_notification->header.size = size;
653
654 log_printf(LOGSYS_LEVEL_DEBUG, "sending nodelist notification to %p, length = %u", conn, size);
655
656 /* Send it to all interested parties */
657 if (conn) {
658 qpd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn);
659
660 if (qpd->model == LIB_QUORUM_MODEL_V1) {
661 corosync_api->ipc_dispatch_send(conn, res_lib_quorum_v1_nodelist_notification, size);
662 }
663 }
664 else {
665 qb_list_for_each(tmp, &lib_trackers_list) {
666 qpd = qb_list_entry(tmp, struct quorum_pd, list);
667
668 if (qpd->model == LIB_QUORUM_MODEL_V1) {
669 corosync_api->ipc_dispatch_send(qpd->conn,
671 }
672 }
673 }
674
675 return;
676}
677
678static void message_handler_req_lib_quorum_getquorate (void *conn,
679 const void *msg)
680{
682
683 log_printf(LOGSYS_LEVEL_DEBUG, "got quorate request on %p", conn);
684
685 /* send status */
686 res_lib_quorum_getquorate.quorate = primary_designated;
689 res_lib_quorum_getquorate.header.error = CS_OK;
690 corosync_api->ipc_response_send(conn, &res_lib_quorum_getquorate, sizeof(res_lib_quorum_getquorate));
691}
692
693static void message_handler_req_lib_quorum_trackstart (void *conn,
694 const void *msg)
695{
697 struct qb_ipc_response_header res;
698 struct quorum_pd *quorum_pd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn);
699 cs_error_t error = CS_OK;
700
701 log_printf(LOGSYS_LEVEL_DEBUG, "got trackstart request on %p", conn);
702
703 /*
704 * If an immediate listing of the current cluster membership
705 * is requested, generate membership list
706 */
709 log_printf(LOGSYS_LEVEL_DEBUG, "sending initial status to %p", conn);
710 send_nodelist_library_notification(conn, 0);
711 send_library_notification(conn);
712 }
713
715 error = CS_ERR_EXIST;
716 goto response_send;
717 }
718
719 /*
720 * Record requests for tracking
721 */
724
727
728 qb_list_add (&quorum_pd->list, &lib_trackers_list);
729 }
730
731response_send:
732 /* send status */
733 res.size = sizeof(res);
735 res.error = error;
736 corosync_api->ipc_response_send(conn, &res, sizeof(struct qb_ipc_response_header));
737}
738
739static void message_handler_req_lib_quorum_trackstop (void *conn, const void *msg)
740{
741 struct qb_ipc_response_header res;
742 struct quorum_pd *quorum_pd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn);
743
744 log_printf(LOGSYS_LEVEL_DEBUG, "got trackstop request on %p", conn);
745
747 res.error = CS_OK;
749 qb_list_del (&quorum_pd->list);
750 qb_list_init (&quorum_pd->list);
751 } else {
752 res.error = CS_ERR_NOT_EXIST;
753 }
754
755 /* send status */
756 res.size = sizeof(res);
758 res.error = CS_OK;
759 corosync_api->ipc_response_send(conn, &res, sizeof(struct qb_ipc_response_header));
760}
761
762static void message_handler_req_lib_quorum_gettype (void *conn,
763 const void *msg)
764{
766
767 log_printf(LOGSYS_LEVEL_DEBUG, "got quorum_type request on %p", conn);
768
769 /* send status */
773 res_lib_quorum_gettype.header.error = CS_OK;
774 corosync_api->ipc_response_send(conn, &res_lib_quorum_gettype, sizeof(res_lib_quorum_gettype));
775}
776
777static void message_handler_req_lib_quorum_model_gettype (void *conn,
778 const void *msg)
779{
782 struct quorum_pd *quorum_pd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn);
783 cs_error_t ret_err;
784
785 log_printf(LOGSYS_LEVEL_DEBUG, "got quorum_model_type request on %p", conn);
786
787 ret_err = CS_OK;
788
791 log_printf(LOGSYS_LEVEL_ERROR, "quorum_model_type request for unsupported model %u",
793
794 ret_err = CS_ERR_INVALID_PARAM;
795 } else {
797 }
798
799 /* send status */
800 res_lib_quorum_model_gettype.quorum_type = quorum_type;
803 res_lib_quorum_model_gettype.header.error = ret_err;
804 corosync_api->ipc_response_send(conn, &res_lib_quorum_model_gettype, sizeof(res_lib_quorum_model_gettype));
805}
@ CS_LIB_ALLOW_INQUORATE
Definition coroapi.h:164
void(* quorum_callback_fn_t)(int quorate, void *context)
The quorum_callback_fn_t callback.
Definition coroapi.h:199
@ CS_LIB_FLOW_CONTROL_NOT_REQUIRED
Definition coroapi.h:153
#define PROCESSOR_COUNT_MAX
Definition coroapi.h:96
@ QUORUM_SERVICE
Definition corodefs.h:47
#define CS_TRACK_CURRENT
Definition corotypes.h:91
#define CS_PRI_NODE_ID
Definition corotypes.h:59
#define CS_TRACK_CHANGES
Definition corotypes.h:92
#define CS_TRACK_CHANGES_ONLY
Definition corotypes.h:93
cs_error_t
The cs_error_t enum.
Definition corotypes.h:98
@ CS_OK
Definition corotypes.h:99
@ CS_ERR_INVALID_PARAM
Definition corotypes.h:105
@ CS_ERR_NOT_EXIST
Definition corotypes.h:110
@ CS_ERR_EXIST
Definition corotypes.h:112
char * votequorum_init(struct corosync_api_v1 *api, quorum_set_quorate_fn_t q_set_quorate_fn)
cs_error_t icmap_get_string(const char *key_name, char **str)
Shortcut for icmap_get for string type.
Definition icmap.c:860
@ MESSAGE_RES_QUORUM_TRACKSTART
Definition ipc_quorum.h:56
@ MESSAGE_RES_QUORUM_V1_QUORUM_NOTIFICATION
Definition ipc_quorum.h:61
@ MESSAGE_RES_QUORUM_TRACKSTOP
Definition ipc_quorum.h:57
@ MESSAGE_RES_QUORUM_V1_NODELIST_NOTIFICATION
Definition ipc_quorum.h:62
@ MESSAGE_RES_QUORUM_GETTYPE
Definition ipc_quorum.h:59
@ MESSAGE_RES_QUORUM_NOTIFICATION
Definition ipc_quorum.h:58
@ MESSAGE_RES_QUORUM_MODEL_GETTYPE
Definition ipc_quorum.h:60
@ MESSAGE_RES_QUORUM_GETQUORATE
Definition ipc_quorum.h:55
lib_quorum_model
Definition ipc_quorum.h:68
@ LIB_QUORUM_MODEL_V1
Definition ipc_quorum.h:70
@ LIB_QUORUM_MODEL_V0
Definition ipc_quorum.h:69
#define LOGSYS_LEVEL_ERROR
Definition logsys.h:72
#define log_printf(level, format, args...)
Definition logsys.h:332
#define LOGSYS_LEVEL_CRIT
Definition logsys.h:71
#define LOGSYS_LEVEL_NOTICE
Definition logsys.h:74
#define LOGSYS_DECLARE_SUBSYS(subsys)
The LOGSYS_DECLARE_SUBSYS macro.
Definition logsys.h:306
#define LOGSYS_LEVEL_DEBUG
Definition logsys.h:76
uint32_t mar_uint32_t
Definition mar_gen.h:53
The corosync_api_v1 struct.
Definition coroapi.h:225
The corosync_lib_handler struct.
Definition coroapi.h:467
The corosync_service_engine struct.
Definition coroapi.h:490
struct qb_list_head list
Definition vsf_quorum.c:88
quorum_callback_fn_t callback
Definition vsf_quorum.c:89
The memb_ring_id struct.
Definition coroapi.h:122
The quorum_callin_functions struct.
Definition coroapi.h:204
unsigned char track_flags
enum lib_quorum_model model
Definition vsf_quorum.c:84
struct qb_list_head list
The req_lib_quorum_trackstart struct.
Definition ipc_quorum.h:81
The res_lib_quorum_getquorate struct.
Definition ipc_quorum.h:89
The res_lib_quorum_gettype struct.
Definition ipc_quorum.h:127
mar_uint32_t quorum_type
Definition ipc_quorum.h:129
The res_lib_quorum_notification struct.
Definition ipc_quorum.h:97
struct memb_ring_id ring_id
Definition totemsrp.c:4
struct corosync_service_engine * vsf_quorum_get_service_engine_ver0(void)
Definition vsf_quorum.c:240
struct quorum_services_api_ver1 * quorum_iface
Definition vsf_quorum.c:132
char * ykd_init(struct corosync_api_v1 *corosync_api, quorum_set_quorate_fn_t set_primary)
Definition vsf_ykd.c:511