[Cluster-devel] cluster/ccs ccs_tool/ccs_tool.c ccs_tool/editc ...

pcaulfield at sourceware.org pcaulfield at sourceware.org
Wed Feb 14 10:15:48 UTC 2007


CVSROOT:	/cvs/cluster
Module name:	cluster
Branch: 	RHEL4
Changes by:	pcaulfield at sourceware.org	2007-02-14 10:15:47

Modified files:
	ccs/ccs_tool   : ccs_tool.c editconf.c editconf.h 
	ccs/man        : ccs_tool.8 

Log message:
	Add the 'addnodeids' feature to ccs_tool so that people can fix cluster.conf
	before upgrading to RHEL5.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/ccs/ccs_tool/ccs_tool.c.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.1.2.2&r2=1.1.2.3
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/ccs/ccs_tool/editconf.c.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.8.2.2&r2=1.8.2.3
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/ccs/ccs_tool/editconf.h.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.1.4.1&r2=1.1.4.2
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/ccs/man/ccs_tool.8.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.1.2.3&r2=1.1.2.4

--- cluster/ccs/ccs_tool/ccs_tool.c	2006/02/02 23:24:42	1.1.2.2
+++ cluster/ccs/ccs_tool/ccs_tool.c	2007/02/14 10:15:46	1.1.2.3
@@ -82,6 +82,10 @@
 	    create_skeleton(argc-1, argv+1);
 	    exit(EXIT_FAILURE);
     }
+    else if(!strcmp(argv[optind], "addnodeids")){
+	    add_nodeids(argc-1, argv+1);
+	    exit(EXIT_FAILURE);
+    }
 
     else {
       fprintf(stderr, "Unknown command, %s.\n"
@@ -116,5 +120,6 @@
 	  "  addfence <fencedev> Add a new fence device\n"
 	  "  delfence <fencedev> Delete a fence device\n"
 	  "  create              Create a skeleton config file\n"
+	  "  addnodeids          Assign node ID numbers to all nodes\n"
 	  "\n");
 }
--- cluster/ccs/ccs_tool/editconf.c	2006/05/24 13:54:57	1.8.2.2
+++ cluster/ccs/ccs_tool/editconf.c	2007/02/14 10:15:46	1.8.2.3
@@ -16,11 +16,16 @@
 #include <sys/stat.h>
 #include <getopt.h>
 #include <errno.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
 
 #include <libxml/tree.h>
 
 #include "update.h"
 
+#define MAX_NODES 256
 #define DEFAULT_CONFIG_FILE "/etc/cluster/cluster.conf"
 char *prog_name = "ccs_tool";
 
@@ -128,6 +133,23 @@
 	exit(0);
 }
 
+static void addnodeid_usage(const char *name)
+{
+	fprintf(stderr, "Add node IDs to all nodes in the config file that don't have them.\n");
+	fprintf(stderr, "Nodes with IDs will not be afftected, so you can run this as many times\n");
+	fprintf(stderr, "as you like without doing any harm.\n");
+	fprintf(stderr, "It will optionally add a multicast address to the cluster config too.\n");
+	fprintf(stderr, "\n");
+	fprintf(stderr, "Usage: %s %s [options] <name>\n", prog_name, name);
+	fprintf(stderr, " -n --nodeid        Nodeid to start with (default 1)\n");
+	fprintf(stderr, " -m --multicast     Set or change the multicast address\n");
+	fprintf(stderr, " -v --verbose       Print nodeids that are assigned\n");
+	config_usage(1);
+	help_usage();
+
+	exit(0);
+}
+
 static void addnode_usage(const char *name)
 {
 	fprintf(stderr, "Usage: %s %s [options] <nodename> [<fencearg>=<value>]...\n", prog_name, name);
@@ -152,6 +174,26 @@
 	exit(0);
 }
 
+/* Is it really ?
+ * Actually, we don't check that this is a valid multicast address(!),
+ * merely that it is a valid IP[46] address.
+ */
+static int valid_mcast_addr(char *mcast)
+{
+        struct addrinfo *ainfo;
+        struct addrinfo ahints;
+	int ret;
+
+        memset(&ahints, 0, sizeof(ahints));
+
+        ret = getaddrinfo(mcast, NULL, &ahints, &ainfo);
+	if (ret) {
+		freeaddrinfo(ainfo);
+		return 0;
+	}
+	return 1;
+}
+
 static void save_file(xmlDoc *doc, struct option_info *ninfo)
 {
 	char tmpfile[strlen(ninfo->outputfile)+5];
@@ -601,6 +643,16 @@
       { NULL, 0, NULL, 0 },
 };
 
+struct option addnodeid_options[] =
+{
+      { "outputfile", required_argument, NULL, 'o'},
+      { "configfile", required_argument, NULL, 'c'},
+      { "multicast", required_argument, NULL, 'm'},
+      { "nodeid", no_argument, NULL, 'n'},
+      { "verbose", no_argument, NULL, 'v'},
+      { NULL, 0, NULL, 0 },
+};
+
 struct option list_options[] =
 {
       { "configfile", required_argument, NULL, 'c'},
@@ -608,6 +660,145 @@
       { NULL, 0, NULL, 0 },
 };
 
+static int next_nodeid(int startid, int *nodeids, int nodecount)
+{
+	int i;
+	int nextid = startid;
+
+retry:
+	for (i=0; i<nodecount; i++)
+	{
+		if (nodeids[i] == nextid)
+		{
+			nextid++;
+			goto retry;
+		}
+	}
+
+	return nextid;
+}
+
+void add_nodeids(int argc, char **argv)
+{
+	struct option_info ninfo;
+	unsigned char *nodenames[MAX_NODES];
+	xmlDoc *doc;
+	xmlNode *root_element;
+	xmlNode *clusternodes;
+	xmlNode *cur_node;
+	int  verbose = 0;
+	int  opt;
+	int  i;
+	int  nodenumbers[MAX_NODES];
+	int  nodeidx;
+	int  totalnodes;
+	int  nextid;
+
+	memset(nodenames, 0, sizeof(nodenames));
+	memset(nodenumbers, 0, sizeof(nodenumbers));
+	memset(&ninfo, 0, sizeof(ninfo));
+	ninfo.nodeid = "1";
+
+	while ( (opt = getopt_long(argc, argv, "n:o:c:m:vh?", addnodeid_options, NULL)) != EOF)
+	{
+		switch(opt)
+		{
+		case 'n':
+			validate_int_arg(opt, optarg);
+			ninfo.nodeid = strdup(optarg);
+			break;
+
+		case 'c':
+			ninfo.configfile = strdup(optarg);
+			break;
+
+		case 'o':
+			ninfo.outputfile = strdup(optarg);
+			break;
+
+		case 'm':
+			if (!valid_mcast_addr(optarg)) {
+				fprintf(stderr, "%s is not a valid multicast address\n", optarg);
+				return;
+			}
+			ninfo.mcast_addr = strdup(optarg);
+			break;
+
+		case 'v':
+			verbose++;
+			break;
+
+		case '?':
+		default:
+			addnodeid_usage(argv[0]);
+		}
+	}
+
+	doc = open_configfile(&ninfo);
+
+	root_element = xmlDocGetRootElement(doc);
+
+	increment_version(root_element);
+
+	/* Get a list of nodes that /do/ have nodeids so we don't generate
+	   any duplicates */
+	nodeidx=0;
+	clusternodes = findnode(root_element, "clusternodes");
+	if (!clusternodes)
+		die("Can't find \"clusternodes\" in %s\n", ninfo.configfile);
+
+
+	for (cur_node = clusternodes->children; cur_node; cur_node = cur_node->next)
+	{
+		if (cur_node->type == XML_ELEMENT_NODE && strcmp((char *)cur_node->name, "clusternode") == 0)
+		{
+			xmlChar *name   = xmlGetProp(cur_node, BAD_CAST "name");
+			xmlChar *nodeid = xmlGetProp(cur_node, BAD_CAST "nodeid");
+			nodenames[nodeidx]  = name;
+			if (nodeid)
+				nodenumbers[nodeidx] = atoi((char*)nodeid);
+			nodeidx++;
+		}
+	}
+	totalnodes = nodeidx;
+
+	/* Loop round nodes adding nodeIDs where they don't exist. */
+	nextid = next_nodeid(atoi(ninfo.nodeid), nodenumbers, totalnodes);
+	for (i=0; i<totalnodes; i++)
+	{
+		if (nodenumbers[i] == 0)
+		{
+			nodenumbers[i] = nextid;
+			nextid = next_nodeid(nextid, nodenumbers, totalnodes);
+			if (verbose)
+				fprintf(stderr, "Node %s now has id %d\n", nodenames[i], nodenumbers[i]);
+		}
+	}
+
+	/* Now write them into the tree */
+	nodeidx = 0;
+	for (cur_node = clusternodes->children; cur_node; cur_node = cur_node->next)
+	{
+		if (cur_node->type == XML_ELEMENT_NODE && strcmp((char *)cur_node->name, "clusternode") == 0)
+		{
+			char tmp[80];
+			xmlChar *name = xmlGetProp(cur_node, BAD_CAST "name");
+
+			assert(strcmp((char*)nodenames[nodeidx], (char*)name) == 0);
+
+			sprintf(tmp, "%d", nodenumbers[nodeidx]);
+			xmlSetProp(cur_node, BAD_CAST "nodeid", BAD_CAST tmp);
+			nodeidx++;
+		}
+	}
+
+
+	/* Write it out */
+	save_file(doc, &ninfo);
+
+	/* Shutdown libxml */
+	xmlCleanupParser();
+}
 
 void add_node(int argc, char **argv)
 {
--- cluster/ccs/ccs_tool/editconf.h	2006/02/02 23:24:42	1.1.4.1
+++ cluster/ccs/ccs_tool/editconf.h	2007/02/14 10:15:46	1.1.4.2
@@ -11,6 +11,7 @@
 ******************************************************************************/
 
 void add_node(int argc, char **argv);
+void add_nodeids(int argc, char **argv);
 void add_fence(int argc, char **argv);
 void del_node(int argc, char **argv);
 void del_fence(int argc, char **argv);
--- cluster/ccs/man/ccs_tool.8	2006/02/03 21:05:32	1.1.2.3
+++ cluster/ccs/man/ccs_tool.8	2007/02/14 10:15:46	1.1.2.4
@@ -187,8 +187,16 @@
 
 \fB-h --help\fP
 Display this help text for \fBccs_tool lsnode\fP.
+
 .TP
+\fBaddnodeids\fP
+Adds node ID numbers to all the nodes in cluster.conf. In RHEL4, node IDs were optional
+and assigned by cman when a node joined the cluster. In RHEL5 they must be pre-assigned
+in cluster.conf. This command will not change any node IDs that are already set in 
+cluster.conf, it will simply add unique node ID numbers to nodes that do not already
+have them.
 
+.TP
 \fBupdate\fP \fI<xml file>\fP
 This command is used to update the config file that ccsd is working with
 while the cluster is operational (i.e. online).  Run this on a single
@@ -205,6 +213,7 @@
 xml format.  \fI<location>\fP is the location of the old archive,
 which can be either a block device archive or a file archive.  The
 converted configuration will be printed to stdout.
+.TP 
 
 .SH SEE ALSO
 ccs(7), ccsd(8), cluster.conf(5)




More information about the Cluster-devel mailing list