Blob Blame History Raw
From bfbed8c320b0c0c5d3db48630f3de77e5fd62b75 Mon Sep 17 00:00:00 2001
From: Jan Friesse <jfriesse@redhat.com>
Date: Thu, 16 Jan 2020 15:43:59 +0100
Subject: [PATCH] votequorum: Reflect runtime change of 2Node to WFA

When 2Node mode is set, WFA is also set unless WFA is configured
explicitly. This behavior was not reflected on runtime change, so
restarted corosync behavior was different (WFA not set). Also when
cluster is reduced from 3 nodes to 2 nodes during runtime, WFA was not
set, what may result in two quorate partitions.

Solution is to set WFA depending on 2Node when WFA
is not explicitly configured.

Signed-off-by: Jan Friesse <jfriesse@redhat.com>
Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
(cherry picked from commit 8ce65bf951bc1e5b2d64b60ea027fbdc551d4fc8)
---
 exec/votequorum.c | 24 +++++++++++++++++++-----
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/exec/votequorum.c b/exec/votequorum.c
index 2fb5db9..d87b6fd 100644
--- a/exec/votequorum.c
+++ b/exec/votequorum.c
@@ -80,6 +80,7 @@ static uint8_t two_node = 0;
 
 static uint8_t wait_for_all = 0;
 static uint8_t wait_for_all_status = 0;
+static uint8_t wait_for_all_autoset = 0; /* Wait for all is not set explicitly and follows two_node */
 
 static enum {ATB_NONE, ATB_LOWEST, ATB_HIGHEST, ATB_LIST} auto_tie_breaker = ATB_NONE, initial_auto_tie_breaker = ATB_NONE;
 static int lowest_node_id = -1;
@@ -1316,12 +1317,10 @@ static char *votequorum_readconfig(int runtime)
 	 * Enable special features
 	 */
 	if (!runtime) {
-		if (two_node) {
-			wait_for_all = 1;
-		}
-
 		(void)icmap_get_uint8("quorum.allow_downscale", &allow_downscale);
-		(void)icmap_get_uint8("quorum.wait_for_all", &wait_for_all);
+		if (icmap_get_uint8("quorum.wait_for_all", &wait_for_all) != CS_OK) {
+			wait_for_all_autoset = 1;
+		}
 		(void)icmap_get_uint8("quorum.last_man_standing", &last_man_standing);
 		(void)icmap_get_uint32("quorum.last_man_standing_window", &last_man_standing_window);
 		(void)icmap_get_uint8("quorum.expected_votes_tracking", &ev_tracking);
@@ -1362,6 +1361,15 @@ static char *votequorum_readconfig(int runtime)
 
 	}
 
+	/*
+	 * Changing of wait_for_all during runtime is not supported, but changing of two_node is
+	 * and two_node may set wfa if not configured explicitly. It is safe to unset it
+	 * (or set it back) when two_node changes.
+	 */
+	if (wait_for_all_autoset) {
+		wait_for_all = two_node;
+	}
+
 	/* two_node and auto_tie_breaker are not compatible as two_node uses
 	 * a fence race to decide quorum whereas ATB decides based on node id
 	 */
@@ -1541,6 +1549,12 @@ static char *votequorum_readconfig(int runtime)
 	update_two_node();
 	if (wait_for_all) {
 		update_wait_for_all_status(1);
+	} else if (wait_for_all_autoset && wait_for_all_status) {
+		/*
+		 * Reset wait for all status for consistency when wfa is auto-unset by 2node.
+		 * wait_for_all_status would be ignored by are_we_quorate anyway.
+		 */
+		update_wait_for_all_status(0);
 	}
 
 out:
-- 
1.8.3.1