43#include <sys/socket.h>
46#include <sys/resource.h>
47#include <netinet/in.h>
59#include <qb/qbipc_common.h>
78 struct qb_list_head
list;
89static void quorum_sync_init (
90 const unsigned int *trans_list,
91 size_t trans_list_entries,
92 const unsigned int *member_list,
93 size_t member_list_entries,
96static int quorum_sync_process (
void);
98static void quorum_sync_activate (
void);
100static void quorum_sync_abort (
void);
102static void message_handler_req_lib_quorum_getquorate (
void *conn,
104static void message_handler_req_lib_quorum_trackstart (
void *conn,
106static void message_handler_req_lib_quorum_trackstop (
void *conn,
108static void message_handler_req_lib_quorum_gettype (
void *conn,
110static void message_handler_req_lib_quorum_model_gettype (
void *conn,
112static void send_library_notification(
void *conn);
113static void send_internal_notification(
void);
114static void send_nodelist_library_notification(
void *conn,
int send_joined_left_list);
116static int quorum_lib_init_fn (
void *conn);
117static int quorum_lib_exit_fn (
void *conn);
119static int primary_designated = 0;
120static int quorum_type = 0;
122static struct qb_list_head lib_trackers_list;
123static struct qb_list_head internal_trackers_list;
126static size_t quorum_view_list_entries = 0;
130static char view_buf[64];
133static size_t my_member_list_entries;
135static size_t my_old_member_list_entries = 0;
137static size_t my_left_list_entries;
139static size_t my_joined_list_entries;
141static void log_view_list(
const unsigned int *view_list,
size_t view_list_entries,
142 const char *view_list_type_str)
144 int total = (int)view_list_entries;
149 len =
sizeof(view_buf);
151 memset(view_buf, 0, len);
153 for (; i < total; i++) {
154 ret = snprintf(view_buf + pos, len - pos,
" " CS_PRI_NODE_ID, view_list[i]);
155 if (ret >= len - pos)
160 view_list_type_str, total, view_buf, i < total ?
"\\" :
"");
168static void quorum_api_set_quorum(
const unsigned int *view_list,
169 size_t view_list_entries,
172 int old_quorum = primary_designated;
173 primary_designated = quorum;
175 if (primary_designated && !old_quorum) {
177 }
else if (!primary_designated && old_quorum) {
181 quorum_view_list_entries = view_list_entries;
183 memcpy(quorum_view_list, view_list,
sizeof(
unsigned int)*view_list_entries);
185 log_view_list(view_list, view_list_entries,
"Members");
188 send_internal_notification();
191 send_library_notification(NULL);
201 .lib_handler_fn = message_handler_req_lib_quorum_trackstart,
205 .lib_handler_fn = message_handler_req_lib_quorum_trackstop,
209 .lib_handler_fn = message_handler_req_lib_quorum_gettype,
213 .lib_handler_fn = message_handler_req_lib_quorum_model_gettype,
219 .
name =
"corosync cluster quorum service v0.1",
222 .private_data_size =
sizeof (
struct quorum_pd),
225 .lib_init_fn = quorum_lib_init_fn,
226 .lib_exit_fn = quorum_lib_exit_fn,
227 .lib_engine = quorum_lib_service,
228 .exec_init_fn = quorum_exec_init_fn,
229 .sync_init = quorum_sync_init,
230 .sync_process = quorum_sync_process,
231 .sync_activate = quorum_sync_activate,
232 .sync_abort = quorum_sync_abort,
238 return (&quorum_service_handler);
248static int quorum_quorate(
void)
250 return primary_designated;
262 qb_list_add (&pd->
list, &internal_trackers_list);
270 struct qb_list_head *tmp, *tmp_iter;
272 qb_list_for_each_safe(tmp, tmp_iter, &internal_trackers_list) {
275 qb_list_del(&pd->
list);
285 .register_callback = quorum_register_callback,
286 .unregister_callback = quorum_unregister_callback
291static void quorum_sync_init (
292 const unsigned int *trans_list,
293 size_t trans_list_entries,
294 const unsigned int *member_list,
295 size_t member_list_entries,
303 memcpy (my_member_list, member_list, member_list_entries *
304 sizeof (
unsigned int));
305 my_member_list_entries = member_list_entries;
313 for (i = 0; i < my_old_member_list_entries; i++) {
315 for (j = 0; j < trans_list_entries; j++) {
316 if (my_old_member_list[i] == trans_list[j]) {
323 my_left_list[entries++] = my_old_member_list[i];
330 for (j = 0; j < my_member_list_entries; j++) {
331 if (my_old_member_list[i] == my_member_list[j]) {
342 my_left_list[entries++] = my_old_member_list[i];
346 my_left_list_entries = entries;
352 for (i = 0; i < my_member_list_entries; i++) {
354 for (j = 0; j < my_old_member_list_entries; j++) {
355 if (my_member_list[i] == my_old_member_list[j]) {
369 for (j = 0; j < my_left_list_entries; j++) {
370 if (my_member_list[i] == my_left_list[j]) {
381 my_joined_list[entries++] = my_member_list[i];
384 my_joined_list_entries = entries;
386 log_view_list(my_member_list, my_member_list_entries,
"Sync members");
388 if (my_joined_list_entries > 0) {
389 log_view_list(my_joined_list, my_joined_list_entries,
"Sync joined");
392 if (my_left_list_entries > 0) {
393 log_view_list(my_left_list, my_left_list_entries,
"Sync left");
397static int quorum_sync_process (
void)
403static void quorum_sync_activate (
void)
406 memcpy (my_old_member_list, my_member_list,
407 my_member_list_entries *
sizeof (
unsigned int));
408 my_old_member_list_entries = my_member_list_entries;
411 send_nodelist_library_notification(NULL, 1);
414static void quorum_sync_abort (
void)
421 char *quorum_module = NULL;
425 qb_list_init (&lib_trackers_list);
426 qb_list_init (&internal_trackers_list);
438 "Using quorum provider %s", quorum_module);
440 error = (
char *)
"Invalid quorum provider";
442 if (strcmp (quorum_module,
"corosync_votequorum") == 0) {
446 if (strcmp (quorum_module,
"corosync_ykd") == 0) {
447 error =
ykd_init (api, quorum_api_set_quorum);
452 "Quorum provider: %s failed to initialize.",
461 quorum_module = NULL;
469 if (quorum_type == 0) {
470 primary_designated = 1;
476static int quorum_lib_init_fn (
void *conn)
482 qb_list_init (&pd->
list);
489static int quorum_lib_exit_fn (
void *
conn)
503static void send_internal_notification(
void)
505 struct qb_list_head *tmp;
508 qb_list_for_each(tmp, &internal_trackers_list) {
515static void prepare_library_notification_v0(
char *buf,
size_t size)
523 for (i=0; i<quorum_view_list_entries; i++) {
532static void prepare_library_notification_v1(
char *buf,
size_t size)
542 for (i=0; i<quorum_view_list_entries; i++) {
551static void send_library_notification(
void *conn)
558 char buf_v0[size_v0];
559 char buf_v1[size_v1];
567 struct qb_list_head *tmp;
571 prepare_library_notification_v0(buf_v0, size_v0);
572 prepare_library_notification_v1(buf_v1, size_v1);
585 qb_list_for_each(tmp, &lib_trackers_list) {
600static void send_nodelist_library_notification(
void *
conn,
int send_joined_left_list)
607 struct qb_list_head *tmp;
611 if (send_joined_left_list) {
617 memset(buf, 0, size);
625 if (send_joined_left_list) {
632 for (i=0; i<my_member_list_entries; i++, ptr++) {
633 *ptr = my_member_list[i];
636 if (send_joined_left_list) {
637 for (i=0; i<my_joined_list_entries; i++, ptr++) {
638 *ptr = my_joined_list[i];
641 for (i=0; i<my_left_list_entries; i++, ptr++) {
642 *ptr = my_left_list[i];
661 qb_list_for_each(tmp, &lib_trackers_list) {
674static void message_handler_req_lib_quorum_getquorate (
void *
conn,
689static void message_handler_req_lib_quorum_trackstart (
void *conn,
693 struct qb_ipc_response_header res;
706 send_nodelist_library_notification(
conn, 0);
707 send_library_notification(
conn);
729 res.size =
sizeof(res);
735static void message_handler_req_lib_quorum_trackstop (
void *
conn,
const void *msg)
737 struct qb_ipc_response_header res;
752 res.size =
sizeof(res);
758static void message_handler_req_lib_quorum_gettype (
void *
conn,
773static void message_handler_req_lib_quorum_model_gettype (
void *conn,
void(* quorum_callback_fn_t)(int quorate, void *context)
The quorum_callback_fn_t callback.
@ CS_LIB_FLOW_CONTROL_NOT_REQUIRED
#define PROCESSOR_COUNT_MAX
#define CS_TRACK_CHANGES_ONLY
cs_error_t
The cs_error_t enum.
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.
@ MESSAGE_RES_QUORUM_TRACKSTART
@ MESSAGE_RES_QUORUM_V1_QUORUM_NOTIFICATION
@ MESSAGE_RES_QUORUM_TRACKSTOP
@ MESSAGE_RES_QUORUM_V1_NODELIST_NOTIFICATION
@ MESSAGE_RES_QUORUM_GETTYPE
@ MESSAGE_RES_QUORUM_NOTIFICATION
@ MESSAGE_RES_QUORUM_MODEL_GETTYPE
@ MESSAGE_RES_QUORUM_GETQUORATE
#define LOGSYS_LEVEL_ERROR
#define log_printf(level, format, args...)
#define LOGSYS_LEVEL_CRIT
#define LOGSYS_LEVEL_NOTICE
#define LOGSYS_LEVEL_DEBUG
The corosync_api_v1 struct.
int(* quorum_initialize)(struct quorum_callin_functions *fns)
void *(* ipc_private_data_get)(void *conn)
int(* ipc_dispatch_send)(void *conn, const void *msg, size_t mlen)
int(* ipc_response_send)(void *conn, const void *msg, size_t mlen)
The corosync_lib_handler struct.
void(* lib_handler_fn)(void *conn, const void *msg)
The corosync_service_engine struct.
quorum_callback_fn_t callback
The quorum_callin_functions struct.
unsigned char track_flags
enum lib_quorum_model model
The req_lib_quorum_trackstart struct.
The res_lib_quorum_getquorate struct.
The res_lib_quorum_gettype struct.
The res_lib_quorum_notification struct.
mar_uint32_t member_list[]
struct memb_ring_id ring_id
struct corosync_service_engine * vsf_quorum_get_service_engine_ver0(void)
LOGSYS_DECLARE_SUBSYS("QUORUM")
struct quorum_services_api_ver1 * quorum_iface
char * ykd_init(struct corosync_api_v1 *corosync_api, quorum_set_quorate_fn_t set_primary)