Reviewed-by: Steven Dake <sdake@xxxxxxxxxx> On 01/10/2012 02:23 AM, Fabio M. Di Nitto wrote: > From: "Fabio M. Di Nitto" <fdinitto@xxxxxxxxxx> > > this flag (0|1) can be configured via quorum.auto_tie_breaker and when > enabled, support for perfect even split is on. > > In case of a 50% of votes loss in one single transition, the partition > with the node that has the lowest node id will remain quorate. > > Signed-off-by: Fabio M. Di Nitto <fdinitto@xxxxxxxxxx> > --- > :100644 100644 abbd512... c088bb3... M exec/coroparse.c > :100644 100644 3ba5978... a11b9b3... M services/votequorum.c > exec/coroparse.c | 1 + > services/votequorum.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 53 insertions(+), 0 deletions(-) > > diff --git a/exec/coroparse.c b/exec/coroparse.c > index abbd512..c088bb3 100644 > --- a/exec/coroparse.c > +++ b/exec/coroparse.c > @@ -369,6 +369,7 @@ static int main_config_parser_cb(const char *path, > if ((strcmp(path, "quorum.disallowed") == 0) || > (strcmp(path, "quorum.two_node") == 0) || > (strcmp(path, "quorum.wait_for_all") == 0) || > + (strcmp(path, "quorum.auto_tie_breaker") == 0) || > (strcmp(path, "quorum.quorate") == 0)) { > i = atoi(value); > icmap_set_uint8(path, i); > diff --git a/services/votequorum.c b/services/votequorum.c > index 3ba5978..a11b9b3 100644 > --- a/services/votequorum.c > +++ b/services/votequorum.c > @@ -125,6 +125,8 @@ static int first_trans = 1; > static unsigned int quorumdev_poll = DEFAULT_QDEV_POLL; > static unsigned int leaving_timeout = DEFAULT_LEAVE_TMO; > static uint8_t wait_for_all = 0; > +static uint8_t auto_tie_breaker = 0; > +static int lowest_node_id = -1; > > static struct cluster_node *us; > static struct cluster_node *quorum_device = NULL; > @@ -387,6 +389,16 @@ static void votequorum_init(struct corosync_api_v1 *api, > set_quorum = report; > > icmap_get_uint8("quorum.wait_for_all", &wait_for_all); > + icmap_get_uint8("quorum.auto_tie_breaker", &auto_tie_breaker); > + > + /* > + * TODO: we need to know the lowest node-id in the cluster > + * current lack of node list with node-id's requires us to see all nodes > + * to determine which is the lowest. > + */ > + if (auto_tie_breaker) { > + wait_for_all = 1; > + } > > /* Load the library-servicing part of this module */ > api->service_link_and_init(api, "corosync_votequorum_iface", 0); > @@ -606,6 +618,39 @@ static void send_expectedvotes_notification(void) > } > } > > +static void get_lowest_node_id(void) > +{ > + struct cluster_node *node = NULL; > + struct list_head *tmp; > + > + lowest_node_id = us->node_id; > + > + list_iterate(tmp, &cluster_members_list) { > + node = list_entry(tmp, struct cluster_node, list); > + if (node->node_id < lowest_node_id) > + lowest_node_id = node->node_id; > + } > + log_printf(LOGSYS_LEVEL_DEBUG, "lowest node id: %d us: %d\n", lowest_node_id, us->node_id); > +} > + > +static int check_low_node_id_partition(void) > +{ > + struct cluster_node *node = NULL; > + struct list_head *tmp; > + int found = 0; > + > + list_iterate(tmp, &cluster_members_list) { > + node = list_entry(tmp, struct cluster_node, list); > + if (node->state == NODESTATE_MEMBER) { > + if (node->node_id == lowest_node_id) { > + found = 1; > + } > + } > + } > + > + return found; > +} > + > static void set_quorate(int total_votes) > { > int quorate; > @@ -626,6 +671,7 @@ static void set_quorate(int total_votes) > return; > } > wait_for_all = 0; > + get_lowest_node_id(); > } > > if (quorum > total_votes) { > @@ -635,6 +681,12 @@ static void set_quorate(int total_votes) > quorate = 1; > } > > + if ((auto_tie_breaker) && > + (total_votes == (us->expected_votes / 2)) && > + (check_low_node_id_partition() == 1)) { > + quorate = 1; > + } > + > if (cluster_is_quorate && !quorate) > log_printf(LOGSYS_LEVEL_INFO, "quorum lost, blocking activity\n"); > if (!cluster_is_quorate && quorate) _______________________________________________ discuss mailing list discuss@xxxxxxxxxxxx http://lists.corosync.org/mailman/listinfo/discuss