All of lore.kernel.org
 help / color / mirror / Atom feed
From: pcaulfield@sourceware.org <pcaulfield@sourceware.org>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] cluster/ccs ccs_tool/ccs_tool.c ccs_tool/editc ...
Date: 14 Feb 2007 10:15:48 -0000	[thread overview]
Message-ID: <20070214101548.26743.qmail@sourceware.org> (raw)

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)



                 reply	other threads:[~2007-02-14 10:15 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20070214101548.26743.qmail@sourceware.org \
    --to=pcaulfield@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.