Răsfoiți Sursa

Qdevice: Send ring id in more messages

To prevent receiving vote from old membership ring id is sent to server
during init and replied back to client in every node list,
ask for vote reply and vote info messages.

Signed-off-by: Jan Friesse <jfriesse@redhat.com>
Jan Friesse 9 ani în urmă
părinte
comite
6f6c80f582

+ 23 - 10
qdevices/msg.c

@@ -273,7 +273,8 @@ msg_create_init(struct dynar *msg, int add_msg_seq_number, uint32_t msg_seq_numb
     enum tlv_decision_algorithm_type decision_algorithm,
     const enum msg_type *supported_msgs, size_t no_supported_msgs,
     const enum tlv_opt_type *supported_opts, size_t no_supported_opts, uint32_t node_id,
-    uint32_t heartbeat_interval, const struct tlv_tie_breaker *tie_breaker)
+    uint32_t heartbeat_interval, const struct tlv_tie_breaker *tie_breaker,
+    const struct tlv_ring_id *ring_id)
 {
 	uint16_t *u16a;
 	int res;
@@ -313,9 +314,9 @@ msg_create_init(struct dynar *msg, int add_msg_seq_number, uint32_t msg_seq_numb
 		}
 	}
 
-        if (tlv_add_node_id(msg, node_id) == -1) {
+	if (tlv_add_node_id(msg, node_id) == -1) {
 		goto small_buf_err;
-        }
+	}
 
 	if (tlv_add_decision_algorithm(msg, decision_algorithm) == -1) {
 		goto small_buf_err;
@@ -329,6 +330,10 @@ msg_create_init(struct dynar *msg, int add_msg_seq_number, uint32_t msg_seq_numb
 		goto small_buf_err;
 	}
 
+	if (tlv_add_ring_id(msg, ring_id) == -1) {
+		goto small_buf_err;
+	}
+
 	msg_set_len(msg, dynar_size(msg) - (MSG_TYPE_LENGTH + MSG_LENGTH_LENGTH));
 
 	return (dynar_size(msg));
@@ -570,7 +575,7 @@ small_buf_err:
 
 size_t
 msg_create_node_list_reply(struct dynar *msg, uint32_t msg_seq_number,
-    enum tlv_node_list_type node_list_type, int add_ring_id, const struct tlv_ring_id *ring_id,
+    enum tlv_node_list_type node_list_type, const struct tlv_ring_id *ring_id,
     enum tlv_vote vote)
 {
 
@@ -587,10 +592,8 @@ msg_create_node_list_reply(struct dynar *msg, uint32_t msg_seq_number,
 		goto small_buf_err;
 	}
 
-	if (add_ring_id) {
-		if (tlv_add_ring_id(msg, ring_id) == -1) {
-			goto small_buf_err;
-		}
+	if (tlv_add_ring_id(msg, ring_id) == -1) {
+		goto small_buf_err;
 	}
 
 	if (tlv_add_vote(msg, vote) == -1) {
@@ -627,7 +630,8 @@ small_buf_err:
 }
 
 size_t
-msg_create_ask_for_vote_reply(struct dynar *msg, uint32_t msg_seq_number, enum tlv_vote vote)
+msg_create_ask_for_vote_reply(struct dynar *msg, uint32_t msg_seq_number,
+    const struct tlv_ring_id *ring_id, enum tlv_vote vote)
 {
 
 	dynar_clean(msg);
@@ -643,6 +647,10 @@ msg_create_ask_for_vote_reply(struct dynar *msg, uint32_t msg_seq_number, enum t
 		goto small_buf_err;
 	}
 
+	if (tlv_add_ring_id(msg, ring_id) == -1) {
+		goto small_buf_err;
+	}
+
 	msg_set_len(msg, dynar_size(msg) - (MSG_TYPE_LENGTH + MSG_LENGTH_LENGTH));
 
 	return (dynar_size(msg));
@@ -652,7 +660,8 @@ small_buf_err:
 }
 
 size_t
-msg_create_vote_info(struct dynar *msg, uint32_t msg_seq_number, enum tlv_vote vote)
+msg_create_vote_info(struct dynar *msg, uint32_t msg_seq_number, const struct tlv_ring_id *ring_id,
+    enum tlv_vote vote)
 {
 
 	dynar_clean(msg);
@@ -668,6 +677,10 @@ msg_create_vote_info(struct dynar *msg, uint32_t msg_seq_number, enum tlv_vote v
 		goto small_buf_err;
 	}
 
+	if (tlv_add_ring_id(msg, ring_id) == -1) {
+		goto small_buf_err;
+	}
+
 	msg_set_len(msg, dynar_size(msg) - (MSG_TYPE_LENGTH + MSG_LENGTH_LENGTH));
 
 	return (dynar_size(msg));

+ 5 - 4
qdevices/msg.h

@@ -127,7 +127,8 @@ extern size_t		msg_create_init(struct dynar *msg, int add_msg_seq_number,
     uint32_t msg_seq_number, enum tlv_decision_algorithm_type decision_algorithm,
     const enum msg_type *supported_msgs, size_t no_supported_msgs,
     const enum tlv_opt_type *supported_opts, size_t no_supported_opts, uint32_t node_id,
-    uint32_t heartbeat_interval, const struct tlv_tie_breaker *tie_breaker);
+    uint32_t heartbeat_interval, const struct tlv_tie_breaker *tie_breaker,
+    const struct tlv_ring_id *ring_id);
 
 extern size_t		msg_create_server_error(struct dynar *msg, int add_msg_seq_number,
     uint32_t msg_seq_number, enum tlv_reply_error_code reply_error_code);
@@ -161,16 +162,16 @@ extern size_t		msg_create_node_list(struct dynar *msg,
     const struct node_list *nodes);
 
 extern size_t		msg_create_node_list_reply(struct dynar *msg, uint32_t msg_seq_number,
-    enum tlv_node_list_type node_list_type, int add_ring_id, const struct tlv_ring_id *ring_id,
+    enum tlv_node_list_type node_list_type, const struct tlv_ring_id *ring_id,
     enum tlv_vote vote);
 
 extern size_t		msg_create_ask_for_vote(struct dynar *msg, uint32_t msg_seq_number);
 
 extern size_t		msg_create_ask_for_vote_reply(struct dynar *msg, uint32_t msg_seq_number,
-    enum tlv_vote vote);
+    const struct tlv_ring_id *ring_id, enum tlv_vote vote);
 
 extern size_t		msg_create_vote_info(struct dynar *msg, uint32_t msg_seq_number,
-    enum tlv_vote vote);
+    const struct tlv_ring_id *ring_id, enum tlv_vote vote);
 
 extern size_t		msg_create_vote_info_reply(struct dynar *msg, uint32_t msg_seq_number);
 

+ 7 - 7
qdevices/nss-sock.c

@@ -94,7 +94,7 @@ nss_sock_create_socket(PRIntn af, int reuse_addr)
 		socket_option.value.reuse_addr = PR_TRUE;
 		if (PR_SetSocketOption(sock, &socket_option) != PR_SUCCESS) {
 			return (NULL);
-	         }
+		}
 	}
 
 	return (sock);
@@ -424,8 +424,8 @@ nss_sock_start_ssl_as_client(PRFileDesc *input_sock, const char *ssl_url,
 			 */
 			*reset_would_block = 1;
 		} else {
-	                return (NULL);
-	        }
+			return (NULL);
+		}
 	}
 
 	return (ssl_sock);
@@ -464,16 +464,16 @@ nss_sock_start_ssl_as_server(PRFileDesc *input_sock, CERTCertificate *server_cer
 		return (NULL);
 	}
 
-        if (force_handshake && SSL_ForceHandshake(ssl_sock) != SECSuccess) {
+	if (force_handshake && SSL_ForceHandshake(ssl_sock) != SECSuccess) {
 		if (PR_GetError() == PR_WOULD_BLOCK_ERROR) {
 			/*
 			 * Mask would block error.
 			 */
 			*reset_would_block = 1;
 		} else {
-	                return (NULL);
-	        }
-        }
+			return (NULL);
+		}
+	}
 
 	return (ssl_sock);
 }

+ 2 - 2
qdevices/qdevice-cmap.c

@@ -222,7 +222,7 @@ qdevice_cmap_init(struct qdevice_instance *instance)
 		(void)poll(NULL, 0, 1000);
 	}
 
-        if (res != CS_OK) {
+	if (res != CS_OK) {
 		errx(1, "Failed to initialize the cmap API. Error %s", cs_strerror(res));
 	}
 
@@ -436,7 +436,7 @@ qdevice_cmap_destroy(struct qdevice_instance *instance)
 
 	res = cmap_finalize(instance->cmap_handle);
 
-        if (res != CS_OK) {
+	if (res != CS_OK) {
 		qdevice_log(LOG_WARNING, "Can't finalize cmap. Error %s", cs_strerror(res));
 	}
 }

+ 1 - 1
qdevices/qdevice-ipc-cmd.c

@@ -84,7 +84,7 @@ static int
 qdevice_ipc_cmd_status_add_config_node_list(struct qdevice_instance *instance, struct dynar *outbuf,
     int verbose)
 {
-        struct node_list_entry *node_info;
+	struct node_list_entry *node_info;
 	size_t zi;
 
 	if (instance->config_node_list_version_set) {

+ 1 - 1
qdevices/qdevice-log-debug.c

@@ -52,5 +52,5 @@ qdevice_log_debug_dump_node_list(const struct node_list *nlist)
 		    zi, node_info->node_id, node_info->data_center_id,
 		    tlv_node_state_to_str(node_info->node_state));
 		zi++;
-        }
+	}
 }

+ 26 - 5
qdevices/qdevice-net-algo-2nodelms.c

@@ -94,41 +94,62 @@ qdevice_net_algo_2nodelms_votequorum_expected_votes_notify(struct qdevice_net_in
 
 int
 qdevice_net_algo_2nodelms_config_node_list_reply_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, int initial, enum tlv_vote *vote)
+    uint32_t seq_number, int initial, const struct tlv_ring_id *ring_id, int ring_id_is_valid, enum tlv_vote *vote)
 {
 
+	if (!ring_id_is_valid) {
+		*vote = TLV_VOTE_NO_CHANGE;
+	}
+
 	return (0);
 }
 
 int
 qdevice_net_algo_2nodelms_membership_node_list_reply_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, const struct tlv_ring_id *ring_id, enum tlv_vote *vote)
+    uint32_t seq_number, const struct tlv_ring_id *ring_id, int ring_id_is_valid,
+    enum tlv_vote *vote)
 {
 
+	if (!ring_id_is_valid) {
+		*vote = TLV_VOTE_NO_CHANGE;
+	}
+
 	return (0);
 }
 
 int
 qdevice_net_algo_2nodelms_quorum_node_list_reply_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, enum tlv_vote *vote)
+    uint32_t seq_number, const struct tlv_ring_id *ring_id, int ring_id_is_valid, enum tlv_vote *vote)
 {
 
+	if (!ring_id_is_valid) {
+		*vote = TLV_VOTE_NO_CHANGE;
+	}
+
 	return (0);
 }
 
 int
 qdevice_net_algo_2nodelms_ask_for_vote_reply_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, enum tlv_vote *vote)
+    uint32_t seq_number, const struct tlv_ring_id *ring_id, int ring_id_is_valid, enum tlv_vote *vote)
 {
 
+	if (!ring_id_is_valid) {
+		*vote = TLV_VOTE_NO_CHANGE;
+	}
+
 	return (0);
 }
 
 int
 qdevice_net_algo_2nodelms_vote_info_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, enum tlv_vote *vote)
+    uint32_t seq_number, const struct tlv_ring_id *ring_id, int ring_id_is_valid, enum tlv_vote *vote)
 {
 
+	if (!ring_id_is_valid) {
+		*vote = TLV_VOTE_NO_CHANGE;
+	}
+
 	return (0);
 }
 

+ 8 - 6
qdevices/qdevice-net-algo-2nodelms.h

@@ -47,7 +47,7 @@ extern int	qdevice_net_algo_2nodelms_connected(struct qdevice_net_instance *inst
     int *send_config_node_list, int *send_membership_node_list, int *send_quorum_node_list,
     enum tlv_vote *vote);
 
-extern int      qdevice_net_algo_2nodelms_config_node_list_changed(
+extern int	qdevice_net_algo_2nodelms_config_node_list_changed(
     struct qdevice_net_instance *instance, const struct node_list *nlist,
     int config_version_set, uint64_t config_version, int *send_node_list, enum tlv_vote *vote);
 
@@ -63,22 +63,24 @@ extern int	qdevice_net_algo_2nodelms_votequorum_expected_votes_notify(
     struct qdevice_net_instance *instance, uint32_t expected_votes, enum tlv_vote *vote);
 
 extern int	qdevice_net_algo_2nodelms_config_node_list_reply_received(
-    struct qdevice_net_instance *instance, uint32_t seq_number, int initial, enum tlv_vote *vote);
+    struct qdevice_net_instance *instance, uint32_t seq_number, int initial,
+    const struct tlv_ring_id *ring_id, int ring_id_is_valid, enum tlv_vote *vote);
 
 extern int	qdevice_net_algo_2nodelms_membership_node_list_reply_received(
     struct qdevice_net_instance *instance, uint32_t seq_number, const struct tlv_ring_id *ring_id,
-    enum tlv_vote *vote);
+    int ring_id_is_valid, enum tlv_vote *vote);
 
 extern int	qdevice_net_algo_2nodelms_quorum_node_list_reply_received(
     struct qdevice_net_instance *instance, uint32_t seq_number,
-    enum tlv_vote *vote);
+    const struct tlv_ring_id *ring_id, int ring_id_is_valid, enum tlv_vote *vote);
 
 extern int	qdevice_net_algo_2nodelms_ask_for_vote_reply_received(
     struct qdevice_net_instance *instance, uint32_t seq_number,
-    enum tlv_vote *vote);
+    const struct tlv_ring_id *ring_id, int ring_id_is_valid, enum tlv_vote *vote);
 
 extern int	qdevice_net_algo_2nodelms_vote_info_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, enum tlv_vote *vote);
+    uint32_t seq_number, const struct tlv_ring_id *ring_id, int ring_id_is_valid,
+    enum tlv_vote *vote);
 
 extern int	qdevice_net_algo_2nodelms_echo_reply_received(
     struct qdevice_net_instance *instance, uint32_t seq_number, int is_expected_seq_number);

+ 26 - 5
qdevices/qdevice-net-algo-ffsplit.c

@@ -172,41 +172,62 @@ qdevice_net_algo_ffsplit_votequorum_expected_votes_notify(struct qdevice_net_ins
 
 int
 qdevice_net_algo_ffsplit_config_node_list_reply_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, int initial, enum tlv_vote *vote)
+    uint32_t seq_number, int initial, const struct tlv_ring_id *ring_id, int ring_id_is_valid,
+    enum tlv_vote *vote)
 {
 
+	if (!ring_id_is_valid) {
+		*vote = TLV_VOTE_NO_CHANGE;
+	}
+
 	return (0);
 }
 
 int
 qdevice_net_algo_ffsplit_membership_node_list_reply_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, const struct tlv_ring_id *ring_id, enum tlv_vote *vote)
+    uint32_t seq_number, const struct tlv_ring_id *ring_id, int ring_id_is_valid, enum tlv_vote *vote)
 {
 
+	if (!ring_id_is_valid) {
+		*vote = TLV_VOTE_NO_CHANGE;
+	}
+
 	return (0);
 }
 
 int
 qdevice_net_algo_ffsplit_quorum_node_list_reply_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, enum tlv_vote *vote)
+    uint32_t seq_number, const struct tlv_ring_id *ring_id, int ring_id_is_valid, enum tlv_vote *vote)
 {
 
+	if (!ring_id_is_valid) {
+		*vote = TLV_VOTE_NO_CHANGE;
+	}
+
 	return (0);
 }
 
 int
 qdevice_net_algo_ffsplit_ask_for_vote_reply_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, enum tlv_vote *vote)
+    uint32_t seq_number, const struct tlv_ring_id *ring_id, int ring_id_is_valid, enum tlv_vote *vote)
 {
 
+	if (!ring_id_is_valid) {
+		*vote = TLV_VOTE_NO_CHANGE;
+	}
+
 	return (0);
 }
 
 int
 qdevice_net_algo_ffsplit_vote_info_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, enum tlv_vote *vote)
+    uint32_t seq_number, const struct tlv_ring_id *ring_id, int ring_id_is_valid, enum tlv_vote *vote)
 {
 
+	if (!ring_id_is_valid) {
+		*vote = TLV_VOTE_NO_CHANGE;
+	}
+
 	return (0);
 }
 

+ 8 - 6
qdevices/qdevice-net-algo-ffsplit.h

@@ -47,7 +47,7 @@ extern int	qdevice_net_algo_ffsplit_connected(struct qdevice_net_instance *insta
     int *send_config_node_list, int *send_membership_node_list, int *send_quorum_node_list,
     enum tlv_vote *vote);
 
-extern int      qdevice_net_algo_ffsplit_config_node_list_changed(
+extern int	qdevice_net_algo_ffsplit_config_node_list_changed(
     struct qdevice_net_instance *instance, const struct node_list *nlist,
     int config_version_set, uint64_t config_version, int *send_node_list, enum tlv_vote *vote);
 
@@ -63,22 +63,24 @@ extern int	qdevice_net_algo_ffsplit_votequorum_expected_votes_notify(
     struct qdevice_net_instance *instance, uint32_t expected_votes, enum tlv_vote *vote);
 
 extern int	qdevice_net_algo_ffsplit_config_node_list_reply_received(
-    struct qdevice_net_instance *instance, uint32_t seq_number, int initial, enum tlv_vote *vote);
+    struct qdevice_net_instance *instance, uint32_t seq_number, int initial,
+    const struct tlv_ring_id *ring_id, int ring_id_is_valid, enum tlv_vote *vote);
 
 extern int	qdevice_net_algo_ffsplit_membership_node_list_reply_received(
     struct qdevice_net_instance *instance, uint32_t seq_number, const struct tlv_ring_id *ring_id,
-    enum tlv_vote *vote);
+    int ring_id_is_valid, enum tlv_vote *vote);
 
 extern int	qdevice_net_algo_ffsplit_quorum_node_list_reply_received(
     struct qdevice_net_instance *instance, uint32_t seq_number,
-    enum tlv_vote *vote);
+    const struct tlv_ring_id *ring_id, int ring_id_is_valid, enum tlv_vote *vote);
 
 extern int	qdevice_net_algo_ffsplit_ask_for_vote_reply_received(
     struct qdevice_net_instance *instance, uint32_t seq_number,
-    enum tlv_vote *vote);
+    const struct tlv_ring_id *ring_id, int ring_id_is_valid, enum tlv_vote *vote);
 
 extern int	qdevice_net_algo_ffsplit_vote_info_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, enum tlv_vote *vote);
+    uint32_t seq_number, const struct tlv_ring_id *ring_id, int ring_id_is_valid,
+    enum tlv_vote *vote);
 
 extern int	qdevice_net_algo_ffsplit_echo_reply_received(
     struct qdevice_net_instance *instance, uint32_t seq_number, int is_expected_seq_number);

+ 33 - 5
qdevices/qdevice-net-algo-lms.c

@@ -112,23 +112,40 @@ qdevice_net_algo_lms_votequorum_quorum_notify(struct qdevice_net_instance *insta
 
 int
 qdevice_net_algo_lms_config_node_list_reply_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, int initial, enum tlv_vote *vote)
+    uint32_t seq_number, int initial, const struct tlv_ring_id *ring_id, int ring_id_is_valid,
+    enum tlv_vote *vote)
 {
 
+	if (!ring_id_is_valid) {
+		*vote = TLV_VOTE_NO_CHANGE;
+	}
+
 	return (0);
 }
 
 int
 qdevice_net_algo_lms_membership_node_list_reply_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, const struct tlv_ring_id *ring_id, enum tlv_vote *vote)
+    uint32_t seq_number, const struct tlv_ring_id *ring_id, int ring_id_is_valid,
+    enum tlv_vote *vote)
 {
+
+	if (!ring_id_is_valid) {
+		*vote = TLV_VOTE_NO_CHANGE;
+	}
+
 	return (0);
 }
 
 int
 qdevice_net_algo_lms_quorum_node_list_reply_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, enum tlv_vote *vote)
+    uint32_t seq_number, const struct tlv_ring_id *ring_id, int ring_id_is_valid,
+    enum tlv_vote *vote)
 {
+
+	if (!ring_id_is_valid) {
+		*vote = TLV_VOTE_NO_CHANGE;
+	}
+
 	return (0);
 }
 
@@ -142,16 +159,27 @@ qdevice_net_algo_lms_votequorum_expected_votes_notify(struct qdevice_net_instanc
 
 int
 qdevice_net_algo_lms_ask_for_vote_reply_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, enum tlv_vote *vote)
+    uint32_t seq_number, const struct tlv_ring_id *ring_id, int ring_id_is_valid,
+    enum tlv_vote *vote)
 {
 
+	if (!ring_id_is_valid) {
+		*vote = TLV_VOTE_NO_CHANGE;
+	}
+
 	return (0);
 }
 
 int
 qdevice_net_algo_lms_vote_info_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, enum tlv_vote *vote)
+    uint32_t seq_number, const struct tlv_ring_id *ring_id, int ring_id_is_valid,
+    enum tlv_vote *vote)
 {
+
+	if (!ring_id_is_valid) {
+		*vote = TLV_VOTE_NO_CHANGE;
+	}
+
 	return (0);
 }
 

+ 8 - 6
qdevices/qdevice-net-algo-lms.h

@@ -47,7 +47,7 @@ extern int	qdevice_net_algo_lms_connected(struct qdevice_net_instance *instance,
     int *send_config_node_list, int *send_membership_node_list, int *send_quorum_node_list,
     enum tlv_vote *vote);
 
-extern int      qdevice_net_algo_lms_config_node_list_changed(
+extern int	qdevice_net_algo_lms_config_node_list_changed(
     struct qdevice_net_instance *instance, const struct node_list *nlist,
     int config_version_set, uint64_t config_version, int *send_node_list, enum tlv_vote *vote);
 
@@ -63,22 +63,24 @@ extern int	qdevice_net_algo_lms_votequorum_expected_votes_notify(
     struct qdevice_net_instance *instance, uint32_t expected_votes, enum tlv_vote *vote);
 
 extern int	qdevice_net_algo_lms_config_node_list_reply_received(
-    struct qdevice_net_instance *instance, uint32_t seq_number, int initial, enum tlv_vote *vote);
+    struct qdevice_net_instance *instance, uint32_t seq_number, int initial,
+    const struct tlv_ring_id *ring_id, int ring_id_is_valid, enum tlv_vote *vote);
 
 extern int	qdevice_net_algo_lms_membership_node_list_reply_received(
     struct qdevice_net_instance *instance, uint32_t seq_number, const struct tlv_ring_id *ring_id,
-    enum tlv_vote *vote);
+    int ring_id_is_valid, enum tlv_vote *vote);
 
 extern int	qdevice_net_algo_lms_quorum_node_list_reply_received(
     struct qdevice_net_instance *instance, uint32_t seq_number,
-    enum tlv_vote *vote);
+    const struct tlv_ring_id *ring_id, int ring_id_is_valid, enum tlv_vote *vote);
 
 extern int	qdevice_net_algo_lms_ask_for_vote_reply_received(
     struct qdevice_net_instance *instance, uint32_t seq_number,
-    enum tlv_vote *vote);
+    const struct tlv_ring_id *ring_id, int ring_id_is_valid, enum tlv_vote *vote);
 
 extern int	qdevice_net_algo_lms_vote_info_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, enum tlv_vote *vote);
+    uint32_t seq_number, const struct tlv_ring_id *ring_id, int ring_id_is_valid,
+    enum tlv_vote *vote);
 
 extern int	qdevice_net_algo_lms_echo_reply_received(
     struct qdevice_net_instance *instance, uint32_t seq_number, int is_expected_seq_number);

+ 42 - 6
qdevices/qdevice-net-algo-test.c

@@ -171,17 +171,23 @@ qdevice_net_algo_test_votequorum_expected_votes_notify(struct qdevice_net_instan
 
 /*
  * Called when config node list reply is received. Vote is set to value returned by server (and can
- * be overwriten by algorithm).
+ * be overwriten by algorithm). ring_id is returned by server. ring_id_is_valid is set to 1 only if
+ * received ring id matches last sent ring id. It usually make sense to not update timer.
  *
  * Callback should return 0 on success or -1 on failure (-> disconnect client).
  */
 int
 qdevice_net_algo_test_config_node_list_reply_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, int initial, enum tlv_vote *vote)
+    uint32_t seq_number, int initial, const struct tlv_ring_id *ring_id, int ring_id_is_valid,
+    enum tlv_vote *vote)
 {
 
 	qdevice_log(LOG_INFO, "algo-test: Config node list reply");
 
+	if (!ring_id_is_valid) {
+		*vote = TLV_VOTE_NO_CHANGE;
+	}
+
 	return (0);
 }
 
@@ -193,15 +199,23 @@ qdevice_net_algo_test_config_node_list_reply_received(struct qdevice_net_instanc
  * with instance->main_timer_list parameter) and ask for reply (qdevice_net_send_ask_for_vote).
  * Another option may be to wait for vote_info message (if server algorithm is configured so).
  *
+ * ring_id and ring_id_is_valid have same meaning as for
+ * qdevice_net_algo_test_config_node_list_reply_received
+ *
  * Callback should return 0 on success or -1 on failure (-> disconnect client).
  */
 int
 qdevice_net_algo_test_membership_node_list_reply_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, const struct tlv_ring_id *ring_id, enum tlv_vote *vote)
+    uint32_t seq_number, const struct tlv_ring_id *ring_id, int ring_id_is_valid,
+    enum tlv_vote *vote)
 {
 
 	qdevice_log(LOG_INFO, "algo-test: Membership node list reply");
 
+	if (!ring_id_is_valid) {
+		*vote = TLV_VOTE_NO_CHANGE;
+	}
+
 	return (0);
 }
 
@@ -209,15 +223,23 @@ qdevice_net_algo_test_membership_node_list_reply_received(struct qdevice_net_ins
  * Called when quorum node list reply (reply for votequorum votequorum_quorum_notify_fn)
  * is received. Vote is set to value returned by server (and can be overwriten by algorithm).
  *
+ * ring_id and ring_id_is_valid have same meaning as for
+ * qdevice_net_algo_test_config_node_list_reply_received
+ *
  * Callback should return 0 on success or -1 on failure (-> disconnect client).
  */
 int
 qdevice_net_algo_test_quorum_node_list_reply_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, enum tlv_vote *vote)
+    uint32_t seq_number, const struct tlv_ring_id *ring_id, int ring_id_is_valid,
+    enum tlv_vote *vote)
 {
 
 	qdevice_log(LOG_INFO, "algo-test: Quorum node list reply");
 
+	if (!ring_id_is_valid) {
+		*vote = TLV_VOTE_NO_CHANGE;
+	}
+
 	return (0);
 }
 
@@ -225,15 +247,22 @@ qdevice_net_algo_test_quorum_node_list_reply_received(struct qdevice_net_instanc
  * Called when reply for ask for vote message was received.
  * Vote is set to value returned by server (and can be overwriten by algorithm).
  *
+ * ring_id and ring_id_is_valid have same meaning as for
+ * qdevice_net_algo_test_config_node_list_reply_received
+ *
  * Callback should return 0 on success or -1 on failure (-> disconnect client).
  */
 int
 qdevice_net_algo_test_ask_for_vote_reply_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, enum tlv_vote *vote)
+    uint32_t seq_number, const struct tlv_ring_id *ring_id, int ring_id_is_valid, enum tlv_vote *vote)
 {
 
 	qdevice_log(LOG_INFO, "algo-test: Ask for vote reply received");
 
+	if (!ring_id_is_valid) {
+		*vote = TLV_VOTE_NO_CHANGE;
+	}
+
 	return (0);
 }
 
@@ -241,15 +270,22 @@ qdevice_net_algo_test_ask_for_vote_reply_received(struct qdevice_net_instance *i
  * Called when vote info message from server was received.
  * Vote is set to value sent by server (and can be overwriten by algorithm).
  *
+ * ring_id and ring_id_is_valid have same meaning as for
+ * qdevice_net_algo_test_config_node_list_reply_received
+ *
  * Callback should return 0 on success or -1 on failure (-> disconnect client).
  */
 int
 qdevice_net_algo_test_vote_info_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, enum tlv_vote *vote)
+    uint32_t seq_number, const struct tlv_ring_id *ring_id, int ring_id_is_valid, enum tlv_vote *vote)
 {
 
 	qdevice_log(LOG_INFO, "algo-test: Vote info received");
 
+	if (!ring_id_is_valid) {
+		*vote = TLV_VOTE_NO_CHANGE;
+	}
+
 	return (0);
 }
 

+ 7 - 6
qdevices/qdevice-net-algo-test.h

@@ -47,7 +47,7 @@ extern int	qdevice_net_algo_test_connected(struct qdevice_net_instance *instance
     int *send_config_node_list, int *send_membership_node_list, int *send_quorum_node_list,
     enum tlv_vote *vote);
 
-extern int      qdevice_net_algo_test_config_node_list_changed(
+extern int	qdevice_net_algo_test_config_node_list_changed(
     struct qdevice_net_instance *instance, const struct node_list *nlist,
     int config_version_set, uint64_t config_version, int *send_node_list, enum tlv_vote *vote);
 
@@ -64,22 +64,23 @@ extern int	qdevice_net_algo_test_votequorum_expected_votes_notify(
 
 extern int	qdevice_net_algo_test_config_node_list_reply_received(
     struct qdevice_net_instance *instance, uint32_t seq_number, int initial,
-    enum tlv_vote *vote);
+    const struct tlv_ring_id *ring_id, int ring_id_is_valid, enum tlv_vote *vote);
 
 extern int	qdevice_net_algo_test_membership_node_list_reply_received(
     struct qdevice_net_instance *instance, uint32_t seq_number, const struct tlv_ring_id *ring_id,
-    enum tlv_vote *vote);
+    int ring_id_is_valid, enum tlv_vote *vote);
 
 extern int	qdevice_net_algo_test_quorum_node_list_reply_received(
     struct qdevice_net_instance *instance, uint32_t seq_number,
-    enum tlv_vote *vote);
+    const struct tlv_ring_id *ring_id, int ring_id_is_valid, enum tlv_vote *vote);
 
 extern int	qdevice_net_algo_test_ask_for_vote_reply_received(
     struct qdevice_net_instance *instance, uint32_t seq_number,
-    enum tlv_vote *vote);
+    const struct tlv_ring_id *ring_id, int ring_id_is_valid, enum tlv_vote *vote);
 
 extern int	qdevice_net_algo_test_vote_info_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, enum tlv_vote *vote);
+    uint32_t seq_number, const struct tlv_ring_id *ring_id, int ring_id_is_valid,
+    enum tlv_vote *vote);
 
 extern int	qdevice_net_algo_test_echo_reply_received(
     struct qdevice_net_instance *instance, uint32_t seq_number, int is_expected_seq_number);

+ 17 - 10
qdevices/qdevice-net-algorithm.c

@@ -143,7 +143,8 @@ qdevice_net_algorithm_votequorum_expected_votes_notify(struct qdevice_net_instan
 
 int
 qdevice_net_algorithm_config_node_list_reply_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, int initial, enum tlv_vote *vote)
+    uint32_t seq_number, int initial, const struct tlv_ring_id *ring_id, int ring_id_is_valid,
+    enum tlv_vote *vote)
 {
 
 	if (instance->decision_algorithm >= QDEVICE_NET_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE ||
@@ -154,12 +155,13 @@ qdevice_net_algorithm_config_node_list_reply_received(struct qdevice_net_instanc
 	}
 
 	return (qdevice_net_algorithm_array[instance->decision_algorithm]->
-	    config_node_list_reply_received(instance, seq_number, initial, vote));
+	    config_node_list_reply_received(instance, seq_number, initial, ring_id,
+	    ring_id_is_valid, vote));
 }
 
 int
 qdevice_net_algorithm_membership_node_list_reply_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, const struct tlv_ring_id *ring_id, enum tlv_vote *vote)
+    uint32_t seq_number, const struct tlv_ring_id *ring_id, int ring_id_is_valid, enum tlv_vote *vote)
 {
 
 	if (instance->decision_algorithm >= QDEVICE_NET_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE ||
@@ -170,12 +172,14 @@ qdevice_net_algorithm_membership_node_list_reply_received(struct qdevice_net_ins
 	}
 
 	return (qdevice_net_algorithm_array[instance->decision_algorithm]->
-	    membership_node_list_reply_received(instance, seq_number, ring_id, vote));
+	    membership_node_list_reply_received(instance, seq_number, ring_id, ring_id_is_valid,
+	    vote));
 }
 
 int
 qdevice_net_algorithm_quorum_node_list_reply_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, enum tlv_vote *vote)
+    uint32_t seq_number, const struct tlv_ring_id *ring_id, int ring_id_is_valid,
+    enum tlv_vote *vote)
 {
 
 	if (instance->decision_algorithm >= QDEVICE_NET_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE ||
@@ -186,12 +190,14 @@ qdevice_net_algorithm_quorum_node_list_reply_received(struct qdevice_net_instanc
 	}
 
 	return (qdevice_net_algorithm_array[instance->decision_algorithm]->
-	    quorum_node_list_reply_received(instance, seq_number, vote));
+	    quorum_node_list_reply_received(instance, seq_number, ring_id, ring_id_is_valid,
+	    vote));
 }
 
 int
 qdevice_net_algorithm_ask_for_vote_reply_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, enum tlv_vote *vote)
+    uint32_t seq_number, const struct tlv_ring_id *ring_id, int ring_id_is_valid,
+    enum tlv_vote *vote)
 {
 
 	if (instance->decision_algorithm >= QDEVICE_NET_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE ||
@@ -202,12 +208,13 @@ qdevice_net_algorithm_ask_for_vote_reply_received(struct qdevice_net_instance *i
 	}
 
 	return (qdevice_net_algorithm_array[instance->decision_algorithm]->
-	    ask_for_vote_reply_received(instance, seq_number, vote));
+	    ask_for_vote_reply_received(instance, seq_number, ring_id, ring_id_is_valid, vote));
 }
 
 int
 qdevice_net_algorithm_vote_info_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, enum tlv_vote *vote)
+    uint32_t seq_number, const struct tlv_ring_id *ring_id, int ring_id_is_valid,
+    enum tlv_vote *vote)
 {
 
 	if (instance->decision_algorithm >= QDEVICE_NET_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE ||
@@ -218,7 +225,7 @@ qdevice_net_algorithm_vote_info_received(struct qdevice_net_instance *instance,
 	}
 
 	return (qdevice_net_algorithm_array[instance->decision_algorithm]->
-	    vote_info_received(instance, seq_number, vote));
+	    vote_info_received(instance, seq_number, ring_id, ring_id_is_valid, vote));
 }
 
 int

+ 17 - 10
qdevices/qdevice-net-algorithm.h

@@ -67,19 +67,21 @@ extern int	qdevice_net_algorithm_votequorum_expected_votes_notify(struct qdevice
     uint32_t expected_votes, enum tlv_vote *vote);
 
 extern int	qdevice_net_algorithm_config_node_list_reply_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, int initial, enum tlv_vote *vote);
+    uint32_t seq_number, int initial, const struct tlv_ring_id *ring_id, int ring_id_is_valid,
+    enum tlv_vote *vote);
 
 extern int	qdevice_net_algorithm_membership_node_list_reply_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, const struct tlv_ring_id *ring_id, enum tlv_vote *vote);
+    uint32_t seq_number, const struct tlv_ring_id *ring_id, int ring_id_is_valid, enum tlv_vote *vote);
 
 extern int	qdevice_net_algorithm_quorum_node_list_reply_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, enum tlv_vote *vote);
+    uint32_t seq_number, const struct tlv_ring_id *ring_id, int ring_id_is_valid, enum tlv_vote *vote);
 
 extern int	qdevice_net_algorithm_ask_for_vote_reply_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, enum tlv_vote *vote);
+    uint32_t seq_number, const struct tlv_ring_id *ring_id, int ring_id_is_valid, enum tlv_vote *vote);
 
 extern int	qdevice_net_algorithm_vote_info_received(struct qdevice_net_instance *instance,
-    uint32_t seq_number, enum tlv_vote *vote);
+    uint32_t seq_number, const struct tlv_ring_id *ring_id, int ring_id_is_valid,
+    enum tlv_vote *vote);
 
 extern int	qdevice_net_algorithm_echo_reply_received(struct qdevice_net_instance *instance,
     uint32_t seq_number, int is_expected_seq_number);
@@ -108,15 +110,20 @@ struct qdevice_net_algorithm {
 	int (*votequorum_expected_votes_notify)(struct qdevice_net_instance *instance,
 	    uint32_t expected_votes, enum tlv_vote *vote);
 	int (*config_node_list_reply_received)(struct qdevice_net_instance *instance,
-	    uint32_t seq_number, int initial, enum tlv_vote *vote);
+	    uint32_t seq_number, int initial, const struct tlv_ring_id *ring_id, int ring_id_is_valid,
+	    enum tlv_vote *vote);
 	int (*membership_node_list_reply_received)(struct qdevice_net_instance *instance,
-	    uint32_t seq_number, const struct tlv_ring_id *ring_id, enum tlv_vote *vote);
+	    uint32_t seq_number, const struct tlv_ring_id *ring_id, int ring_id_is_valid,
+	    enum tlv_vote *vote);
 	int (*quorum_node_list_reply_received)(struct qdevice_net_instance *instance,
-	    uint32_t seq_number, enum tlv_vote *vote);
+	    uint32_t seq_number, const struct tlv_ring_id *ring_id, int ring_id_is_valid,
+	    enum tlv_vote *vote);
 	int (*ask_for_vote_reply_received)(struct qdevice_net_instance *instance,
-	    uint32_t seq_number, enum tlv_vote *vote);
+	    uint32_t seq_number, const struct tlv_ring_id *ring_id, int ring_id_is_valid,
+	    enum tlv_vote *vote);
 	int (*vote_info_received)(struct qdevice_net_instance *instance,
-	    uint32_t seq_number, enum tlv_vote *vote);
+	    uint32_t seq_number, const struct tlv_ring_id *ring_id, int ring_id_is_valid,
+	    enum tlv_vote *vote);
 	int (*echo_reply_received)(struct qdevice_net_instance *instance,
 	    uint32_t seq_number, int is_expected_seq_number);
 	int (*echo_reply_not_received)(struct qdevice_net_instance *instance);

+ 2 - 2
qdevices/qdevice-net-instance.h

@@ -78,8 +78,8 @@ struct qdevice_net_instance {
 	enum tlv_tls_supported tls_supported;
 	int using_tls;
 	int tls_client_cert_sent;
-	uint32_t heartbeat_interval;            /* Adjusted heartbeat interval during normal operation */
-	uint32_t sync_heartbeat_interval;       /* Adjusted heartbeat interval during corosync sync */
+	uint32_t heartbeat_interval;		/* Adjusted heartbeat interval during normal operation */
+	uint32_t sync_heartbeat_interval;	/* Adjusted heartbeat interval during corosync sync */
 	uint32_t cast_vote_timer_interval;	/* Timer for cast vote */
 	uint32_t connect_timeout;
 	struct timer_list_entry *cast_vote_timer;

+ 46 - 27
qdevices/qdevice-net-msg-received.c

@@ -553,6 +553,7 @@ qdevice_net_msg_received_node_list_reply(struct qdevice_net_instance *instance,
 	enum tlv_vote result_vote;
 	int res;
 	int case_processed;
+	int ring_id_is_valid;
 
 	if (instance->state != QDEVICE_NET_INSTANCE_STATE_WAITING_VOTEQUORUM_CMAP_EVENTS) {
 		qdevice_log(LOG_ERR, "Received unexpected node list reply message. "
@@ -570,8 +571,8 @@ qdevice_net_msg_received_node_list_reply(struct qdevice_net_instance *instance,
 		return (-1);
 	}
 
-	if (msg->node_list_type == TLV_NODE_LIST_TYPE_MEMBERSHIP && !msg->ring_id_set) {
-		qdevice_log(LOG_ERR, "Received node list reply message with type membership "
+	if (!msg->ring_id_set) {
+		qdevice_log(LOG_ERR, "Received node list reply message "
 		    "without ring id set. Disconnecting from server");
 
 		instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_REQUIRED_OPTION_MISSING;
@@ -600,16 +601,21 @@ qdevice_net_msg_received_node_list_reply(struct qdevice_net_instance *instance,
 	qdevice_log(LOG_DEBUG, "Received %s node list reply", str);
 	qdevice_log(LOG_DEBUG, "  seq = "UTILS_PRI_MSG_SEQ, msg->seq_number);
 	qdevice_log(LOG_DEBUG, "  vote = %s", tlv_vote_to_str(msg->vote));
-	if (msg->ring_id_set) {
-		qdevice_log(LOG_DEBUG, "  ring id = ("UTILS_PRI_RING_ID")",
+	qdevice_log(LOG_DEBUG, "  ring id = ("UTILS_PRI_RING_ID")",
 		    msg->ring_id.node_id, msg->ring_id.seq);
-	}
 
 	/*
 	 * Call algorithm
 	 */
 	result_vote = msg->vote;
 
+	if (!tlv_ring_id_eq(&msg->ring_id, &instance->last_sent_ring_id)) {
+		ring_id_is_valid = 0;
+		qdevice_log(LOG_DEBUG, "Received node list reply with old ring id.");
+	} else {
+		ring_id_is_valid = 1;
+	}
+
 	case_processed = 0;
 	switch (msg->node_list_type) {
 	case TLV_NODE_LIST_TYPE_INITIAL_CONFIG:
@@ -617,17 +623,17 @@ qdevice_net_msg_received_node_list_reply(struct qdevice_net_instance *instance,
 		case_processed = 1;
 		res = qdevice_net_algorithm_config_node_list_reply_received(instance,
 		    msg->seq_number, (msg->node_list_type == TLV_NODE_LIST_TYPE_INITIAL_CONFIG),
-		    &result_vote);
+		    &msg->ring_id, ring_id_is_valid, &result_vote);
 		break;
 	case TLV_NODE_LIST_TYPE_MEMBERSHIP:
 		case_processed = 1;
 		res = qdevice_net_algorithm_membership_node_list_reply_received(instance,
-		    msg->seq_number, &msg->ring_id, &result_vote);
+		    msg->seq_number, &msg->ring_id, ring_id_is_valid, &result_vote);
 		break;
 	case TLV_NODE_LIST_TYPE_QUORUM:
 		case_processed = 1;
 		res = qdevice_net_algorithm_quorum_node_list_reply_received(instance,
-		    msg->seq_number, &result_vote);
+		    msg->seq_number, &msg->ring_id, ring_id_is_valid, &result_vote);
 		break;
 	/*
 	 * Default is not defined intentionally. Compiler shows warning when new node list type
@@ -647,20 +653,12 @@ qdevice_net_msg_received_node_list_reply(struct qdevice_net_instance *instance,
 		instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_ALGO_NODE_LIST_REPLY_ERR;
 		return (-1);
 	} else {
-		qdevice_log(LOG_DEBUG, "Algorithm result vote is %s", tlv_vote_to_str(msg->vote));
-	}
-
-	if (result_vote != TLV_VOTE_NO_CHANGE) {
-		if (msg->node_list_type == TLV_NODE_LIST_TYPE_MEMBERSHIP &&
-		    !tlv_ring_id_eq(&msg->ring_id, &instance->last_sent_ring_id)) {
-			qdevice_log(LOG_INFO, "Received membership node list reply with "
-			    "old ring id. Not updating timer");
-		} else {
-			if (qdevice_net_cast_vote_timer_update(instance, result_vote) != 0) {
-				instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_CANT_SCHEDULE_VOTING_TIMER;
-				return (-1);
-			}
-		}
+		qdevice_log(LOG_DEBUG, "Algorithm result vote is %s", tlv_vote_to_str(result_vote));
+	}
+
+	if (qdevice_net_cast_vote_timer_update(instance, result_vote) != 0) {
+		instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_CANT_SCHEDULE_VOTING_TIMER;
+		return (-1);
 	}
 
 	return (0);
@@ -679,6 +677,7 @@ qdevice_net_msg_received_ask_for_vote_reply(struct qdevice_net_instance *instanc
     const struct msg_decoded *msg)
 {
 	enum tlv_vote result_vote;
+	int ring_id_is_valid;
 
 	if (instance->state != QDEVICE_NET_INSTANCE_STATE_WAITING_VOTEQUORUM_CMAP_EVENTS) {
 		qdevice_log(LOG_ERR, "Received unexpected ask for vote reply message. "
@@ -688,7 +687,7 @@ qdevice_net_msg_received_ask_for_vote_reply(struct qdevice_net_instance *instanc
 		return (-1);
 	}
 
-	if (!msg->vote_set || !msg->seq_number_set) {
+	if (!msg->vote_set || !msg->seq_number_set || !msg->ring_id_set) {
 		qdevice_log(LOG_ERR, "Received node list reply message without "
 		    "required options. Disconnecting from server");
 
@@ -699,17 +698,26 @@ qdevice_net_msg_received_ask_for_vote_reply(struct qdevice_net_instance *instanc
 	qdevice_log(LOG_DEBUG, "Received ask for vote reply");
 	qdevice_log(LOG_DEBUG, "  seq = "UTILS_PRI_MSG_SEQ, msg->seq_number);
 	qdevice_log(LOG_DEBUG, "  vote = %s", tlv_vote_to_str(msg->vote));
+	qdevice_log(LOG_DEBUG, "  ring id = ("UTILS_PRI_RING_ID")",
+		    msg->ring_id.node_id, msg->ring_id.seq);
 
 	result_vote = msg->vote;
 
+	if (!tlv_ring_id_eq(&msg->ring_id, &instance->last_sent_ring_id)) {
+		ring_id_is_valid = 0;
+		qdevice_log(LOG_DEBUG, "Received ask for vote reply with old ring id.");
+	} else {
+		ring_id_is_valid = 1;
+	}
+
 	if (qdevice_net_algorithm_ask_for_vote_reply_received(instance, msg->seq_number,
-	    &result_vote) != 0) {
+	    &msg->ring_id, ring_id_is_valid, &result_vote) != 0) {
 		qdevice_log(LOG_DEBUG, "Algorithm returned error. Disconnecting.");
 
 		instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_ALGO_ASK_FOR_VOTE_REPLY_ERR;
 		return (-1);
 	} else {
-		qdevice_log(LOG_DEBUG, "Algorithm result vote is %s", tlv_vote_to_str(msg->vote));
+		qdevice_log(LOG_DEBUG, "Algorithm result vote is %s", tlv_vote_to_str(result_vote));
 	}
 
 	if (qdevice_net_cast_vote_timer_update(instance, result_vote) != 0) {
@@ -726,6 +734,7 @@ qdevice_net_msg_received_vote_info(struct qdevice_net_instance *instance,
 {
 	struct send_buffer_list_entry *send_buffer;
 	enum tlv_vote result_vote;
+	int ring_id_is_valid;
 
 	if (instance->state != QDEVICE_NET_INSTANCE_STATE_WAITING_VOTEQUORUM_CMAP_EVENTS) {
 		qdevice_log(LOG_ERR, "Received unexpected vote info message. "
@@ -735,7 +744,7 @@ qdevice_net_msg_received_vote_info(struct qdevice_net_instance *instance,
 		return (-1);
 	}
 
-	if (!msg->vote_set || !msg->seq_number_set) {
+	if (!msg->vote_set || !msg->seq_number_set || !msg->ring_id_set) {
 		qdevice_log(LOG_ERR, "Received node list reply message without "
 		    "required options. Disconnecting from server");
 		instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_REQUIRED_OPTION_MISSING;
@@ -745,10 +754,20 @@ qdevice_net_msg_received_vote_info(struct qdevice_net_instance *instance,
 	qdevice_log(LOG_DEBUG, "Received vote info");
 	qdevice_log(LOG_DEBUG, "  seq = "UTILS_PRI_MSG_SEQ, msg->seq_number);
 	qdevice_log(LOG_DEBUG, "  vote = %s", tlv_vote_to_str(msg->vote));
+	qdevice_log(LOG_DEBUG, "  ring id = ("UTILS_PRI_RING_ID")",
+		    msg->ring_id.node_id, msg->ring_id.seq);
 
 	result_vote = msg->vote;
+
+	if (!tlv_ring_id_eq(&msg->ring_id, &instance->last_sent_ring_id)) {
+		ring_id_is_valid = 0;
+		qdevice_log(LOG_DEBUG, "Received vote info with old ring id.");
+	} else {
+		ring_id_is_valid = 1;
+	}
+
 	if (qdevice_net_algorithm_vote_info_received(instance, msg->seq_number,
-	    &result_vote) != 0) {
+	    &msg->ring_id, ring_id_is_valid, &result_vote) != 0) {
 		qdevice_log(LOG_DEBUG, "Algorithm returned error. Disconnecting.");
 
 		instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_ALGO_VOTE_INFO_ERR;

+ 1 - 1
qdevices/qdevice-net-nss.c

@@ -50,7 +50,7 @@ qdevice_net_nss_bad_cert_hook(void *arg, PRFileDesc *fd) {
 		qdevice_log(LOG_WARNING, "Server certificate is expired.");
 
 		return (SECSuccess);
-        }
+	}
 
 	qdevice_log_nss(LOG_ERR, "Server certificate verification failure.");
 

+ 7 - 1
qdevices/qdevice-net-send.c

@@ -100,6 +100,7 @@ qdevice_net_send_init(struct qdevice_net_instance *instance)
 	enum tlv_opt_type *supported_opts;
 	size_t no_supported_opts;
 	struct send_buffer_list_entry *send_buffer;
+	struct tlv_ring_id tlv_rid;
 
 	tlv_get_supported_options(&supported_opts, &no_supported_opts);
 	msg_get_supported_messages(&supported_msgs, &no_supported_msgs);
@@ -112,17 +113,22 @@ qdevice_net_send_init(struct qdevice_net_instance *instance)
 		return (-1);
 	}
 
+	qdevice_net_votequorum_ring_id_to_tlv(&tlv_rid,
+	    &instance->qdevice_instance_ptr->vq_node_list_ring_id);
+
 	if (msg_create_init(&send_buffer->buffer, 1, instance->last_msg_seq_num,
 	    instance->decision_algorithm,
 	    supported_msgs, no_supported_msgs, supported_opts, no_supported_opts,
 	    instance->qdevice_instance_ptr->node_id, instance->heartbeat_interval,
-	    &instance->tie_breaker) == 0) {
+	    &instance->tie_breaker, &tlv_rid) == 0) {
 		qdevice_log(LOG_ERR, "Can't allocate send buffer for init msg");
 
 		send_buffer_list_discard_new(&instance->send_buffer_list, send_buffer);
 		return (-1);
 	}
 
+	memcpy(&instance->last_sent_ring_id, &tlv_rid, sizeof(instance->last_sent_ring_id));
+
 	send_buffer_list_put(&instance->send_buffer_list, send_buffer);
 
 	instance->state = QDEVICE_NET_INSTANCE_STATE_WAITING_INIT_REPLY;

+ 6 - 6
qdevices/qdevice-votequorum.c

@@ -175,7 +175,7 @@ qdevice_votequorum_init(struct qdevice_instance *instance)
 		(void)poll(NULL, 0, 1000);
 	}
 
-        if (res != CS_OK) {
+	if (res != CS_OK) {
 		qdevice_log(LOG_CRIT, "Failed to initialize the votequorum API. Error %s", cs_strerror(res));
 		exit(1);
 	}
@@ -227,8 +227,8 @@ qdevice_votequorum_destroy(struct qdevice_instance *instance)
 	res = votequorum_qdevice_unregister(instance->votequorum_handle,
 		instance->advanced_settings->votequorum_device_name);
 
-        if (res != CS_OK) {
-                qdevice_log(LOG_WARNING, "Unable to unregister votequorum device. Error %s", cs_strerror(res));
+	if (res != CS_OK) {
+		qdevice_log(LOG_WARNING, "Unable to unregister votequorum device. Error %s", cs_strerror(res));
 	}
 
 	res = votequorum_finalize(instance->votequorum_handle);
@@ -244,9 +244,9 @@ qdevice_votequorum_wait_for_ring_id(struct qdevice_instance *instance)
 
 	no_retries = 0;
 
-	while (!instance->vq_node_list_ring_id_set &&
-	    qdevice_votequorum_dispatch(instance) != -1 &&
-	    no_retries++ < instance->advanced_settings->max_cs_try_again) {
+	while (qdevice_votequorum_dispatch(instance) != -1 &&
+	    no_retries++ < instance->advanced_settings->max_cs_try_again &&
+	    !instance->vq_node_list_ring_id_set) {
 		(void)poll(NULL, 0, 1000);
 	}
 

+ 1 - 1
qdevices/qnet-config.h

@@ -128,7 +128,7 @@ extern "C" {
 /*
  * Decision algorithms supported by qnetd
  */
-#define QNETD_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE         4
+#define QNETD_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE	4
 
 extern enum tlv_decision_algorithm_type
     qnetd_static_supported_decision_algorithms[QNETD_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE];

+ 8 - 8
qdevices/qnetd-algo-2nodelms.c

@@ -305,14 +305,14 @@ qnetd_algo_2nodelms_timer_callback(struct qnetd_client *client, int *reschedule_
 }
 
 static struct qnetd_algorithm qnetd_algo_2nodelms = {
-	.init                          = qnetd_algo_2nodelms_client_init,
-	.config_node_list_received     = qnetd_algo_2nodelms_config_node_list_received,
-	.membership_node_list_received = qnetd_algo_2nodelms_membership_node_list_received,
-	.quorum_node_list_received     = qnetd_algo_2nodelms_quorum_node_list_received,
-	.client_disconnect             = qnetd_algo_2nodelms_client_disconnect,
-	.ask_for_vote_received         = qnetd_algo_2nodelms_ask_for_vote_received,
-	.vote_info_reply_received      = qnetd_algo_2nodelms_vote_info_reply_received,
-	.timer_callback                = qnetd_algo_2nodelms_timer_callback,
+	.init				= qnetd_algo_2nodelms_client_init,
+	.config_node_list_received	= qnetd_algo_2nodelms_config_node_list_received,
+	.membership_node_list_received	= qnetd_algo_2nodelms_membership_node_list_received,
+	.quorum_node_list_received	= qnetd_algo_2nodelms_quorum_node_list_received,
+	.client_disconnect		= qnetd_algo_2nodelms_client_disconnect,
+	.ask_for_vote_received		= qnetd_algo_2nodelms_ask_for_vote_received,
+	.vote_info_reply_received	= qnetd_algo_2nodelms_vote_info_reply_received,
+	.timer_callback			= qnetd_algo_2nodelms_timer_callback,
 };
 
 enum tlv_reply_error_code qnetd_algo_2nodelms_register()

+ 8 - 8
qdevices/qnetd-algo-ffsplit.c

@@ -281,14 +281,14 @@ qnetd_algo_ffsplit_timer_callback(struct qnetd_client *client, int *reschedule_t
 }
 
 static struct qnetd_algorithm qnetd_algo_ffsplit = {
-	.init                          = qnetd_algo_ffsplit_client_init,
-	.config_node_list_received     = qnetd_algo_ffsplit_config_node_list_received,
-	.membership_node_list_received = qnetd_algo_ffsplit_membership_node_list_received,
-	.quorum_node_list_received     = qnetd_algo_ffsplit_quorum_node_list_received,
-	.client_disconnect             = qnetd_algo_ffsplit_client_disconnect,
-	.ask_for_vote_received         = qnetd_algo_ffsplit_ask_for_vote_received,
-	.vote_info_reply_received      = qnetd_algo_ffsplit_vote_info_reply_received,
-	.timer_callback                = qnetd_algo_ffsplit_timer_callback,
+	.init				= qnetd_algo_ffsplit_client_init,
+	.config_node_list_received	= qnetd_algo_ffsplit_config_node_list_received,
+	.membership_node_list_received	= qnetd_algo_ffsplit_membership_node_list_received,
+	.quorum_node_list_received	= qnetd_algo_ffsplit_quorum_node_list_received,
+	.client_disconnect		= qnetd_algo_ffsplit_client_disconnect,
+	.ask_for_vote_received		= qnetd_algo_ffsplit_ask_for_vote_received,
+	.vote_info_reply_received	= qnetd_algo_ffsplit_vote_info_reply_received,
+	.timer_callback			= qnetd_algo_ffsplit_timer_callback,
 };
 
 enum tlv_reply_error_code qnetd_algo_ffsplit_register()

+ 8 - 8
qdevices/qnetd-algo-lms.c

@@ -365,14 +365,14 @@ qnetd_algo_lms_timer_callback(struct qnetd_client *client, int *reschedule_timer
 }
 
 static struct qnetd_algorithm qnetd_algo_lms = {
-	.init                          = qnetd_algo_lms_client_init,
-	.config_node_list_received     = qnetd_algo_lms_config_node_list_received,
-	.membership_node_list_received = qnetd_algo_lms_membership_node_list_received,
-	.quorum_node_list_received     = qnetd_algo_lms_quorum_node_list_received,
-	.client_disconnect             = qnetd_algo_lms_client_disconnect,
-	.ask_for_vote_received         = qnetd_algo_lms_ask_for_vote_received,
-	.vote_info_reply_received      = qnetd_algo_lms_vote_info_reply_received,
-	.timer_callback                = qnetd_algo_lms_timer_callback,
+	.init				= qnetd_algo_lms_client_init,
+	.config_node_list_received	= qnetd_algo_lms_config_node_list_received,
+	.membership_node_list_received	= qnetd_algo_lms_membership_node_list_received,
+	.quorum_node_list_received	= qnetd_algo_lms_quorum_node_list_received,
+	.client_disconnect		= qnetd_algo_lms_client_disconnect,
+	.ask_for_vote_received		= qnetd_algo_lms_ask_for_vote_received,
+	.vote_info_reply_received	= qnetd_algo_lms_vote_info_reply_received,
+	.timer_callback			= qnetd_algo_lms_timer_callback,
 };
 
 enum tlv_reply_error_code qnetd_algo_lms_register()

+ 1 - 0
qdevices/qnetd-algo-test.c

@@ -52,6 +52,7 @@
  * - client->node_id (client->node_id_set = 1)
  * - client->decision_algorithm
  * - client->cluster
+ * - client->last_ring_id
  *
  * Callback is designed mainly for allocating client->algorithm_data. It's also already
  * part of the cluster, so can access (alloc) client->cluster->algorithm_data.

+ 1 - 1
qdevices/qnetd-algorithm.c

@@ -65,7 +65,7 @@ qnetd_algorithm_config_node_list_received(struct qnetd_client *client,
 	if (client->decision_algorithm >= QNETD_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE ||
 	    qnetd_algorithm_array[client->decision_algorithm] == NULL) {
 		qnetd_log(LOG_CRIT, "qnetd_algorithm_config_node_list_received unhandled "
-		     "decision algorithm");
+		    "decision algorithm");
 		return (TLV_REPLY_ERROR_CODE_INTERNAL_ERROR);
 	}
 

+ 11 - 2
qdevices/qnetd-client-msg-received.c

@@ -344,6 +344,15 @@ qnetd_client_msg_received_init(struct qnetd_instance *instance, struct qnetd_cli
 		client->node_id = msg->node_id;
 	}
 
+	if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR && !msg->ring_id_set) {
+		qnetd_log(LOG_ERR, "Received init message without ring id set. "
+		    "Sending error reply.");
+
+		reply_error_code = TLV_REPLY_ERROR_CODE_DOESNT_CONTAIN_REQUIRED_OPTION;
+	} else {
+		memcpy(&client->last_ring_id, &msg->ring_id, sizeof(struct tlv_ring_id));
+	}
+
 	if (reply_error_code == TLV_REPLY_ERROR_CODE_NO_ERROR && !msg->heartbeat_interval_set) {
 		qnetd_log(LOG_ERR, "Received init message without heartbeat interval set. "
 		    "Sending error reply.");
@@ -839,7 +848,7 @@ qnetd_client_msg_received_node_list(struct qnetd_instance *instance, struct qnet
 	}
 
 	if (msg_create_node_list_reply(&send_buffer->buffer, msg->seq_number, msg->node_list_type,
-	    msg->ring_id_set, &msg->ring_id, result_vote) == -1) {
+	    &client->last_ring_id, result_vote) == -1) {
 		qnetd_log(LOG_ERR, "Can't alloc node list reply msg. "
 		    "Disconnecting client connection.");
 
@@ -936,7 +945,7 @@ qnetd_client_msg_received_ask_for_vote(struct qnetd_instance *instance, struct q
 	}
 
 	if (msg_create_ask_for_vote_reply(&send_buffer->buffer, msg->seq_number,
-	    result_vote) == -1) {
+	    &client->last_ring_id, result_vote) == -1) {
 		qnetd_log(LOG_ERR, "Can't alloc ask for vote reply msg. "
 		    "Disconnecting client connection.");
 

+ 1 - 1
qdevices/qnetd-client-net.c

@@ -192,7 +192,7 @@ qnetd_client_net_accept(struct qnetd_instance *instance)
 
 	res_err = -1;
 
-        if ((client_socket = PR_Accept(instance->server.socket, &client_addr,
+	if ((client_socket = PR_Accept(instance->server.socket, &client_addr,
 	    PR_INTERVAL_NO_TIMEOUT)) == NULL) {
 		qnetd_log_nss(LOG_ERR, "Can't accept connection");
 		return (-1);

+ 3 - 2
qdevices/qnetd-client-send.c

@@ -75,7 +75,7 @@ qnetd_client_send_vote_info(struct qnetd_client *client, uint32_t msg_seq_number
 {
 	struct send_buffer_list_entry *send_buffer;
 
-        /*
+	/*
 	 * Store result vote
 	 */
 	client->last_sent_vote = vote;
@@ -93,7 +93,8 @@ qnetd_client_send_vote_info(struct qnetd_client *client, uint32_t msg_seq_number
 		return (-1);
 	}
 
-	if (msg_create_vote_info(&send_buffer->buffer, msg_seq_number, vote) == 0) {
+	if (msg_create_vote_info(&send_buffer->buffer, msg_seq_number,
+	    &client->last_ring_id, vote) == 0) {
 		qnetd_log(LOG_ERR, "Can't alloc vote info msg. "
 		    "Disconnecting client connection.");
 

+ 1 - 1
qdevices/qnetd-cluster-list.c

@@ -118,7 +118,7 @@ qnetd_cluster_list_free(struct qnetd_cluster_list *list)
 		free(cluster);
 
 		cluster = cluster_next;
-        }
+	}
 
 	TAILQ_INIT(list);
 }

+ 2 - 0
qdevices/qnetd-log-debug.c

@@ -60,6 +60,8 @@ qnetd_log_debug_new_client_connected(struct qnetd_client *client)
 	qnetd_log(LOG_DEBUG, "  node_id = "UTILS_PRI_NODE_ID, client->node_id);
 	qnetd_log(LOG_DEBUG, "  pointer = %p", client);
 	qnetd_log(LOG_DEBUG, "  addr_str = %s", client->addr_str);
+	qnetd_log(LOG_DEBUG, "  ring id = (" UTILS_PRI_RING_ID ")", client->last_ring_id.node_id,
+	    client->last_ring_id.seq);
 
 	qnetd_log_debug_dump_cluster(client->cluster);
 }

+ 1 - 1
qdevices/tlv.c

@@ -56,7 +56,7 @@
 #define TLV_TYPE_LENGTH		2
 #define TLV_LENGTH_LENGTH	2
 
-#define TLV_STATIC_SUPPORTED_OPTIONS_SIZE      22
+#define TLV_STATIC_SUPPORTED_OPTIONS_SIZE	22
 
 enum tlv_opt_type tlv_static_supported_options[TLV_STATIC_SUPPORTED_OPTIONS_SIZE] = {
     TLV_OPT_MSG_SEQ_NUMBER,

+ 2 - 2
qdevices/unix-socket.c

@@ -55,9 +55,9 @@ unix_socket_set_non_blocking(int fd)
 	flags |= O_NONBLOCK;
 	if (fcntl(fd, F_SETFL, flags) < 0) {
 		return (-1);
-        }
+	}
 
-        return (0);
+	return (0);
 }
 
 int