[PATCH 13/25] qdevice: implement master_wins partition

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: "Fabio M. Di Nitto" <fdinitto@xxxxxxxxxx>

in previous incarnation of qdisk + cman, master_wins was restricted
to 2 node only.

In this new version it is possible to use master_wins for any cluster
size.

Let's assume a 4 node cluster. Each node votes 1, qdevice votes 3.

node 1 becomes qdevice master
node 2/3/4 no

In case of a split (let's assume 2/2):

partition 1: {4, 1}
partition 2: {1, 1}

node 2 in partition 1 would normally be unquorate, leaving effectively
only node 1 active.

master_wins allows node 2 to recognize to be part of a quorate partition
(since node1 is broadcasting that qdevice is voting) and retain
quorum.

node1 has never lost quorate status since qdevice is voting there.

Signed-off-by: Fabio M. Di Nitto <fdinitto@xxxxxxxxxx>
---
:100644 100644 490f4bf... 7a2b2a8... M	exec/coroparse.c
:100644 100644 f768d6d... 5667ace... M	exec/votequorum.c
 exec/coroparse.c  |    7 +++++++
 exec/votequorum.c |   31 +++++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+), 0 deletions(-)

diff --git a/exec/coroparse.c b/exec/coroparse.c
index 490f4bf..7a2b2a8 100644
--- a/exec/coroparse.c
+++ b/exec/coroparse.c
@@ -430,6 +430,13 @@ static int main_config_parser_cb(const char *path,
 				icmap_set_uint32(path, i);
 				add_as_string = 0;
 			}
+			if ((strcmp(path, "quorum.device.master_wins") == 0)) {
+				if (safe_atoi(value, &i) != 0) {
+					goto atoi_error;
+				}
+				icmap_set_uint8(path, i);
+				add_as_string = 0;
+			}
 		case MAIN_CP_CB_DATA_STATE_TOTEM:
 			if ((strcmp(path, "totem.version") == 0) ||
 			    (strcmp(path, "totem.nodeid") == 0) ||
diff --git a/exec/votequorum.c b/exec/votequorum.c
index f768d6d..5667ace 100644
--- a/exec/votequorum.c
+++ b/exec/votequorum.c
@@ -69,6 +69,7 @@ static struct cluster_node *qdevice = NULL;
 static unsigned int qdevice_timeout = DEFAULT_QDEVICE_TIMEOUT;
 static uint8_t qdevice_can_operate = 1;
 static void *qdevice_reg_conn = NULL;
+static uint8_t qdevice_master_wins = 0;
 
 static uint8_t two_node = 0;
 
@@ -542,6 +543,26 @@ static int check_low_node_id_partition(void)
 	return found;
 }
 
+static int check_qdevice_master(void)
+{
+	struct cluster_node *node = NULL;
+	struct list_head *tmp;
+	int found = 0;
+
+	ENTER();
+
+	list_iterate(tmp, &cluster_members_list) {
+		node = list_entry(tmp, struct cluster_node, list);
+		if ((node->state == NODESTATE_MEMBER) &&
+		    (node->flags & NODE_FLAGS_QDEVICE_CAST_VOTE)) {
+				found = 1;
+		}
+	}
+
+	LEAVE();
+	return found;
+}
+
 static void decode_flags(uint32_t flags)
 {
 	log_printf(LOGSYS_LEVEL_DEBUG,
@@ -701,6 +722,13 @@ static void are_we_quorate(unsigned int total_votes)
 		quorate = 1;
 	}
 
+	if ((qdevice_master_wins) &&
+	    (!quorate) &&
+	    (check_qdevice_master() == 1)) {
+		log_printf(LOGSYS_LEVEL_DEBUG, "node is quorate as part of master_wins partition");
+		quorate = 1;
+	}
+
 	if (cluster_is_quorate && !quorate) {
 		quorum_change = 1;
 		log_printf(LOGSYS_LEVEL_DEBUG, "quorum lost, blocking activity");
@@ -871,6 +899,9 @@ static int votequorum_qdevice_is_configured(uint32_t *qdevice_votes)
 		if (icmap_get_uint32("quorum.device.timeout", &qdevice_timeout) != CS_OK) {
 			qdevice_timeout = DEFAULT_QDEVICE_TIMEOUT;
 		}
+		if (icmap_get_uint8("quorum.device.master_wins", &qdevice_master_wins) != CS_OK) {
+			qdevice_master_wins = 0;
+		}
 		update_qdevice_can_operate(1);
 		return 1;
 	}
-- 
1.7.7.6

_______________________________________________
discuss mailing list
discuss@xxxxxxxxxxxx
http://lists.corosync.org/mailman/listinfo/discuss


[Index of Archives]     [Linux Clusters]     [Corosync Project]     [Linux USB Devel]     [Linux Audio Users]     [Photo]     [Yosemite News]    [Yosemite Photos]    [Linux Kernel]     [Linux SCSI]     [X.Org]

  Powered by Linux