Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 24e278e14a25367b8cb2fce8af484abd > files > 43

cman-2.0.115-96.el5_8.3.src.rpm

From 72ec71ba0a79be20edf1093d0185c67dd01970da Mon Sep 17 00:00:00 2001
From: Lon Hohberger <lhh@redhat.com>
Date: Wed, 28 Jul 2010 15:49:12 -0400
Subject: [PATCH] cman: fix consensus calculation

This is a backport of Fabio's patch:

043c603d46ab401e69cb8e09a3a818e2006134c5

Instead of using the object database, it
simply queries CCS to gather the node count
for consensus calculation later.

Resolves: rhbz#611391

Signed-off-by: Lon Hohberger <lhh@redhat.com>
---
 cman/daemon/ais.c    |   28 ++++++++++++++++++++++------
 cman/daemon/config.c |   25 +++++++++++++++++++++++++
 2 files changed, 47 insertions(+), 6 deletions(-)

diff --git a/cman/daemon/ais.c b/cman/daemon/ais.c
index efb2b44..b6f23c4 100644
--- a/cman/daemon/ais.c
+++ b/cman/daemon/ais.c
@@ -52,7 +52,6 @@ extern char *key_filename;
 extern unsigned int quorumdev_poll;
 extern unsigned int ccsd_poll_interval;
 extern unsigned int shutdown_timeout;
-extern int two_node;
 extern int init_config(struct objdb_iface_ver0 *objdb);
 
 struct totem_ip_address mcast_addr[MAX_INTERFACES];
@@ -60,6 +59,7 @@ struct totem_ip_address ifaddrs[MAX_INTERFACES];
 int num_interfaces;
 uint64_t incarnation;
 int num_ais_nodes;
+unsigned int node_count = 0;
 
 static int config_run;
 static int startup_pipe;
@@ -527,9 +527,20 @@ static int comms_init_ais(struct objdb_iface_ver0 *objdb)
 							"2500", strlen("2500")+1);
 		}
 
-		/* bz#611391
-		 * consensus should be 1.2*token or for 0.2*token for two_node clusters
+		/*
+		 * consensus should be:
+		 * 2 nodes   - 200 ms <= consensus = token * 0.2 <= 2000
+		 * > 2 nodes - consensus = token + 2000
+		 *
+		 * autoconfig clusters will work as > 2 nodes
+		 *
+		 * See 611391#c19
 		 */
+
+		/* if we are running in autoconfig or we can't count the nodes, then play safe */
+		if ((getenv("CMAN_NOCONFIG")) || (node_count == 0))
+			node_count=3;
+
  		if (objdb_get_string(objdb, object_handle, "consensus", &value)) {
  		        unsigned int token=0;
 			unsigned int consensus;
@@ -537,10 +548,15 @@ static int comms_init_ais(struct objdb_iface_ver0 *objdb)
 
  			objdb_get_int(objdb, object_handle, "token", &token);
 
-			if (two_node)
+			if (node_count > 2) {
+				consensus = (float)token+2000;
+			} else {
 				consensus = (float)token*0.2;
-			else
-				consensus = (float)token*1.2;
+				if (consensus < 200)
+					consensus = 200;
+				if (consensus > 2000)
+					consensus = 2000;
+			}
 
 			snprintf(calc_consensus, sizeof(calc_consensus), "%d", consensus);
  			objdb->object_key_create(object_handle, "consensus", strlen("consensus"),
diff --git a/cman/daemon/config.c b/cman/daemon/config.c
index 86ea2fe..29049d7 100644
--- a/cman/daemon/config.c
+++ b/cman/daemon/config.c
@@ -22,6 +22,8 @@
 #define MAXXMLNODES 1024
 #endif
 
+extern int node_count;
+
 static int read_config_for(int ccs_fd, struct objdb_iface_ver0 *objdb, unsigned int parent,
 			   char *object, char *key, int always_create)
 {
@@ -128,6 +130,27 @@ static int read_config_for(int ccs_fd, struct objdb_iface_ver0 *objdb, unsigned
 	return gotcount;
 }
 
+static int count_clusternodes(int cd)
+{
+	char path[256];
+	int count = 1;
+	char *val;
+
+	do {
+		snprintf(path, sizeof(path),
+			 "/cluster/clusternodes/clusternode[%d]/@name", 
+			 count);
+
+		if (ccs_get(cd, path, &val) != 0)
+			break;
+
+		free(val);
+		++count;
+	} while (1);
+
+	return count-1;
+}
+
 int init_config(struct objdb_iface_ver0 *objdb)
 {
 	int cd, err;
@@ -136,6 +159,8 @@ int init_config(struct objdb_iface_ver0 *objdb)
 	if (cd < 0)
 		return -1;
 
+	node_count = count_clusternodes(cd);
+
 	/* These first few are just versions of openais.conf */
 	err = read_config_for(cd, objdb, OBJECT_PARENT_HANDLE, "totem", "totem", 1);
 	if (err < 0)
-- 
1.6.2.5