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