39 #include <sys/types.h>
43 #include <sys/socket.h>
46 #include <sys/resource.h>
47 #include <netinet/in.h>
48 #include <arpa/inet.h>
59 #include <qb/qbipc_common.h>
89 static void message_handler_req_lib_quorum_getquorate (
void *conn,
91 static void message_handler_req_lib_quorum_trackstart (
void *conn,
93 static void message_handler_req_lib_quorum_trackstop (
void *conn,
95 static void message_handler_req_lib_quorum_gettype (
void *conn,
97 static void send_library_notification(
void *conn);
98 static void send_internal_notification(
void);
100 static int quorum_lib_init_fn (
void *conn);
101 static int quorum_lib_exit_fn (
void *conn);
103 static int primary_designated = 0;
104 static int quorum_type = 0;
106 static struct list_head lib_trackers_list;
107 static struct list_head internal_trackers_list;
109 static size_t quorum_view_list_entries = 0;
112 static char view_buf[64];
114 static void log_view_list(
const unsigned int *view_list,
size_t view_list_entries)
116 int total = (int)view_list_entries;
121 len =
sizeof(view_buf);
123 memset(view_buf, 0, len);
125 for (; i < total; i++) {
126 ret = snprintf(view_buf + pos, len - pos,
" %d", view_list[i]);
127 if (ret >= len - pos)
132 total, view_buf, i < total ?
"\\" :
"");
140 static void quorum_api_set_quorum(
const unsigned int *view_list,
141 size_t view_list_entries,
144 int old_quorum = primary_designated;
145 primary_designated = quorum;
147 if (primary_designated && !old_quorum) {
149 }
else if (!primary_designated && old_quorum) {
153 quorum_view_list_entries = view_list_entries;
154 memcpy(&quorum_ring_id, ring_id,
sizeof (quorum_ring_id));
155 memcpy(quorum_view_list, view_list,
sizeof(
unsigned int)*view_list_entries);
157 log_view_list(view_list, view_list_entries);
160 send_internal_notification();
163 send_library_notification(NULL);
173 .lib_handler_fn = message_handler_req_lib_quorum_trackstart,
177 .lib_handler_fn = message_handler_req_lib_quorum_trackstop,
181 .lib_handler_fn = message_handler_req_lib_quorum_gettype,
187 .
name =
"corosync cluster quorum service v0.1",
190 .private_data_size =
sizeof (
struct quorum_pd),
193 .lib_init_fn = quorum_lib_init_fn,
194 .lib_exit_fn = quorum_lib_exit_fn,
195 .lib_engine = quorum_lib_service,
196 .exec_init_fn = quorum_exec_init_fn,
202 return (&quorum_service_handler);
212 static int quorum_quorate(
void)
214 return primary_designated;
226 list_add (&pd->
list, &internal_trackers_list);
236 for (tmp = internal_trackers_list.
next; tmp != &internal_trackers_list; tmp = tmp->
next) {
250 .register_callback = quorum_register_callback,
251 .unregister_callback = quorum_unregister_callback
258 char *quorum_module = NULL;
262 list_init (&lib_trackers_list);
263 list_init (&internal_trackers_list);
275 "Using quorum provider %s", quorum_module);
277 error = (
char *)
"Invalid quorum provider";
279 if (strcmp (quorum_module,
"corosync_votequorum") == 0) {
283 if (strcmp (quorum_module,
"corosync_ykd") == 0) {
284 error =
ykd_init (api, quorum_api_set_quorum);
289 "Quorum provider: %s failed to initialize.",
298 quorum_module = NULL;
306 if (quorum_type == 0) {
307 primary_designated = 1;
313 static int quorum_lib_init_fn (
void *conn)
319 list_init (&pd->
list);
325 static int quorum_lib_exit_fn (
void *conn)
332 list_del (&quorum_pd->
list);
333 list_init (&quorum_pd->
list);
339 static void send_internal_notification(
void)
344 for (tmp = internal_trackers_list.
next; tmp != &internal_trackers_list; tmp = tmp->
next) {
352 static void send_library_notification(
void *conn)
362 res_lib_quorum_notification->quorate = primary_designated;
363 res_lib_quorum_notification->ring_seq = quorum_ring_id.
seq;
364 res_lib_quorum_notification->view_list_entries = quorum_view_list_entries;
365 for (i=0; i<quorum_view_list_entries; i++) {
366 res_lib_quorum_notification->
view_list[i] = quorum_view_list[i];
370 res_lib_quorum_notification->header.size = size;
371 res_lib_quorum_notification->header.error =
CS_OK;
378 struct quorum_pd *qpd;
380 for (tmp = lib_trackers_list.
next; tmp != &lib_trackers_list; tmp = tmp->
next) {
385 res_lib_quorum_notification, size);
391 static void message_handler_req_lib_quorum_getquorate (
void *conn,
406 static void message_handler_req_lib_quorum_trackstart (
void *conn,
410 struct qb_ipc_response_header res;
423 send_library_notification(conn);
440 list_add (&quorum_pd->
list, &lib_trackers_list);
445 res.size =
sizeof(res);
448 corosync_api->
ipc_response_send(conn, &res,
sizeof(
struct qb_ipc_response_header));
451 static void message_handler_req_lib_quorum_trackstop (
void *conn,
const void *msg)
453 struct qb_ipc_response_header res;
461 list_del (&quorum_pd->
list);
462 list_init (&quorum_pd->
list);
468 res.size =
sizeof(res);
471 corosync_api->
ipc_response_send(conn, &res,
sizeof(
struct qb_ipc_response_header));
474 static void message_handler_req_lib_quorum_gettype (
void *conn,
void(* lib_handler_fn)(void *conn, const void *msg)
char * votequorum_init(struct corosync_api_v1 *api, quorum_set_quorate_fn_t q_set_quorate_fn)
char * ykd_init(struct corosync_api_v1 *corosync_api, quorum_set_quorate_fn_t set_primary)
quorum_callback_fn_t callback
struct quorum_services_api_ver1 * quorum_iface
#define log_printf(level, format, args...)
LOGSYS_DECLARE_SUBSYS("QUORUM")
int(* quorum_initialize)(struct quorum_callin_functions *fns)
void *(* ipc_private_data_get)(void *conn)
#define CS_TRACK_CHANGES_ONLY
unsigned char track_flags
#define LOGSYS_LEVEL_DEBUG
int(* ipc_dispatch_send)(void *conn, const void *msg, size_t mlen)
int(* ipc_response_send)(void *conn, const void *msg, size_t mlen)
#define PROCESSOR_COUNT_MAX
cs_error_t icmap_get_string(const char *key_name, char **str)
#define LOGSYS_LEVEL_CRIT
#define list_entry(ptr, type, member)
#define LOGSYS_LEVEL_NOTICE
void(* quorum_callback_fn_t)(int quorate, void *context)
struct memb_ring_id ring_id
struct corosync_service_engine * vsf_quorum_get_service_engine_ver0(void)