فهرست منبع

votequorum: Add ring id to poll call

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@redhat.com>
Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
Jan Friesse 11 سال پیش
والد
کامیت
b8902464d1
7فایلهای تغییر یافته به همراه72 افزوده شده و 7 حذف شده
  1. 9 0
      exec/votequorum.c
  2. 9 0
      include/corosync/ipc_votequorum.h
  3. 2 1
      include/corosync/votequorum.h
  4. 1 1
      lib/libvotequorum.verso
  5. 3 1
      lib/votequorum.c
  6. 4 1
      man/votequorum_qdevice_poll.3.in
  7. 44 3
      test/testvotequorum2.c

+ 9 - 0
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 (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)) {
 		if (strncmp(req_lib_votequorum_qdevice_poll->name, qdevice_name, VOTEQUORUM_QDEVICE_MAX_NAME_LEN)) {
 			error = CS_ERR_INVALID_PARAM;
 			error = CS_ERR_INVALID_PARAM;
 			goto out;
 			goto out;

+ 9 - 0
include/corosync/ipc_votequorum.h

@@ -86,6 +86,7 @@ struct req_lib_votequorum_qdevice_poll {
 	struct qb_ipc_request_header header __attribute__((aligned(8)));
 	struct qb_ipc_request_header header __attribute__((aligned(8)));
 	char name[VOTEQUORUM_QDEVICE_MAX_NAME_LEN];
 	char name[VOTEQUORUM_QDEVICE_MAX_NAME_LEN];
 	int cast_vote;
 	int cast_vote;
+	struct mar_votequorum_ring_id ring_id __attribute__((aligned(8)));
 };
 };
 
 
 struct req_lib_votequorum_qdevice_master_wins {
 struct req_lib_votequorum_qdevice_master_wins {
@@ -181,4 +182,12 @@ static inline void marshall_from_mar_votequorum_ring_id (
 	dest->seq = src->seq;
 	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
 #endif

+ 2 - 1
include/corosync/votequorum.h

@@ -211,7 +211,8 @@ cs_error_t votequorum_qdevice_update (
 cs_error_t votequorum_qdevice_poll (
 cs_error_t votequorum_qdevice_poll (
 	votequorum_handle_t handle,
 	votequorum_handle_t handle,
 	const char *name,
 	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
  * Allow qdevice to tell votequorum if master_wins can be enabled or not

+ 1 - 1
lib/libvotequorum.verso

@@ -1 +1 @@
-6.0.0
+7.0.0

+ 3 - 1
lib/votequorum.c

@@ -607,7 +607,8 @@ error_exit:
 cs_error_t votequorum_qdevice_poll (
 cs_error_t votequorum_qdevice_poll (
 	votequorum_handle_t handle,
 	votequorum_handle_t handle,
 	const char *name,
 	const char *name,
-	unsigned int cast_vote)
+	unsigned int cast_vote,
+	votequorum_ring_id_t ring_id)
 {
 {
 	cs_error_t error;
 	cs_error_t error;
 	struct votequorum_inst *votequorum_inst;
 	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;
 	req_lib_votequorum_qdevice_poll.header.id = MESSAGE_REQ_VOTEQUORUM_QDEVICE_POLL;
 	strcpy(req_lib_votequorum_qdevice_poll.name, name);
 	strcpy(req_lib_votequorum_qdevice_poll.name, name);
 	req_lib_votequorum_qdevice_poll.cast_vote = cast_vote;
 	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_base = (char *)&req_lib_votequorum_qdevice_poll;
 	iov.iov_len = sizeof (struct req_lib_votequorum_qdevice_poll);
 	iov.iov_len = sizeof (struct req_lib_votequorum_qdevice_poll);

+ 4 - 1
man/votequorum_qdevice_poll.3.in

@@ -37,7 +37,7 @@ votequorum_qdevice_poll \- Tells votequorum the result of the quorum device poll
 .SH SYNOPSIS
 .SH SYNOPSIS
 .B #include <corosync/votequorum.h>
 .B #include <corosync/votequorum.h>
 .sp
 .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
 .SH DESCRIPTION
 The
 The
 .B votequorum_qdevice_poll
 .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
 the voting system if the quorum device is present/active or not. If
 .B cast_vote
 .B cast_vote
 is 1 then the votes for the device are included in the quorum calculation, otherwise not.
 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
 This routine should be called at regular intervals to ensure that the device status
 is always known to votequorum. If
 is always known to votequorum. If
 .B votequorum_qdevice_poll
 .B votequorum_qdevice_poll

+ 44 - 3
test/testvotequorum2.c

@@ -35,6 +35,7 @@
 #include <config.h>
 #include <config.h>
 
 
 #include <sys/types.h>
 #include <sys/types.h>
+#include <inttypes.h>
 #include <stdio.h>
 #include <stdio.h>
 #include <stdint.h>
 #include <stdint.h>
 #include <string.h>
 #include <string.h>
@@ -45,6 +46,8 @@
 
 
 static votequorum_handle_t handle;
 static votequorum_handle_t handle;
 
 
+static votequorum_ring_id_t last_received_ring_id;
+
 static int print_info(int ok_to_fail)
 static int print_info(int ok_to_fail)
 {
 {
 	struct votequorum_info info;
 	struct votequorum_info info;
@@ -71,6 +74,22 @@ static int print_info(int ok_to_fail)
 	return 0;
 	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)
 static void usage(const char *command)
 {
 {
   printf("%s [-p <num>] [-t <time>] [-n <name>] [-c] [-m]\n", 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 pollcount=0, polltime=1, quiet=0, once=0;
 	int err;
 	int err;
 	int opt;
 	int opt;
+	votequorum_callbacks_t callbacks;
 	const char *devicename = "QDEVICE";
 	const char *devicename = "QDEVICE";
 	const char *options = "n:p:t:cmq1h";
 	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) {
 	while ((opt = getopt(argc, argv, options)) != -1) {
 		switch (opt) {
 		switch (opt) {
 		case 'm':
 		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);
 		fprintf(stderr, "votequorum_initialize FAILED: %d\n", err);
 		return -1;
 		return -1;
 	}
 	}
@@ -141,6 +164,12 @@ int main(int argc, char *argv[])
 	}
 	}
 
 
 	if (argc >= 2) {
 	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) {
 		if ( (err=votequorum_qdevice_register(handle, devicename)) != CS_OK) {
 			fprintf(stderr, "qdevice_register FAILED: %d\n", err);
 			fprintf(stderr, "qdevice_register FAILED: %d\n", err);
 			ret = -1;
 			ret = -1;
@@ -153,13 +182,25 @@ int main(int argc, char *argv[])
 			goto out;
 			goto out;
 		}
 		}
 
 
+
 		while (--pollcount) {
 		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 (!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);
 				fprintf(stderr, "qdevice poll FAILED: %d\n", err);
 				ret = -1;
 				ret = -1;
 				goto out;
 				goto out;
 			}
 			}
+			if (err == CS_ERR_MESSAGE_ERROR) {
+				fprintf(stderr, "qdevice poll passed OLD ring_id\n");
+			}
+
 			if (!quiet) print_info(0);
 			if (!quiet) print_info(0);
 			sleep(polltime);
 			sleep(polltime);
 		}
 		}