From: "Fabio M. Di Nitto" <fdinitto@xxxxxxxxxx> corosync internal theory of operation is that without a quorum provider the cluster is always quorate. This is fine for membership free clusters but it does pose a problem for applications that need membership and "real" quorum. this change add quorum_type to quorum_initialize call to return QUORUM_FREE or QUORUM_SET. Applications can then make their own decisions to error out or continue operating. The only other way to know if a quorum provider is enabled/configured is to poke at confdb/objdb, but adds an unnecessary burden to applications that really don't need to use an entire library for a boolean value. Signed-off-by: Fabio M. Di Nitto <fdinitto@xxxxxxxxxx> --- :100644 100644 ceb983e... 15f4a0a... M cts/agents/votequorum_test_agent.c :100644 100644 99ccda4... ebe8147... M exec/vsf_quorum.c :100644 100644 01e63c3... 32e21a3... M include/corosync/ipc_quorum.h :100644 100644 ab45aea... 78a2ad2... M include/corosync/quorum.h :100644 100644 c55f6c6... 8feabe3... M lib/quorum.c :100644 100644 0cfdbbe... 1596ae2... M lib/sam.c :100644 100644 74b97ec... 0c4ec6f... M test/testquorum.c :100644 100644 e11c357... 39c447c... M tools/corosync-notifyd.c :100644 100644 d0b6335... bfa20ee... M tools/corosync-quorumtool.c cts/agents/votequorum_test_agent.c | 3 ++- exec/vsf_quorum.c | 26 +++++++++++++++++++++++++- include/corosync/ipc_quorum.h | 13 ++++++++++--- include/corosync/quorum.h | 5 ++++- lib/quorum.c | 29 +++++++++++++++++++++++++++-- lib/sam.c | 3 ++- test/testquorum.c | 3 ++- tools/corosync-notifyd.c | 4 +++- tools/corosync-quorumtool.c | 12 +++++++++++- 9 files changed, 86 insertions(+), 12 deletions(-) diff --git a/cts/agents/votequorum_test_agent.c b/cts/agents/votequorum_test_agent.c index ceb983e..15f4a0a 100644 --- a/cts/agents/votequorum_test_agent.c +++ b/cts/agents/votequorum_test_agent.c @@ -151,9 +151,10 @@ static int q_lib_init(void) } } if (q_handle == 0) { + uint32_t q_type; syslog (LOG_INFO, "quorum_initialize"); q_callbacks.quorum_notify_fn = quorum_notification_fn; - ret = quorum_initialize (&q_handle, &q_callbacks); + ret = quorum_initialize (&q_handle, &q_callbacks, &q_type); if (ret != CS_OK) { syslog (LOG_ERR, "quorum_initialize FAILED: %d\n", ret); q_handle = 0; diff --git a/exec/vsf_quorum.c b/exec/vsf_quorum.c index 99ccda4..ebe8147 100644 --- a/exec/vsf_quorum.c +++ b/exec/vsf_quorum.c @@ -90,6 +90,8 @@ static void message_handler_req_lib_quorum_trackstart (void *conn, const void *msg); 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 send_library_notification(void *conn); static void send_internal_notification(void); static int quorum_exec_init_fn (struct corosync_api_v1 *api); @@ -97,6 +99,7 @@ static int quorum_lib_init_fn (void *conn); static int quorum_lib_exit_fn (void *conn); static int primary_designated = 0; +static int quorum_type = 0; static struct corosync_api_v1 *corosync_api; static struct list_head lib_trackers_list; static struct list_head internal_trackers_list; @@ -171,6 +174,10 @@ static struct corosync_lib_handler quorum_lib_service[] = { /* 2 */ .lib_handler_fn = message_handler_req_lib_quorum_trackstop, .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED + }, + { /* 3 */ + .lib_handler_fn = message_handler_req_lib_quorum_gettype, + .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED } }; @@ -329,6 +336,7 @@ static int quorum_exec_init_fn (struct corosync_api_v1 *api) quorum_iface = (struct quorum_services_api_ver1 *)quorum_iface_p; quorum_iface->init (api, quorum_api_set_quorum); + quorum_type = 1; free(quorum_module); } if (!quorum_iface) { @@ -336,6 +344,7 @@ static int quorum_exec_init_fn (struct corosync_api_v1 *api) * With no quorum provider, we are always quorate */ primary_designated = 1; + quorum_type = 0; } return (0); @@ -434,7 +443,6 @@ static void message_handler_req_lib_quorum_getquorate (void *conn, corosync_api->ipc_response_send(conn, &res_lib_quorum_getquorate, sizeof(res_lib_quorum_getquorate)); } - static void message_handler_req_lib_quorum_trackstart (void *conn, const void *msg) { @@ -495,3 +503,19 @@ static void message_handler_req_lib_quorum_trackstop (void *conn, const void *ms res.error = CS_OK; corosync_api->ipc_response_send(conn, &res, sizeof(struct qb_ipc_response_header)); } + +static void message_handler_req_lib_quorum_gettype (void *conn, + const void *msg) +{ + struct res_lib_quorum_gettype res_lib_quorum_gettype; + + log_printf(LOGSYS_LEVEL_DEBUG, "got quorum_type request on %p\n", conn); + + /* send status */ + res_lib_quorum_gettype.quorum_type = quorum_type; + res_lib_quorum_gettype.header.size = sizeof(res_lib_quorum_gettype); + res_lib_quorum_gettype.header.id = MESSAGE_RES_QUORUM_GETTYPE; + res_lib_quorum_gettype.header.error = CS_OK; + corosync_api->ipc_response_send(conn, &res_lib_quorum_gettype, sizeof(res_lib_quorum_gettype)); +} + diff --git a/include/corosync/ipc_quorum.h b/include/corosync/ipc_quorum.h index 01e63c3..32e21a3 100644 --- a/include/corosync/ipc_quorum.h +++ b/include/corosync/ipc_quorum.h @@ -40,14 +40,16 @@ enum req_quorum_types { MESSAGE_REQ_QUORUM_GETQUORATE = 0, MESSAGE_REQ_QUORUM_TRACKSTART, - MESSAGE_REQ_QUORUM_TRACKSTOP + MESSAGE_REQ_QUORUM_TRACKSTOP, + MESSAGE_REQ_QUORUM_GETTYPE }; enum res_quorum_types { MESSAGE_RES_QUORUM_GETQUORATE = 0, MESSAGE_RES_QUORUM_TRACKSTART, MESSAGE_RES_QUORUM_TRACKSTOP, - MESSAGE_RES_QUORUM_NOTIFICATION + MESSAGE_RES_QUORUM_NOTIFICATION, + MESSAGE_RES_QUORUM_GETTYPE }; struct req_lib_quorum_trackstart { @@ -57,7 +59,7 @@ struct req_lib_quorum_trackstart { struct res_lib_quorum_getquorate { - struct qb_ipc_response_header header __attribute__((aligned(8))); + struct qb_ipc_response_header header __attribute__((aligned(8))); mar_uint32_t quorate; }; @@ -69,4 +71,9 @@ struct res_lib_quorum_notification { mar_uint32_t view_list[]; }; +struct res_lib_quorum_gettype { + struct qb_ipc_response_header header __attribute__((aligned(8))); + mar_uint32_t quorum_type; +}; + #endif diff --git a/include/corosync/quorum.h b/include/corosync/quorum.h index ab45aea..78a2ad2 100644 --- a/include/corosync/quorum.h +++ b/include/corosync/quorum.h @@ -59,13 +59,16 @@ typedef struct { quorum_notification_fn_t quorum_notify_fn; } quorum_callbacks_t; +#define QUORUM_FREE 0 +#define QUORUM_SET 1 /** * Create a new quorum connection */ cs_error_t quorum_initialize ( quorum_handle_t *handle, - quorum_callbacks_t *callbacks); + quorum_callbacks_t *callbacks, + uint32_t *quorum_type); /** * Close the quorum handle diff --git a/lib/quorum.c b/lib/quorum.c index c55f6c6..8feabe3 100644 --- a/lib/quorum.c +++ b/lib/quorum.c @@ -65,10 +65,14 @@ DECLARE_HDB_DATABASE(quorum_handle_t_db,NULL); cs_error_t quorum_initialize ( quorum_handle_t *handle, - quorum_callbacks_t *callbacks) + quorum_callbacks_t *callbacks, + uint32_t *quorum_type) { cs_error_t error; struct quorum_inst *quorum_inst; + struct iovec iov; + struct qb_ipc_request_header req; + struct res_lib_quorum_gettype res_lib_quorum_gettype; error = hdb_error_to_cs(hdb_handle_create (&quorum_handle_t_db, sizeof (struct quorum_inst), handle)); if (error != CS_OK) { @@ -87,6 +91,27 @@ cs_error_t quorum_initialize ( goto error_put_destroy; } + req.size = sizeof (req); + req.id = MESSAGE_REQ_QUORUM_GETTYPE; + + iov.iov_base = (char *)&req; + iov.iov_len = sizeof (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)); + + if (error != CS_OK) { + goto error_put_destroy; + } + + error = res_lib_quorum_gettype.header.error; + + *quorum_type = res_lib_quorum_gettype.quorum_type; + if (callbacks) memcpy(&quorum_inst->callbacks, callbacks, sizeof (*callbacks)); else @@ -155,7 +180,7 @@ cs_error_t quorum_getquorate ( iov.iov_base = (char *)&req; iov.iov_len = sizeof (req); - error = qb_to_cs_error(qb_ipcc_sendv_recv ( + error = qb_to_cs_error(qb_ipcc_sendv_recv ( quorum_inst->c, &iov, 1, diff --git a/lib/sam.c b/lib/sam.c index 0cfdbbe..1596ae2 100644 --- a/lib/sam.c +++ b/lib/sam.c @@ -256,6 +256,7 @@ cs_error_t sam_initialize ( sam_recovery_policy_t recovery_policy) { quorum_callbacks_t quorum_callbacks; + uint32_t quorum_type; cs_error_t err; if (sam_internal_data.internal_status != SAM_INTERNAL_STATUS_NOT_INITIALIZED) { @@ -272,7 +273,7 @@ cs_error_t sam_initialize ( * Initialize quorum */ quorum_callbacks.quorum_notify_fn = quorum_notification_fn; - if ((err = quorum_initialize (&sam_internal_data.quorum_handle, &quorum_callbacks)) != CS_OK) { + if ((err = quorum_initialize (&sam_internal_data.quorum_handle, &quorum_callbacks, &quorum_type)) != CS_OK) { goto exit_error; } diff --git a/test/testquorum.c b/test/testquorum.c index 74b97ec..0c4ec6f 100644 --- a/test/testquorum.c +++ b/test/testquorum.c @@ -35,10 +35,11 @@ int main(int argc, char *argv[]) { int quorate; quorum_callbacks_t callbacks; + uint32_t quorum_type; int err; callbacks.quorum_notify_fn = quorum_notification_fn; - if ( (err=quorum_initialize(&g_handle, &callbacks)) != CS_OK) + if ( (err=quorum_initialize(&g_handle, &callbacks, &quorum_type)) != CS_OK) fprintf(stderr, "quorum_initialize FAILED: %d\n", err); if ( (err=quorum_trackstart(g_handle, CS_TRACK_CHANGES)) != CS_OK) diff --git a/tools/corosync-notifyd.c b/tools/corosync-notifyd.c index e11c357..39c447c 100644 --- a/tools/corosync-notifyd.c +++ b/tools/corosync-notifyd.c @@ -356,13 +356,15 @@ static void _cs_quorum_init(void) { cs_error_t rc; + uint32_t quorum_type; int fd; quorum_callbacks_t quorum_callbacks = { .quorum_notify_fn = _cs_quorum_notification, }; - rc = quorum_initialize (&quorum_handle, &quorum_callbacks); + rc = quorum_initialize (&quorum_handle, &quorum_callbacks, + &quorum_type); if (rc != CS_OK) { qb_log(LOG_ERR, "Could not connect to corosync(quorum)"); return; diff --git a/tools/corosync-quorumtool.c b/tools/corosync-quorumtool.c index d0b6335..bfa20ee 100644 --- a/tools/corosync-quorumtool.c +++ b/tools/corosync-quorumtool.c @@ -95,6 +95,7 @@ static void quorum_notification_fn( uint32_t *view_list); static quorum_handle_t q_handle; +static uint32_t q_type; static quorum_callbacks_t q_callbacks = { .quorum_notify_fn = quorum_notification_fn }; @@ -157,6 +158,10 @@ static int get_quorum_type(char *quorum_type, size_t quorum_type_len) return -1; } + if (q_type == QUORUM_FREE) { + return -1; + } + if ((err = cmap_get_string(cmap_handle, "quorum.provider", &str)) != CS_OK) { goto out; } @@ -374,6 +379,11 @@ static int monitor_status(nodeid_format_t nodeid_format, name_format_t name_form show_status(); + if (q_type == QUORUM_FREE) { + printf("\nQuorum is not configured - cannot monitor\n"); + return 0; + } + printf("starting monitoring loop\n"); err=quorum_trackstart(q_handle, CS_TRACK_CHANGES); @@ -481,7 +491,7 @@ static int init_all(void) { goto out; } - if (quorum_initialize(&q_handle, &q_callbacks) != CS_OK) { + if (quorum_initialize(&q_handle, &q_callbacks, &q_type) != CS_OK) { fprintf(stderr, "Cannot initialize QUORUM service\n"); q_handle = 0; goto out; -- 1.7.7.5 _______________________________________________ discuss mailing list discuss@xxxxxxxxxxxx http://lists.corosync.org/mailman/listinfo/discuss