Blame SOURCES/bz1780137-2-votequorum-Reflect-runtime-change-of-2Node-to-WFA.patch

cfddb1
From 8ce65bf951bc1e5b2d64b60ea027fbdc551d4fc8 Mon Sep 17 00:00:00 2001
cfddb1
From: Jan Friesse <jfriesse@redhat.com>
cfddb1
Date: Thu, 16 Jan 2020 15:43:59 +0100
cfddb1
Subject: [PATCH] votequorum: Reflect runtime change of 2Node to WFA
cfddb1
cfddb1
When 2Node mode is set, WFA is also set unless WFA is configured
cfddb1
explicitly. This behavior was not reflected on runtime change, so
cfddb1
restarted corosync behavior was different (WFA not set). Also when
cfddb1
cluster is reduced from 3 nodes to 2 nodes during runtime, WFA was not
cfddb1
set, what may result in two quorate partitions.
cfddb1
cfddb1
Solution is to set WFA depending on 2Node when WFA
cfddb1
is not explicitly configured.
cfddb1
cfddb1
Signed-off-by: Jan Friesse <jfriesse@redhat.com>
cfddb1
Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
cfddb1
---
cfddb1
 exec/votequorum.c | 24 +++++++++++++++++++-----
cfddb1
 1 file changed, 19 insertions(+), 5 deletions(-)
cfddb1
cfddb1
diff --git a/exec/votequorum.c b/exec/votequorum.c
cfddb1
index 0cde8f8..52424fa 100644
cfddb1
--- a/exec/votequorum.c
cfddb1
+++ b/exec/votequorum.c
cfddb1
@@ -80,6 +80,7 @@ static uint8_t two_node = 0;
cfddb1
 
cfddb1
 static uint8_t wait_for_all = 0;
cfddb1
 static uint8_t wait_for_all_status = 0;
cfddb1
+static uint8_t wait_for_all_autoset = 0; /* Wait for all is not set explicitly and follows two_node */
cfddb1
 
cfddb1
 static enum {ATB_NONE, ATB_LOWEST, ATB_HIGHEST, ATB_LIST} auto_tie_breaker = ATB_NONE, initial_auto_tie_breaker = ATB_NONE;
cfddb1
 static int lowest_node_id = -1;
cfddb1
@@ -1315,12 +1316,10 @@ static char *votequorum_readconfig(int runtime)
cfddb1
 	 * Enable special features
cfddb1
 	 */
cfddb1
 	if (!runtime) {
cfddb1
-		if (two_node) {
cfddb1
-			wait_for_all = 1;
cfddb1
-		}
cfddb1
-
cfddb1
 		(void)icmap_get_uint8("quorum.allow_downscale", &allow_downscale);
cfddb1
-		(void)icmap_get_uint8("quorum.wait_for_all", &wait_for_all);
cfddb1
+		if (icmap_get_uint8("quorum.wait_for_all", &wait_for_all) != CS_OK) {
cfddb1
+			wait_for_all_autoset = 1;
cfddb1
+		}
cfddb1
 		(void)icmap_get_uint8("quorum.last_man_standing", &last_man_standing);
cfddb1
 		(void)icmap_get_uint32("quorum.last_man_standing_window", &last_man_standing_window);
cfddb1
 		(void)icmap_get_uint8("quorum.expected_votes_tracking", &ev_tracking);
cfddb1
@@ -1361,6 +1360,15 @@ static char *votequorum_readconfig(int runtime)
cfddb1
 
cfddb1
 	}
cfddb1
 
cfddb1
+	/*
cfddb1
+	 * Changing of wait_for_all during runtime is not supported, but changing of two_node is
cfddb1
+	 * and two_node may set wfa if not configured explicitly. It is safe to unset it
cfddb1
+	 * (or set it back) when two_node changes.
cfddb1
+	 */
cfddb1
+	if (wait_for_all_autoset) {
cfddb1
+		wait_for_all = two_node;
cfddb1
+	}
cfddb1
+
cfddb1
 	/* two_node and auto_tie_breaker are not compatible as two_node uses
cfddb1
 	 * a fence race to decide quorum whereas ATB decides based on node id
cfddb1
 	 */
cfddb1
@@ -1540,6 +1548,12 @@ static char *votequorum_readconfig(int runtime)
cfddb1
 	update_two_node();
cfddb1
 	if (wait_for_all) {
cfddb1
 		update_wait_for_all_status(1);
cfddb1
+	} else if (wait_for_all_autoset && wait_for_all_status) {
cfddb1
+		/*
cfddb1
+		 * Reset wait for all status for consistency when wfa is auto-unset by 2node.
cfddb1
+		 * wait_for_all_status would be ignored by are_we_quorate anyway.
cfddb1
+		 */
cfddb1
+		update_wait_for_all_status(0);
cfddb1
 	}
cfddb1
 
cfddb1
 out:
cfddb1
-- 
cfddb1
1.8.3.1
cfddb1