diff --git a/exec/vsf_quorum.c b/exec/vsf_quorum.c index f62ffa81b..e07134b68 100644 --- a/exec/vsf_quorum.c +++ b/exec/vsf_quorum.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2015 Red Hat, Inc. + * Copyright (c) 2008-2020 Red Hat, Inc. * * All rights reserved. * @@ -77,6 +77,7 @@ struct quorum_pd { int tracking_enabled; struct qb_list_head list; void *conn; + enum lib_quorum_model model; }; struct internal_callback_pd { @@ -85,6 +86,19 @@ struct internal_callback_pd { void *context; }; +static void quorum_sync_init ( + const unsigned int *trans_list, + size_t trans_list_entries, + const unsigned int *member_list, + size_t member_list_entries, + const struct memb_ring_id *ring_id); + +static int quorum_sync_process (void); + +static void quorum_sync_activate (void); + +static void quorum_sync_abort (void); + static void message_handler_req_lib_quorum_getquorate (void *conn, const void *msg); static void message_handler_req_lib_quorum_trackstart (void *conn, @@ -93,8 +107,11 @@ static void message_handler_req_lib_quorum_trackstop (void *conn, const void *msg); static void message_handler_req_lib_quorum_gettype (void *conn, const void *msg); +static void message_handler_req_lib_quorum_model_gettype (void *conn, + const void *msg); static void send_library_notification(void *conn); static void send_internal_notification(void); +static void send_nodelist_library_notification(void *conn, int send_joined_left_list); static char *quorum_exec_init_fn (struct corosync_api_v1 *api); static int quorum_lib_init_fn (void *conn); static int quorum_lib_exit_fn (void *conn); @@ -105,12 +122,24 @@ static struct corosync_api_v1 *corosync_api; static struct qb_list_head lib_trackers_list; static struct qb_list_head internal_trackers_list; static struct memb_ring_id quorum_ring_id; +static struct memb_ring_id last_sync_ring_id; static size_t quorum_view_list_entries = 0; static int quorum_view_list[PROCESSOR_COUNT_MAX]; struct quorum_services_api_ver1 *quorum_iface = NULL; + static char view_buf[64]; -static void log_view_list(const unsigned int *view_list, size_t view_list_entries) +static unsigned int my_member_list[PROCESSOR_COUNT_MAX]; +static size_t my_member_list_entries; +static unsigned int my_old_member_list[PROCESSOR_COUNT_MAX]; +static size_t my_old_member_list_entries = 0; +static unsigned int my_left_list[PROCESSOR_COUNT_MAX]; +static size_t my_left_list_entries; +static unsigned int my_joined_list[PROCESSOR_COUNT_MAX]; +static size_t my_joined_list_entries; + +static void log_view_list(const unsigned int *view_list, size_t view_list_entries, + const char *view_list_type_str) { int total = (int)view_list_entries; int len, pos, ret; @@ -127,8 +156,8 @@ static void log_view_list(const unsigned int *view_list, size_t view_list_entrie break; pos += ret; } - log_printf (LOGSYS_LEVEL_NOTICE, "Members[%d]:%s%s", - total, view_buf, i < total ? "\\" : ""); + log_printf (LOGSYS_LEVEL_NOTICE, "%s[%d]:%s%s", + view_list_type_str, total, view_buf, i < total ? "\\" : ""); if (i == total) break; @@ -153,7 +182,7 @@ static void quorum_api_set_quorum(const unsigned int *view_list, memcpy(&quorum_ring_id, ring_id, sizeof (quorum_ring_id)); memcpy(quorum_view_list, view_list, sizeof(unsigned int)*view_list_entries); - log_view_list(view_list, view_list_entries); + log_view_list(view_list, view_list_entries, "Members"); /* Tell internal listeners */ send_internal_notification(); @@ -179,6 +208,10 @@ static struct corosync_lib_handler quorum_lib_service[] = { /* 3 */ .lib_handler_fn = message_handler_req_lib_quorum_gettype, .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED + }, + { /* 4 */ + .lib_handler_fn = message_handler_req_lib_quorum_model_gettype, + .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED } }; @@ -193,6 +226,10 @@ static struct corosync_service_engine quorum_service_handler = { .lib_exit_fn = quorum_lib_exit_fn, .lib_engine = quorum_lib_service, .exec_init_fn = quorum_exec_init_fn, + .sync_init = quorum_sync_init, + .sync_process = quorum_sync_process, + .sync_activate = quorum_sync_activate, + .sync_abort = quorum_sync_abort, .lib_engine_count = sizeof (quorum_lib_service) / sizeof (struct corosync_lib_handler) }; @@ -251,6 +288,134 @@ static struct quorum_callin_functions callins = { /* --------------------------------------------------------------------- */ +static void quorum_sync_init ( + const unsigned int *trans_list, + size_t trans_list_entries, + const unsigned int *member_list, + size_t member_list_entries, + const struct memb_ring_id *ring_id) +{ + int found; + int i, j; + int entries; + int node_joined; + + memcpy (my_member_list, member_list, member_list_entries * + sizeof (unsigned int)); + my_member_list_entries = member_list_entries; + + last_sync_ring_id = *ring_id; + + /* + * Determine left list of nodeids + */ + entries = 0; + for (i = 0; i < my_old_member_list_entries; i++) { + found = 0; + for (j = 0; j < trans_list_entries; j++) { + if (my_old_member_list[i] == trans_list[j]) { + found = 1; + break; + } + } + + if (found == 0) { + my_left_list[entries++] = my_old_member_list[i]; + } else { + /* + * Check it is really in new membership + */ + found = 0; + + for (j = 0; j < my_member_list_entries; j++) { + if (my_old_member_list[i] == my_member_list[j]) { + found = 1; + break; + } + } + + /* + * Node is in both old_member_list and trans list but not in my_member_list. + * (This shouldn't really happen). + */ + if (!found) { + my_left_list[entries++] = my_old_member_list[i]; + } + } + } + my_left_list_entries = entries; + + /* + * Determine joined list of nodeids + */ + entries = 0; + for (i = 0; i < my_member_list_entries; i++) { + node_joined = 1; + for (j = 0; j < my_old_member_list_entries; j++) { + if (my_member_list[i] == my_old_member_list[j]) { + /* + * Node is in member list and also in my_old_member list -> check + * if it is in left_list. + */ + node_joined = 0; + break; + } + } + + if (!node_joined) { + /* + * Check if node is in left list. + */ + for (j = 0; j < my_left_list_entries; j++) { + if (my_member_list[i] == my_left_list[j]) { + /* + * Node is both in left and also in member list -> joined + */ + node_joined = 1; + break; + } + } + } + + if (node_joined) { + my_joined_list[entries++] = my_member_list[i]; + } + } + my_joined_list_entries = entries; + + log_view_list(my_member_list, my_member_list_entries, "Sync members"); + + if (my_joined_list_entries > 0) { + log_view_list(my_joined_list, my_joined_list_entries, "Sync joined"); + } + + if (my_left_list_entries > 0) { + log_view_list(my_left_list, my_left_list_entries, "Sync left"); + } +} + +static int quorum_sync_process (void) +{ + + return (0); +} + +static void quorum_sync_activate (void) +{ + + memcpy (my_old_member_list, my_member_list, + my_member_list_entries * sizeof (unsigned int)); + my_old_member_list_entries = my_member_list_entries; + + /* Tell IPC listeners */ + send_nodelist_library_notification(NULL, 1); +} + +static void quorum_sync_abort (void) +{ + +} + static char *quorum_exec_init_fn (struct corosync_api_v1 *api) { char *quorum_module = NULL; @@ -316,6 +481,7 @@ static int quorum_lib_init_fn (void *conn) qb_list_init (&pd->list); pd->conn = conn; + pd->model = LIB_QUORUM_MODEL_V0; return (0); } @@ -346,16 +512,11 @@ static void send_internal_notification(void) } } -static void send_library_notification(void *conn) +static void prepare_library_notification_v0(char *buf, size_t size) { - int size = sizeof(struct res_lib_quorum_notification) + sizeof(unsigned int)*quorum_view_list_entries; - char buf[size]; struct res_lib_quorum_notification *res_lib_quorum_notification = (struct res_lib_quorum_notification *)buf; - struct qb_list_head *tmp; int i; - log_printf(LOGSYS_LEVEL_DEBUG, "sending quorum notification to %p, length = %d", conn, size); - res_lib_quorum_notification->quorate = primary_designated; res_lib_quorum_notification->ring_seq = quorum_ring_id.seq; res_lib_quorum_notification->view_list_entries = quorum_view_list_entries; @@ -366,21 +527,147 @@ static void send_library_notification(void *conn) res_lib_quorum_notification->header.id = MESSAGE_RES_QUORUM_NOTIFICATION; res_lib_quorum_notification->header.size = size; res_lib_quorum_notification->header.error = CS_OK; +} + +static void prepare_library_notification_v1(char *buf, size_t size) +{ + struct res_lib_quorum_v1_quorum_notification *res_lib_quorum_v1_quorum_notification = + (struct res_lib_quorum_v1_quorum_notification *)buf; + int i; + + res_lib_quorum_v1_quorum_notification->quorate = primary_designated; + res_lib_quorum_v1_quorum_notification->ring_id.nodeid = quorum_ring_id.nodeid; + res_lib_quorum_v1_quorum_notification->ring_id.seq = quorum_ring_id.seq; + res_lib_quorum_v1_quorum_notification->view_list_entries = quorum_view_list_entries; + for (i=0; iview_list[i] = quorum_view_list[i]; + } + + res_lib_quorum_v1_quorum_notification->header.id = MESSAGE_RES_QUORUM_V1_QUORUM_NOTIFICATION; + res_lib_quorum_v1_quorum_notification->header.size = size; + res_lib_quorum_v1_quorum_notification->header.error = CS_OK; +} + +static void send_library_notification(void *conn) +{ + int size_v0 = sizeof(struct res_lib_quorum_notification) + + sizeof(mar_uint32_t) * quorum_view_list_entries; + int size_v1 = sizeof(struct res_lib_quorum_v1_quorum_notification) + + sizeof(mar_uint32_t)*quorum_view_list_entries; + + char buf_v0[size_v0]; + char buf_v1[size_v1]; + + struct res_lib_quorum_notification *res_lib_quorum_notification = + (struct res_lib_quorum_notification *)buf_v0; + struct res_lib_quorum_v1_quorum_notification *res_lib_quorum_v1_quorum_notification = + (struct res_lib_quorum_v1_quorum_notification *)buf_v1; + + struct quorum_pd *qpd; + struct qb_list_head *tmp; + + log_printf(LOGSYS_LEVEL_DEBUG, "sending quorum notification to %p, length = %u/%u", conn, size_v0, size_v1); + + prepare_library_notification_v0(buf_v0, size_v0); + prepare_library_notification_v1(buf_v1, size_v1); /* Send it to all interested parties */ if (conn) { - corosync_api->ipc_dispatch_send(conn, res_lib_quorum_notification, size); + qpd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn); + + if (qpd->model == LIB_QUORUM_MODEL_V0) { + corosync_api->ipc_dispatch_send(conn, res_lib_quorum_notification, size_v0); + } else if (qpd->model == LIB_QUORUM_MODEL_V1) { + corosync_api->ipc_dispatch_send(conn, res_lib_quorum_v1_quorum_notification, size_v1); + } } else { - struct quorum_pd *qpd; + qb_list_for_each(tmp, &lib_trackers_list) { + qpd = qb_list_entry(tmp, struct quorum_pd, list); + + if (qpd->model == LIB_QUORUM_MODEL_V0) { + corosync_api->ipc_dispatch_send(qpd->conn, + res_lib_quorum_notification, size_v0); + } else if (qpd->model == LIB_QUORUM_MODEL_V1) { + corosync_api->ipc_dispatch_send(qpd->conn, + res_lib_quorum_v1_quorum_notification, size_v1); + } + } + } + return; +} + +static void send_nodelist_library_notification(void *conn, int send_joined_left_list) +{ + int size = sizeof(struct res_lib_quorum_v1_nodelist_notification) + + sizeof(mar_uint32_t) * my_member_list_entries; + char *buf; + struct res_lib_quorum_v1_nodelist_notification *res_lib_quorum_v1_nodelist_notification; + struct quorum_pd *qpd; + struct qb_list_head *tmp; + mar_uint32_t *ptr; + int i; + + if (send_joined_left_list) { + size += sizeof(mar_uint32_t) * my_joined_list_entries; + size += sizeof(mar_uint32_t) * my_left_list_entries; + } + + buf = alloca(size); + memset(buf, 0, size); + + res_lib_quorum_v1_nodelist_notification = (struct res_lib_quorum_v1_nodelist_notification *)buf; + + res_lib_quorum_v1_nodelist_notification->ring_id.nodeid = last_sync_ring_id.nodeid; + res_lib_quorum_v1_nodelist_notification->ring_id.seq = last_sync_ring_id.seq; + res_lib_quorum_v1_nodelist_notification->member_list_entries = my_member_list_entries; + + if (send_joined_left_list) { + res_lib_quorum_v1_nodelist_notification->joined_list_entries = my_joined_list_entries; + res_lib_quorum_v1_nodelist_notification->left_list_entries = my_left_list_entries; + } + + ptr = res_lib_quorum_v1_nodelist_notification->member_list; + + for (i=0; iheader.id = MESSAGE_RES_QUORUM_V1_NODELIST_NOTIFICATION; + res_lib_quorum_v1_nodelist_notification->header.size = size; + res_lib_quorum_v1_nodelist_notification->header.error = CS_OK; + + log_printf(LOGSYS_LEVEL_DEBUG, "sending nodelist notification to %p, length = %u", conn, size); + + /* Send it to all interested parties */ + if (conn) { + qpd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn); + + if (qpd->model == LIB_QUORUM_MODEL_V1) { + corosync_api->ipc_dispatch_send(conn, res_lib_quorum_v1_nodelist_notification, size); + } + } + else { qb_list_for_each(tmp, &lib_trackers_list) { qpd = qb_list_entry(tmp, struct quorum_pd, list); - corosync_api->ipc_dispatch_send(qpd->conn, - res_lib_quorum_notification, size); + if (qpd->model == LIB_QUORUM_MODEL_V1) { + corosync_api->ipc_dispatch_send(qpd->conn, + res_lib_quorum_v1_nodelist_notification, size); + } } } + return; } @@ -416,6 +703,7 @@ static void message_handler_req_lib_quorum_trackstart (void *conn, if (req_lib_quorum_trackstart->track_flags & CS_TRACK_CURRENT || req_lib_quorum_trackstart->track_flags & CS_TRACK_CHANGES) { log_printf(LOGSYS_LEVEL_DEBUG, "sending initial status to %p", conn); + send_nodelist_library_notification(conn, 0); send_library_notification(conn); } @@ -482,3 +770,32 @@ static void message_handler_req_lib_quorum_gettype (void *conn, corosync_api->ipc_response_send(conn, &res_lib_quorum_gettype, sizeof(res_lib_quorum_gettype)); } +static void message_handler_req_lib_quorum_model_gettype (void *conn, + const void *msg) +{ + const struct req_lib_quorum_model_gettype *req_lib_quorum_model_gettype = msg; + struct res_lib_quorum_model_gettype res_lib_quorum_model_gettype; + struct quorum_pd *quorum_pd = (struct quorum_pd *)corosync_api->ipc_private_data_get (conn); + cs_error_t ret_err; + + log_printf(LOGSYS_LEVEL_DEBUG, "got quorum_model_type request on %p", conn); + + ret_err = CS_OK; + + if (req_lib_quorum_model_gettype->model != LIB_QUORUM_MODEL_V0 && + req_lib_quorum_model_gettype->model != LIB_QUORUM_MODEL_V1) { + log_printf(LOGSYS_LEVEL_ERROR, "quorum_model_type request for unsupported model %u", + req_lib_quorum_model_gettype->model); + + ret_err = CS_ERR_INVALID_PARAM; + } else { + quorum_pd->model = req_lib_quorum_model_gettype->model; + } + + /* send status */ + res_lib_quorum_model_gettype.quorum_type = quorum_type; + res_lib_quorum_model_gettype.header.size = sizeof(res_lib_quorum_model_gettype); + res_lib_quorum_model_gettype.header.id = MESSAGE_RES_QUORUM_MODEL_GETTYPE; + res_lib_quorum_model_gettype.header.error = ret_err; + corosync_api->ipc_response_send(conn, &res_lib_quorum_model_gettype, sizeof(res_lib_quorum_model_gettype)); +} diff --git a/include/corosync/ipc_quorum.h b/include/corosync/ipc_quorum.h index 2b98bf89a..62c7ddf3c 100644 --- a/include/corosync/ipc_quorum.h +++ b/include/corosync/ipc_quorum.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2011 Red Hat, Inc. + * Copyright (c) 2008-2020 Red Hat, Inc. * * All rights reserved. * @@ -44,7 +44,8 @@ enum req_quorum_types { MESSAGE_REQ_QUORUM_GETQUORATE = 0, MESSAGE_REQ_QUORUM_TRACKSTART, MESSAGE_REQ_QUORUM_TRACKSTOP, - MESSAGE_REQ_QUORUM_GETTYPE + MESSAGE_REQ_QUORUM_GETTYPE, + MESSAGE_REQ_QUORUM_MODEL_GETTYPE }; /** @@ -55,9 +56,25 @@ enum res_quorum_types { MESSAGE_RES_QUORUM_TRACKSTART, MESSAGE_RES_QUORUM_TRACKSTOP, MESSAGE_RES_QUORUM_NOTIFICATION, - MESSAGE_RES_QUORUM_GETTYPE + MESSAGE_RES_QUORUM_GETTYPE, + MESSAGE_RES_QUORUM_MODEL_GETTYPE, + MESSAGE_RES_QUORUM_V1_QUORUM_NOTIFICATION, + MESSAGE_RES_QUORUM_V1_NODELIST_NOTIFICATION }; +/* + * Must be in sync with definition in quorum.h + */ +enum lib_quorum_model { + LIB_QUORUM_MODEL_V0 = 0, + LIB_QUORUM_MODEL_V1 = 1, +}; + +typedef struct { + mar_uint32_t nodeid __attribute__((aligned(8))); + mar_uint64_t seq __attribute__((aligned(8))); +} mar_quorum_ring_id_t; + /** * @brief The req_lib_quorum_trackstart struct */ @@ -85,6 +102,25 @@ struct res_lib_quorum_notification { mar_uint32_t view_list[]; }; +struct res_lib_quorum_v1_quorum_notification { + struct qb_ipc_response_header header __attribute__((aligned(8))); + mar_int32_t quorate __attribute__((aligned(8))); + mar_quorum_ring_id_t ring_id __attribute__((aligned(8))); + mar_uint32_t view_list_entries __attribute__((aligned(8))); + mar_uint32_t view_list[]; +}; + +struct res_lib_quorum_v1_nodelist_notification { + struct qb_ipc_response_header header __attribute__((aligned(8))); + mar_quorum_ring_id_t ring_id __attribute__((aligned(8))); + mar_uint32_t member_list_entries __attribute__((aligned(8))); + mar_uint32_t joined_list_entries __attribute__((aligned(8))); + mar_uint32_t left_list_entries __attribute__((aligned(8))); + mar_uint32_t member_list[]; +// mar_uint32_t joined_list[]; +// mar_uint32_t left_list[]; +}; + /** * @brief The res_lib_quorum_gettype struct */ @@ -93,4 +129,14 @@ struct res_lib_quorum_gettype { mar_uint32_t quorum_type; }; +struct req_lib_quorum_model_gettype { + struct qb_ipc_request_header header __attribute__((aligned(8))); + mar_uint32_t model __attribute__((aligned(8))); +}; + +struct res_lib_quorum_model_gettype { + struct qb_ipc_response_header header __attribute__((aligned(8))); + mar_uint32_t quorum_type __attribute__((aligned(8))); +}; + #endif diff --git a/include/corosync/quorum.h b/include/corosync/quorum.h index e60c894bc..93c46be67 100644 --- a/include/corosync/quorum.h +++ b/include/corosync/quorum.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Red Hat, Inc. + * Copyright (c) 2008-2020 Red Hat, Inc. * * All rights reserved. * @@ -40,11 +40,21 @@ extern "C" { #endif +typedef enum { + QUORUM_MODEL_V0 = 0, + QUORUM_MODEL_V1 = 1, +} quorum_model_t; + /** * @brief quorum_handle_t */ typedef uint64_t quorum_handle_t; +struct quorum_ring_id { + uint32_t nodeid; + uint64_t seq; +}; + /** * @brief The quorum_notification_fn_t callback */ @@ -56,6 +66,21 @@ typedef void (*quorum_notification_fn_t) ( uint32_t *view_list ); +typedef void (*quorum_v1_quorum_notification_fn_t) ( + quorum_handle_t handle, + uint32_t quorate, + struct quorum_ring_id ring_id, + uint32_t member_list_entries, const uint32_t *member_list +); + +typedef void (*quorum_v1_nodelist_notification_fn_t) ( + quorum_handle_t handle, + struct quorum_ring_id ring_id, + uint32_t member_list_entries, const uint32_t *member_list, + uint32_t joined_list_entries, const uint32_t *joined_list, + uint32_t left_list_entries, const uint32_t *left_list +); + /** * @brief The quorum_callbacks_t struct */ @@ -63,6 +88,21 @@ typedef struct { quorum_notification_fn_t quorum_notify_fn; } quorum_callbacks_t; +typedef struct { + quorum_model_t model; +} quorum_model_data_t; + +typedef struct { + quorum_model_t model; + quorum_notification_fn_t quorum_notify_fn; +} quorum_model_v0_data_t; + +typedef struct { + quorum_model_t model; + quorum_v1_quorum_notification_fn_t quorum_notify_fn; + quorum_v1_nodelist_notification_fn_t nodelist_notify_fn; +} quorum_model_v1_data_t; + #define QUORUM_FREE 0 #define QUORUM_SET 1 @@ -78,6 +118,13 @@ cs_error_t quorum_initialize ( quorum_callbacks_t *callbacks, uint32_t *quorum_type); +cs_error_t quorum_model_initialize ( + quorum_handle_t *handle, + quorum_model_t model, + quorum_model_data_t *model_data, + uint32_t *quorum_type, + void *context); + /** * @brief Close the quorum handle * @param handle diff --git a/lib/Makefile.am b/lib/Makefile.am index ca6984c0a..002866a41 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright (c) 2009 Red Hat, Inc. +# Copyright (c) 2009-2020 Red Hat, Inc. # # Authors: Andrew Beekhof # Steven Dake (sdake@redhat.com) diff --git a/lib/libquorum.verso b/lib/libquorum.verso index 0062ac971..831446cbd 100644 --- a/lib/libquorum.verso +++ b/lib/libquorum.verso @@ -1 +1 @@ -5.0.0 +5.1.0 diff --git a/lib/quorum.c b/lib/quorum.c index 92748da68..c1139c08b 100644 --- a/lib/quorum.c +++ b/lib/quorum.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Red Hat, Inc. + * Copyright (c) 2008-2020 Red Hat, Inc. * * All rights reserved. * @@ -59,7 +59,11 @@ struct quorum_inst { qb_ipcc_connection_t *c; int finalize; const void *context; - quorum_callbacks_t callbacks; + union { + quorum_model_data_t model_data; + quorum_model_v0_data_t model_v0_data; + quorum_model_v1_data_t model_v1_data; + }; }; static void quorum_inst_free (void *inst); @@ -70,12 +74,39 @@ cs_error_t quorum_initialize ( quorum_handle_t *handle, quorum_callbacks_t *callbacks, uint32_t *quorum_type) +{ + quorum_model_v0_data_t model_v0_data; + + memset (&model_v0_data, 0, sizeof(quorum_model_v0_data_t)); + + if (callbacks) { + model_v0_data.quorum_notify_fn = callbacks->quorum_notify_fn; + } + + return (quorum_model_initialize(handle, QUORUM_MODEL_V0, + (quorum_model_data_t *)&model_v0_data, quorum_type, NULL)); +} + +cs_error_t quorum_model_initialize ( + quorum_handle_t *handle, + quorum_model_t model, + quorum_model_data_t *model_data, + uint32_t *quorum_type, + void *context) { cs_error_t error; struct quorum_inst *quorum_inst; struct iovec iov; - struct qb_ipc_request_header req; + struct qb_ipc_request_header quorum_gettype_req; + struct req_lib_quorum_model_gettype quorum_model_gettype_req; struct res_lib_quorum_gettype res_lib_quorum_gettype; + struct res_lib_quorum_model_gettype res_lib_quorum_model_gettype; + uint32_t local_quorum_type; + + if (model != QUORUM_MODEL_V0 && model != QUORUM_MODEL_V1) { + error = CS_ERR_INVALID_PARAM; + goto error_no_destroy; + } error = hdb_error_to_cs(hdb_handle_create (&quorum_handle_t_db, sizeof (struct quorum_inst), handle)); if (error != CS_OK) { @@ -95,35 +126,71 @@ cs_error_t quorum_initialize ( goto error_put_destroy; } - req.size = sizeof (req); - req.id = MESSAGE_REQ_QUORUM_GETTYPE; + switch (model) { + case QUORUM_MODEL_V0: + quorum_gettype_req.size = sizeof (quorum_gettype_req); + quorum_gettype_req.id = MESSAGE_REQ_QUORUM_GETTYPE; - iov.iov_base = (char *)&req; - iov.iov_len = sizeof (req); + iov.iov_base = (char *)&quorum_gettype_req; + iov.iov_len = sizeof (quorum_gettype_req); - error = qb_to_cs_error(qb_ipcc_sendv_recv ( - quorum_inst->c, - &iov, - 1, - &res_lib_quorum_gettype, - sizeof (struct res_lib_quorum_gettype), -1)); + error = qb_to_cs_error(qb_ipcc_sendv_recv ( + quorum_inst->c, + &iov, + 1, + &res_lib_quorum_gettype, + sizeof(res_lib_quorum_gettype), -1)); - if (error != CS_OK) { - goto error_put_destroy; + if (error != CS_OK) { + goto error_put_destroy; + } + error = res_lib_quorum_gettype.header.error; + local_quorum_type = res_lib_quorum_gettype.quorum_type; + break; + case QUORUM_MODEL_V1: + quorum_model_gettype_req.header.size = sizeof (quorum_model_gettype_req); + quorum_model_gettype_req.header.id = MESSAGE_REQ_QUORUM_MODEL_GETTYPE; + quorum_model_gettype_req.model = model; + + iov.iov_base = (char *)&quorum_model_gettype_req; + iov.iov_len = sizeof (quorum_model_gettype_req); + + error = qb_to_cs_error(qb_ipcc_sendv_recv ( + quorum_inst->c, + &iov, + 1, + &res_lib_quorum_model_gettype, + sizeof(res_lib_quorum_model_gettype), -1)); + + if (error != CS_OK) { + goto error_put_destroy; + } + error = res_lib_quorum_model_gettype.header.error; + local_quorum_type = res_lib_quorum_model_gettype.quorum_type; + break; } - error = res_lib_quorum_gettype.header.error; + if (quorum_type != NULL) { + *quorum_type = local_quorum_type; + } - *quorum_type = res_lib_quorum_gettype.quorum_type; + if (model_data != NULL) { + switch (model) { + case QUORUM_MODEL_V0: + memcpy(&quorum_inst->model_v0_data, model_data, sizeof(quorum_model_v0_data_t)); + break; + case QUORUM_MODEL_V1: + memcpy(&quorum_inst->model_v1_data, model_data, sizeof(quorum_model_v1_data_t)); + break; + } + } - if (callbacks) - memcpy(&quorum_inst->callbacks, callbacks, sizeof (*callbacks)); - else - memset(&quorum_inst->callbacks, 0, sizeof (*callbacks)); + quorum_inst->model_data.model = model; + quorum_inst->context = context; (void)hdb_handle_put (&quorum_handle_t_db, *handle); - return (CS_OK); + return (error); error_put_destroy: (void)hdb_handle_put (&quorum_handle_t_db, *handle); @@ -356,10 +423,15 @@ cs_error_t quorum_dispatch ( cs_error_t error; int cont = 1; /* always continue do loop except when set to 0 */ struct quorum_inst *quorum_inst; - quorum_callbacks_t callbacks; + struct quorum_inst quorum_inst_copy; struct qb_ipc_response_header *dispatch_data; char dispatch_buf[IPC_DISPATCH_SIZE]; struct res_lib_quorum_notification *res_lib_quorum_notification; + struct res_lib_quorum_v1_quorum_notification *res_lib_quorum_v1_quorum_notification; + struct res_lib_quorum_v1_nodelist_notification *res_lib_quorum_v1_nodelist_notification; + struct quorum_ring_id ring_id; + mar_uint32_t *joined_list; + mar_uint32_t *left_list; if (dispatch_types != CS_DISPATCH_ONE && dispatch_types != CS_DISPATCH_ALL && @@ -417,29 +489,82 @@ cs_error_t quorum_dispatch ( * A risk of this dispatch method is that the callback routines may * operate at the same time that quorum_finalize has been called in another thread. */ - memcpy (&callbacks, &quorum_inst->callbacks, sizeof (quorum_callbacks_t)); - /* - * Dispatch incoming message - */ - switch (dispatch_data->id) { - - case MESSAGE_RES_QUORUM_NOTIFICATION: - if (callbacks.quorum_notify_fn == NULL) { + memcpy (&quorum_inst_copy, quorum_inst, sizeof(quorum_inst_copy)); + switch (quorum_inst_copy.model_data.model) { + case QUORUM_MODEL_V0: + /* + * Dispatch incoming message + */ + switch (dispatch_data->id) { + case MESSAGE_RES_QUORUM_NOTIFICATION: + if (quorum_inst_copy.model_v0_data.quorum_notify_fn == NULL) { + break; + } + res_lib_quorum_notification = (struct res_lib_quorum_notification *)dispatch_data; + + quorum_inst_copy.model_v0_data.quorum_notify_fn ( handle, + res_lib_quorum_notification->quorate, + res_lib_quorum_notification->ring_seq, + res_lib_quorum_notification->view_list_entries, + res_lib_quorum_notification->view_list); break; - } - res_lib_quorum_notification = (struct res_lib_quorum_notification *)dispatch_data; - - callbacks.quorum_notify_fn ( handle, - res_lib_quorum_notification->quorate, - res_lib_quorum_notification->ring_seq, - res_lib_quorum_notification->view_list_entries, - res_lib_quorum_notification->view_list); - break; - - default: - error = CS_ERR_LIBRARY; - goto error_put; - break; + default: + error = CS_ERR_LIBRARY; + goto error_put; + break; + } /* switch (dispatch_data->id) */ + break; /* case QUORUM_MODEL_V0 */ + case QUORUM_MODEL_V1: + /* + * Dispatch incoming message + */ + switch (dispatch_data->id) { + case MESSAGE_RES_QUORUM_V1_QUORUM_NOTIFICATION: + if (quorum_inst_copy.model_v1_data.quorum_notify_fn == NULL) { + break; + } + res_lib_quorum_v1_quorum_notification = + (struct res_lib_quorum_v1_quorum_notification *)dispatch_data; + + ring_id.nodeid = res_lib_quorum_v1_quorum_notification->ring_id.nodeid; + ring_id.seq = res_lib_quorum_v1_quorum_notification->ring_id.seq; + + quorum_inst_copy.model_v1_data.quorum_notify_fn ( handle, + res_lib_quorum_v1_quorum_notification->quorate, + ring_id, + res_lib_quorum_v1_quorum_notification->view_list_entries, + res_lib_quorum_v1_quorum_notification->view_list); + break; + case MESSAGE_RES_QUORUM_V1_NODELIST_NOTIFICATION: + if (quorum_inst_copy.model_v1_data.nodelist_notify_fn == NULL) { + break; + } + res_lib_quorum_v1_nodelist_notification = + (struct res_lib_quorum_v1_nodelist_notification *)dispatch_data; + + ring_id.nodeid = res_lib_quorum_v1_nodelist_notification->ring_id.nodeid; + ring_id.seq = res_lib_quorum_v1_nodelist_notification->ring_id.seq; + + joined_list = res_lib_quorum_v1_nodelist_notification->member_list + + res_lib_quorum_v1_nodelist_notification->member_list_entries; + left_list = joined_list + + res_lib_quorum_v1_nodelist_notification->joined_list_entries; + + quorum_inst_copy.model_v1_data.nodelist_notify_fn ( handle, + ring_id, + res_lib_quorum_v1_nodelist_notification->member_list_entries, + res_lib_quorum_v1_nodelist_notification->member_list, + res_lib_quorum_v1_nodelist_notification->joined_list_entries, + joined_list, + res_lib_quorum_v1_nodelist_notification->left_list_entries, + left_list); + break; + default: + error = CS_ERR_LIBRARY; + goto error_put; + break; + } /* switch (dispatch_data->id) */ + break; /* case QUORUM_MODEL_V1 */ } if (quorum_inst->finalize) { /* diff --git a/man/Makefile.am b/man/Makefile.am index 92a76edab..a57af142a 100644 --- a/man/Makefile.am +++ b/man/Makefile.am @@ -60,6 +60,7 @@ autogen_man = cpg_context_get.3 \ cpg_iteration_initialize.3 \ cpg_iteration_next.3 \ quorum_initialize.3 \ + quorum_model_initialize.3 \ quorum_finalize.3 \ quorum_fd_get.3 \ quorum_dispatch.3 \ diff --git a/man/quorum_context_get.3.in b/man/quorum_context_get.3.in index c5461ea99..e4c5cf104 100644 --- a/man/quorum_context_get.3.in +++ b/man/quorum_context_get.3.in @@ -1,5 +1,5 @@ .\"/* -.\" * Copyright (c) 2012 Red Hat, Inc. +.\" * Copyright (c) 2012-2020 Red Hat, Inc. .\" * .\" * All rights reserved. .\" * @@ -51,6 +51,7 @@ This call returns the CS_OK value if successful, otherwise an error is returned. .SH "SEE ALSO" .BR quorum_overview (3), .BR quorum_initialize (3), +.BR quorum_model_initialize (3), .BR quorum_finalize (3), .BR quorum_getquorate (3), .BR quorum_trackstart (3), diff --git a/man/quorum_context_set.3.in b/man/quorum_context_set.3.in index 56b06289c..cdc1b3b1f 100644 --- a/man/quorum_context_set.3.in +++ b/man/quorum_context_set.3.in @@ -1,5 +1,5 @@ .\"/* -.\" * Copyright (c) 2012 Red Hat, Inc. +.\" * Copyright (c) 2012-2020 Red Hat, Inc. .\" * .\" * All rights reserved. .\" * @@ -53,6 +53,7 @@ This call returns the CS_OK value if successful, otherwise an error is returned. .SH "SEE ALSO" .BR quorum_overview (3), .BR quorum_initialize (3), +.BR quorum_model_initialize (3), .BR quorum_finalize (3), .BR quorum_getquorate (3), .BR quorum_trackstart (3), diff --git a/man/quorum_dispatch.3.in b/man/quorum_dispatch.3.in index a11b02dfa..c8b822a11 100644 --- a/man/quorum_dispatch.3.in +++ b/man/quorum_dispatch.3.in @@ -1,5 +1,5 @@ .\"/* -.\" * Copyright (c) 2012 Red Hat, Inc. +.\" * Copyright (c) 2012-2020 Red Hat, Inc. .\" * .\" * All rights reserved. .\" * @@ -87,6 +87,7 @@ This call returns the CS_OK value if successful, otherwise an error is returned. .SH "SEE ALSO" .BR quorum_overview (3), .BR quorum_initialize (3), +.BR quorum_model_initialize (3), .BR quorum_finalize (3), .BR quorum_getquorate (3), .BR quorum_trackstart (3), diff --git a/man/quorum_fd_get.3.in b/man/quorum_fd_get.3.in index b7ca6e836..1f99399bc 100644 --- a/man/quorum_fd_get.3.in +++ b/man/quorum_fd_get.3.in @@ -1,5 +1,5 @@ .\"/* -.\" * Copyright (c) 2012 Red Hat, Inc. +.\" * Copyright (c) 2012-2020 Red Hat, Inc. .\" * .\" * All rights reserved. .\" * @@ -58,6 +58,7 @@ This call returns the CS_OK value if successful, otherwise an error is returned. .SH "SEE ALSO" .BR quorum_overview (3), .BR quorum_initialize (3), +.BR quorum_model_initialize (3), .BR quorum_finalize (3), .BR quorum_getquorate (3), .BR quorum_trackstart (3), diff --git a/man/quorum_finalize.3.in b/man/quorum_finalize.3.in index b324a9415..d914b3067 100644 --- a/man/quorum_finalize.3.in +++ b/man/quorum_finalize.3.in @@ -1,5 +1,5 @@ .\"/* -.\" * Copyright (c) 2012 Red Hat, Inc. +.\" * Copyright (c) 2012-2020 Red Hat, Inc. .\" * .\" * All rights reserved. .\" * @@ -55,6 +55,7 @@ This call returns the CS_OK value if successful, otherwise an error is returned. .SH "SEE ALSO" .BR quorum_overview (3), .BR quorum_initialize (3), +.BR quorum_model_initialize (3), .BR quorum_getquorate (3), .BR quorum_trackstart (3), .BR quorum_trackstop (3), diff --git a/man/quorum_getquorate.3.in b/man/quorum_getquorate.3.in index e48e1201a..281efdc20 100644 --- a/man/quorum_getquorate.3.in +++ b/man/quorum_getquorate.3.in @@ -1,5 +1,5 @@ .\"/* -.\" * Copyright (c) 2012 Red Hat, Inc. +.\" * Copyright (c) 2012-2020 Red Hat, Inc. .\" * .\" * All rights reserved. .\" * @@ -51,6 +51,7 @@ This call returns the CS_OK value if successful, otherwise an error is returned. .SH "SEE ALSO" .BR quorum_overview (3), .BR quorum_initialize (3), +.BR quorum_model_initialize (3), .BR quorum_finalize (3), .BR quorum_trackstart (3), .BR quorum_trackstop (3), diff --git a/man/quorum_initialize.3.in b/man/quorum_initialize.3.in index 126107aeb..91eb81567 100644 --- a/man/quorum_initialize.3.in +++ b/man/quorum_initialize.3.in @@ -1,5 +1,5 @@ .\"/* -.\" * Copyright (c) 2012 Red Hat, Inc. +.\" * Copyright (c) 2012-2020 Red Hat, Inc. .\" * .\" * All rights reserved. .\" * @@ -102,6 +102,7 @@ This call returns the CS_OK value if successful, otherwise an error is returned. @COMMONIPCERRORS@ .SH "SEE ALSO" .BR quorum_overview (3), +.BR quorum_model_initialize (3), .BR quorum_finalize (3), .BR quorum_getquorate (3), .BR quorum_trackstart (3), diff --git a/man/quorum_model_initialize.3.in b/man/quorum_model_initialize.3.in new file mode 100644 index 000000000..0ac6c263d --- /dev/null +++ b/man/quorum_model_initialize.3.in @@ -0,0 +1,165 @@ +.\"/* +.\" * Copyright (c) 2012-2020 Red Hat, Inc. +.\" * +.\" * All rights reserved. +.\" * +.\" * Authors: Jan Friesse +.\" * Fabio M. Di Nitto +.\" * +.\" * This software licensed under BSD license, the text of which follows: +.\" * +.\" * Redistribution and use in source and binary forms, with or without +.\" * modification, are permitted provided that the following conditions are met: +.\" * +.\" * - Redistributions of source code must retain the above copyright notice, +.\" * this list of conditions and the following disclaimer. +.\" * - Redistributions in binary form must reproduce the above copyright notice, +.\" * this list of conditions and the following disclaimer in the documentation +.\" * and/or other materials provided with the distribution. +.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its +.\" * contributors may be used to endorse or promote products derived from this +.\" * software without specific prior written permission. +.\" * +.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +.\" * THE POSSIBILITY OF SUCH DAMAGE. +.\" */ +.TH QUORUM_MODEL_INITIALIZE 3 @BUILDDATE@ "corosync Man Page" "Corosync Cluster Engine Programmer's Manual" +.SH NAME +quorum_model_initialize \- Create a new connection to the Quorum service +.SH SYNOPSIS +.B #include +.sp +.BI "cs_error_t quorum_model_initialize(quorum_handle_t *" handle ", quorum_model_t " model ", quorum_model_data_t *" model_data ", uint32_t *" quorum_type ",void *" context ");" +.SH DESCRIPTION +The +.B quorum_model_initialize +function is an enhanced way to initialize a connection to the quorum API. +.PP +Each application may have several connections to the quorum API. Each application +uses the +.I handle +argument to uniquely identify the connection. The +.I handle +argument is then used in other function calls to identify the connection to be used +for communication with the quorum service. +.PP +The +.I model +is used to explicitly choose set of callbacks and internal parameters. Currently two models +.I QUORUM_MODEL_V0 +and +.I QUORUM_MODEL_V1 +are defined. +.I QUORUM_MODEL_V0 +exists only for compatibility reasons with +.B quorum_initialize(3) +function and it is not recommended to be used as an argument for +.B quorum_model_initialize(3). + +The Following description is focused only on +.I QUORUM_MODEL_V1 +model. + +.PP +Every time the voting configuration changes (eg a node joins or leave the cluster) or the quorum status changes +the quorum callback is called. +The quorum callback function is described by the following type definitions: + +.nf +typedef void (*quorum_v1_quorum_notification_fn_t) ( + quorum_handle_t handle, + uint32_t quorate, + struct quorum_ring_id ring_id, + uint32_t member_list_entries, + const uint32_t *member_list +); +.fi +.PP +Also every time when membership configuration changes (eg a node joins or leave the cluster) the node list change +callback is called before the quorum callback. +The node list change callback function is described by the following type definitions: + +.nf +typedef void (*quorum_v1_nodelist_notification_fn_t) ( + quorum_handle_t handle, + struct quorum_ring_id ring_id, + uint32_t member_list_entries, + const uint32_t *member_list, + uint32_t joined_list_entries, + const uint32_t *joined_list, + uint32_t left_list_entries, + const uint32_t *left_list +); +.fi +.PP +The +.I model_data +argument for +.I QUORUM_MODEL_V1 +is of the type: + +.nf +typedef struct { + quorum_model_t model; + quorum_v1_quorum_notification_fn_t quorum_notify_fn; + quorum_v1_nodelist_notification_fn_t nodelist_notify_fn; +} quorum_model_v1_data_t; +.fi + +It's not required (nor recommended) to set +.I model +field in the structure. It is also fine if only some of notification callbacks are +used (only these events will be delivered then). + +.PP +The +.I quorum_type +argument is set to: + +.nf +#define QUORUM_FREE 0 +#define QUORUM_SET 1 +.fi +.PP +.I QUORUM_FREE +value means that no quorum algorithm is loaded and that no callbacks will take place. +.PP +.I QUORUM_SET +value means that one quorum algorithm is configured and that callbacks will take place. +.PP +The +.I context +argument sets context same way as +.B quorum_context_set(3). +.PP +When a configuration change occurs, the callback +is called from the +.B quorum_dispatch(3) +function. +.PP +.SH RETURN VALUE +This call returns the CS_OK value if successful, otherwise an error is returned. +.PP +.SH ERRORS +@COMMONIPCERRORS@ +.SH "SEE ALSO" +.BR quorum_overview (3), +.BR quorum_initialize (3), +.BR quorum_finalize (3), +.BR quorum_getquorate (3), +.BR quorum_trackstart (3), +.BR quorum_trackstop (3), +.BR quorum_fd_get (3), +.BR quorum_dispatch (3), +.BR quorum_context_set (3), +.BR quorum_context_get (3) +.PP diff --git a/man/quorum_overview.3 b/man/quorum_overview.3 index d81b09e39..8c42b1a12 100644 --- a/man/quorum_overview.3 +++ b/man/quorum_overview.3 @@ -1,5 +1,5 @@ .\"/* -.\" * Copyright (c) 2008, 2012 Red Hat, Inc. +.\" * Copyright (c) 2008-2020 Red Hat, Inc. .\" * .\" * All rights reserved. .\" * @@ -32,7 +32,7 @@ .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF .\" * THE POSSIBILITY OF SUCH DAMAGE. .\" */ -.TH QUORUM_OVERVIEW 3 2012-02-09 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual" +.TH QUORUM_OVERVIEW 3 2020-02-14 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual" .SH NAME quorum_overview \- Quorum Library Overview .SH OVERVIEW @@ -46,6 +46,8 @@ The library provides a mechanism to: * Query the quorum status .PP * Receive notifications of quorum state changes +.PP +* Receive notifications of membership changes .SH BUGS No known bugs at the time of writing. The authors are from outerspace. Deal with it. .SH "SEE ALSO" @@ -53,6 +55,7 @@ No known bugs at the time of writing. The authors are from outerspace. Deal with .BR corosync.conf (5), .BR votequorum (5), .BR quorum_initialize (3), +.BR quorum_model_initialize (3), .BR quorum_finalize (3), .BR quorum_getquorate (3), .BR quorum_trackstart (3), diff --git a/man/quorum_trackstart.3.in b/man/quorum_trackstart.3.in index a7bf67f9b..2474b10b6 100644 --- a/man/quorum_trackstart.3.in +++ b/man/quorum_trackstart.3.in @@ -1,5 +1,5 @@ .\"/* -.\" * Copyright (c) 2012 Red Hat, Inc. +.\" * Copyright (c) 2012-2020 Red Hat, Inc. .\" * .\" * All rights reserved. .\" * @@ -67,6 +67,7 @@ This call returns the CS_OK value if successful, otherwise an error is returned. .SH "SEE ALSO" .BR quorum_overview (3), .BR quorum_initialize (3), +.BR quorum_model_initialize (3), .BR quorum_finalize (3), .BR quorum_getquorate (3), .BR quorum_trackstop (3), diff --git a/man/quorum_trackstop.3.in b/man/quorum_trackstop.3.in index fa0d9a379..fc1f1bab8 100644 --- a/man/quorum_trackstop.3.in +++ b/man/quorum_trackstop.3.in @@ -1,5 +1,5 @@ .\"/* -.\" * Copyright (c) 2012 Red Hat, Inc. +.\" * Copyright (c) 2012-2020 Red Hat, Inc. .\" * .\" * All rights reserved. .\" * @@ -51,6 +51,7 @@ This call returns the CS_OK value if successful, otherwise an error is returned. .SH "SEE ALSO" .BR quorum_overview (3), .BR quorum_initialize (3), +.BR quorum_model_initialize (3), .BR quorum_finalize (3), .BR quorum_getquorate (3), .BR quorum_trackstart (3), diff --git a/test/.gitignore b/test/.gitignore index d24935c20..34eb1c167 100644 --- a/test/.gitignore +++ b/test/.gitignore @@ -12,6 +12,7 @@ stress_cpgfdget testcpg testcpg2 testquorum +testquorummodel testsam testvotequorum1 testvotequorum2 diff --git a/test/Makefile.am b/test/Makefile.am index 1994a3c51..22feedf03 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright (c) 2009 Red Hat, Inc. +# Copyright (c) 2009-2020 Red Hat, Inc. # # Authors: Andrew Beekhof # Steven Dake (sdake@redhat.com) @@ -37,7 +37,8 @@ EXTRA_DIST = ploadstart.sh noinst_PROGRAMS = testcpg testcpg2 cpgbench \ testquorum testvotequorum1 testvotequorum2 \ stress_cpgfdget stress_cpgcontext cpgbound testsam \ - testcpgzc cpgbenchzc testzcgc stress_cpgzc + testcpgzc cpgbenchzc testzcgc stress_cpgzc \ + testquorummodel noinst_SCRIPTS = ploadstart @@ -49,6 +50,7 @@ stress_cpgzc_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcpg.la stress_cpgfdget_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcpg.la stress_cpgcontext_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcpg.la testquorum_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libquorum.la +testquorummodel_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libquorum.la testvotequorum1_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libvotequorum.la testvotequorum2_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libvotequorum.la cpgbound_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcpg.la diff --git a/test/testquorummodel.c b/test/testquorummodel.c new file mode 100644 index 000000000..825714740 --- /dev/null +++ b/test/testquorummodel.c @@ -0,0 +1,103 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static quorum_handle_t g_handle; + +static void quorum_notification_fn( + quorum_handle_t handle, + uint32_t quorate, + struct quorum_ring_id ring_id, + uint32_t view_list_entries, + const uint32_t *view_list) +{ + int i; + + printf("quorum notification called \n"); + printf(" quorate = %lu\n", (long unsigned int) quorate); + printf(" ring id = " CS_PRI_RING_ID "\n", ring_id.nodeid, ring_id.seq); + printf(" num nodes = %lu ", (long unsigned int) view_list_entries); + + for (i=0; i