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