If votequorum service receives incorrect (not current) ringid, call is ignored and CS_ERR_MESSAGE_ERROR is returned. This and previous commits makes incompatible changes in votequorum API/ABI, so library version is increased. Signed-off-by: Jan Friesse <jfriesse@xxxxxxxxxx> --- exec/votequorum.c | 9 +++++++ include/corosync/ipc_votequorum.h | 9 +++++++ include/corosync/votequorum.h | 3 +- lib/libvotequorum.verso | 2 +- lib/votequorum.c | 4 ++- man/votequorum_qdevice_poll.3.in | 5 +++- test/testvotequorum2.c | 47 ++++++++++++++++++++++++++++++++++-- 7 files changed, 72 insertions(+), 7 deletions(-) diff --git a/exec/votequorum.c b/exec/votequorum.c index 54b6fbe..dd5bea7 100644 --- a/exec/votequorum.c +++ b/exec/votequorum.c @@ -2741,6 +2741,15 @@ static void message_handler_req_lib_votequorum_qdevice_poll (void *conn, } if (us->flags & NODE_FLAGS_QDEVICE_REGISTERED) { + if (!(req_lib_votequorum_qdevice_poll->ring_id.nodeid == quorum_ringid.rep.nodeid && + req_lib_votequorum_qdevice_poll->ring_id.seq == quorum_ringid.seq)) { + log_printf(LOGSYS_LEVEL_DEBUG, "Received poll ring id (%u.%"PRIu64") != last sync " + "ring id (%u.%"PRIu64"). Ignoring poll call.", + req_lib_votequorum_qdevice_poll->ring_id.nodeid, req_lib_votequorum_qdevice_poll->ring_id.seq, + quorum_ringid.rep.nodeid, quorum_ringid.seq); + error = CS_ERR_MESSAGE_ERROR; + goto out; + } if (strncmp(req_lib_votequorum_qdevice_poll->name, qdevice_name, VOTEQUORUM_QDEVICE_MAX_NAME_LEN)) { error = CS_ERR_INVALID_PARAM; goto out; diff --git a/include/corosync/ipc_votequorum.h b/include/corosync/ipc_votequorum.h index 0fdcd8b..c06814f 100644 --- a/include/corosync/ipc_votequorum.h +++ b/include/corosync/ipc_votequorum.h @@ -86,6 +86,7 @@ struct req_lib_votequorum_qdevice_poll { struct qb_ipc_request_header header __attribute__((aligned(8))); char name[VOTEQUORUM_QDEVICE_MAX_NAME_LEN]; int cast_vote; + struct mar_votequorum_ring_id ring_id __attribute__((aligned(8))); }; struct req_lib_votequorum_qdevice_master_wins { @@ -181,4 +182,12 @@ static inline void marshall_from_mar_votequorum_ring_id ( dest->seq = src->seq; }; +static inline void marshall_to_mar_votequorum_ring_id ( + struct mar_votequorum_ring_id *dest, + const votequorum_ring_id_t *src) +{ + dest->nodeid = src->nodeid; + dest->seq = src->seq; +}; + #endif diff --git a/include/corosync/votequorum.h b/include/corosync/votequorum.h index bba964b..ef5294a 100644 --- a/include/corosync/votequorum.h +++ b/include/corosync/votequorum.h @@ -211,7 +211,8 @@ cs_error_t votequorum_qdevice_update ( cs_error_t votequorum_qdevice_poll ( votequorum_handle_t handle, const char *name, - unsigned int cast_vote); + unsigned int cast_vote, + votequorum_ring_id_t ring_id); /** * Allow qdevice to tell votequorum if master_wins can be enabled or not diff --git a/lib/libvotequorum.verso b/lib/libvotequorum.verso index 09b254e..66ce77b 100644 --- a/lib/libvotequorum.verso +++ b/lib/libvotequorum.verso @@ -1 +1 @@ -6.0.0 +7.0.0 diff --git a/lib/votequorum.c b/lib/votequorum.c index 20843cf..be4ef43 100644 --- a/lib/votequorum.c +++ b/lib/votequorum.c @@ -607,7 +607,8 @@ error_exit: cs_error_t votequorum_qdevice_poll ( votequorum_handle_t handle, const char *name, - unsigned int cast_vote) + unsigned int cast_vote, + votequorum_ring_id_t ring_id) { cs_error_t error; struct votequorum_inst *votequorum_inst; @@ -629,6 +630,7 @@ cs_error_t votequorum_qdevice_poll ( req_lib_votequorum_qdevice_poll.header.id = MESSAGE_REQ_VOTEQUORUM_QDEVICE_POLL; strcpy(req_lib_votequorum_qdevice_poll.name, name); req_lib_votequorum_qdevice_poll.cast_vote = cast_vote; + marshall_to_mar_votequorum_ring_id(&req_lib_votequorum_qdevice_poll.ring_id, &ring_id); iov.iov_base = (char *)&req_lib_votequorum_qdevice_poll; iov.iov_len = sizeof (struct req_lib_votequorum_qdevice_poll); diff --git a/man/votequorum_qdevice_poll.3.in b/man/votequorum_qdevice_poll.3.in index 348b84d..b8299df 100644 --- a/man/votequorum_qdevice_poll.3.in +++ b/man/votequorum_qdevice_poll.3.in @@ -37,7 +37,7 @@ votequorum_qdevice_poll \- Tells votequorum the result of the quorum device poll .SH SYNOPSIS .B #include <corosync/votequorum.h> .sp -.BI "int votequorum_qdevice_poll(votequorum_handle_t " handle ", const char * " name ", unsigned int " cast_vote ");" +.BI "int votequorum_qdevice_poll(votequorum_handle_t " handle ", const char * " name ", unsigned int " cast_vote ", votequorum_ring_id_t " ring_id ");" .SH DESCRIPTION The .B votequorum_qdevice_poll @@ -45,6 +45,9 @@ is called by the quorum device subsystem (not provided as part of votequorum) to the voting system if the quorum device is present/active or not. If .B cast_vote is 1 then the votes for the device are included in the quorum calculation, otherwise not. +Current +.B ring_id +must be set (one get in votequorum_notification_fn callback) otherwise poll is ignored. This routine should be called at regular intervals to ensure that the device status is always known to votequorum. If .B votequorum_qdevice_poll diff --git a/test/testvotequorum2.c b/test/testvotequorum2.c index 3e4bd34..f545070 100644 --- a/test/testvotequorum2.c +++ b/test/testvotequorum2.c @@ -35,6 +35,7 @@ #include <config.h> #include <sys/types.h> +#include <inttypes.h> #include <stdio.h> #include <stdint.h> #include <string.h> @@ -45,6 +46,8 @@ static votequorum_handle_t handle; +static votequorum_ring_id_t last_received_ring_id; + static int print_info(int ok_to_fail) { struct votequorum_info info; @@ -71,6 +74,22 @@ static int print_info(int ok_to_fail) return 0; } +static void votequorum_notification_fn( + votequorum_handle_t vq_handle, + uint64_t context, + uint32_t quorate, + votequorum_ring_id_t ring_id, + uint32_t node_list_entries, + votequorum_node_t node_list[]) +{ + + printf("votequorum notification called \n"); + printf(" current ringid = (%u.%"PRIu64")\n", ring_id.nodeid, ring_id.seq); + printf("\n"); + + memcpy(&last_received_ring_id, &ring_id, sizeof(ring_id)); +} + static void usage(const char *command) { printf("%s [-p <num>] [-t <time>] [-n <name>] [-c] [-m]\n", command); @@ -90,9 +109,13 @@ int main(int argc, char *argv[]) int pollcount=0, polltime=1, quiet=0, once=0; int err; int opt; + votequorum_callbacks_t callbacks; const char *devicename = "QDEVICE"; const char *options = "n:p:t:cmq1h"; - + + memset(&callbacks, 0, sizeof(callbacks)); + callbacks.votequorum_notify_fn = votequorum_notification_fn; + while ((opt = getopt(argc, argv, options)) != -1) { switch (opt) { case 'm': @@ -122,7 +145,7 @@ int main(int argc, char *argv[]) } } - if ( (err=votequorum_initialize(&handle, NULL)) != CS_OK) { + if ( (err=votequorum_initialize(&handle, &callbacks)) != CS_OK) { fprintf(stderr, "votequorum_initialize FAILED: %d\n", err); return -1; } @@ -141,6 +164,12 @@ int main(int argc, char *argv[]) } if (argc >= 2) { + if ( (err = votequorum_trackstart(handle, handle, CS_TRACK_CHANGES)) != CS_OK) { + fprintf(stderr, "votequorum_trackstart FAILED: %d\n", err); + ret = -1; + goto out; + } + if ( (err=votequorum_qdevice_register(handle, devicename)) != CS_OK) { fprintf(stderr, "qdevice_register FAILED: %d\n", err); ret = -1; @@ -153,13 +182,25 @@ int main(int argc, char *argv[]) goto out; } + while (--pollcount) { + if (votequorum_dispatch(handle, CS_DISPATCH_ALL) != CS_OK) { + fprintf(stderr, "votequorum_dispatch error\n"); + ret = -1; + goto out; + } + if (!quiet) print_info(0); - if ((err=votequorum_qdevice_poll(handle, devicename, cast_vote)) != CS_OK) { + if ((err=votequorum_qdevice_poll(handle, devicename, cast_vote, last_received_ring_id)) != CS_OK && + err != CS_ERR_MESSAGE_ERROR) { fprintf(stderr, "qdevice poll FAILED: %d\n", err); ret = -1; goto out; } + if (err == CS_ERR_MESSAGE_ERROR) { + fprintf(stderr, "qdevice poll passed OLD ring_id\n"); + } + if (!quiet) print_info(0); sleep(polltime); } -- 1.7.1 _______________________________________________ discuss mailing list discuss@xxxxxxxxxxxx http://lists.corosync.org/mailman/listinfo/discuss