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

[Cluster-devel] [PATCH] RFC: cman changes



This patch changes the way cman works internally - it decouples it from
CCS so that any configuration system can be used. Provided the necessary
keys are filled in the objdb then cman can use them. Currently the only
alternative is /etc/ais/openais.conf, but it should be relatively easy
to add others (eg LDAP) as people feel the need.

Patrick
diff -urN --exclude='*CVS*' cman/cman_tool/join.c ../gittest/cman3-cvs/cman/cman_tool/join.c
--- cman/cman_tool/join.c	2007-11-29 10:25:24.000000000 +0000
+++ ../gittest/cman3-cvs/cman/cman_tool/join.c	2008-01-03 11:02:53.000000000 +0000
@@ -113,17 +113,24 @@
 		snprintf(scratch, sizeof(scratch), "CMAN_KEYFILE=%s", comline->key_filename);
 		envp[envptr++] = strdup(scratch);
 	}
+	if (comline->two_node) {
+		snprintf(scratch, sizeof(scratch), "CMAN_2NODE=true");
+		envp[envptr++] = strdup(scratch);
+	}
 	if (comline->verbose) {
 		snprintf(scratch, sizeof(scratch), "CMAN_DEBUGLOG=%d", comline->verbose);
 		envp[envptr++] = strdup(scratch);
 	}
 	if (comline->noccs_opt) {
-		snprintf(scratch, sizeof(scratch), "CMAN_NOCCS=TRUE");
-		envp[envptr++] = strdup(scratch);
+		envp[envptr++] = strdup("CMAN_NOCCS=true");
+		envp[envptr++] = strdup("OPENAIS_DEFAULT_CONFIG_IFACE=cmanpreconfig");
+	}
+	else {
+		envp[envptr++] = strdup("OPENAIS_DEFAULT_CONFIG_IFACE=ccsconfig:cmanpreconfig");
 	}
 
 	/* Use cman to configure services */
-	envp[envptr++] = strdup("OPENAIS_DEFAULT_CONFIG_IFACE=cmanconfig");
+
 
 	/* Create a pipe to monitor cman startup progress */
 	pipe(p);
diff -urN --exclude='*CVS*' cman/daemon/ais.c ../gittest/cman3-cvs/cman/daemon/ais.c
--- cman/daemon/ais.c	2008-01-02 16:33:27.000000000 +0000
+++ ../gittest/cman3-cvs/cman/daemon/ais.c	2008-01-03 13:08:12.000000000 +0000
@@ -1,7 +1,7 @@
 /******************************************************************************
 *******************************************************************************
 **
-**  Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2004-2008 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
@@ -46,7 +46,7 @@
 #include "logging.h"
 
 #include "ais.h"
-#include "cmanccs.h"
+#include "cmanconfig.h"
 #include "daemon.h"
 
 extern int our_nodeid();
@@ -62,12 +62,11 @@
 int num_interfaces;
 uint64_t incarnation;
 int num_ais_nodes;
+extern unsigned int config_version;
 
-static int config_run;
 static int startup_pipe;
 static unsigned int debug_mask;
 static int first_trans = 1;
-static struct objdb_iface_ver0 *global_objdb;
 static totempg_groups_handle group_handle;
 static struct totempg_group cman_group[1] = {
         { .group          = "CMAN", .group_len      = 4},
@@ -86,7 +85,6 @@
 	int            tgtid;	/* Node ID of the target */
 };
 
-static int comms_init_ais(struct objdb_iface_ver0 *objdb);
 static void cman_deliver_fn(unsigned int nodeid, struct iovec *iovec, int iov_len,
 			    int endian_conversion_required);
 static void cman_confchg_fn(enum totem_configuration_type configuration_type,
@@ -94,7 +92,6 @@
 			    unsigned int *left_list, int left_list_entries,
 			    unsigned int *joined_list, int joined_list_entries,
 			    struct memb_ring_id *ring_id);
-static int cman_readconfig(struct objdb_iface_ver0 *objdb, char **error_string);
 
 /* Plugin-specific code */
 /* Need some better way of determining these.... */
@@ -103,43 +100,11 @@
 static int cman_exit_fn(void *conn_info);
 static int cman_exec_init_fn(struct objdb_iface_ver0 *objdb);
 
-/* These just makes the code below a little neater */
-static inline int objdb_get_string(struct objdb_iface_ver0 *objdb, unsigned int object_service_handle,
-				   char *key, char **value)
-{
-	int res;
-
-	*value = NULL;
-	if ( !(res = objdb->object_key_get(object_service_handle,
-					   key,
-					   strlen(key),
-					   (void *)value,
-					   NULL))) {
-		if (*value)
-			return 0;
-	}
-	return -1;
-}
-
-static inline void objdb_get_int(struct objdb_iface_ver0 *objdb, unsigned int object_service_handle,
-				   char *key, unsigned int *intvalue)
-{
-	char *value = NULL;
-
-	if (!objdb->object_key_get(object_service_handle, key, strlen(key),
-				   (void *)&value, NULL)) {
-		if (value) {
-			*intvalue = atoi(value);
-		}
-	}
-}
-
-
 /*
  * Exports the interface for the service
  */
 static struct openais_service_handler cman_service_handler = {
-	.name		    		= (char *)"openais CMAN membership service 2.01",
+	.name		    		= (char *)"openais CMAN membership service 2.50",
 	.id			        = CMAN_SERVICE,
 	.flow_control			= OPENAIS_FLOW_CONTROL_NOT_REQUIRED,
 	.lib_exit_fn		       	= cman_exit_fn,
@@ -157,23 +122,7 @@
 };
 
 
-
-static struct config_iface_ver0 cmanconfig_iface_ver0 = {
-	.config_readconfig        = cman_readconfig
-};
-
-static struct lcr_iface ifaces_ver0[2] = {
-	{
-		.name		       	= "cmanconfig",
-		.version	       	= 0,
-		.versions_replace      	= 0,
-		.versions_replace_count	= 0,
-		.dependencies	       	= 0,
-		.dependency_count      	= 0,
-		.constructor	       	= NULL,
-		.destructor	       	= NULL,
-		.interfaces	       	= NULL,
-	},
+static struct lcr_iface ifaces_ver0[1] = {
 	{
 		.name		        = "openais_cman",
 		.version	        = 0,
@@ -188,73 +137,43 @@
 };
 
 static struct lcr_comp cman_comp_ver0 = {
-	.iface_count				= 2,
+	.iface_count				= 1,
 	.ifaces					= ifaces_ver0,
 };
 
 
 
 __attribute__ ((constructor)) static void cman_comp_register(void) {
-	lcr_interfaces_set(&ifaces_ver0[0], &cmanconfig_iface_ver0);
-	lcr_interfaces_set(&ifaces_ver0[1], &cman_service_handler_iface);
+	lcr_interfaces_set(&ifaces_ver0[0], &cman_service_handler_iface);
 	lcr_component_register(&cman_comp_ver0);
 }
 
 /* ------------------------------- */
 
-static int cman_readconfig(struct objdb_iface_ver0 *objdb, char **error_string)
+
+static int cman_exec_init_fn(struct objdb_iface_ver0 *objdb)
 {
-	int error;
+	unsigned int object_handle;
 
-	/* Initialise early logging */
 	if (getenv("CMAN_DEBUGLOG"))
 		debug_mask = atoi(getenv("CMAN_DEBUGLOG"));
 
-	if (getenv("CMAN_PIPE"))
-		startup_pipe = atoi(getenv("CMAN_PIPE"));
-
 	set_debuglog(debug_mask);
 
 	/* We need to set this up to internal defaults too early */
 	openlog("openais", LOG_CONS|LOG_PID, LOG_LOCAL4);
 
-	global_objdb = objdb;
-
 	/* Enable stderr logging if requested by cman_tool */
-	if (debug_mask)
-		logsys_config_subsys_set(CMAN_NAME, LOGSYS_TAG_LOG, LOG_DEBUG);
-
-	/* Read low-level totem/aisexec etc config from CCS */
-	init_config(objdb);
-
-	/* Read cman-specific config from CCS */
-	error = read_ccs_config();
-	if (error)
-	{
-		write_cman_pipe("Error reading config from CCS");
-		*error_string = "Error reading config from CCS";
-		return -1;
+	if (debug_mask) {
+		logsys_config_subsys_set("CMAN", LOGSYS_TAG_LOG, LOG_DEBUG);
 	}
 
-	/* Do config overrides */
-	comms_init_ais(objdb);
-
-	config_run = 1;
-
-	*error_string = "Successfully read configuration from CCS";
-
-	return 0;
-}
-
-static int cman_exec_init_fn(struct objdb_iface_ver0 *objdb)
-{
-	unsigned int object_handle;
+	if (getenv("CMAN_PIPE"))
+                startup_pipe = atoi(getenv("CMAN_PIPE"));
 
-	/* We can only work if our config interface was run first */
-	if (!config_run)
-		return 0;
+	P_DAEMON("CMAN starting");
 
-	/* Get our config variable */
+        /* Get our config variable */
 	objdb->object_find_reset(OBJECT_PARENT_HANDLE);
 	if (objdb->object_find(OBJECT_PARENT_HANDLE, "cman", strlen("cman"), &object_handle) == 0)
 	{
@@ -271,6 +190,7 @@
 	}
 
 	/* Open local sockets and initialise I/O queues */
+	read_cman_config(objdb, &config_version);
 	cman_init();
 
 	/* Let cman_tool know we are running */
@@ -293,71 +213,6 @@
 
 /* END Plugin-specific code */
 
-int ais_add_ifaddr(char *mcast, char *ifaddr, int portnum)
-{
-	struct totem_ip_address localhost;
-	unsigned int totem_object_handle;
-	unsigned int interface_object_handle;
-	char tmp[132];
-	int ret = 0;
-
-	P_AIS("Adding local address %s\n", ifaddr);
-
-	global_objdb->object_find_reset(OBJECT_PARENT_HANDLE);
-	if (global_objdb->object_find(OBJECT_PARENT_HANDLE,
-				       "totem", strlen("totem"), &totem_object_handle)) {
-
-		global_objdb->object_create(OBJECT_PARENT_HANDLE, &totem_object_handle,
-					    "totem", strlen("totem"));
-	}
-
-	global_objdb->object_find_reset(OBJECT_PARENT_HANDLE);
-	if (global_objdb->object_find(OBJECT_PARENT_HANDLE,
-				      "totem", strlen("totem"), &totem_object_handle) == 0) {
-		if (global_objdb->object_create(totem_object_handle, &interface_object_handle,
-						"interface", strlen("interface")) == 0) {
-
-			P_AIS("Setting if %d, name: %s,  mcast: %s,  port=%d, \n",
-			      num_interfaces, ifaddr, mcast, portnum);
-			sprintf(tmp, "%d", num_interfaces);
-			global_objdb->object_key_create(interface_object_handle, "ringnumber", strlen("ringnumber"),
-							tmp, strlen(tmp)+1);
-
-			global_objdb->object_key_create(interface_object_handle, "bindnetaddr", strlen("bindnetaddr"),
-							ifaddr, strlen(ifaddr)+1);
-
-			global_objdb->object_key_create(interface_object_handle, "mcastaddr", strlen("mcastaddr"),
-							mcast, strlen(mcast)+1);
-
-			sprintf(tmp, "%d", portnum);
-			global_objdb->object_key_create(interface_object_handle, "mcastport", strlen("mcastport"),
-							tmp, strlen(tmp)+1);
-
-			/* Save a local copy */
-			ret = totemip_parse(&mcast_addr[num_interfaces], mcast, 0);
-			if (!ret)
-				ret = totemip_parse(&ifaddrs[num_interfaces], ifaddr,
-						    mcast_addr[num_interfaces].family);
-			if (ret) {
-				errno = EPROTOTYPE;
-				return ret;
-			}
-
-			/* Check it's not bound to localhost, sigh */
-			totemip_localhost(mcast_addr[num_interfaces].family, &localhost);
-			if (totemip_equal(&localhost, &ifaddrs[num_interfaces])) {
-				errno = EADDRINUSE;
-				return -1;
-			}
-
-			num_interfaces++;
-		}
-	}
-
-	return ret;
-}
-
-
 int comms_send_message(void *buf, int len,
 		       unsigned char toport, unsigned char fromport,
 		       int nodeid,
@@ -471,153 +326,6 @@
 	}
 }
 
-/* These are basically our overrides to the totem config bits */
-static int comms_init_ais(struct objdb_iface_ver0 *objdb)
-{
-	unsigned int object_handle;
-	char tmp[256];
-
-	P_AIS("comms_init_ais()\n");
-
-	objdb->object_find_reset(OBJECT_PARENT_HANDLE);
-
-	if (objdb->object_find(OBJECT_PARENT_HANDLE,
-			       "totem", strlen("totem"),
-			       &object_handle) == 0)
-	{
-		char *value;
-
-		objdb->object_key_create(object_handle, "version", strlen("version"),
-					 "2", 2);
-
-		sprintf(tmp, "%d", our_nodeid());
-		objdb->object_key_create(object_handle, "nodeid", strlen("nodeid"),
-					 tmp, strlen(tmp)+1);
-
-		objdb->object_key_create(object_handle, "vsftype", strlen("vsftype"),
-					 "none", strlen("none")+1);
-
-		/* Set the token timeout is 10 seconds, but don't overrride anything that
-		   might be in cluster.conf */
-		if (objdb_get_string(objdb, object_handle, "token", &value)) {
-			global_objdb->object_key_create(object_handle, "token", strlen("token"),
-							"10000", strlen("10000")+1);
-		}
-		if (objdb_get_string(objdb, object_handle, "token_retransmits_before_loss_const", &value)) {
-			global_objdb->object_key_create(object_handle, "token_retransmits_before_loss_const",
-							strlen("token_retransmits_before_loss_const"),
-							"20", strlen("20")+1);
-		}
-
-		/* Extend consensus & join timeouts per bz#214290 */
-		if (objdb_get_string(objdb, object_handle, "join", &value)) {
-			global_objdb->object_key_create(object_handle, "join", strlen("join"),
-							"60", strlen("60")+1);
-		}
-		if (objdb_get_string(objdb, object_handle, "consensus", &value)) {
-			global_objdb->object_key_create(object_handle, "consensus", strlen("consensus"),
-							"4800", strlen("4800")+1);
-		}
-
-
-		/* Set RRP mode appropriately */
-		if (objdb_get_string(objdb, object_handle, "rrp_mode", &value)) {
-			if (num_interfaces > 1) {
-				global_objdb->object_key_create(object_handle, "rrp_mode", strlen("rrp_mode"),
-								"active", strlen("active")+1);
-			}
-			else {
-				global_objdb->object_key_create(object_handle, "rrp_mode", strlen("rrp_mode"),
-								"none", strlen("none")+1);
-			}
-		}
-
-		if (objdb_get_string(objdb, object_handle, "secauth", &value)) {
-			sprintf(tmp, "%d", 1);
-			objdb->object_key_create(object_handle, "secauth", strlen("secauth"),
-						 tmp, strlen(tmp)+1);
-		}
-
-		if (key_filename)
-		{
-			objdb->object_key_create(object_handle, "keyfile", strlen("keyfile"),
-						 key_filename, strlen(key_filename)+1);
-		}
-		else /* Use the cluster name as key,
-		      * This isn't a good isolation strategy but it does make sure that
-		      * clusters on the same port/multicast by mistake don't actually interfere
-		      * and that we have some form of encryption going.
-		      */
-		{
-			int keylen;
-			memset(tmp, 0, sizeof(tmp));
-
-			strcpy(tmp, cluster_name);
-
-			/* Key length must be a multiple of 4 */
-			keylen = (strlen(cluster_name)+4) & 0xFC;
-			objdb->object_key_create(object_handle, "key", strlen("key"),
-						 tmp, keylen);
-		}
-	}
-
-	/* Make sure mainconfig doesn't stomp on our logging options */
-	if (global_objdb->object_find(OBJECT_PARENT_HANDLE,
-				      "logging", strlen("logging"), &object_handle)) {
-
-		global_objdb->object_create(OBJECT_PARENT_HANDLE, &object_handle,
-					    "logging", strlen("logging"));
-	}
-
-	objdb->object_find_reset(OBJECT_PARENT_HANDLE);
-	if (objdb->object_find(OBJECT_PARENT_HANDLE,
-			       "logging", strlen("logging"),
-			       &object_handle) == 0)
-	{
-		unsigned int logger_object_handle;
-		char *logstr;
-
-		/* Default logging facility is "local4" unless overridden by the user */
-		if (objdb_get_string(objdb, object_handle, "syslog_facility", &logstr)) {
-			objdb->object_key_create(object_handle, "syslog_facility", strlen("syslog_facility"),
-						 "local4", strlen("local4")+1);
-		}
-
-		objdb->object_create(object_handle, &logger_object_handle,
-				      "logger_subsys", strlen("logger_subsys"));
-		objdb->object_key_create(logger_object_handle, "subsys", strlen("subsys"),
-					 CMAN_NAME, strlen(CMAN_NAME)+1);
-
-		if (debug_mask) {
-			objdb->object_key_create(logger_object_handle, "debug", strlen("debug"),
-						 "on", strlen("on")+1);
-			objdb->object_key_create(object_handle, "to_stderr", strlen("to_stderr"),
-						 "yes", strlen("yes")+1);
-		}
-	}
-
-	/* Don't run under user "ais" */
-	objdb->object_find_reset(OBJECT_PARENT_HANDLE);
-	if (objdb->object_find(OBJECT_PARENT_HANDLE, "aisexec", strlen("aisexec"), &object_handle) == 0)
-	{
-		objdb->object_key_create(object_handle, "user", strlen("user"),
-				 "root", strlen("root") + 1);
-		objdb->object_key_create(object_handle, "group", strlen("group"),
-				 "root", strlen("root") + 1);
-	}
-
-	/* Make sure we load our alter-ego */
-	objdb->object_create(OBJECT_PARENT_HANDLE, &object_handle,
-			     "service", strlen("service"));
-	objdb->object_key_create(object_handle, "name", strlen("name"),
-				 "openais_cman", strlen("openais_cman") + 1);
-	objdb->object_key_create(object_handle, "ver", strlen("ver"),
-				 "0", 2);
-
-	return 0;
-}
-
-
 /* Write an error message down the CMAN startup pipe so
    that cman_tool can display it */
 void write_cman_pipe(char *message)
diff -urN --exclude='*CVS*' cman/daemon/ais.h ../gittest/cman3-cvs/cman/daemon/ais.h
--- cman/daemon/ais.h	2007-10-01 09:42:15.000000000 +0100
+++ ../gittest/cman3-cvs/cman/daemon/ais.h	2008-01-03 13:08:19.000000000 +0000
@@ -1,7 +1,7 @@
 /******************************************************************************
 *******************************************************************************
 **
-**  Copyright (C) 2005 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2005-2008 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
@@ -19,10 +19,5 @@
 			      unsigned char toport, unsigned char fromport,
 			      int nodeid,
 			      unsigned int flags);
-extern void write_cman_pipe(char *message);
-
 extern uint64_t incarnation;
-extern struct totem_ip_address mcast_addr[MAX_INTERFACES];
-extern struct totem_ip_address ifaddrs[MAX_INTERFACES];
-extern int num_interfaces;
 extern int num_ais_nodes;
diff -urN --exclude='*CVS*' cman/daemon/barrier.c ../gittest/cman3-cvs/cman/daemon/barrier.c
--- cman/daemon/barrier.c	2008-01-02 16:28:23.000000000 +0000
+++ ../gittest/cman3-cvs/cman/daemon/barrier.c	2008-01-03 13:11:29.000000000 +0000
@@ -2,7 +2,7 @@
 *******************************************************************************
 **
 **  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
-**  Copyright (C) 2004-5 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2004-2008 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
diff -urN --exclude='*CVS*' cman/daemon/barrier.h ../gittest/cman3-cvs/cman/daemon/barrier.h
--- cman/daemon/barrier.h	2005-08-30 13:13:58.000000000 +0100
+++ ../gittest/cman3-cvs/cman/daemon/barrier.h	2008-01-03 13:11:35.000000000 +0000
@@ -1,7 +1,7 @@
 /******************************************************************************
 *******************************************************************************
 **
-**  Copyright (C) 2005 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2005-2008 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
diff -urN --exclude='*CVS*' cman/daemon/ccs.h ../gittest/cman3-cvs/cman/daemon/ccs.h
--- cman/daemon/ccs.h	2007-10-30 09:35:09.000000000 +0000
+++ ../gittest/cman3-cvs/cman/daemon/ccs.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,25 +0,0 @@
-/******************************************************************************
-*******************************************************************************
-**
-**  Copyright (C) 2004-2007 Red Hat, Inc.  All rights reserved.
-**
-**  This copyrighted material is made available to anyone wishing to use,
-**  modify, copy, or redistribute it subject to the terms and conditions
-**  of the GNU General Public License v.2.
-**
-*******************************************************************************
-******************************************************************************/
-#ifndef __CCS_DOT_H__
-#define __CCS_DOT_H__
-
-int ccs_connect(void);
-int ccs_force_connect(char const *cluster_name, int blocking);
-int ccs_disconnect(int desc);
-int ccs_get(int desc, const char *query, char **rtn);
-int ccs_get_list(int desc, const char *query, char **rtn);
-int ccs_set(int desc, const char *path, char *val);
-int ccs_get_state(int desc, char **cw_path, char **prev_query);
-int ccs_set_state(int desc, const char *cw_path, int reset_query);
-int ccs_lookup_nodename(int desc, const char *nodename, char **rtn);
-
-#endif /*  __CCS_DOT_H__ */
diff -urN --exclude='*CVS*' cman/daemon/cmanccs.c ../gittest/cman3-cvs/cman/daemon/cmanccs.c
--- cman/daemon/cmanccs.c	2008-01-02 16:28:31.000000000 +0000
+++ ../gittest/cman3-cvs/cman/daemon/cmanccs.c	2008-01-03 13:08:32.000000000 +0000
@@ -1,7 +1,7 @@
 /******************************************************************************
 *******************************************************************************
 **
-**  Copyright (C) 2005-2007 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2005-2008 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
diff -urN --exclude='*CVS*' cman/daemon/cmanccs.h ../gittest/cman3-cvs/cman/daemon/cmanccs.h
--- cman/daemon/cmanccs.h	2007-10-30 09:35:09.000000000 +0000
+++ ../gittest/cman3-cvs/cman/daemon/cmanccs.h	2008-01-03 13:08:45.000000000 +0000
@@ -1,7 +1,7 @@
 /******************************************************************************
 *******************************************************************************
 **
-**  Copyright (C) 2005 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2005-2008 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
diff -urN --exclude='*CVS*' cman/daemon/cmanconfig.c ../gittest/cman3-cvs/cman/daemon/cmanconfig.c
--- cman/daemon/cmanconfig.c	1970-01-01 01:00:00.000000000 +0100
+++ ../gittest/cman3-cvs/cman/daemon/cmanconfig.c	2008-01-03 13:08:51.000000000 +0000
@@ -0,0 +1,301 @@
+/******************************************************************************
+*******************************************************************************
+**
+**  Copyright (C) 2005-2008 Red Hat, Inc.  All rights reserved.
+**
+**  This copyrighted material is made available to anyone wishing to use,
+**  modify, copy, or redistribute it subject to the terms and conditions
+**  of the GNU General Public License v.2.
+**
+*******************************************************************************
+******************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <netinet/in.h>
+#include <syslog.h>
+#include <string.h>
+#include <errno.h>
+#include <netdb.h>
+
+#include <openais/service/objdb.h>
+#include <openais/service/swab.h>
+#include <openais/service/logsys.h>
+
+#include "list.h"
+#include "cnxman-socket.h"
+#include "cnxman-private.h"
+#include "logging.h"
+#include "commands.h"
+#include "cmanconfig.h"
+LOGSYS_DECLARE_SUBSYS (CMAN_NAME, LOG_INFO);
+#include "nodelist.h"
+#include "ais.h"
+#include "cman.h"
+
+/* Local vars - things we get from ccs */
+       int two_node;
+static int nodeid;
+static unsigned int cluster_id;
+static char cluster_name[MAX_CLUSTER_NAME_LEN + 1];
+static unsigned int expected_votes;
+static char *our_nodename;
+static int our_votes;
+
+/* Get all the cluster node names from objdb and
+ * add them to our node list.
+ * Called when we start up and on "cman_tool version".
+ */
+int read_cman_nodes(struct objdb_iface_ver0 *objdb, unsigned int *config_version, int check_nodeids)
+{
+    int error;
+    unsigned int expected = 0;
+    unsigned int votes = 0;
+    int nodeid;
+    unsigned int object_handle;
+    unsigned int nodes_handle;
+    unsigned int parent_handle;
+    char *nodename;
+
+    /* New config version */
+    objdb_get_int(objdb, OBJECT_PARENT_HANDLE, "config_version", config_version);
+
+    objdb->object_find_reset(OBJECT_PARENT_HANDLE);
+
+    if (objdb->object_find(OBJECT_PARENT_HANDLE,
+			   "cman", strlen("cman"),
+			   &object_handle) == 0)
+    {
+	    /* This overrides any other expected votes calculation /except/ for
+	       one specified on a join command-line */
+	    objdb_get_int(objdb, object_handle, "expected_votes", &expected);
+	    objdb_get_int(objdb, object_handle, "two_node", (unsigned int *)&two_node);
+	    objdb_get_int(objdb, object_handle, "cluster_id", &cluster_id);
+	    objdb_get_string(objdb, object_handle, "nodename", &our_nodename);
+    }
+
+    /* Get the nodes list */
+    nodes_handle = nodeslist_init(objdb, &parent_handle);
+    do {
+	    if (objdb_get_string(objdb, nodes_handle, "name", &nodename)) {
+		    log_printf(LOG_ERR, "Cannot get node name");
+		    continue;
+	    }
+
+	    objdb_get_int(objdb, nodes_handle, "votes", (unsigned int *)&votes);
+	    if (votes == 0)
+		    votes = 1;
+
+	    objdb_get_int(objdb, nodes_handle, "nodeid", (unsigned int *)&nodeid);
+
+	    if (check_nodeids && nodeid == 0) {
+		    char message[132];
+
+		    snprintf(message, sizeof(message),
+			     "No node ID for %s, run 'ccs_tool addnodeids' to fix",
+			     nodename);
+		    log_printf(LOG_ERR, "%s", message);
+		    write_cman_pipe(message);
+		    error = -EINVAL;
+		    goto out_err;
+	    }
+
+	    P_MEMB("Got node %s from ccs (id=%d, votes=%d)\n", nodename, nodeid, votes);
+	    add_ccs_node(nodename, nodeid, votes, expected);
+	    nodes_handle = nodeslist_next(objdb, parent_handle);
+    } while (nodes_handle);
+
+    if (expected)
+	    override_expected(expected);
+
+    error = 0;
+
+out_err:
+    return error;
+}
+
+static int join(struct objdb_iface_ver0 *objdb)
+{
+	int error;
+	error = cman_set_nodename(our_nodename);
+	error = cman_set_nodeid(nodeid);
+
+        /*
+	 * Setup join information
+	 */
+	error = cman_join_cluster(objdb, cluster_name, cluster_id,
+				  two_node, our_votes, expected_votes);
+	if (error == -EINVAL) {
+		write_cman_pipe("Cannot start, cluster name is too long or other CCS error");
+		return error;
+	}
+	if (error) {
+		write_cman_pipe("Cannot start, ais may already be running");
+		return error;
+	}
+
+	return 0;
+}
+
+static int get_cman_join_info(struct objdb_iface_ver0 *objdb)
+{
+	char *cname = NULL;
+	int  error, vote_sum = 0, node_count = 0;
+	int votes;
+	unsigned int object_handle;
+	unsigned int node_object;
+
+	/* Cluster name */
+	if (objdb_get_string(objdb, OBJECT_PARENT_HANDLE, "name", &cname)) {
+		log_printf(LOG_ERR, "cannot find cluster name in config file");
+		write_cman_pipe("Can't find cluster name in CCS");
+		error = -ENOENT;
+		goto out;
+	}
+
+	strcpy(cluster_name, cname);
+
+	expected_votes = 0;
+	if (getenv("CMAN_EXPECTEDVOTES")) {
+		expected_votes = atoi(getenv("CMAN_EXPECTEDVOTES"));
+		if (expected_votes < 1) {
+			log_printf(LOG_ERR, "CMAN_EXPECTEDVOTES environment variable is invalid, ignoring");
+			expected_votes = 0;
+		}
+		else {
+			log_printf(LOG_INFO, "Using override expected votes %d\n", expected_votes);
+		}
+	}
+
+	/* Sum node votes for expected */
+	if (expected_votes == 0) {
+		unsigned int nodes_handle;
+		unsigned int parent_handle;
+
+		nodes_handle = nodeslist_init(objdb, &parent_handle);
+		do {
+			int votes;
+
+			node_count++;
+
+			objdb_get_int(objdb, nodes_handle, "votes", (unsigned int *)&votes);
+			if (votes == 0)
+				votes = 1;
+
+			if (votes < 0) {
+				log_printf(LOG_ERR, "negative votes not allowed");
+				write_cman_pipe("Found negative votes for this node in CCS");
+				error = -EINVAL;
+				goto out;
+			}
+			vote_sum += votes;
+			nodes_handle = nodeslist_next(objdb, parent_handle);
+		} while (nodes_handle);
+
+		objdb->object_find_reset(OBJECT_PARENT_HANDLE);
+		if (objdb->object_find(OBJECT_PARENT_HANDLE,
+				       "cman", strlen("cman"),
+				       &object_handle) == 0)
+		{
+
+			/* optional expected_votes supercedes vote sum */
+			objdb_get_int(objdb, object_handle, "expected_votes", (unsigned int *)&expected_votes);
+			if (!expected_votes)
+				expected_votes = vote_sum;
+		}
+	}
+
+	/* find our own number of votes */
+	if (getenv("CMAN_VOTES")) {
+		votes = atoi(getenv("CMAN_VOTES"));
+		log_printf(LOG_INFO, "Using override votes %d\n", votes);
+	}
+
+	node_object = nodelist_byname(objdb, our_nodename);
+	if (!node_object) {
+		log_printf(LOG_ERR, "unable to find votes for %s", our_nodename);
+		write_cman_pipe("Unable to find votes for node in CCS");
+		return -E2BIG;
+	}
+
+	if (!votes) {
+		unsigned int votestmp=-1;
+		objdb_get_int(objdb, node_object, "votes", &votestmp);
+		if (votestmp == -1)
+			votestmp = 1;
+
+		if (votestmp < 0 || votestmp > 255) {
+			log_printf(LOG_ERR, "invalid votes value %d", votestmp);
+			write_cman_pipe("Found invalid votes for node in CCS");
+			return -EINVAL;
+		}
+		votes = votestmp;
+	}
+	if (!votes) {
+		votes = 1;
+	}
+	our_votes = votes;
+
+	/* nodeid */
+	if (getenv("CMAN_NODEID")) {
+		nodeid = atoi(getenv("CMAN_NODEID"));
+		log_printf(LOG_INFO, "Using override nodeid %d\n", nodeid);
+	}
+
+	if (!nodeid) {
+		objdb_get_int(objdb, node_object, "nodeid", (unsigned int *)&nodeid);
+	}
+
+	if (!nodeid) {
+		log_printf(LOG_ERR, "No nodeid specified in cluster.conf");
+		write_cman_pipe("CCS does not have a nodeid for this node, run 'ccs_tool addnodeids' to fix");
+		return -EINVAL;
+	}
+
+	/* two_node mode */
+	if (two_node) {
+		if (node_count != 2 || vote_sum != 2) {
+			log_printf(LOG_ERR, "the two-node option requires exactly two "
+				   "nodes with one vote each and expected "
+				   "votes of 1 (node_count=%d vote_sum=%d)",
+				   node_count, vote_sum);
+			write_cman_pipe("two_node set but there are more than 2 nodes");
+			error = -EINVAL;
+			goto out;
+		}
+
+		if (votes != 1) {
+			log_printf(LOG_ERR, "the two-node option requires exactly two "
+				   "nodes with one vote each and expected "
+				   "votes of 1 (votes=%d)", votes);
+			write_cman_pipe("two_node set but votes not set to 1");
+			error = -EINVAL;
+			goto out;
+		}
+	}
+
+	error = 0;
+
+out:
+	return error;
+}
+
+
+
+/* Read the stuff we need to get started.
+   This does what 'cman_tool join' used to to */
+int read_cman_config(struct objdb_iface_ver0 *objdb, unsigned int *config_version)
+{
+	int error;
+
+	read_cman_nodes(objdb, config_version, 1);
+	error = get_cman_join_info(objdb);
+	if (error) {
+		log_printf(LOG_ERR, "Error reading configuration, cannot start");
+		return error;
+	}
+
+	error = join(objdb);
+
+	return error;
+}
diff -urN --exclude='*CVS*' cman/daemon/cmanconfig.h ../gittest/cman3-cvs/cman/daemon/cmanconfig.h
--- cman/daemon/cmanconfig.h	1970-01-01 01:00:00.000000000 +0100
+++ ../gittest/cman3-cvs/cman/daemon/cmanconfig.h	2008-01-03 13:09:00.000000000 +0000
@@ -0,0 +1,45 @@
+/******************************************************************************
+*******************************************************************************
+**
+**  Copyright (C) 2007-2008 Red Hat, Inc.  All rights reserved.
+**
+**  This copyrighted material is made available to anyone wishing to use,
+**  modify, copy, or redistribute it subject to the terms and conditions
+**  of the GNU General Public License v.2.
+**
+*******************************************************************************
+******************************************************************************/
+
+int read_cman_nodes(struct objdb_iface_ver0 *objdb, unsigned int *config_version, int check_nodeids);
+int read_cman_config(struct objdb_iface_ver0 *objdb, unsigned int *config_version);
+
+/* These just make the access a little neater */
+static inline int objdb_get_string(struct objdb_iface_ver0 *objdb, unsigned int object_service_handle,
+				   char *key, char **value)
+{
+	int res;
+
+	*value = NULL;
+	if ( !(res = objdb->object_key_get(object_service_handle,
+					   key,
+					   strlen(key),
+					   (void *)value,
+					   NULL))) {
+		if (*value)
+			return 0;
+	}
+	return -1;
+}
+
+static inline void objdb_get_int(struct objdb_iface_ver0 *objdb, unsigned int object_service_handle,
+				   char *key, unsigned int *intvalue)
+{
+	char *value = NULL;
+
+	if (!objdb->object_key_get(object_service_handle, key, strlen(key),
+				   (void *)&value, NULL)) {
+		if (value) {
+			*intvalue = atoi(value);
+		}
+	}
+}
diff -urN --exclude='*CVS*' cman/daemon/cman.h ../gittest/cman3-cvs/cman/daemon/cman.h
--- cman/daemon/cman.h	1970-01-01 01:00:00.000000000 +0100
+++ ../gittest/cman3-cvs/cman/daemon/cman.h	2008-01-03 13:09:08.000000000 +0000
@@ -0,0 +1,15 @@
+/******************************************************************************
+*******************************************************************************
+**
+**  Copyright (C) 2007-2008 Red Hat, Inc.  All rights reserved.
+**
+**  This copyrighted material is made available to anyone wishing to use,
+**  modify, copy, or redistribute it subject to the terms and conditions
+**  of the GNU General Public License v.2.
+**
+*******************************************************************************
+******************************************************************************/
+
+/* General cman bits */
+extern void write_cman_pipe(char *message);
+extern void close_cman_pipe(void);
diff -urN --exclude='*CVS*' cman/daemon/cman-preconfig.c ../gittest/cman3-cvs/cman/daemon/cman-preconfig.c
--- cman/daemon/cman-preconfig.c	1970-01-01 01:00:00.000000000 +0100
+++ ../gittest/cman3-cvs/cman/daemon/cman-preconfig.c	2008-01-03 14:32:22.000000000 +0000
@@ -0,0 +1,872 @@
+/******************************************************************************
+*******************************************************************************
+**
+**  Copyright (C) 2007-2008 Red Hat, Inc.  All rights reserved.
+**
+**  This copyrighted material is made available to anyone wishing to use,
+**  modify, copy, or redistribute it subject to the terms and conditions
+**  of the GNU General Public License v.2.
+**
+*******************************************************************************
+******************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/utsname.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/errno.h>
+#include <netdb.h>
+#include <ifaddrs.h>
+
+#define DEFAULT_PORT            5405
+#define DEFAULT_CLUSTER_NAME    "RHCluster"
+#define NOCCS_KEY_FILENAME      "/etc/cluster/cman_authkey"
+
+/* openais headers */
+#include <openais/service/objdb.h>
+#include <openais/service/swab.h>
+#include <openais/totem/totemip.h>
+#include <openais/totem/totempg.h>
+#include <openais/totem/aispoll.h>
+#include <openais/service/service.h>
+#include <openais/service/config.h>
+#include <openais/lcr/lcr_comp.h>
+#include <openais/service/swab.h>
+#include <openais/service/logsys.h>
+
+LOGSYS_DECLARE_SUBSYS ("CMAN", LOG_INFO);
+
+#include "cman.h"
+#include "cmanconfig.h"
+#include "cnxman-socket.h"
+#include "nodelist.h"
+#include "logging.h"
+
+#define MAX_PATH_LEN PATH_MAX
+
+static unsigned int debug_mask;
+static int cmanpre_readconfig(struct objdb_iface_ver0 *objdb, char **error_string);
+
+static char *nodename_env;
+static int expected_votes;
+static int votes;
+static int num_interfaces;
+static int startup_pipe;
+static unsigned int cluster_id;
+static char nodename[MAX_CLUSTER_MEMBER_NAME_LEN];
+static int nodeid;
+static int two_node;
+static unsigned int portnum;
+static int num_nodenames;
+static char *key_filename;
+static char *mcast_name;
+static char *cluster_name;
+static char error_reason[1024];
+
+/*
+ * Exports the interface for the service
+ */
+
+static struct config_iface_ver0 cmanpreconfig_iface_ver0 = {
+	.config_readconfig        = cmanpre_readconfig
+};
+
+static struct lcr_iface ifaces_ver0[2] = {
+	{
+		.name		       	= "cmanpreconfig",
+		.version	       	= 0,
+		.versions_replace      	= 0,
+		.versions_replace_count	= 0,
+		.dependencies	       	= 0,
+		.dependency_count      	= 0,
+		.constructor	       	= NULL,
+		.destructor	       	= NULL,
+		.interfaces	       	= NULL,
+	}
+};
+
+static struct lcr_comp cmanpre_comp_ver0 = {
+	.iface_count				= 1,
+	.ifaces					= ifaces_ver0,
+};
+
+
+
+__attribute__ ((constructor)) static void cmanpre_comp_register(void) {
+	lcr_interfaces_set(&ifaces_ver0[0], &cmanpreconfig_iface_ver0);
+	lcr_component_register(&cmanpre_comp_ver0);
+}
+
+static int add_ifaddr(struct objdb_iface_ver0 *objdb, char *mcast, char *ifaddr, int portnum)
+{
+	unsigned int totem_object_handle;
+	unsigned int interface_object_handle;
+	struct totem_ip_address if_addr, localhost, mcast_addr;
+	char tmp[132];
+	int ret = 0;
+
+	P_AIS("Adding local address %s\n", ifaddr);
+
+	/* Check the families match */
+	ret = totemip_parse(&mcast_addr, mcast, 0);
+	if (!ret)
+		ret = totemip_parse(&if_addr, ifaddr, mcast_addr.family);
+	if (ret) {
+		errno = EPROTOTYPE;
+		return ret;
+	}
+
+	/* Check it's not bound to localhost, sigh */
+	totemip_localhost(mcast_addr.family, &localhost);
+	if (totemip_equal(&localhost, &if_addr)) {
+		errno = EADDRINUSE;
+		return -1;
+	}
+
+        if (objdb->object_find(OBJECT_PARENT_HANDLE,
+			       "totem", strlen("totem"), &totem_object_handle)) {
+
+                objdb->object_create(OBJECT_PARENT_HANDLE, &totem_object_handle,
+                                            "totem", strlen("totem"));
+        }
+
+	objdb->object_find_reset(OBJECT_PARENT_HANDLE);
+	if (objdb->object_find(OBJECT_PARENT_HANDLE,
+				      "totem", strlen("totem"), &totem_object_handle) == 0) {
+
+		if (objdb->object_create(totem_object_handle, &interface_object_handle,
+						"interface", strlen("interface")) == 0) {
+
+			P_AIS("Setting if %d, name: %s,  mcast: %s,  port=%d, \n",
+			      num_interfaces, ifaddr, mcast, portnum);
+			sprintf(tmp, "%d", num_interfaces);
+			objdb->object_key_create(interface_object_handle, "ringnumber", strlen("ringnumber"),
+							tmp, strlen(tmp)+1);
+
+			objdb->object_key_create(interface_object_handle, "bindnetaddr", strlen("bindnetaddr"),
+							ifaddr, strlen(ifaddr)+1);
+
+			objdb->object_key_create(interface_object_handle, "mcastaddr", strlen("mcastaddr"),
+							mcast, strlen(mcast)+1);
+
+			sprintf(tmp, "%d", portnum);
+			objdb->object_key_create(interface_object_handle, "mcastport", strlen("mcastport"),
+							tmp, strlen(tmp)+1);
+
+			num_interfaces++;
+		}
+	}
+	return ret;
+}
+
+static uint16_t generate_cluster_id(char *name)
+{
+	int i;
+	int value = 0;
+
+	for (i=0; i<strlen(name); i++) {
+		value <<= 1;
+		value += name[i];
+	}
+	P_MEMB("Generated cluster id for '%s' is %d\n", name, value & 0xFFFF);
+	return value & 0xFFFF;
+}
+
+static char *default_mcast(char *nodename, uint16_t cluster_id)
+{
+        struct addrinfo *ainfo;
+        struct addrinfo ahints;
+	int ret;
+	int family;
+	static char addr[132];
+
+        memset(&ahints, 0, sizeof(ahints));
+
+        /* Lookup the the nodename address and use it's IP type to
+	   default a multicast address */
+        ret = getaddrinfo(nodename, NULL, &ahints, &ainfo);
+	if (ret) {
+		log_printf(LOG_ERR, "Can't determine address family of nodename %s\n", nodename);
+		write_cman_pipe("Can't determine address family of nodename");
+		return NULL;
+	}
+
+	family = ainfo->ai_family;
+	freeaddrinfo(ainfo);
+
+	if (family == AF_INET) {
+		snprintf(addr, sizeof(addr), "239.192.%d.%d", cluster_id >> 8, cluster_id % 0xFF);
+		return addr;
+	}
+	if (family == AF_INET6) {
+		snprintf(addr, sizeof(addr), "ff15::%x", cluster_id);
+		return addr;
+	}
+
+	return NULL;
+}
+
+static int verify_nodename(struct objdb_iface_ver0 *objdb, char *nodename)
+{
+	char nodename2[MAX_CLUSTER_MEMBER_NAME_LEN+1];
+	char nodename3[MAX_CLUSTER_MEMBER_NAME_LEN+1];
+	char *str, *dot = NULL;
+	struct ifaddrs *ifa, *ifa_list;
+	struct sockaddr *sa;
+	unsigned int nodes_handle;
+	unsigned int parent_handle;
+	int error;
+
+	/* nodename is either from commandline or from uname */
+	if (nodelist_byname(objdb, nodename))
+		return 0;
+
+	/* If nodename was from uname, try a domain-less version of it */
+	strcpy(nodename2, nodename);
+	dot = strchr(nodename2, '.');
+	if (dot) {
+		*dot = '\0';
+
+		if (nodelist_byname(objdb, nodename2)) {
+			strcpy(nodename, nodename2);
+			return 0;
+		}
+	}
+
+	/* If nodename (from uname) is domain-less, try to match against
+	   cluster.conf names which may have domainname specified */
+	nodes_handle = nodeslist_init(objdb, &parent_handle);
+	do {
+		int len;
+
+		if (objdb_get_string(objdb, nodes_handle, "name", &str)) {
+			log_printf(LOG_ERR, "Cannot get node name");
+			break;
+		}
+
+		fprintf(stderr, "nodelist. got name %s\n", str);
+
+		strcpy(nodename3, str);
+		dot = strchr(nodename3, '.');
+		if (dot)
+			len = dot-nodename3;
+		else
+			len = strlen(nodename3);
+
+		if (strlen(nodename2) == len &&
+		    !strncmp(nodename2, nodename3, len)) {
+			strcpy(nodename, nodename3);
+			return 0;
+		}
+		nodes_handle = nodeslist_next(objdb, parent_handle);
+	} while (nodes_handle);
+
+
+	/* The cluster.conf names may not be related to uname at all,
+	   they may match a hostname on some network interface.
+	   NOTE: This is IPv4 only */
+	error = getifaddrs(&ifa_list);
+	if (error)
+		return -1;
+
+	for (ifa = ifa_list; ifa; ifa = ifa->ifa_next) {
+		/* Restore this */
+		strcpy(nodename2, nodename);
+		sa = ifa->ifa_addr;
+		if (!sa || sa->sa_family != AF_INET)
+			continue;
+
+		error = getnameinfo(sa, sizeof(*sa), nodename2,
+				    sizeof(nodename2), NULL, 0, 0);
+		if (error)
+			goto out;
+
+		if (nodelist_byname(objdb, nodename2)) {
+			strcpy(nodename, nodename2);
+			goto out;
+		}
+
+		/* truncate this name and try again */
+
+		dot = strchr(nodename2, '.');
+		if (!dot)
+			continue;
+		*dot = '\0';
+
+		if (nodelist_byname(objdb, nodename2)) {
+			strcpy(nodename, nodename2);
+			goto out;
+		}
+
+		/* See if it's the IP address that's in cluster.conf */
+		error = getnameinfo(sa, sizeof(*sa), nodename2,
+				    sizeof(nodename2), NULL, 0, NI_NUMERICHOST);
+		if (error)
+			goto out;
+
+		if (nodelist_byname(objdb, nodename2)) {
+			strcpy(nodename, nodename2);
+			goto out;
+		}
+	}
+
+	error = -1;
+ out:
+	freeifaddrs(ifa_list);
+	return error;
+}
+
+/* Get any environment variable overrides */
+static int get_env_overrides()
+{
+	if (getenv("CMAN_CLUSTER_NAME")) {
+		cluster_name = strdup(getenv("CMAN_CLUSTER_NAME"));
+		log_printf(LOG_INFO, "Using override cluster name %s\n", cluster_name);
+	}
+
+	nodename_env = getenv("CMAN_NODENAME");
+	if (nodename_env) {
+		log_printf(LOG_INFO, "Using override node name %s\n", nodename_env);
+	}
+
+	expected_votes = 0;
+	if (getenv("CMAN_EXPECTEDVOTES")) {
+		expected_votes = atoi(getenv("CMAN_EXPECTEDVOTES"));
+		if (expected_votes < 1) {
+			log_printf(LOG_ERR, "CMAN_EXPECTEDVOTES environment variable is invalid, ignoring");
+			expected_votes = 0;
+		}
+		else {
+			log_printf(LOG_INFO, "Using override expected votes %d\n", expected_votes);
+		}
+	}
+
+	/* optional port */
+	if (getenv("CMAN_IP_PORT")) {
+		portnum = atoi(getenv("CMAN_IP_PORT"));
+		log_printf(LOG_INFO, "Using override IP port %d\n", portnum);
+	}
+
+	/* optional security key filename */
+	if (getenv("CMAN_KEYFILE")) {
+		key_filename = strdup(getenv("CMAN_KEYFILE"));
+		if (key_filename == NULL)
+			return -ENOMEM;
+	}
+
+	/* find our own number of votes */
+	if (getenv("CMAN_VOTES")) {
+		votes = atoi(getenv("CMAN_VOTES"));
+		log_printf(LOG_INFO, "Using override votes %d\n", votes);
+	}
+
+	/* nodeid */
+	if (getenv("CMAN_NODEID")) {
+		nodeid = atoi(getenv("CMAN_NODEID"));
+		log_printf(LOG_INFO, "Using override nodeid %d\n", nodeid);
+	}
+
+	if (getenv("CMAN_MCAST_ADDR")) {
+		mcast_name = getenv("CMAN_MCAST_ADDR");
+		log_printf(LOG_INFO, "Using override multicast address %s\n", mcast_name);
+	}
+
+	if (getenv("CMAN_2NODE")) {
+		two_node = 1;
+		expected_votes = 1;
+		votes = 1;
+		log_printf(LOG_INFO, "Setting two_node mode from cman_tool\n");
+	}
+	return 0;
+}
+
+
+static int get_nodename(struct objdb_iface_ver0 *objdb)
+{
+	char *nodeid_str;
+	unsigned int object_handle;
+	unsigned int node_object_handle;
+	unsigned int alt_object;
+	int error;
+
+	/* our nodename */
+	if (nodename_env != NULL) {
+
+		if (strlen(nodename_env) >= sizeof(nodename)) {
+			log_printf(LOG_ERR, "Overridden node name %s is too long", nodename);
+			write_cman_pipe("Overridden node name is too long");
+			error = -E2BIG;
+			goto out;
+		}
+
+		strcpy(nodename, nodename_env);
+		log_printf(LOG_INFO, "Using override node name %s\n", nodename);
+
+		if (objdb->object_find(object_handle,
+				       nodename, strlen(nodename),
+				       &node_object_handle) == 0) {
+			log_printf(LOG_ERR, "Overridden node name %s is not in CCS", nodename);
+			write_cman_pipe("Overridden node name is not in CCS");
+			error = -ENOENT;
+			goto out;
+		}
+
+	} else {
+		struct utsname utsname;
+
+		error = uname(&utsname);
+		if (error) {
+			log_printf(LOG_ERR, "cannot get node name, uname failed");
+			write_cman_pipe("Can't determine local node name");
+			error = -ENOENT;
+			goto out;
+		}
+
+		if (strlen(utsname.nodename) >= sizeof(nodename)) {
+			log_printf(LOG_ERR, "node name from uname is too long");
+			write_cman_pipe("Can't determine local node name");
+			error = -E2BIG;
+			goto out;
+		}
+
+		strcpy(nodename, utsname.nodename);
+	}
+	if (verify_nodename(objdb, nodename))
+		return -EINVAL;
+
+
+	// Add <cman nodename>
+	if ( (node_object_handle = nodelist_byname(objdb, nodename))) {
+		if (objdb_get_string(objdb, node_object_handle, "nodeid", &nodeid_str)) {
+			log_printf(LOG_ERR, "Cannot get node ID");
+			return -EINVAL;
+		}
+	}
+
+	objdb->object_find_reset(OBJECT_PARENT_HANDLE);
+
+	if (objdb->object_find(OBJECT_PARENT_HANDLE,
+			       "cman", strlen("cman"),
+			       &object_handle) == 0) {
+
+		unsigned int mcast_handle;
+
+		if (!mcast_name) {
+
+			objdb->object_find_reset(object_handle);
+			if (objdb->object_find(object_handle,
+					       "multicast", strlen("multicast"),
+					       &mcast_handle) == 0) {
+
+				objdb_get_string(objdb, mcast_handle, "addr", &mcast_name);
+			}
+		}
+
+		if (!mcast_name) {
+			mcast_name = default_mcast(nodename, cluster_id);
+			log_printf(LOG_INFO, "Using default multicast address of %s\n", mcast_name);
+		}
+
+		objdb->object_key_create(object_handle, "nodename", strlen("nodename"),
+					 nodename, strlen(nodename)+1);
+	}
+
+	nodeid = atoi(nodeid_str);
+	error = 0;
+
+	/* optional port */
+	if (!portnum) {
+		objdb_get_int(objdb, object_handle, "port", &portnum);
+		if (!portnum)
+			portnum = DEFAULT_PORT;
+	}
+
+	add_ifaddr(objdb, mcast_name, nodename, portnum);
+
+	/* Get all alternative node names */
+	num_nodenames = 1;
+	objdb->object_find_reset(node_object_handle);
+	while (objdb->object_find(node_object_handle,
+				  "altname", strlen("altname"),
+				  &alt_object) == 0) {
+		unsigned int port;
+		char *nodename;
+		char *mcast;
+
+		if (objdb_get_string(objdb, alt_object, "name", &nodename)) {
+			continue;
+		}
+
+		objdb_get_int(objdb, alt_object, "port", &port);
+		if (!port)
+			port = portnum;
+
+		if (objdb_get_string(objdb, alt_object, "mcast", &mcast)) {
+			mcast = mcast_name;
+		}
+
+		add_ifaddr(objdb, mcast, nodename, portnum);
+
+		num_nodenames++;
+	}
+
+out:
+	return error;
+}
+
+/* These are basically cman overrides to the totem config bits */
+static void add_cman_overrides(struct objdb_iface_ver0 *objdb)
+{
+	unsigned int object_handle;
+	char tmp[256];
+
+	P_AIS("comms_init_ais()\n");
+
+	/* "totem" key already exists, because we have added the interfaces by now */
+	objdb->object_find_reset(OBJECT_PARENT_HANDLE);
+	if (objdb->object_find(OBJECT_PARENT_HANDLE,
+			       "totem", strlen("totem"),
+			       &object_handle) == 0)
+	{
+		char *value;
+
+		objdb->object_key_create(object_handle, "version", strlen("version"),
+					 "2", 2);
+
+		sprintf(tmp, "%d", nodeid);
+		objdb->object_key_create(object_handle, "nodeid", strlen("nodeid"),
+					 tmp, strlen(tmp)+1);
+
+		objdb->object_key_create(object_handle, "vsftype", strlen("vsftype"),
+					 "none", strlen("none")+1);
+
+		/* Set the token timeout is 10 seconds, but don't overrride anything that
+		   might be in cluster.conf */
+		if (objdb_get_string(objdb, object_handle, "token", &value)) {
+			objdb->object_key_create(object_handle, "token", strlen("token"),
+						 "10000", strlen("10000")+1);
+		}
+		if (objdb_get_string(objdb, object_handle, "token_retransmits_before_loss_const", &value)) {
+			objdb->object_key_create(object_handle, "token_retransmits_before_loss_const",
+						 strlen("token_retransmits_before_loss_const"),
+						 "20", strlen("20")+1);
+		}
+
+		/* Extend consensus & join timeouts per bz#214290 */
+		if (objdb_get_string(objdb, object_handle, "join", &value)) {
+			objdb->object_key_create(object_handle, "join", strlen("join"),
+						 "60", strlen("60")+1);
+		}
+		if (objdb_get_string(objdb, object_handle, "consensus", &value)) {
+			objdb->object_key_create(object_handle, "consensus", strlen("consensus"),
+						 "4800", strlen("4800")+1);
+		}
+
+
+		/* Set RRP mode appropriately */
+		if (objdb_get_string(objdb, object_handle, "rrp_mode", &value)) {
+			if (num_interfaces > 1) {
+				objdb->object_key_create(object_handle, "rrp_mode", strlen("rrp_mode"),
+							 "active", strlen("active")+1);
+			}
+			else {
+				objdb->object_key_create(object_handle, "rrp_mode", strlen("rrp_mode"),
+							 "none", strlen("none")+1);
+			}
+		}
+
+		if (objdb_get_string(objdb, object_handle, "secauth", &value)) {
+			sprintf(tmp, "%d", 1);
+			objdb->object_key_create(object_handle, "secauth", strlen("secauth"),
+						 tmp, strlen(tmp)+1);
+		}
+
+		/* optional security key filename */
+		if (!key_filename) {
+			objdb_get_string(objdb, object_handle, "keyfile", &key_filename);
+		}
+		else {
+			objdb->object_key_create(object_handle, "keyfile", strlen("keyfile"),
+						 key_filename, strlen(key_filename)+1);
+		}
+		if (!key_filename) {
+			/* Use the cluster name as key,
+			 * This isn't a good isolation strategy but it does make sure that
+			 * clusters on the same port/multicast by mistake don't actually interfere
+			 * and that we have some form of encryption going.
+			 */
+
+			int keylen;
+			memset(tmp, 0, sizeof(tmp));
+
+			strcpy(tmp, cluster_name);
+
+			/* Key length must be a multiple of 4 */
+			keylen = (strlen(cluster_name)+4) & 0xFC;
+			objdb->object_key_create(object_handle, "key", strlen("key"),
+						 tmp, keylen);
+		}
+	}
+
+	/* Make sure mainconfig doesn't stomp on our logging options */
+	if (objdb->object_find(OBJECT_PARENT_HANDLE,
+			       "logging", strlen("logging"), &object_handle)) {
+
+                objdb->object_create(OBJECT_PARENT_HANDLE, &object_handle,
+					    "logging", strlen("logging"));
+        }
+
+	objdb->object_find_reset(OBJECT_PARENT_HANDLE);
+	if (objdb->object_find(OBJECT_PARENT_HANDLE,
+			       "logging", strlen("logging"),
+			       &object_handle) == 0) {
+		unsigned int logger_object_handle;
+		char *logstr;
+
+		/* Default logging facility is "local4" unless overridden by the user */
+		if (objdb_get_string(objdb, object_handle, "syslog_facility", &logstr)) {
+			objdb->object_key_create(object_handle, "syslog_facility", strlen("syslog_facility"),
+						 "local4", strlen("local4")+1);
+		}
+
+		objdb->object_create(object_handle, &logger_object_handle,
+				      "logger_subsys", strlen("logger_subsys"));
+		objdb->object_key_create(logger_object_handle, "subsys", strlen("subsys"),
+					 "CMAN", strlen("CMAN")+1);
+
+		if (debug_mask) {
+			objdb->object_key_create(logger_object_handle, "debug", strlen("debug"),
+						 "on", strlen("on")+1);
+			objdb->object_key_create(object_handle, "to_stderr", strlen("to_stderr"),
+						 "yes", strlen("yes")+1);
+		}
+	}
+
+	/* Don't run under user "ais" */
+	objdb->object_find_reset(OBJECT_PARENT_HANDLE);
+	if (objdb->object_find(OBJECT_PARENT_HANDLE, "aisexec", strlen("aisexec"), &object_handle) == 0)
+	{
+		objdb->object_key_create(object_handle, "user", strlen("user"),
+				 "root", strlen("root") + 1);
+		objdb->object_key_create(object_handle, "group", strlen("group"),
+				 "root", strlen("root") + 1);
+	}
+
+	objdb->object_find_reset(OBJECT_PARENT_HANDLE);
+	if (objdb->object_find(OBJECT_PARENT_HANDLE, "cman", strlen("cman"), &object_handle) == 0)
+	{
+		char str[255];
+
+		sprintf(str, "%d", cluster_id);
+
+		objdb->object_key_create(object_handle, "cluster_id", strlen("cluster_id"),
+					 str, strlen(str) + 1);
+
+		if (two_node) {
+			sprintf(str, "%d", 1);
+			objdb->object_key_create(object_handle, "two_node", strlen("two_node"),
+						 str, strlen(str) + 1);
+		}
+
+	}
+
+	/* Make sure we load our alter-ego - the main cman module */
+	objdb->object_create(OBJECT_PARENT_HANDLE, &object_handle,
+			     "service", strlen("service"));
+	objdb->object_key_create(object_handle, "name", strlen("name"),
+				 "openais_cman", strlen("openais_cman") + 1);
+	objdb->object_key_create(object_handle, "ver", strlen("ver"),
+				 "0", 2);
+}
+
+/* If ccs is not available then use some defaults */
+static int set_noccs_defaults(struct objdb_iface_ver0 *objdb)
+{
+	char tmp[255];
+	unsigned int object_handle;
+
+	/* Enforce key */
+	key_filename = NOCCS_KEY_FILENAME;
+
+	if (!cluster_name)
+		cluster_name = DEFAULT_CLUSTER_NAME;
+
+	if (!cluster_id)
+		cluster_id = generate_cluster_id(cluster_name);
+
+	if (!nodename_env) {
+		int error;
+		struct utsname utsname;
+
+		error = uname(&utsname);
+		if (error) {
+			log_printf(LOG_ERR, "cannot get node name, uname failed");
+			write_cman_pipe("Can't determine local node name");
+			return -ENOENT;
+		}
+
+		nodename_env = (char *)&utsname.nodename;
+	}
+	strcpy(nodename, nodename_env);
+	num_nodenames = 1;
+
+	if (!mcast_name) {
+		mcast_name = default_mcast(nodename, cluster_id);
+		log_printf(LOG_INFO, "Using default multicast address of %s\n", mcast_name);
+	}
+
+	/* This will increase as nodes join the cluster */
+	if (!expected_votes)
+		expected_votes = 1;
+	if (!votes)
+		votes = 1;
+
+	if (!portnum)
+		portnum = DEFAULT_PORT;
+
+	/* Invent a node ID */
+	if (!nodeid) {
+		struct addrinfo *ainfo;
+		struct addrinfo ahints;
+		int ret;
+
+		memset(&ahints, 0, sizeof(ahints));
+		ret = getaddrinfo(nodename, NULL, &ahints, &ainfo);
+		if (ret) {
+			log_printf(LOG_ERR, "Can't determine address family of nodename %s\n", nodename);
+			write_cman_pipe("Can't determine address family of nodename");
+			return -EINVAL;
+		}
+
+		if (ainfo->ai_family == AF_INET) {
+			struct sockaddr_in *addr = (struct sockaddr_in *)ainfo->ai_addr;
+			memcpy(&nodeid, &addr->sin_addr, sizeof(int));
+		}
+		if (ainfo->ai_family == AF_INET6) {
+			struct sockaddr_in6 *addr = (struct sockaddr_in6 *)ainfo->ai_addr;
+			memcpy(&nodeid, &addr->sin6_addr.in6_u.u6_addr32[3], sizeof(int));
+		}
+		log_printf(LOG_INFO, "Our Node ID is %d\n", nodeid);
+		freeaddrinfo(ainfo);
+	}
+
+	/* Write a local <clusternode> entry to keep the rest of the code happy */
+	objdb->object_create(OBJECT_PARENT_HANDLE, &object_handle,
+			     "clusternodes", strlen("clusternodes"));
+	objdb->object_create(object_handle, &object_handle,
+			     "clusternode", strlen("clusternode"));
+	objdb->object_key_create(object_handle, "name", strlen("name"),
+				 nodename, strlen(nodename)+1);
+
+	sprintf(tmp, "%d", votes);
+	objdb->object_key_create(object_handle, "votes", strlen("votes"),
+				 tmp, strlen(tmp)+1);
+
+	sprintf(tmp, "%d", nodeid);
+	objdb->object_key_create(object_handle, "nodeid", strlen("nodeid"),
+				 tmp, strlen(tmp)+1);
+
+	/* Write the default cluster name & ID in here too */
+	objdb->object_key_create(OBJECT_PARENT_HANDLE, "name", strlen("name"),
+				 cluster_name, strlen(cluster_name)+1);
+
+
+        if (objdb->object_find(OBJECT_PARENT_HANDLE,
+			       "cman", strlen("cman"), &object_handle)) {
+
+                objdb->object_create(OBJECT_PARENT_HANDLE, &object_handle,
+                                            "cman", strlen("cman"));
+        }
+
+	objdb->object_find_reset(OBJECT_PARENT_HANDLE);
+	if (objdb->object_find(OBJECT_PARENT_HANDLE,
+			       "cman", strlen("cman"),
+			       &object_handle) == 0) {
+
+		sprintf(tmp, "%d", cluster_id);
+		objdb->object_key_create(object_handle, "cluster_id", strlen("cluster_id"),
+					 tmp, strlen(tmp)+1);
+
+		sprintf(tmp, "%d", expected_votes);
+		objdb->object_key_create(object_handle, "expected_votes", strlen("expected_votes"),
+					 tmp, strlen(tmp)+1);
+	}
+	return 0;
+}
+
+static int get_cman_globals(struct objdb_iface_ver0 *objdb)
+{
+	unsigned int object_handle;
+
+	objdb_get_string(objdb, OBJECT_PARENT_HANDLE, "name", &cluster_name);
+
+	/* Get the <cman> bits that override <totem> bits */
+	objdb->object_find_reset(OBJECT_PARENT_HANDLE);
+	if (objdb->object_find(OBJECT_PARENT_HANDLE,
+			       "cman", strlen("cman"),
+			       &object_handle) == 0) {
+		if (!portnum)
+			objdb_get_int(objdb, object_handle, "port", &portnum);
+
+		if (!key_filename)
+			objdb_get_string(objdb, object_handle, "keyfile", &key_filename);
+
+		if (!cluster_id)
+			objdb_get_int(objdb, object_handle, "cluster_id", &cluster_id);
+
+		if (!cluster_id)
+			cluster_id = generate_cluster_id(cluster_name);
+	}
+	return 0;
+}
+
+static int cmanpre_readconfig(struct objdb_iface_ver0 *objdb, char **error_string)
+{
+	int ret = 0;
+
+	if (getenv("CMAN_PIPE"))
+                startup_pipe = atoi(getenv("CMAN_PIPE"));
+
+	/* Initialise early logging */
+	if (getenv("CMAN_DEBUGLOG"))
+		debug_mask = atoi(getenv("CMAN_DEBUGLOG"));
+
+	set_debuglog(debug_mask);
+
+	/* We need to set this up to internal defaults too early */
+	openlog("openais", LOG_CONS|LOG_PID, LOG_LOCAL4);
+
+	/* Enable stderr logging if requested by cman_tool */
+	if (debug_mask) {
+		logsys_config_subsys_set("CMAN", LOGSYS_TAG_LOG, LOG_DEBUG);
+	}
+
+	get_env_overrides();
+	if (getenv("CMAN_NOCCS"))
+		ret = set_noccs_defaults(objdb);
+	else
+		get_cman_globals(objdb);
+
+	if (!ret) {
+		ret = get_nodename(objdb);
+		add_cman_overrides(objdb);
+	}
+	if (!ret)
+		sprintf (error_reason, "%s", "Successfully parsed cman config\n");
+	else
+		sprintf (error_reason, "%s", "Error parsing cman config\n");
+        *error_string = error_reason;
+
+	return ret;
+}
+
+/* Write an error message down the CMAN startup pipe so
+   that cman_tool can display it */
+void write_cman_pipe(char *message)
+{
+	if (startup_pipe)
+		write(startup_pipe, message, strlen(message)+1);
+}
diff -urN --exclude='*CVS*' cman/daemon/cnxman-private.h ../gittest/cman3-cvs/cman/daemon/cnxman-private.h
--- cman/daemon/cnxman-private.h	2007-10-01 09:42:15.000000000 +0100
+++ ../gittest/cman3-cvs/cman/daemon/cnxman-private.h	2008-01-03 13:09:20.000000000 +0000
@@ -2,7 +2,7 @@
 *******************************************************************************
 **
 **  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
-**  Copyright (C) 2004 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2004-2008 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
@@ -21,17 +21,9 @@
 #define CNXMAN_MINOR_VERSION 1
 #define CNXMAN_PATCH_VERSION 0
 
-/* How we announce ourself in console events */
+/* How we announce ourself in syslog */
 #define CMAN_NAME "CMAN"
 
-/* This is now just a convenient way to pass around
-   node/port pairs */
-struct sockaddr_cl {
-	unsigned char scl_port;
-	int           scl_nodeid;
-};
-
-
 struct cman_timer
 {
 	struct list list;
@@ -203,6 +195,4 @@
 #define CLUSTER_KILL_CMANTOOL   2
 #define CLUSTER_KILL_REJOIN     3
 
-#define MAX_ADDR_PRINTED_LEN (address_length*3 + 1)
-
 #endif
diff -urN --exclude='*CVS*' cman/daemon/cnxman-socket.h ../gittest/cman3-cvs/cman/daemon/cnxman-socket.h
--- cman/daemon/cnxman-socket.h	2007-12-05 14:11:16.000000000 +0000
+++ ../gittest/cman3-cvs/cman/daemon/cnxman-socket.h	2008-01-03 13:09:27.000000000 +0000
@@ -2,7 +2,7 @@
 *******************************************************************************
 **
 **  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
-**  Copyright (C) 2004-2007 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2004-2008 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
diff -urN --exclude='*CVS*' cman/daemon/commands.c ../gittest/cman3-cvs/cman/daemon/commands.c
--- cman/daemon/commands.c	2008-01-03 15:25:34.000000000 +0000
+++ ../gittest/cman3-cvs/cman/daemon/commands.c	2008-01-03 13:09:34.000000000 +0000
@@ -2,7 +2,7 @@
 *******************************************************************************
 **
 **  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
-**  Copyright (C) 2004-2007 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2004-2008 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
@@ -30,6 +30,7 @@
 #include <netinet/in.h>
 #include <sys/errno.h>
 
+#include <openais/service/objdb.h>
 #include <openais/service/swab.h>
 #include <openais/totem/totemip.h>
 #include <openais/totem/totempg.h>
@@ -43,7 +44,7 @@
 #include "daemon.h"
 #include "barrier.h"
 #include "logging.h"
-#include "cmanccs.h"
+#include "cmanconfig.h"
 #include "commands.h"
 #include "ais.h"
 
@@ -77,6 +78,7 @@
 static int ais_running;
 static time_t join_time;
 static openais_timer_handle quorum_device_timer;
+static struct objdb_iface_ver0 *global_objdb;
 
 /* If CCS gets out of sync, we poll it until it isn't */
 static openais_timer_handle ccsd_timer;
@@ -386,7 +388,9 @@
 	return 0;
 }
 
-int cman_join_cluster(char *name, unsigned short cl_id, int two_node_flag, int expected_votes)
+int cman_join_cluster(struct objdb_iface_ver0 *objdb,
+		      char *name, unsigned short cl_id,
+		      int two_node_flag, int votes, int expected_votes)
 {
 	if (ais_running)
 		return -EALREADY;
@@ -397,14 +401,12 @@
 	cluster_id = cl_id;
 	strncpy(cluster_name, name, MAX_CLUSTER_NAME_LEN);
 	two_node = two_node_flag;
+	global_objdb = objdb;
 
 	quit_threads = 0;
 	ais_running = 1;
 
-	if (read_ccs_nodes(&config_version, 1)) {
-		log_printf(LOG_ERR, "Can't initialise list of nodes from CCS\n");
-		return -EINVAL;
-	}
+	// TODO get config_version ??
 
 	/* Make sure we have a node name */
 	if (nodename[0] == '\0') {
@@ -414,7 +416,7 @@
 	}
 
 	time(&join_time);
-	us = add_new_node(nodename, wanted_nodeid, 1, expected_votes,
+	us = add_new_node(nodename, wanted_nodeid, votes, expected_votes,
 			  NODESTATE_DEAD);
 	set_port_bit(us, 0);
 	us->us = 1;
@@ -449,10 +451,15 @@
 {
 	char *outbuf = *retbuf + offset;
 	struct cl_extra_info *einfo = (struct cl_extra_info *)outbuf;
+	struct totem_ip_address node_ifs[MAX_INTERFACES];
 	int total_votes = 0;
 	int max_expected = 0;
 	int addrlen;
 	int uncounted = 0;
+	unsigned int num_interfaces;
+	unsigned int totem_object_handle;
+	unsigned int object_handle;
+	char **status;
 	struct cluster_node *node;
 	struct sockaddr_storage *ss;
 	char *ptr;
@@ -461,6 +468,8 @@
 	if (!we_are_a_cluster_member)
 		return -ENOENT;
 
+	totempg_ifaces_get(us->node_id, node_ifs, &status, &num_interfaces);
+
 	list_iterate_items(node, &cluster_members_list) {
 		if (node->state == NODESTATE_MEMBER) {
 			total_votes += node->votes;
@@ -474,9 +483,9 @@
 
         /* Enough room for addresses ? */
 	if (retsize < (sizeof(struct cl_extra_info) +
-		       sizeof(struct sockaddr_storage) * (num_interfaces*2))) {
+		       sizeof(struct sockaddr_storage) * (MAX_INTERFACES*2))) {
 
-		*retbuf = malloc(sizeof(struct cl_extra_info) + sizeof(struct sockaddr_storage) * (num_interfaces*2));
+		*retbuf = malloc(sizeof(struct cl_extra_info) + sizeof(struct sockaddr_storage) * (MAX_INTERFACES*2));
 		outbuf = *retbuf + offset;
 		einfo = (struct cl_extra_info *)outbuf;
 
@@ -504,15 +513,30 @@
 		einfo->flags |= CMAN_EXTRA_FLAG_DIRTY;
 
 	ptr = einfo->addresses;
-	for (i=0; i<num_interfaces; i++) {
-		ss = (struct sockaddr_storage *)ptr;
-		totemip_totemip_to_sockaddr_convert(&mcast_addr[i], 0, ss, &addrlen);
-		ptr += sizeof(struct sockaddr_storage);
+
+	global_objdb->object_find_reset(OBJECT_PARENT_HANDLE);
+	if (global_objdb->object_find(OBJECT_PARENT_HANDLE,
+				      "totem", strlen("totem"),
+				      &totem_object_handle) == 0) {
+
+		while (global_objdb->object_find(totem_object_handle,
+						 "interface", strlen("interface"),
+						 &object_handle) == 0) {
+
+			char *mcast;
+			struct totem_ip_address totemip;
+
+			objdb_get_string(global_objdb, object_handle, "mcastaddr", &mcast);
+			ss = (struct sockaddr_storage *)ptr;
+			totemip_parse(&totemip, mcast, 0);
+			totemip_totemip_to_sockaddr_convert(&totemip, 0, ss, &addrlen);
+			ptr += sizeof(struct sockaddr_storage);
+		}
 	}
 
 	for (i=0; i<num_interfaces; i++) {
 		ss = (struct sockaddr_storage *)ptr;
-		totemip_totemip_to_sockaddr_convert(&ifaddrs[i], 0, ss, &addrlen);
+		totemip_totemip_to_sockaddr_convert(&node_ifs[i], 0, ss, &addrlen);
 		ptr += sizeof(struct sockaddr_storage);
 	}
 
@@ -1044,7 +1068,7 @@
 	int ccs_err;
 
 	log_printf(LOG_DEBUG, "Polling ccsd for updated information\n");
-	ccs_err = read_ccs_nodes(&config_version, 0);
+	ccs_err = read_cman_nodes(global_objdb, &config_version, 0);
 	if (ccs_err || config_version < wanted_config_version) {
 		log_printf(LOG_ERR, "Can't read CCS to get updated config version %d. Activity suspended on this node\n",
 				wanted_config_version);
@@ -1200,7 +1224,7 @@
 						    &addrs->addrs[i].addrlen);
 	}
 	*retlen = sizeof(struct cl_get_node_addrs) +
-		num_interfaces * sizeof(struct cl_node_addrs);
+		addrs->numaddrs * sizeof(struct cl_node_addrs);
 
 	return 0;
 }
@@ -1526,7 +1550,7 @@
 	if (msg->config_version > config_version) {
 		int ccs_err;
 
-		ccs_err = read_ccs_nodes(&config_version, 0);
+		ccs_err = read_cman_nodes(global_objdb, &config_version, 0);
 		if (ccs_err || config_version < msg->config_version) {
 			config_error = 1;
 			log_printf(LOG_ERR, "Can't read CCS to get updated config version %d. Activity suspended on this node\n",
@@ -1685,7 +1709,7 @@
 		break;
 
 	case RECONFIG_PARAM_CONFIG_VERSION:
-		if (read_ccs_nodes(&config_version, 0)) {
+		if (read_cman_nodes(global_objdb, &config_version, 0)) {
 			log_printf(LOG_ERR, "Can't read CCS to get updated config version %d. Activity suspended on this node\n",
 				msg->value);
 
@@ -2031,7 +2055,6 @@
 	switch (node->state) {
 	case NODESTATE_MEMBER:
 		node->state = NODESTATE_DEAD;
-		memset(&node->port_bits, 0, sizeof(node->port_bits));
 		cluster_members--;
 		recalculate_quorum(0, 0);
 		break;
diff -urN --exclude='*CVS*' cman/daemon/commands.h ../gittest/cman3-cvs/cman/daemon/commands.h
--- cman/daemon/commands.h	2006-08-17 14:22:39.000000000 +0100
+++ ../gittest/cman3-cvs/cman/daemon/commands.h	2008-01-03 13:09:44.000000000 +0000
@@ -1,7 +1,7 @@
 /******************************************************************************
 *******************************************************************************
 **
-**  Copyright (C) 2005 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2005-2008 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
@@ -10,6 +10,7 @@
 *******************************************************************************
 ******************************************************************************/
 
+#include <openais/service/objdb.h>
 struct cluster_node;
 struct connection;
 extern void process_cnxman_message(char *data, int len, char *addr, int addrlen,
@@ -39,7 +40,8 @@
 /* Startup stuff called from cmanccs: */
 extern int cman_set_nodename(char *name);
 extern int cman_set_nodeid(int nodeid);
-extern int cman_join_cluster(char *name, unsigned short cluster_id, int two_node,
-			     int expected_votes);
+extern int cman_join_cluster(struct objdb_iface_ver0 *objdb,
+			     char *name, unsigned short cluster_id, int two_node,
+			     int votes, int expected_votes);
 
 extern int cluster_members;
diff -urN --exclude='*CVS*' cman/daemon/config.c ../gittest/cman3-cvs/cman/daemon/config.c
--- cman/daemon/config.c	2008-01-02 16:32:00.000000000 +0000
+++ ../gittest/cman3-cvs/cman/daemon/config.c	2008-01-03 14:32:12.000000000 +0000
@@ -1,8 +1,7 @@
 /******************************************************************************
 *******************************************************************************
 **
-**  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
-**  Copyright (C) 2004-2005 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2007-2008 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
@@ -16,14 +15,67 @@
 #include <string.h>
 #include <netinet/in.h>
 
+/* openais headers */
 #include <openais/service/objdb.h>
 #include "list.h"
 #include "cnxman-socket.h"
 #include "cnxman-private.h"
+#include <openais/service/swab.h>
+#include <openais/totem/totemip.h>
+#include <openais/totem/totempg.h>
+#include <openais/totem/aispoll.h>
+#include <openais/service/service.h>
+#include <openais/service/config.h>
+#include <openais/lcr/lcr_comp.h>
+#include <openais/service/swab.h>
+#include <openais/service/logsys.h>
+
 #include "ccs.h"
 #include "logging.h"
 
-LOGSYS_DECLARE_SUBSYS (CMAN_NAME, LOG_INFO);
+#define CONFIG_VERSION_PATH	"/cluster/@config_version"
+#define CONFIG_NAME_PATH	"/cluster/@name"
+
+LOGSYS_DECLARE_SUBSYS ("CCS", LOG_INFO);
+
+static unsigned int debug_mask;
+static int ccs_readconfig(struct objdb_iface_ver0 *objdb, char **error_string);
+static int init_config(struct objdb_iface_ver0 *objdb, char *error_string);
+static char error_reason[1024];
+
+/*
+ * Exports the interface for the service
+ */
+
+static struct config_iface_ver0 ccsconfig_iface_ver0 = {
+	.config_readconfig        = ccs_readconfig
+};
+
+static struct lcr_iface ifaces_ver0[2] = {
+	{
+		.name		       	= "ccsconfig",
+		.version	       	= 0,
+		.versions_replace      	= 0,
+		.versions_replace_count	= 0,
+		.dependencies	       	= 0,
+		.dependency_count      	= 0,
+		.constructor	       	= NULL,
+		.destructor	       	= NULL,
+		.interfaces	       	= NULL,
+	}
+};
+
+static struct lcr_comp ccs_comp_ver0 = {
+	.iface_count				= 1,
+	.ifaces					= ifaces_ver0,
+};
+
+
+
+__attribute__ ((constructor)) static void ccs_comp_register(void) {
+	lcr_interfaces_set(&ifaces_ver0[0], &ccsconfig_iface_ver0);
+	lcr_component_register(&ccs_comp_ver0);
+}
 
 static int read_config_for(int ccs_fd, struct objdb_iface_ver0 *objdb, unsigned int parent,
 			   char *object, char *key, int always_create)
@@ -59,7 +111,7 @@
 		if (equal)
 		{
 			*equal = 0;
-			P_DAEMON("CCS: got config item %s: '%s' = '%s'\n", object, str, equal+1);
+			fprintf(stderr, "CCS: got config item %s: '%s' = '%s'\n", object, str, equal+1);
 			objdb->object_key_create(object_handle, str, strlen(str),
 						 equal+1, strlen(equal+1)+1);
 			gotcount++;
@@ -125,13 +177,51 @@
 	return gotcount;
 }
 
-void init_config(struct objdb_iface_ver0 *objdb)
+static int ccs_readconfig(struct objdb_iface_ver0 *objdb, char **error_string)
+{
+	int ret;
+
+	/* Initialise early logging */
+	if (getenv("CCS_DEBUGLOG"))
+		debug_mask = atoi(getenv("CCS_DEBUGLOG"));
+
+	set_debuglog(debug_mask);
+
+	/* We need to set this up to internal defaults too early */
+	openlog("openais", LOG_CONS|LOG_PID, LOG_LOCAL4);
+
+	/* Enable stderr logging if requested by cman_tool */
+	if (debug_mask) {
+		logsys_config_subsys_set("CCS", LOGSYS_TAG_LOG, LOG_DEBUG);
+	}
+
+	/* Read low-level totem/aisexec etc config from CCS */
+	if ( !(ret = init_config(objdb, error_reason)) )
+	    sprintf (error_reason, "%s", "Successfully read config from CCS\n");
+
+        *error_string = error_reason;
+
+	return ret;
+}
+
+
+static int init_config(struct objdb_iface_ver0 *objdb, char *error_string)
 {
 	int cd;
+	char *cname = NULL;
+	char *str;
+
+	/* Connect to ccsd */
+	if (getenv("CCS_CLUSTER_NAME")) {
+		cname = getenv("CCS_CLUSTER_NAME");
+		log_printf(LOG_INFO, "Using override cluster name %s\n", cname);
+	}
 
-	cd = ccs_force_connect(NULL, 0);
-	if (cd < 0)
-		return;
+	cd = ccs_force_connect(cname, 0);
+	if (cd < 0) {
+		strcpy(error_string, "Error connecting to CCS to get configuration. Check ccsd is running");
+		return -1;
+	}
 
 	/* These first few are just versions of openais.conf */
 	read_config_for(cd, objdb, OBJECT_PARENT_HANDLE, "totem", "totem", 1);
@@ -143,5 +233,24 @@
 	/* This is stuff specific to us, eg quorum device timeout */
 	read_config_for(cd, objdb, OBJECT_PARENT_HANDLE, "cman", "cman", 1);
 
+	/* Nodes information */
+	read_config_for(cd, objdb, OBJECT_PARENT_HANDLE, "clusternodes", "clusternodes", 1);
+
+        /* Also get cluster name and config version number */
+	if (!ccs_get(cd, CONFIG_VERSION_PATH, &str)) {
+		objdb->object_key_create(OBJECT_PARENT_HANDLE,
+					 "config_version", strlen("config_version"),
+					 str, strlen(str)+1);
+		free(str);
+	}
+
+	if (!ccs_get(cd, CONFIG_NAME_PATH, &str)) {
+		objdb->object_key_create(OBJECT_PARENT_HANDLE,
+					 "name", strlen("name"),
+					 str, strlen(str)+1);
+		free(str);
+	}
 	ccs_disconnect(cd);
+	return 0;
 }
+
diff -urN --exclude='*CVS*' cman/daemon/daemon.c ../gittest/cman3-cvs/cman/daemon/daemon.c
--- cman/daemon/daemon.c	2008-01-02 16:28:59.000000000 +0000
+++ ../gittest/cman3-cvs/cman/daemon/daemon.c	2008-01-03 13:10:00.000000000 +0000
@@ -1,7 +1,7 @@
 /******************************************************************************
 *******************************************************************************
 **
-**  Copyright (C) 2005-2006 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2005-2008 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
@@ -41,6 +41,7 @@
 #include "commands.h"
 #include "barrier.h"
 #include "ais.h"
+#include "cman.h"
 
 LOGSYS_DECLARE_SUBSYS (CMAN_NAME, LOG_INFO);
 
diff -urN --exclude='*CVS*' cman/daemon/daemon.h ../gittest/cman3-cvs/cman/daemon/daemon.h
--- cman/daemon/daemon.h	2007-10-01 09:42:15.000000000 +0100
+++ ../gittest/cman3-cvs/cman/daemon/daemon.h	2008-01-03 13:10:10.000000000 +0000
@@ -1,7 +1,7 @@
 /******************************************************************************
 *******************************************************************************
 **
-**  Copyright (C) 2005 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2005-2008 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
diff -urN --exclude='*CVS*' cman/daemon/logging.c ../gittest/cman3-cvs/cman/daemon/logging.c
--- cman/daemon/logging.c	2008-01-02 16:32:50.000000000 +0000
+++ ../gittest/cman3-cvs/cman/daemon/logging.c	2008-01-03 13:10:21.000000000 +0000
@@ -1,7 +1,7 @@
 /******************************************************************************
 *******************************************************************************
 **
-**  Copyright (C) 2005-2007 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2005-2008 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
diff -urN --exclude='*CVS*' cman/daemon/logging.h ../gittest/cman3-cvs/cman/daemon/logging.h
--- cman/daemon/logging.h	2007-10-03 11:06:32.000000000 +0100
+++ ../gittest/cman3-cvs/cman/daemon/logging.h	2008-01-03 13:10:26.000000000 +0000
@@ -1,7 +1,7 @@
 /******************************************************************************
 *******************************************************************************
 **
-**  Copyright (C) 2005-2007 Red Hat, Inc.  All rights reserved.
+**  Copyright (C) 2005-2008 Red Hat, Inc.  All rights reserved.
 **
 **  This copyrighted material is made available to anyone wishing to use,
 **  modify, copy, or redistribute it subject to the terms and conditions
diff -urN --exclude='*CVS*' cman/daemon/Makefile ../gittest/cman3-cvs/cman/daemon/Makefile
--- cman/daemon/Makefile	2008-01-02 07:45:38.000000000 +0000
+++ ../gittest/cman3-cvs/cman/daemon/Makefile	2008-01-03 13:54:18.000000000 +0000
@@ -10,11 +10,13 @@
 ###############################################################################
 ###############################################################################
 
-TARGET= service_cman.lcrso
+TARGET1= service_cman.lcrso
+TARGET2= config_ccs.lcrso
+TARGET3= config_cmanpre.lcrso
 
-LCRSOT=$(TARGET)
+LCRSOT=$(TARGET1) $(TARGET2) $(TARGET3)
 
-all: depends ${TARGET}
+all: depends ${TARGET1} ${TARGET2} ${TARGET3}
 
 include ../../make/defines.mk
 include $(OBJDIR)/make/cobj.mk
@@ -22,23 +24,31 @@
 include $(OBJDIR)/make/install.mk
 include $(OBJDIR)/make/uninstall.mk
 
-CFLAGS += -DOPENAIS_EXTERNAL_SERVICE
 CFLAGS += -fPIC
 CFLAGS += -I${ccsincdir} -I${openaisincdir}
 CFLAGS += -I${incdir}
 
 LDFLAGS += -L${ccslibdir} -lccs 
 
-OBJS=	daemon.o \
-	config.o \
+OBJS1=	daemon.o \
 	logging.o \
 	ais.o \
 	commands.o \
 	barrier.o \
-	cmanccs.o
+	cmanconfig.o 
 
+OBJS2=	config.o logging.o
 
-${TARGET}: ${OBJS}
+OBJS3=	cman-preconfig.o \
+	logging.o
+
+${TARGET1}: ${OBJS1}
+	$(CC) -shared -Wl,-soname,$@ -o $@ $^ $(LDFLAGS)
+
+${TARGET2}: ${OBJS2}
+	$(CC) -shared -Wl,-soname,$@ -o $@ $^ $(LDFLAGS)
+
+${TARGET3}: ${OBJS3}
 	$(CC) -shared -Wl,-soname,$@ -o $@ $^ $(LDFLAGS)
 
 depends:
diff -urN --exclude='*CVS*' cman/daemon/nodelist.h ../gittest/cman3-cvs/cman/daemon/nodelist.h
--- cman/daemon/nodelist.h	1970-01-01 01:00:00.000000000 +0100
+++ ../gittest/cman3-cvs/cman/daemon/nodelist.h	2008-01-03 13:11:16.000000000 +0000
@@ -0,0 +1,69 @@
+/******************************************************************************
+ *******************************************************************************
+ ***
+ ***  Copyright (C) 2005-2008 Red Hat, Inc.  All rights reserved.
+ ***
+ ***  This copyrighted material is made available to anyone wishing to use,
+ ***  modify, copy, or redistribute it subject to the terms and conditions
+ ***  of the GNU General Public License v.2.
+ ***
+ *******************************************************************************
+ ******************************************************************************/
+
+
+/* Helper functions for navigating the nodes list */
+static unsigned int nodeslist_init(struct objdb_iface_ver0 *objdb, unsigned int *parent_handle)
+{
+	unsigned int object_handle;
+
+	objdb->object_find_reset(OBJECT_PARENT_HANDLE);
+	if (objdb->object_find(OBJECT_PARENT_HANDLE,
+			       "clusternodes", strlen("clusternodes"),
+			       &object_handle) == 0)
+	{
+		unsigned int nodes_handle;
+		objdb->object_find_reset(object_handle);
+
+		if (objdb->object_find(object_handle,
+				       "clusternode", strlen("clusternode"),
+				       &nodes_handle) == 0)
+		{
+			*parent_handle = object_handle;
+			return nodes_handle;
+		}
+	}
+	return 0;
+}
+
+static unsigned int nodeslist_next(struct objdb_iface_ver0 *objdb, unsigned int parent_handle)
+{
+	unsigned int nodes_handle;
+
+	if (objdb->object_find(parent_handle,
+			       "clusternode", strlen("clusternode"),
+			       &nodes_handle) == 0)
+		return nodes_handle;
+	else
+		return 0;
+}
+
+static unsigned int nodelist_byname(struct objdb_iface_ver0 *objdb, char *name)
+{
+	char *nodename;
+	unsigned int nodes_handle;
+	unsigned int parent_handle;
+
+	nodes_handle = nodeslist_init(objdb, &parent_handle);
+	while (nodes_handle) {
+		if (objdb_get_string(objdb, nodes_handle, "name", &nodename)) {
+			log_printf(LOG_ERR, "Cannot get node name");
+			break;
+		}
+		if (strcmp(nodename, name) == 0)
+			return nodes_handle;
+
+		nodes_handle = nodeslist_next(objdb, parent_handle);
+	}
+
+	return 0;
+}

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