[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