All of lore.kernel.org
 help / color / mirror / Atom feed
* [Cluster-devel] [PATCH 0/8] ccs_tool enhancement
@ 2010-12-10  9:00 Dmitry Mishin
  2010-12-10  9:00 ` [Cluster-devel] [PATCH 1/8] Add "service" object manipulations Dmitry Mishin
                   ` (8 more replies)
  0 siblings, 9 replies; 13+ messages in thread
From: Dmitry Mishin @ 2010-12-10  9:00 UTC (permalink / raw)
  To: cluster-devel.redhat.com

This patchset enhances ccs_tool allowing to create basic cluster configs
entirely via this tool.

Thanks,
Dmitry.



^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Cluster-devel] [PATCH 1/8] Add "service" object manipulations
  2010-12-10  9:00 [Cluster-devel] [PATCH 0/8] ccs_tool enhancement Dmitry Mishin
@ 2010-12-10  9:00 ` Dmitry Mishin
  2010-12-10  9:00 ` [Cluster-devel] [PATCH 2/8] Unify 'del' functions Dmitry Mishin
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: Dmitry Mishin @ 2010-12-10  9:00 UTC (permalink / raw)
  To: cluster-devel.redhat.com

In order to be useful, cluster needs service defined, which it will take care
of. Patch adds ability to define service using already defined resources (like
fs, script, ip, etc.)

Signed-off-by: Dmitry Mishin <dim@parallels.com>
---
 config/tools/ccs_tool/ccs_tool.c |   15 ++
 config/tools/ccs_tool/editconf.c |  386 +++++++++++++++++++++++++++++++++++++-
 config/tools/ccs_tool/editconf.h |    3 +
 3 files changed, 400 insertions(+), 4 deletions(-)

diff --git a/config/tools/ccs_tool/ccs_tool.c b/config/tools/ccs_tool/ccs_tool.c
index a00f0dc..824da6d 100644
--- a/config/tools/ccs_tool/ccs_tool.c
+++ b/config/tools/ccs_tool/ccs_tool.c
@@ -227,6 +227,14 @@ static int tool_main(int argc, char *argv[])
 	    del_node(argc-1, argv+1);
 	    exit(EXIT_SUCCESS);
     }
+    else if(!strcmp(argv[optind], "addservice")){
+	    add_service(argc-1, argv+1);
+	    exit(EXIT_SUCCESS);
+    }
+    else if(!strcmp(argv[optind], "delservice")){
+	    del_service(argc-1, argv+1);
+	    exit(EXIT_SUCCESS);
+    }
     else if(!strcmp(argv[optind], "addfence")){
 	    add_fence(argc-1, argv+1);
 	    exit(EXIT_SUCCESS);
@@ -239,6 +247,10 @@ static int tool_main(int argc, char *argv[])
 	    list_nodes(argc-1, argv+1);
 	    exit(EXIT_SUCCESS);
     }
+    else if(!strcmp(argv[optind], "lsservice")){
+	    list_services(argc-1, argv+1);
+	    exit(EXIT_SUCCESS);
+    }
     else if(!strcmp(argv[optind], "lsfence")){
 	    list_fences(argc-1, argv+1);
 	    exit(EXIT_SUCCESS);
@@ -281,6 +293,9 @@ static void tool_print_usage(FILE *stream){
 	  "  addnode <node>      Add a node\n"
           "  delnode <node>      Delete a node\n"
           "  lsnode              List nodes\n"
+	  "  addservice <name>   Add a service\n"
+          "  delservice <name>   Delete a service\n"
+          "  lsservice           List services\n"
           "  lsfence             List fence devices\n"
 	  "  addfence <fencedev> Add a new fence device\n"
 	  "  delfence <fencedev> Delete a fence device\n"
diff --git a/config/tools/ccs_tool/editconf.c b/config/tools/ccs_tool/editconf.c
index 5205257..b33f288 100644
--- a/config/tools/ccs_tool/editconf.c
+++ b/config/tools/ccs_tool/editconf.c
@@ -34,7 +34,14 @@ struct option_info
 	const char *votes;
 	const char *nodeid;
 	const char *mcast_addr;
+	const char *ip_addr;
 	const char *fence_type;
+	const char *autostart;
+	const char *exclusive;
+	const char *recovery;
+	const char *fs;
+	const char *script;
+	const char *mountpoint;
 	const char *configfile;
 	const char *outputfile;
 	int  do_delete;
@@ -123,6 +130,15 @@ static void delnode_usage(const char *name)
 	exit(0);
 }
 
+static void delservice_usage(const char *name)
+{
+	fprintf(stderr, "Usage: %s %s [options] <name>\n", prog_name, name);
+	config_usage(1);
+	help_usage();
+
+	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");
@@ -162,6 +178,15 @@ static void addnode_usage(const char *name)
 	exit(0);
 }
 
+static void addservice_usage(const char *name)
+{
+	fprintf(stderr, "Usage: %s %s [options] <servicename>\n", prog_name, name);
+	config_usage(1);
+	help_usage();
+
+	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.
@@ -380,15 +405,17 @@ static xmlNode *find_multicast_addr(xmlNode *clusternodes)
 	return NULL;
 }
 
-static xmlNode *find_node(xmlNode *clusternodes, const char *nodename)
+static xmlNode *do_find_node(xmlNode *root, const char *nodename,
+	const char *elem_name, const char *attrib_name)
 {
 	xmlNode *cur_node;
 
-	for (cur_node = clusternodes->children; cur_node; cur_node = cur_node->next)
+	for (cur_node = root->children; cur_node; cur_node = cur_node->next)
 	{
-		if (cur_node->type == XML_ELEMENT_NODE && strcmp((char *)cur_node->name, "clusternode") == 0)
+		if (cur_node->type == XML_ELEMENT_NODE &&
+			strcmp((char *)cur_node->name, elem_name) == 0)
 		{
-			xmlChar *name = xmlGetProp(cur_node, BAD_CAST "name");
+			xmlChar *name = xmlGetProp(cur_node, BAD_CAST attrib_name);
 			if (strcmp((char *)name, nodename) == 0)
 				return cur_node;
 		}
@@ -396,6 +423,31 @@ static xmlNode *find_node(xmlNode *clusternodes, const char *nodename)
 	return NULL;
 }
 
+static xmlNode *find_node(xmlNode *clusternodes, const char *nodename)
+{
+	return do_find_node(clusternodes, nodename, "clusternode", "name");
+}
+
+static xmlNode *find_service(xmlNode *root, const char *servicename)
+{
+	return do_find_node(root, servicename, "service", "name");
+}
+
+static xmlNode *find_fs_resource(xmlNode *root, const char *name)
+{
+	return do_find_node(root, name, "fs", "name");
+}
+
+static xmlNode *find_script_resource(xmlNode *root, const char *name)
+{
+	return do_find_node(root, name, "script", "name");
+}
+
+static xmlNode *find_ip_resource(xmlNode *root, const char *name)
+{
+	return do_find_node(root, name, "ip", "name");
+}
+
 /* Print name=value pairs for a (n XML) node.
  * "ignore" is a string to ignore if present as a property (probably already printed on the main line)
  */
@@ -517,6 +569,79 @@ static void add_clusternode(xmlNode *root_element, struct option_info *ninfo,
 	xmlAddChild(newfencemethod, newfencedevice);
 }
 
+static void add_clusterservice(xmlNode *root_element, struct option_info *ninfo,
+			    int argc, char **argv, int optindex)
+{
+	xmlNode *rm;
+	xmlNode *rs;
+	xmlNode *newnode;
+
+	xmlNode *newfs = NULL;
+	xmlNode *newfsscript;
+	xmlNode *newfsip;
+
+	rm = findnode(root_element, "rm");
+	if (!rm)
+		die("Can't find \"rm\" in %s\n", ninfo->configfile);
+
+	/* Don't allow duplicate service names */
+	if (find_service(rm, ninfo->name))
+		die("service %s already exists in %s\n", ninfo->name,
+				ninfo->configfile);
+
+	rs = findnode(rm, "resources");
+	if (ninfo->fs && (!rs || !find_fs_resource(rs, ninfo->fs)))
+		die("fs resource %s doesn't exist in %s\n", ninfo->fs,
+				ninfo->configfile);
+	if (ninfo->script && (!rs || !find_script_resource(rs, ninfo->script)))
+		die("script resource %s doesn't exist in %s\n", ninfo->script,
+				ninfo->configfile);
+	if (ninfo->ip_addr && (!rs || !find_ip_resource(rs, ninfo->ip_addr)))
+		die("ip resource %s doesn't exist in %s\n", ninfo->ip_addr,
+				ninfo->configfile);
+
+	/* Add the new service */
+	newnode = xmlNewNode(NULL, BAD_CAST "service");
+	xmlSetProp(newnode, BAD_CAST "name", BAD_CAST ninfo->name);
+	xmlSetProp(newnode, BAD_CAST "autostart", BAD_CAST ninfo->autostart);
+	if (ninfo->exclusive)
+		xmlSetProp(newnode, BAD_CAST "exclusive",
+				BAD_CAST ninfo->exclusive);
+	xmlSetProp(newnode, BAD_CAST "recovery", BAD_CAST ninfo->recovery);
+	xmlAddChild(rm, newnode);
+
+	/* Add the fs reference */
+	if (ninfo->fs)
+	{
+		newfs = xmlNewNode(NULL, BAD_CAST "fs");
+		xmlSetProp(newfs, BAD_CAST "ref", BAD_CAST ninfo->fs);
+		xmlAddChild(newnode, newfs);
+	}
+
+	/* Add the script reference */
+	if (ninfo->script)
+	{
+		newfsscript = xmlNewNode(NULL, BAD_CAST "script");
+		xmlSetProp(newfsscript, BAD_CAST "ref", BAD_CAST ninfo->script);
+		if (newfs)
+			xmlAddChild(newfs, newfsscript);
+		else
+			xmlAddChild(newnode, newfsscript);
+	}
+
+	/* Add the ip reference */
+	if (ninfo->ip_addr)
+	{
+		newfsip = xmlNewNode(NULL, BAD_CAST "ip");
+		xmlSetProp(newfsip, BAD_CAST "ref", BAD_CAST
+				ninfo->ip_addr);
+		if (newfs)
+			xmlAddChild(newfs, newfsip);
+		else
+			xmlAddChild(newnode, newfsip);
+	}
+}
+
 static xmlDoc *open_configfile(struct option_info *ninfo)
 {
 	xmlDoc *doc;
@@ -561,6 +686,28 @@ static void del_clusternode(xmlNode *root_element, struct option_info *ninfo)
 	xmlUnlinkNode(oldnode);
 }
 
+static void del_clusterservice(xmlNode *root_element, struct option_info *ninfo)
+{
+	xmlNode *rm;
+	xmlNode *oldnode;
+
+	rm = findnode(root_element, "rm");
+	if (!rm)
+	{
+		fprintf(stderr, "Can't find \"rm\" in %s\n", ninfo->configfile);
+		exit(1);
+	}
+
+	oldnode = find_service(rm, ninfo->name);
+	if (!oldnode)
+	{
+		fprintf(stderr, "service %s does not exist in %s\n", ninfo->name, ninfo->configfile);
+		exit(1);
+	}
+
+	xmlUnlinkNode(oldnode);
+}
+
 struct option addnode_options[] =
 {
       { "votes", required_argument, NULL, 'v'},
@@ -609,6 +756,29 @@ struct option list_options[] =
       { NULL, 0, NULL, 0 },
 };
 
+struct option addservice_options[] =
+{
+      { "autostart", required_argument, NULL, 'a'},
+      { "exclusive", required_argument, NULL, 'x'},
+      { "recovery", required_argument, NULL, 'r'},
+      { "fs", required_argument, NULL, 'f'},
+      { "script", required_argument, NULL, 's'},
+      { "ip", required_argument, NULL, 'i'},
+      { "outputfile", required_argument, NULL, 'o'},
+      { "configfile", required_argument, NULL, 'c'},
+      { "no_ccs", no_argument, NULL, 'C'},
+      { "force_ccs", no_argument, NULL, 'F'},
+      { NULL, 0, NULL, 0 },
+};
+
+struct option delservice_options[] =
+{
+      { "outputfile", required_argument, NULL, 'o'},
+      { "configfile", required_argument, NULL, 'c'},
+      { "no_ccs", no_argument, NULL, 'C'},
+      { "force_ccs", no_argument, NULL, 'F'},
+      { NULL, 0, NULL, 0 },
+};
 
 static int next_nodeid(int startid, int *nodeids, int nodecount)
 {
@@ -984,6 +1154,214 @@ void list_nodes(int argc, char **argv)
 	}
 }
 
+void add_service(int argc, char **argv)
+{
+	struct option_info ninfo;
+	int opt;
+	xmlDoc *doc;
+	xmlNode *root_element;
+
+	memset(&ninfo, 0, sizeof(ninfo));
+	ninfo.tell_ccsd = 1;
+	ninfo.autostart = "1";
+	ninfo.recovery = "relocate";
+
+	while ( (opt = getopt_long(argc, argv, "a:x:r:f:o:c:s:i:CFh?", addservice_options, NULL)) != EOF)
+	{
+		switch(opt)
+		{
+		case 'a':
+			validate_int_arg(opt, optarg);
+			ninfo.autostart = optarg;
+			break;
+
+		case 'x':
+			validate_int_arg(opt, optarg);
+			ninfo.exclusive = optarg;
+			break;
+
+		case 'r':
+			ninfo.recovery = strdup(optarg);
+			break;
+
+		case 'f':
+			ninfo.fs = strdup(optarg);
+			break;
+
+		case 's':
+			ninfo.script = strdup(optarg);
+			break;
+
+		case 'i':
+			ninfo.ip_addr = strdup(optarg);
+			break;
+
+		case 'c':
+			ninfo.configfile = strdup(optarg);
+			break;
+
+		case 'o':
+			ninfo.outputfile = strdup(optarg);
+			break;
+
+		case 'C':
+			ninfo.tell_ccsd = 0;
+			break;
+
+		case 'F':
+			ninfo.force_ccsd = 1;
+			break;
+
+		case '?':
+		default:
+			addservice_usage(argv[0]);
+		}
+	}
+
+	/* Get service name parameter */
+	if (optind < argc)
+		ninfo.name = strdup(argv[optind]);
+	else
+		addservice_usage(argv[0]);
+
+
+	doc = open_configfile(&ninfo);
+
+	root_element = xmlDocGetRootElement(doc);
+
+	increment_version(root_element);
+
+	add_clusterservice(root_element, &ninfo, argc, argv, optind);
+
+	/* Write it out */
+	save_file(doc, &ninfo);
+	/* Shutdown libxml */
+	xmlCleanupParser();
+
+}
+
+void del_service(int argc, char **argv)
+{
+	struct option_info ninfo;
+	int opt;
+	xmlDoc *doc;
+	xmlNode *root_element;
+
+	memset(&ninfo, 0, sizeof(ninfo));
+	ninfo.tell_ccsd = 1;
+
+	while ( (opt = getopt_long(argc, argv, "o:c:CFh?", delservice_options, NULL)) != EOF)
+	{
+		switch(opt)
+		{
+		case 'c':
+			ninfo.configfile = strdup(optarg);
+			break;
+
+		case 'o':
+			ninfo.outputfile = strdup(optarg);
+			break;
+
+		case 'C':
+			ninfo.tell_ccsd = 0;
+			break;
+
+		case 'F':
+			ninfo.force_ccsd = 1;
+			break;
+
+		case '?':
+		default:
+			delservice_usage(argv[0]);
+		}
+	}
+
+	/* Get service name parameter */
+	if (optind < argc)
+		ninfo.name = strdup(argv[optind]);
+	else
+		delservice_usage(argv[0]);
+
+	doc = open_configfile(&ninfo);
+
+	root_element = xmlDocGetRootElement(doc);
+
+	increment_version(root_element);
+
+	del_clusterservice(root_element, &ninfo);
+
+	/* Write it out */
+	save_file(doc, &ninfo);
+}
+
+void list_services(int argc, char **argv)
+{
+	xmlNode *cur_service;
+	xmlNode *root_element;
+	xmlNode *rm;
+	xmlDocPtr doc;
+	struct option_info ninfo;
+	int opt;
+	int verbose = 0;
+
+	memset(&ninfo, 0, sizeof(ninfo));
+
+	while ( (opt = getopt_long(argc, argv, "c:vh?", list_options, NULL)) != EOF)
+	{
+		switch(opt)
+		{
+		case 'c':
+			ninfo.configfile = strdup(optarg);
+			break;
+		case 'v':
+			verbose++;
+			break;
+		case '?':
+		default:
+			list_usage(argv[0]);
+		}
+	}
+	doc = open_configfile(&ninfo);
+
+	root_element = xmlDocGetRootElement(doc);
+
+
+	printf("\nCluster name: %s, config_version: %s\n\n",
+	       (char *)cluster_name(root_element),
+	       (char *)find_version(root_element));
+
+	rm = findnode(root_element, "rm");
+	if (!rm)
+		die("Can't find \"rm\" in %s\n", ninfo.configfile);
+
+	printf("Name                             Autostart Exclusive Recovery\n");
+	for (cur_service = rm->children; cur_service;
+			cur_service = cur_service->next)
+	{
+		xmlChar *name, *autostart, *exclusive, *recovery;
+
+		if (!cur_service->type == XML_ELEMENT_NODE ||
+			strcmp((char *)cur_service->name, "service") != 0)
+			continue;
+
+		name = xmlGetProp(cur_service, BAD_CAST "name");
+		autostart = xmlGetProp(cur_service, BAD_CAST "autostart");
+		exclusive = xmlGetProp(cur_service, BAD_CAST "exclusive");
+		recovery = xmlGetProp(cur_service, BAD_CAST "recovery");
+
+		if (!autostart)
+			autostart = (unsigned char *)"0";
+		if (!exclusive)
+			exclusive = (unsigned char *)"0";
+		if (!recovery)
+			recovery = (unsigned char *)"-";
+
+		printf("%-32s       %3d       %3d %s\n", name,
+			atoi((char *)autostart), atoi((char *)exclusive),
+			(char *)recovery);
+	}
+}
+
 void create_skeleton(int argc, char **argv)
 {
 	xmlNode *root_element;
diff --git a/config/tools/ccs_tool/editconf.h b/config/tools/ccs_tool/editconf.h
index 1847e2c..be8945e 100644
--- a/config/tools/ccs_tool/editconf.h
+++ b/config/tools/ccs_tool/editconf.h
@@ -1,8 +1,11 @@
 void add_node(int argc, char **argv);
 void add_nodeids(int argc, char **argv);
+void add_service(int argc, char **argv);
 void add_fence(int argc, char **argv);
 void del_node(int argc, char **argv);
+void del_service(int argc, char **argv);
 void del_fence(int argc, char **argv);
 void list_nodes(int argc, char **argv);
+void list_services(int argc, char **argv);
 void list_fences(int argc, char **argv);
 void create_skeleton(int argc, char **argv);
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Cluster-devel] [PATCH 2/8] Unify 'del' functions
  2010-12-10  9:00 [Cluster-devel] [PATCH 0/8] ccs_tool enhancement Dmitry Mishin
  2010-12-10  9:00 ` [Cluster-devel] [PATCH 1/8] Add "service" object manipulations Dmitry Mishin
@ 2010-12-10  9:00 ` Dmitry Mishin
  2010-12-10  9:00 ` [Cluster-devel] [PATCH 3/8] Add "script" object manipulations Dmitry Mishin
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: Dmitry Mishin @ 2010-12-10  9:00 UTC (permalink / raw)
  To: cluster-devel.redhat.com

No need to keep 2 copies with almost the same logic inside - better to add if..
else clause.

Signed-off-by: Dmitry Mishin <dim@parallels.com>
---
 config/tools/ccs_tool/ccs_tool.c |    2 +-
 config/tools/ccs_tool/editconf.c |   68 ++-----------------------------------
 config/tools/ccs_tool/editconf.h |    1 -
 3 files changed, 5 insertions(+), 66 deletions(-)

diff --git a/config/tools/ccs_tool/ccs_tool.c b/config/tools/ccs_tool/ccs_tool.c
index 824da6d..12d447c 100644
--- a/config/tools/ccs_tool/ccs_tool.c
+++ b/config/tools/ccs_tool/ccs_tool.c
@@ -232,7 +232,7 @@ static int tool_main(int argc, char *argv[])
 	    exit(EXIT_SUCCESS);
     }
     else if(!strcmp(argv[optind], "delservice")){
-	    del_service(argc-1, argv+1);
+	    del_node(argc-1, argv+1);
 	    exit(EXIT_SUCCESS);
     }
     else if(!strcmp(argv[optind], "addfence")){
diff --git a/config/tools/ccs_tool/editconf.c b/config/tools/ccs_tool/editconf.c
index b33f288..a4ef407 100644
--- a/config/tools/ccs_tool/editconf.c
+++ b/config/tools/ccs_tool/editconf.c
@@ -130,15 +130,6 @@ static void delnode_usage(const char *name)
 	exit(0);
 }
 
-static void delservice_usage(const char *name)
-{
-	fprintf(stderr, "Usage: %s %s [options] <name>\n", prog_name, name);
-	config_usage(1);
-	help_usage();
-
-	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");
@@ -1067,7 +1058,10 @@ void del_node(int argc, char **argv)
 
 	increment_version(root_element);
 
-	del_clusternode(root_element, &ninfo);
+	if (!strcmp(argv[0], "delnode"))
+		del_clusternode(root_element, &ninfo);
+	else if (!strcmp(argv[0], "delservice"))
+		del_clusterservice(root_element, &ninfo);
 
 	/* Write it out */
 	save_file(doc, &ninfo);
@@ -1240,60 +1234,6 @@ void add_service(int argc, char **argv)
 
 }
 
-void del_service(int argc, char **argv)
-{
-	struct option_info ninfo;
-	int opt;
-	xmlDoc *doc;
-	xmlNode *root_element;
-
-	memset(&ninfo, 0, sizeof(ninfo));
-	ninfo.tell_ccsd = 1;
-
-	while ( (opt = getopt_long(argc, argv, "o:c:CFh?", delservice_options, NULL)) != EOF)
-	{
-		switch(opt)
-		{
-		case 'c':
-			ninfo.configfile = strdup(optarg);
-			break;
-
-		case 'o':
-			ninfo.outputfile = strdup(optarg);
-			break;
-
-		case 'C':
-			ninfo.tell_ccsd = 0;
-			break;
-
-		case 'F':
-			ninfo.force_ccsd = 1;
-			break;
-
-		case '?':
-		default:
-			delservice_usage(argv[0]);
-		}
-	}
-
-	/* Get service name parameter */
-	if (optind < argc)
-		ninfo.name = strdup(argv[optind]);
-	else
-		delservice_usage(argv[0]);
-
-	doc = open_configfile(&ninfo);
-
-	root_element = xmlDocGetRootElement(doc);
-
-	increment_version(root_element);
-
-	del_clusterservice(root_element, &ninfo);
-
-	/* Write it out */
-	save_file(doc, &ninfo);
-}
-
 void list_services(int argc, char **argv)
 {
 	xmlNode *cur_service;
diff --git a/config/tools/ccs_tool/editconf.h b/config/tools/ccs_tool/editconf.h
index be8945e..0090ab6 100644
--- a/config/tools/ccs_tool/editconf.h
+++ b/config/tools/ccs_tool/editconf.h
@@ -3,7 +3,6 @@ void add_nodeids(int argc, char **argv);
 void add_service(int argc, char **argv);
 void add_fence(int argc, char **argv);
 void del_node(int argc, char **argv);
-void del_service(int argc, char **argv);
 void del_fence(int argc, char **argv);
 void list_nodes(int argc, char **argv);
 void list_services(int argc, char **argv);
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Cluster-devel] [PATCH 3/8] Add "script" object manipulations
  2010-12-10  9:00 [Cluster-devel] [PATCH 0/8] ccs_tool enhancement Dmitry Mishin
  2010-12-10  9:00 ` [Cluster-devel] [PATCH 1/8] Add "service" object manipulations Dmitry Mishin
  2010-12-10  9:00 ` [Cluster-devel] [PATCH 2/8] Unify 'del' functions Dmitry Mishin
@ 2010-12-10  9:00 ` Dmitry Mishin
  2010-12-10  9:00 ` [Cluster-devel] [PATCH 4/8] Unify parsing of options Dmitry Mishin
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: Dmitry Mishin @ 2010-12-10  9:00 UTC (permalink / raw)
  To: cluster-devel.redhat.com

Script object is used when one needs to perform some actions on service
relocation event. This patch adds ability to add, delete and list scripts in
cluster config.

Signed-off-by: Dmitry Mishin <dim@parallels.com>
---
 config/tools/ccs_tool/ccs_tool.c |   15 +++
 config/tools/ccs_tool/editconf.c |  201 ++++++++++++++++++++++++++++++++++++++
 config/tools/ccs_tool/editconf.h |    2 +
 3 files changed, 218 insertions(+), 0 deletions(-)

diff --git a/config/tools/ccs_tool/ccs_tool.c b/config/tools/ccs_tool/ccs_tool.c
index 12d447c..bb91389 100644
--- a/config/tools/ccs_tool/ccs_tool.c
+++ b/config/tools/ccs_tool/ccs_tool.c
@@ -235,6 +235,14 @@ static int tool_main(int argc, char *argv[])
 	    del_node(argc-1, argv+1);
 	    exit(EXIT_SUCCESS);
     }
+    else if(!strcmp(argv[optind], "addscript")){
+	    add_script(argc-1, argv+1);
+	    exit(EXIT_SUCCESS);
+    }
+    else if(!strcmp(argv[optind], "delscript")){
+	    del_node(argc-1, argv+1);
+	    exit(EXIT_SUCCESS);
+    }
     else if(!strcmp(argv[optind], "addfence")){
 	    add_fence(argc-1, argv+1);
 	    exit(EXIT_SUCCESS);
@@ -255,6 +263,10 @@ static int tool_main(int argc, char *argv[])
 	    list_fences(argc-1, argv+1);
 	    exit(EXIT_SUCCESS);
     }
+    else if(!strcmp(argv[optind], "lsscript")){
+	    list_scripts(argc-1, argv+1);
+	    exit(EXIT_SUCCESS);
+    }
     else if(!strcmp(argv[optind], "create")){
 	    create_skeleton(argc-1, argv+1);
 	    exit(EXIT_SUCCESS);
@@ -299,6 +311,9 @@ static void tool_print_usage(FILE *stream){
           "  lsfence             List fence devices\n"
 	  "  addfence <fencedev> Add a new fence device\n"
 	  "  delfence <fencedev> Delete a fence device\n"
+	  "  addscript <name>    Add a script resource\n"
+	  "  delscript <name>    Delete a script resource\n"
+          "  lsscript            List script resources\n"
 	  "  create              Create a skeleton config file\n"
 	  "  addnodeids          Assign node ID numbers to all nodes\n"
 	  "\n");
diff --git a/config/tools/ccs_tool/editconf.c b/config/tools/ccs_tool/editconf.c
index a4ef407..13aa33b 100644
--- a/config/tools/ccs_tool/editconf.c
+++ b/config/tools/ccs_tool/editconf.c
@@ -130,6 +130,16 @@ static void delnode_usage(const char *name)
 	exit(0);
 }
 
+static void addscript_usage(const char *name)
+{
+	fprintf(stderr, "Usage: %s %s [options] <name> <path_to_script>\n",
+			prog_name, name);
+	config_usage(1);
+	help_usage();
+
+	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");
@@ -414,6 +424,26 @@ static xmlNode *do_find_node(xmlNode *root, const char *nodename,
 	return NULL;
 }
 
+static xmlNode *do_find_resource_ref(xmlNode *root, const char *name,
+		const char *res_type)
+{
+	xmlNode *cur_node;
+	xmlNode *res = NULL;
+
+	for (cur_node = root->children; cur_node; cur_node = cur_node->next)
+	{
+		if (cur_node->type == XML_ELEMENT_NODE &&
+			strcmp((char *)cur_node->name, "service") == 0)
+		{
+			res = do_find_node(cur_node, name, res_type, "ref");
+			if (res)
+				break;
+		}
+	}
+
+	return res;
+}
+
 static xmlNode *find_node(xmlNode *clusternodes, const char *nodename)
 {
 	return do_find_node(clusternodes, nodename, "clusternode", "name");
@@ -434,6 +464,11 @@ static xmlNode *find_script_resource(xmlNode *root, const char *name)
 	return do_find_node(root, name, "script", "name");
 }
 
+static xmlNode *find_script_ref(xmlNode *root, const char *name)
+{
+	return do_find_resource_ref(root, name, "script");
+}
+
 static xmlNode *find_ip_resource(xmlNode *root, const char *name)
 {
 	return do_find_node(root, name, "ip", "name");
@@ -699,6 +734,45 @@ static void del_clusterservice(xmlNode *root_element, struct option_info *ninfo)
 	xmlUnlinkNode(oldnode);
 }
 
+static void del_clusterscript(xmlNode *root_element, struct option_info *ninfo)
+{
+	xmlNode *rm, *rs;
+	xmlNode *node;
+
+	rm = findnode(root_element, "rm");
+	if (!rm)
+	{
+		fprintf(stderr, "Can't find \"rm\" in %s\n", ninfo->configfile);
+		exit(1);
+	}
+
+	rs = findnode(rm, "resources");
+	if (!rs)
+	{
+		fprintf(stderr, "Can't find \"resources\" in %s\n", ninfo->configfile);
+		exit(1);
+	}
+
+	/* Check that not used */
+	node = find_script_ref(rm, ninfo->name);
+	if (node)
+	{
+		fprintf(stderr, "Script %s is referenced in service in %s,"
+			" please remove reference first.\n", ninfo->name,
+			ninfo->configfile);
+		exit(1);
+	}
+
+	node = find_script_resource(rs, ninfo->name);
+	if (!node)
+	{
+		fprintf(stderr, "Script %s does not exist in %s\n", ninfo->name, ninfo->configfile);
+		exit(1);
+	}
+
+	xmlUnlinkNode(node);
+}
+
 struct option addnode_options[] =
 {
       { "votes", required_argument, NULL, 'v'},
@@ -1062,6 +1136,8 @@ void del_node(int argc, char **argv)
 		del_clusternode(root_element, &ninfo);
 	else if (!strcmp(argv[0], "delservice"))
 		del_clusterservice(root_element, &ninfo);
+	else if (!strcmp(argv[0], "delscript"))
+		del_clusterscript(root_element, &ninfo);
 
 	/* Write it out */
 	save_file(doc, &ninfo);
@@ -1302,6 +1378,81 @@ void list_services(int argc, char **argv)
 	}
 }
 
+void add_script(int argc, char **argv)
+{
+	struct option_info ninfo;
+	int opt;
+	xmlDoc *doc;
+	xmlNode *root_element;
+	xmlNode *rm, *rs, *node;
+	char *name;
+	char *sc_file;
+
+	memset(&ninfo, 0, sizeof(ninfo));
+	ninfo.tell_ccsd = 1;
+
+	while ( (opt = getopt_long(argc, argv, "o:c:CFh?", addfence_options, NULL)) != EOF)
+	{
+		switch(opt)
+		{
+		case 'c':
+			ninfo.configfile = strdup(optarg);
+			break;
+
+		case 'o':
+			ninfo.outputfile = strdup(optarg);
+			break;
+
+		case 'C':
+			ninfo.tell_ccsd = 0;
+			break;
+
+		case 'F':
+			ninfo.force_ccsd = 1;
+			break;
+
+		case '?':
+		default:
+			addscript_usage(argv[0]);
+		}
+	}
+
+	if (argc - optind < 2)
+		addscript_usage(argv[0]);
+
+	doc = open_configfile(&ninfo);
+
+	root_element = xmlDocGetRootElement(doc);
+
+	increment_version(root_element);
+
+	rm = findnode(root_element, "rm");
+	if (!rm)
+		die("Can't find \"rm\" %s\n", ninfo.configfile);
+
+	rs = findnode(rm, "resources");
+	if (!rs)
+		die("Can't find \"resources\" %s\n", ninfo.configfile);
+
+	/* First param is the script name - check it doesn't already exist */
+	name = argv[optind++];
+	if (find_script_resource(rs, name))
+		die("Script %s already exists\n", name);
+	sc_file = argv[optind++];
+
+	/* Add it */
+	node = xmlNewNode(NULL, BAD_CAST "script");
+	xmlSetProp(node, BAD_CAST "file", BAD_CAST sc_file);
+	xmlSetProp(node, BAD_CAST "name", BAD_CAST name);
+	xmlAddChild(rs, node);
+
+	/* Write it out */
+	save_file(doc, &ninfo);
+
+	/* Shutdown libxml */
+	xmlCleanupParser();
+}
+
 void create_skeleton(int argc, char **argv)
 {
 	xmlNode *root_element;
@@ -1568,3 +1719,53 @@ void list_fences(int argc, char **argv)
 	}
 }
 
+void list_scripts(int argc, char **argv)
+{
+	xmlNode *cur_node;
+	xmlNode *root_element;
+	xmlNode *rm, *rs;
+	xmlDocPtr doc;
+	struct option_info ninfo;
+	int opt;
+	int verbose=0;
+
+	memset(&ninfo, 0, sizeof(ninfo));
+
+	while ( (opt = getopt_long(argc, argv, "c:hv?", list_options, NULL)) != EOF)
+	{
+		switch(opt)
+		{
+		case 'c':
+			ninfo.configfile = strdup(optarg);
+			break;
+		case 'v':
+			verbose++;
+			break;
+		case '?':
+		default:
+			list_usage(argv[0]);
+		}
+	}
+	doc = open_configfile(&ninfo);
+	root_element = xmlDocGetRootElement(doc);
+
+	rm = findnode(root_element, "rm");
+	if (!rm)
+		die("Can't find \"rm\" in %s\n", ninfo.configfile);
+
+	rs = findnode(rm, "resources");
+	if (!rs)
+		die("Can't find \"resources\" in %s\n", ninfo.configfile);
+
+	printf("Name             Path\n");
+	for (cur_node = rs->children; cur_node; cur_node = cur_node->next)
+	{
+		if (cur_node->type == XML_ELEMENT_NODE && strcmp((char *)cur_node->name, "script") == 0)
+		{
+			xmlChar *name  = xmlGetProp(cur_node, BAD_CAST "name");
+			xmlChar *path = xmlGetProp(cur_node, BAD_CAST "file");
+
+			printf("%-16s %s\n", name, path);
+		}
+	}
+}
diff --git a/config/tools/ccs_tool/editconf.h b/config/tools/ccs_tool/editconf.h
index 0090ab6..c83af1d 100644
--- a/config/tools/ccs_tool/editconf.h
+++ b/config/tools/ccs_tool/editconf.h
@@ -1,10 +1,12 @@
 void add_node(int argc, char **argv);
 void add_nodeids(int argc, char **argv);
 void add_service(int argc, char **argv);
+void add_script(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);
 void list_nodes(int argc, char **argv);
 void list_services(int argc, char **argv);
 void list_fences(int argc, char **argv);
+void list_scripts(int argc, char **argv);
 void create_skeleton(int argc, char **argv);
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Cluster-devel] [PATCH 4/8] Unify parsing of options
  2010-12-10  9:00 [Cluster-devel] [PATCH 0/8] ccs_tool enhancement Dmitry Mishin
                   ` (2 preceding siblings ...)
  2010-12-10  9:00 ` [Cluster-devel] [PATCH 3/8] Add "script" object manipulations Dmitry Mishin
@ 2010-12-10  9:00 ` Dmitry Mishin
  2010-12-10  9:00 ` [Cluster-devel] [PATCH 5/8] Added "ip" object manipulations Dmitry Mishin
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: Dmitry Mishin @ 2010-12-10  9:00 UTC (permalink / raw)
  To: cluster-devel.redhat.com

This patch unifies options parsing for operations, which changes config and
supports only standard options.

Signed-off-by: Dmitry Mishin <dim@parallels.com>
---
 config/tools/ccs_tool/editconf.c |  174 +++++++++----------------------------
 1 files changed, 43 insertions(+), 131 deletions(-)

diff --git a/config/tools/ccs_tool/editconf.c b/config/tools/ccs_tool/editconf.c
index 13aa33b..313f83f 100644
--- a/config/tools/ccs_tool/editconf.c
+++ b/config/tools/ccs_tool/editconf.c
@@ -786,16 +786,7 @@ struct option addnode_options[] =
       { NULL, 0, NULL, 0 },
 };
 
-struct option delnode_options[] =
-{
-      { "outputfile", required_argument, NULL, 'o'},
-      { "configfile", required_argument, NULL, 'c'},
-      { "no_ccs", no_argument, NULL, 'C'},
-      { "force_ccs", no_argument, NULL, 'F'},
-      { NULL, 0, NULL, 0 },
-};
-
-struct option addfence_options[] =
+struct option commonw_options[] =
 {
       { "outputfile", required_argument, NULL, 'o'},
       { "configfile", required_argument, NULL, 'c'},
@@ -836,14 +827,41 @@ struct option addservice_options[] =
       { NULL, 0, NULL, 0 },
 };
 
-struct option delservice_options[] =
+static int parse_commonw_options(int argc, char **argv,
+	struct option_info *ninfo)
 {
-      { "outputfile", required_argument, NULL, 'o'},
-      { "configfile", required_argument, NULL, 'c'},
-      { "no_ccs", no_argument, NULL, 'C'},
-      { "force_ccs", no_argument, NULL, 'F'},
-      { NULL, 0, NULL, 0 },
-};
+	int opt;
+
+	memset(ninfo, 0, sizeof(*ninfo));
+	ninfo->tell_ccsd = 1;
+
+	while ( (opt = getopt_long(argc, argv, "o:c:CFh?", commonw_options, NULL)) != EOF)
+	{
+		switch(opt)
+		{
+		case 'c':
+			ninfo->configfile = strdup(optarg);
+			break;
+
+		case 'o':
+			ninfo->outputfile = strdup(optarg);
+			break;
+
+		case 'C':
+			ninfo->tell_ccsd = 0;
+			break;
+
+		case 'F':
+			ninfo->force_ccsd = 1;
+			break;
+
+		case '?':
+		default:
+			return 1;
+		}
+	}
+	return 0;
+}
 
 static int next_nodeid(int startid, int *nodeids, int nodecount)
 {
@@ -1087,38 +1105,11 @@ void add_node(int argc, char **argv)
 void del_node(int argc, char **argv)
 {
 	struct option_info ninfo;
-	int opt;
 	xmlDoc *doc;
 	xmlNode *root_element;
 
-	memset(&ninfo, 0, sizeof(ninfo));
-	ninfo.tell_ccsd = 1;
-
-	while ( (opt = getopt_long(argc, argv, "o:c:CFh?", delnode_options, NULL)) != EOF)
-	{
-		switch(opt)
-		{
-		case 'c':
-			ninfo.configfile = strdup(optarg);
-			break;
-
-		case 'o':
-			ninfo.outputfile = strdup(optarg);
-			break;
-
-		case 'C':
-			ninfo.tell_ccsd = 0;
-			break;
-
-		case 'F':
-			ninfo.force_ccsd = 1;
-			break;
-
-		case '?':
-		default:
-			delnode_usage(argv[0]);
-		}
-	}
+	if (parse_commonw_options(argc, argv, &ninfo))
+		delnode_usage(argv[0]);
 
 	/* Get node name parameter */
 	if (optind < argc)
@@ -1381,41 +1372,14 @@ void list_services(int argc, char **argv)
 void add_script(int argc, char **argv)
 {
 	struct option_info ninfo;
-	int opt;
 	xmlDoc *doc;
 	xmlNode *root_element;
 	xmlNode *rm, *rs, *node;
 	char *name;
 	char *sc_file;
 
-	memset(&ninfo, 0, sizeof(ninfo));
-	ninfo.tell_ccsd = 1;
-
-	while ( (opt = getopt_long(argc, argv, "o:c:CFh?", addfence_options, NULL)) != EOF)
-	{
-		switch(opt)
-		{
-		case 'c':
-			ninfo.configfile = strdup(optarg);
-			break;
-
-		case 'o':
-			ninfo.outputfile = strdup(optarg);
-			break;
-
-		case 'C':
-			ninfo.tell_ccsd = 0;
-			break;
-
-		case 'F':
-			ninfo.force_ccsd = 1;
-			break;
-
-		case '?':
-		default:
-			addscript_usage(argv[0]);
-		}
-	}
+	if (parse_commonw_options(argc, argv, &ninfo))
+		addscript_usage(argv[0]);
 
 	if (argc - optind < 2)
 		addscript_usage(argv[0]);
@@ -1546,35 +1510,9 @@ void add_fence(int argc, char **argv)
 	char *fencename;
 	char *agentname;
 	struct option_info ninfo;
-	int opt;
-
-	memset(&ninfo, 0, sizeof(ninfo));
-	ninfo.tell_ccsd = 1;
-
-	while ( (opt = getopt_long(argc, argv, "c:o:CFh?", list_options, NULL)) != EOF)
-	{
-		switch(opt)
-		{
-		case 'c':
-			ninfo.configfile = strdup(optarg);
-			break;
-		case 'o':
-			ninfo.outputfile = strdup(optarg);
-			break;
-
-		case 'C':
-			ninfo.tell_ccsd = 0;
-			break;
 
-		case 'F':
-			ninfo.force_ccsd = 1;
-			break;
-
-		case '?':
-		default:
-			addfence_usage(argv[0]);
-		}
-	}
+	if (parse_commonw_options(argc, argv, &ninfo))
+		addfence_usage(argv[0]);
 
 	if (argc - optind < 2)
 		addfence_usage(argv[0]);
@@ -1617,35 +1555,9 @@ void del_fence(int argc, char **argv)
 	xmlDocPtr doc;
 	char *fencename;
 	struct option_info ninfo;
-	int opt;
-
-	memset(&ninfo, 0, sizeof(ninfo));
-	ninfo.tell_ccsd = 1;
-
-	while ( (opt = getopt_long(argc, argv, "c:o:CFhv?", list_options, NULL)) != EOF)
-	{
-		switch(opt)
-		{
-		case 'c':
-			ninfo.configfile = strdup(optarg);
-			break;
-		case 'o':
-			ninfo.outputfile = strdup(optarg);
-			break;
-
-		case 'C':
-			ninfo.tell_ccsd = 0;
-			break;
 
-		case 'F':
-			ninfo.force_ccsd = 1;
-			break;
-
-		case '?':
-		default:
-			delfence_usage(argv[0]);
-		}
-	}
+	if (parse_commonw_options(argc, argv, &ninfo))
+		delfence_usage(argv[0]);
 
 	if (argc - optind < 1)
 		delfence_usage(argv[0]);
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Cluster-devel] [PATCH 5/8] Added "ip" object manipulations
  2010-12-10  9:00 [Cluster-devel] [PATCH 0/8] ccs_tool enhancement Dmitry Mishin
                   ` (3 preceding siblings ...)
  2010-12-10  9:00 ` [Cluster-devel] [PATCH 4/8] Unify parsing of options Dmitry Mishin
@ 2010-12-10  9:00 ` Dmitry Mishin
  2010-12-10  9:00 ` [Cluster-devel] [PATCH 6/8] Added 'fs' " Dmitry Mishin
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: Dmitry Mishin @ 2010-12-10  9:00 UTC (permalink / raw)
  To: cluster-devel.redhat.com

Signed-off-by: Dmitry Mishin <dim@parallels.com>
---
 config/tools/ccs_tool/ccs_tool.c |   17 ++++-
 config/tools/ccs_tool/editconf.c |  155 +++++++++++++++++++++++++++++++++++++-
 config/tools/ccs_tool/editconf.h |    2 +
 3 files changed, 172 insertions(+), 2 deletions(-)

diff --git a/config/tools/ccs_tool/ccs_tool.c b/config/tools/ccs_tool/ccs_tool.c
index bb91389..441f495 100644
--- a/config/tools/ccs_tool/ccs_tool.c
+++ b/config/tools/ccs_tool/ccs_tool.c
@@ -243,6 +243,14 @@ static int tool_main(int argc, char *argv[])
 	    del_node(argc-1, argv+1);
 	    exit(EXIT_SUCCESS);
     }
+    else if(!strcmp(argv[optind], "addip")){
+	    add_ip(argc-1, argv+1);
+	    exit(EXIT_SUCCESS);
+    }
+    else if(!strcmp(argv[optind], "delip")){
+	    del_node(argc-1, argv+1);
+	    exit(EXIT_SUCCESS);
+    }
     else if(!strcmp(argv[optind], "addfence")){
 	    add_fence(argc-1, argv+1);
 	    exit(EXIT_SUCCESS);
@@ -267,6 +275,10 @@ static int tool_main(int argc, char *argv[])
 	    list_scripts(argc-1, argv+1);
 	    exit(EXIT_SUCCESS);
     }
+    else if(!strcmp(argv[optind], "lsip")){
+	    list_ips(argc-1, argv+1);
+	    exit(EXIT_SUCCESS);
+    }
     else if(!strcmp(argv[optind], "create")){
 	    create_skeleton(argc-1, argv+1);
 	    exit(EXIT_SUCCESS);
@@ -313,7 +325,10 @@ static void tool_print_usage(FILE *stream){
 	  "  delfence <fencedev> Delete a fence device\n"
 	  "  addscript <name>    Add a script resource\n"
 	  "  delscript <name>    Delete a script resource\n"
-          "  lsscript            List script resources\n"
+	  "  lsscript            List script resources\n"
+	  "  addip <name>        Add an IP address resource\n"
+	  "  delip <name>        Delete an IP address resource\n"
+	  "  lsip                List IP address resources\n"
 	  "  create              Create a skeleton config file\n"
 	  "  addnodeids          Assign node ID numbers to all nodes\n"
 	  "\n");
diff --git a/config/tools/ccs_tool/editconf.c b/config/tools/ccs_tool/editconf.c
index 313f83f..0f642e6 100644
--- a/config/tools/ccs_tool/editconf.c
+++ b/config/tools/ccs_tool/editconf.c
@@ -140,6 +140,16 @@ static void addscript_usage(const char *name)
 	exit(0);
 }
 
+static void addip_usage(const char *name)
+{
+	fprintf(stderr, "Usage: %s %s [options] <IP_address>\n",
+			prog_name, name);
+	config_usage(1);
+	help_usage();
+
+	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");
@@ -471,7 +481,12 @@ static xmlNode *find_script_ref(xmlNode *root, const char *name)
 
 static xmlNode *find_ip_resource(xmlNode *root, const char *name)
 {
-	return do_find_node(root, name, "ip", "name");
+	return do_find_node(root, name, "ip", "address");
+}
+
+static xmlNode *find_ip_ref(xmlNode *root, const char *name)
+{
+	return do_find_resource_ref(root, name, "ip");
 }
 
 /* Print name=value pairs for a (n XML) node.
@@ -773,6 +788,45 @@ static void del_clusterscript(xmlNode *root_element, struct option_info *ninfo)
 	xmlUnlinkNode(node);
 }
 
+static void del_clusterip(xmlNode *root_element, struct option_info *ninfo)
+{
+	xmlNode *rm, *rs;
+	xmlNode *node;
+
+	rm = findnode(root_element, "rm");
+	if (!rm)
+	{
+		fprintf(stderr, "Can't find \"rm\" in %s\n", ninfo->configfile);
+		exit(1);
+	}
+
+	rs = findnode(rm, "resources");
+	if (!rs)
+	{
+		fprintf(stderr, "Can't find \"resources\" in %s\n", ninfo->configfile);
+		exit(1);
+	}
+
+	/* Check that not used */
+	node = find_ip_ref(rm, ninfo->name);
+	if (node)
+	{
+		fprintf(stderr, "IP %s is referenced in service in %s,"
+			" please remove reference first.\n", ninfo->name,
+			ninfo->configfile);
+		exit(1);
+	}
+
+	node = find_ip_resource(rs, ninfo->name);
+	if (!node)
+	{
+		fprintf(stderr, "IP %s does not exist in %s\n", ninfo->name, ninfo->configfile);
+		exit(1);
+	}
+
+	xmlUnlinkNode(node);
+}
+
 struct option addnode_options[] =
 {
       { "votes", required_argument, NULL, 'v'},
@@ -1129,6 +1183,8 @@ void del_node(int argc, char **argv)
 		del_clusterservice(root_element, &ninfo);
 	else if (!strcmp(argv[0], "delscript"))
 		del_clusterscript(root_element, &ninfo);
+	else if (!strcmp(argv[0], "delip"))
+		del_clusterip(root_element, &ninfo);
 
 	/* Write it out */
 	save_file(doc, &ninfo);
@@ -1417,6 +1473,52 @@ void add_script(int argc, char **argv)
 	xmlCleanupParser();
 }
 
+void add_ip(int argc, char **argv)
+{
+	struct option_info ninfo;
+	xmlDoc *doc;
+	xmlNode *root_element;
+	xmlNode *rm, *rs, *node;
+
+	if (parse_commonw_options(argc, argv, &ninfo))
+		addip_usage(argv[0]);
+
+	if (optind < argc)
+		ninfo.ip_addr = strdup(argv[optind]);
+	else
+		addip_usage(argv[0]);
+
+	doc = open_configfile(&ninfo);
+
+	root_element = xmlDocGetRootElement(doc);
+
+	increment_version(root_element);
+
+	rm = findnode(root_element, "rm");
+	if (!rm)
+		die("Can't find \"rm\" %s\n", ninfo.configfile);
+
+	rs = findnode(rm, "resources");
+	if (!rs)
+		die("Can't find \"resources\" %s\n", ninfo.configfile);
+
+	/* Check it doesn't already exist */
+	if (find_ip_resource(rs, ninfo.ip_addr))
+		die("IP %s already exists\n", ninfo.ip_addr);
+
+	/* Add it */
+	node = xmlNewNode(NULL, BAD_CAST "ip");
+	xmlSetProp(node, BAD_CAST "address", BAD_CAST ninfo.ip_addr);
+	xmlSetProp(node, BAD_CAST "monitor_link", BAD_CAST "1");
+	xmlAddChild(rs, node);
+
+	/* Write it out */
+	save_file(doc, &ninfo);
+
+	/* Shutdown libxml */
+	xmlCleanupParser();
+}
+
 void create_skeleton(int argc, char **argv)
 {
 	xmlNode *root_element;
@@ -1681,3 +1783,54 @@ void list_scripts(int argc, char **argv)
 		}
 	}
 }
+
+void list_ips(int argc, char **argv)
+{
+	xmlNode *cur_node;
+	xmlNode *root_element;
+	xmlNode *rm, *rs;
+	xmlDocPtr doc;
+	struct option_info ninfo;
+	int opt;
+	int verbose=0;
+
+	memset(&ninfo, 0, sizeof(ninfo));
+
+	while ( (opt = getopt_long(argc, argv, "c:hv?", list_options, NULL)) != EOF)
+	{
+		switch(opt)
+		{
+		case 'c':
+			ninfo.configfile = strdup(optarg);
+			break;
+		case 'v':
+			verbose++;
+			break;
+		case '?':
+		default:
+			list_usage(argv[0]);
+		}
+	}
+	doc = open_configfile(&ninfo);
+	root_element = xmlDocGetRootElement(doc);
+
+	rm = findnode(root_element, "rm");
+	if (!rm)
+		die("Can't find \"rm\" in %s\n", ninfo.configfile);
+
+	rs = findnode(rm, "resources");
+	if (!rs)
+		die("Can't find \"resources\" in %s\n", ninfo.configfile);
+
+	printf("IP\n");
+	for (cur_node = rs->children; cur_node; cur_node = cur_node->next)
+	{
+		if (cur_node->type == XML_ELEMENT_NODE &&
+			strcmp((char *)cur_node->name, "ip") == 0)
+		{
+			xmlChar *ip  = xmlGetProp(cur_node, BAD_CAST "address");
+
+			printf("%s\n", ip);
+		}
+	}
+}
diff --git a/config/tools/ccs_tool/editconf.h b/config/tools/ccs_tool/editconf.h
index c83af1d..a1119d7 100644
--- a/config/tools/ccs_tool/editconf.h
+++ b/config/tools/ccs_tool/editconf.h
@@ -2,6 +2,7 @@ void add_node(int argc, char **argv);
 void add_nodeids(int argc, char **argv);
 void add_service(int argc, char **argv);
 void add_script(int argc, char **argv);
+void add_ip(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);
@@ -9,4 +10,5 @@ void list_nodes(int argc, char **argv);
 void list_services(int argc, char **argv);
 void list_fences(int argc, char **argv);
 void list_scripts(int argc, char **argv);
+void list_ips(int argc, char **argv);
 void create_skeleton(int argc, char **argv);
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Cluster-devel] [PATCH 6/8] Added 'fs' object manipulations
  2010-12-10  9:00 [Cluster-devel] [PATCH 0/8] ccs_tool enhancement Dmitry Mishin
                   ` (4 preceding siblings ...)
  2010-12-10  9:00 ` [Cluster-devel] [PATCH 5/8] Added "ip" object manipulations Dmitry Mishin
@ 2010-12-10  9:00 ` Dmitry Mishin
  2010-12-10  9:00 ` [Cluster-devel] [PATCH 7/8] Added 'failoverdomain' " Dmitry Mishin
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: Dmitry Mishin @ 2010-12-10  9:00 UTC (permalink / raw)
  To: cluster-devel.redhat.com

Signed-off-by: Dmitry Mishin <dim@parallels.com>
---
 config/tools/ccs_tool/ccs_tool.c |   15 ++
 config/tools/ccs_tool/editconf.c |  275 ++++++++++++++++++++++++++++++++++++++
 config/tools/ccs_tool/editconf.h |    2 +
 3 files changed, 292 insertions(+), 0 deletions(-)

diff --git a/config/tools/ccs_tool/ccs_tool.c b/config/tools/ccs_tool/ccs_tool.c
index 441f495..dfe5610 100644
--- a/config/tools/ccs_tool/ccs_tool.c
+++ b/config/tools/ccs_tool/ccs_tool.c
@@ -251,6 +251,14 @@ static int tool_main(int argc, char *argv[])
 	    del_node(argc-1, argv+1);
 	    exit(EXIT_SUCCESS);
     }
+    else if(!strcmp(argv[optind], "addfs")){
+	    add_fs(argc-1, argv+1);
+	    exit(EXIT_SUCCESS);
+    }
+    else if(!strcmp(argv[optind], "delfs")){
+	    del_node(argc-1, argv+1);
+	    exit(EXIT_SUCCESS);
+    }
     else if(!strcmp(argv[optind], "addfence")){
 	    add_fence(argc-1, argv+1);
 	    exit(EXIT_SUCCESS);
@@ -279,6 +287,10 @@ static int tool_main(int argc, char *argv[])
 	    list_ips(argc-1, argv+1);
 	    exit(EXIT_SUCCESS);
     }
+    else if(!strcmp(argv[optind], "lsfs")){
+	    list_fs(argc-1, argv+1);
+	    exit(EXIT_SUCCESS);
+    }
     else if(!strcmp(argv[optind], "create")){
 	    create_skeleton(argc-1, argv+1);
 	    exit(EXIT_SUCCESS);
@@ -329,6 +341,9 @@ static void tool_print_usage(FILE *stream){
 	  "  addip <name>        Add an IP address resource\n"
 	  "  delip <name>        Delete an IP address resource\n"
 	  "  lsip                List IP address resources\n"
+	  "  addfs <name>        Add an IP address resource\n"
+	  "  delfs <name>        Delete an IP address resource\n"
+	  "  lsfs                List IP address resources\n"
 	  "  create              Create a skeleton config file\n"
 	  "  addnodeids          Assign node ID numbers to all nodes\n"
 	  "\n");
diff --git a/config/tools/ccs_tool/editconf.c b/config/tools/ccs_tool/editconf.c
index 0f642e6..aa6c7cd 100644
--- a/config/tools/ccs_tool/editconf.c
+++ b/config/tools/ccs_tool/editconf.c
@@ -42,9 +42,15 @@ struct option_info
 	const char *fs;
 	const char *script;
 	const char *mountpoint;
+	const char *type;
+	const char *device;
+	const char *options;
 	const char *configfile;
 	const char *outputfile;
 	int  do_delete;
+	int  force_fsck;
+	int  force_unmount;
+	int  self_fence;
 	int  tell_ccsd;
 	int  force_ccsd;
 };
@@ -150,6 +156,22 @@ static void addip_usage(const char *name)
 	exit(0);
 }
 
+static void addfs_usage(const char *name)
+{
+	fprintf(stderr, "Usage: %s %s [options] <name> <device> <mountpoint>\n",
+			prog_name, name);
+	fprintf(stderr, " -t --type          Type of the filesystem (ext3, ext4, etc.)\n");
+	fprintf(stderr, "                    Default type is ext3.\n");
+	fprintf(stderr, " -p --options       Mount options\n");
+	fprintf(stderr, " -k --force_fsck    Force fsck before mount\n");
+	fprintf(stderr, " -u --force_unmount Call umount with force flag\n");
+	fprintf(stderr, " -s --self_fence    Use 'self_fence' feature\n");
+	config_usage(1);
+	help_usage();
+
+	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");
@@ -325,6 +347,13 @@ static void increment_version(xmlNode *root_element)
 	xmlSetProp(root_element, BAD_CAST "config_version", BAD_CAST newver);
 }
 
+static void _xmlSetIntProp(xmlNode *element, const char *property, const int value)
+{
+	char buf[32];
+	snprintf(buf, sizeof(buf), "%d", value);
+	xmlSetProp(element, BAD_CAST property, BAD_CAST buf);
+}
+
 static xmlNode *findnode(xmlNode *root, const char *name)
 {
 	xmlNode *cur_node;
@@ -489,6 +518,11 @@ static xmlNode *find_ip_ref(xmlNode *root, const char *name)
 	return do_find_resource_ref(root, name, "ip");
 }
 
+static xmlNode *find_fs_ref(xmlNode *root, const char *name)
+{
+	return do_find_resource_ref(root, name, "fs");
+}
+
 /* Print name=value pairs for a (n XML) node.
  * "ignore" is a string to ignore if present as a property (probably already printed on the main line)
  */
@@ -683,6 +717,39 @@ static void add_clusterservice(xmlNode *root_element, struct option_info *ninfo,
 	}
 }
 
+static void add_clusterfs(xmlNode *root_element, struct option_info *ninfo,
+			    int argc, char **argv, int optindex)
+{
+	xmlNode *rm;
+	xmlNode *rs;
+	xmlNode *node;
+
+	rm = findnode(root_element, "rm");
+	if (!rm)
+		die("Can't find \"rm\" in %s\n", ninfo->configfile);
+
+	rs = findnode(rm, "resources");
+	if (!rs)
+		die("Can't find \"resources\" %s\n", ninfo->configfile);
+
+	/* Check it doesn't already exist */
+	if (find_fs_resource(rs, ninfo->name))
+		die("fs %s already exists\n", ninfo->name);
+
+	/* Add the new fs resource */
+	node = xmlNewNode(NULL, BAD_CAST "fs");
+	xmlSetProp(node, BAD_CAST "device", BAD_CAST ninfo->device);
+	_xmlSetIntProp(node, "force_fsck", ninfo->force_fsck);
+	_xmlSetIntProp(node, "force_unmount", ninfo->force_unmount);
+	xmlSetProp(node, BAD_CAST "fstype", BAD_CAST ninfo->type);
+	xmlSetProp(node, BAD_CAST "mountpoint", BAD_CAST ninfo->mountpoint);
+	xmlSetProp(node, BAD_CAST "name", BAD_CAST ninfo->name);
+	xmlSetProp(node, BAD_CAST "options", (ninfo->options) ?
+					BAD_CAST ninfo->options : BAD_CAST "");
+	_xmlSetIntProp(node, "self_fence", ninfo->self_fence);
+	xmlAddChild(rs, node);
+}
+
 static xmlDoc *open_configfile(struct option_info *ninfo)
 {
 	xmlDoc *doc;
@@ -827,6 +894,45 @@ static void del_clusterip(xmlNode *root_element, struct option_info *ninfo)
 	xmlUnlinkNode(node);
 }
 
+static void del_clusterfs(xmlNode *root_element, struct option_info *ninfo)
+{
+	xmlNode *rm, *rs;
+	xmlNode *node;
+
+	rm = findnode(root_element, "rm");
+	if (!rm)
+	{
+		fprintf(stderr, "Can't find \"rm\" in %s\n", ninfo->configfile);
+		exit(1);
+	}
+
+	rs = findnode(rm, "resources");
+	if (!rs)
+	{
+		fprintf(stderr, "Can't find \"resources\" in %s\n", ninfo->configfile);
+		exit(1);
+	}
+
+	/* Check that not used */
+	node = find_fs_ref(rm, ninfo->name);
+	if (node)
+	{
+		fprintf(stderr, "fs %s is referenced in service in %s,"
+			" please remove reference first.\n", ninfo->name,
+			ninfo->configfile);
+		exit(1);
+	}
+
+	node = find_fs_resource(rs, ninfo->name);
+	if (!node)
+	{
+		fprintf(stderr, "fs %s does not exist in %s\n", ninfo->name, ninfo->configfile);
+		exit(1);
+	}
+
+	xmlUnlinkNode(node);
+}
+
 struct option addnode_options[] =
 {
       { "votes", required_argument, NULL, 'v'},
@@ -840,6 +946,20 @@ struct option addnode_options[] =
       { NULL, 0, NULL, 0 },
 };
 
+struct option addfs_options[] =
+{
+      { "type", required_argument, NULL, 't'},
+      { "options", required_argument, NULL, 'p'},
+      { "outputfile", required_argument, NULL, 'o'},
+      { "configfile", required_argument, NULL, 'c'},
+      { "no_ccs", no_argument, NULL, 'C'},
+      { "force_ccs", no_argument, NULL, 'F'},
+      { "force_fsck", no_argument, NULL, 'k'},
+      { "force_unmount", no_argument, NULL, 'u'},
+      { "self_fence", no_argument, NULL, 's'},
+      { NULL, 0, NULL, 0 },
+};
+
 struct option commonw_options[] =
 {
       { "outputfile", required_argument, NULL, 'o'},
@@ -1185,6 +1305,8 @@ void del_node(int argc, char **argv)
 		del_clusterscript(root_element, &ninfo);
 	else if (!strcmp(argv[0], "delip"))
 		del_clusterip(root_element, &ninfo);
+	else if (!strcmp(argv[0], "delfs"))
+		del_clusterfs(root_element, &ninfo);
 
 	/* Write it out */
 	save_file(doc, &ninfo);
@@ -1519,6 +1641,86 @@ void add_ip(int argc, char **argv)
 	xmlCleanupParser();
 }
 
+void add_fs(int argc, char **argv)
+{
+	struct option_info ninfo;
+	xmlDoc *doc;
+	xmlNode *root_element;
+	int opt;
+
+	memset(&ninfo, 0, sizeof(ninfo));
+	ninfo.tell_ccsd = 1;
+
+	while ( (opt = getopt_long(argc, argv, "t:p:o:c:CFh?kus", addfs_options, NULL)) != EOF)
+	{
+		switch(opt)
+		{
+		case 't':
+			ninfo.type = strdup(optarg);
+			break;
+
+		case 'p':
+			ninfo.options = strdup(optarg);
+			break;
+
+		case 'c':
+			ninfo.configfile = strdup(optarg);
+			break;
+
+		case 'o':
+			ninfo.outputfile = strdup(optarg);
+			break;
+
+		case 'C':
+			ninfo.tell_ccsd = 0;
+			break;
+
+		case 'F':
+			ninfo.force_ccsd = 1;
+			break;
+
+		case 'k':
+			ninfo.force_fsck = 1;
+			break;
+
+		case 'u':
+			ninfo.force_unmount = 1;
+			break;
+
+		case 's':
+			ninfo.self_fence = 1;
+			break;
+
+		case '?':
+		default:
+			addfs_usage(argv[0]);
+		}
+	}
+
+	if (optind < argc - 2) {
+		ninfo.name = strdup(argv[optind]);
+		ninfo.device = strdup(argv[optind + 1]);
+		ninfo.mountpoint = strdup(argv[optind + 2]);
+	} else
+		addfs_usage(argv[0]);
+
+	if (!ninfo.type)
+		ninfo.type = "ext3";
+
+	doc = open_configfile(&ninfo);
+
+	root_element = xmlDocGetRootElement(doc);
+
+	increment_version(root_element);
+
+	add_clusterfs(root_element, &ninfo, argc, argv, optind);
+
+	/* Write it out */
+	save_file(doc, &ninfo);
+	/* Shutdown libxml */
+	xmlCleanupParser();
+}
+
 void create_skeleton(int argc, char **argv)
 {
 	xmlNode *root_element;
@@ -1834,3 +2036,76 @@ void list_ips(int argc, char **argv)
 		}
 	}
 }
+
+void list_fs(int argc, char **argv)
+{
+	xmlNode *cur_node;
+	xmlNode *root_element;
+	xmlNode *rm, *rs;
+	xmlDocPtr doc;
+	struct option_info ninfo;
+	int opt;
+	int verbose=0;
+
+	memset(&ninfo, 0, sizeof(ninfo));
+
+	while ( (opt = getopt_long(argc, argv, "c:hv?", list_options, NULL)) != EOF)
+	{
+		switch(opt)
+		{
+		case 'c':
+			ninfo.configfile = strdup(optarg);
+			break;
+		case 'v':
+			verbose++;
+			break;
+		case '?':
+		default:
+			list_usage(argv[0]);
+		}
+	}
+	doc = open_configfile(&ninfo);
+	root_element = xmlDocGetRootElement(doc);
+
+	rm = findnode(root_element, "rm");
+	if (!rm)
+		die("Can't find \"rm\" in %s\n", ninfo.configfile);
+
+	rs = findnode(rm, "resources");
+	if (!rs)
+		die("Can't find \"resources\" in %s\n", ninfo.configfile);
+
+	printf("Name             Type  FUS Device              Mountpoint\n");
+	for (cur_node = rs->children; cur_node; cur_node = cur_node->next)
+	{
+		if (cur_node->type == XML_ELEMENT_NODE &&
+			strcmp((char *)cur_node->name, "fs") == 0)
+		{
+			xmlChar *name  = xmlGetProp(cur_node, BAD_CAST "name");
+			xmlChar *type  = xmlGetProp(cur_node, BAD_CAST "fstype");
+			xmlChar *force_fsck  = xmlGetProp(cur_node,
+						BAD_CAST "force_fsck");
+			xmlChar *force_unmount  = xmlGetProp(cur_node,
+						BAD_CAST "force_unmount");
+			xmlChar *self_fence  = xmlGetProp(cur_node,
+						BAD_CAST "self_fence");
+			xmlChar *device  = xmlGetProp(cur_node,
+						BAD_CAST "device");
+			xmlChar *mnt  = xmlGetProp(cur_node,
+						BAD_CAST "mountpoint");
+
+			char f, u, s;
+#define INT_TO_CHAR(x, str) \
+	if (str && atoi((const char *)str)) \
+		x = '*'; \
+	else \
+		x = ' ';
+			INT_TO_CHAR(f, force_fsck)
+			INT_TO_CHAR(u, force_unmount)
+			INT_TO_CHAR(s, self_fence)
+#undef INT_TO_CHAR
+			printf("%-16.16s %-5.5s %c%c%c %-19.19s %s\n", name, type, f, u,
+					s, device, mnt);
+		}
+	}
+}
diff --git a/config/tools/ccs_tool/editconf.h b/config/tools/ccs_tool/editconf.h
index a1119d7..3d1f5c2 100644
--- a/config/tools/ccs_tool/editconf.h
+++ b/config/tools/ccs_tool/editconf.h
@@ -3,6 +3,7 @@ void add_nodeids(int argc, char **argv);
 void add_service(int argc, char **argv);
 void add_script(int argc, char **argv);
 void add_ip(int argc, char **argv);
+void add_fs(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);
@@ -11,4 +12,5 @@ void list_services(int argc, char **argv);
 void list_fences(int argc, char **argv);
 void list_scripts(int argc, char **argv);
 void list_ips(int argc, char **argv);
+void list_fs(int argc, char **argv);
 void create_skeleton(int argc, char **argv);
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Cluster-devel] [PATCH 7/8] Added 'failoverdomain' object manipulations
  2010-12-10  9:00 [Cluster-devel] [PATCH 0/8] ccs_tool enhancement Dmitry Mishin
                   ` (5 preceding siblings ...)
  2010-12-10  9:00 ` [Cluster-devel] [PATCH 6/8] Added 'fs' " Dmitry Mishin
@ 2010-12-10  9:00 ` Dmitry Mishin
  2010-12-10  9:00 ` [Cluster-devel] [PATCH 8/8] Added ability to reference domains from services Dmitry Mishin
  2010-12-10  9:12 ` [Cluster-devel] [PATCH 0/8] ccs_tool enhancement Fabio M. Di Nitto
  8 siblings, 0 replies; 13+ messages in thread
From: Dmitry Mishin @ 2010-12-10  9:00 UTC (permalink / raw)
  To: cluster-devel.redhat.com

Signed-off-by: Dmitry Mishin <dim@parallels.com>
---
 config/tools/ccs_tool/ccs_tool.c |   21 +++-
 config/tools/ccs_tool/editconf.c |  292 +++++++++++++++++++++++++++++++++++++-
 config/tools/ccs_tool/editconf.h |    2 +
 3 files changed, 305 insertions(+), 10 deletions(-)

diff --git a/config/tools/ccs_tool/ccs_tool.c b/config/tools/ccs_tool/ccs_tool.c
index dfe5610..e1dc3cc 100644
--- a/config/tools/ccs_tool/ccs_tool.c
+++ b/config/tools/ccs_tool/ccs_tool.c
@@ -259,6 +259,14 @@ static int tool_main(int argc, char *argv[])
 	    del_node(argc-1, argv+1);
 	    exit(EXIT_SUCCESS);
     }
+    else if(!strcmp(argv[optind], "addfdomain")){
+	    add_fdomain(argc-1, argv+1);
+	    exit(EXIT_SUCCESS);
+    }
+    else if(!strcmp(argv[optind], "delfdomain")){
+	    del_node(argc-1, argv+1);
+	    exit(EXIT_SUCCESS);
+    }
     else if(!strcmp(argv[optind], "addfence")){
 	    add_fence(argc-1, argv+1);
 	    exit(EXIT_SUCCESS);
@@ -291,6 +299,10 @@ static int tool_main(int argc, char *argv[])
 	    list_fs(argc-1, argv+1);
 	    exit(EXIT_SUCCESS);
     }
+    else if(!strcmp(argv[optind], "lsfdomains")){
+	    list_fdomains(argc-1, argv+1);
+	    exit(EXIT_SUCCESS);
+    }
     else if(!strcmp(argv[optind], "create")){
 	    create_skeleton(argc-1, argv+1);
 	    exit(EXIT_SUCCESS);
@@ -341,9 +353,12 @@ static void tool_print_usage(FILE *stream){
 	  "  addip <name>        Add an IP address resource\n"
 	  "  delip <name>        Delete an IP address resource\n"
 	  "  lsip                List IP address resources\n"
-	  "  addfs <name>        Add an IP address resource\n"
-	  "  delfs <name>        Delete an IP address resource\n"
-	  "  lsfs                List IP address resources\n"
+	  "  addfs <name>        Add an filesystem resource\n"
+	  "  delfs <name>        Delete an filesystem resource\n"
+	  "  lsfs                List filesystem resources\n"
+	  "  addfdomain <name>   Add an failover domain\n"
+	  "  delfdomain <name>   Delete an failover domain\n"
+	  "  lsfdomains          List failover domains\n"
 	  "  create              Create a skeleton config file\n"
 	  "  addnodeids          Assign node ID numbers to all nodes\n"
 	  "\n");
diff --git a/config/tools/ccs_tool/editconf.c b/config/tools/ccs_tool/editconf.c
index aa6c7cd..aae1095 100644
--- a/config/tools/ccs_tool/editconf.c
+++ b/config/tools/ccs_tool/editconf.c
@@ -27,6 +27,12 @@ do { \
 } while (0)
 
 
+#define INT_TO_CHAR(x, str) \
+	if (str && atoi((const char *)str)) \
+		x = '*'; \
+	else \
+		x = ' ';
+
 struct option_info
 {
 	const char *name;
@@ -47,10 +53,13 @@ struct option_info
 	const char *options;
 	const char *configfile;
 	const char *outputfile;
+	const char **failover_nodes;
 	int  do_delete;
 	int  force_fsck;
 	int  force_unmount;
 	int  self_fence;
+	int  ordered;
+	int  restricted;
 	int  tell_ccsd;
 	int  force_ccsd;
 };
@@ -172,6 +181,20 @@ static void addfs_usage(const char *name)
 	exit(0);
 }
 
+static void addfdomain_usage(const char *name)
+{
+	fprintf(stderr, "Usage: %s %s [options] <name> <node1> ... <nodeN>\n",
+			prog_name, name);
+	fprintf(stderr, " -p --ordered       Allows you to specify a preference order\n");
+	fprintf(stderr, "                    among the members of a failover domain\n");
+	fprintf(stderr, " -r --restricted    Allows you to restrict the members that can\n");
+	fprintf(stderr, "                    run a particular cluster service.\n");
+	config_usage(1);
+	help_usage();
+
+	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");
@@ -456,7 +479,7 @@ static xmlNode *do_find_node(xmlNode *root, const char *nodename,
 			strcmp((char *)cur_node->name, elem_name) == 0)
 		{
 			xmlChar *name = xmlGetProp(cur_node, BAD_CAST attrib_name);
-			if (strcmp((char *)name, nodename) == 0)
+			if (name && strcmp((char *)name, nodename) == 0)
 				return cur_node;
 		}
 	}
@@ -498,6 +521,11 @@ static xmlNode *find_fs_resource(xmlNode *root, const char *name)
 	return do_find_node(root, name, "fs", "name");
 }
 
+static xmlNode *find_fdomain_resource(xmlNode *root, const char *name)
+{
+	return do_find_node(root, name, "failoverdomain", "name");
+}
+
 static xmlNode *find_script_resource(xmlNode *root, const char *name)
 {
 	return do_find_node(root, name, "script", "name");
@@ -523,6 +551,24 @@ static xmlNode *find_fs_ref(xmlNode *root, const char *name)
 	return do_find_resource_ref(root, name, "fs");
 }
 
+static xmlNode *find_fdomain_ref(xmlNode *root, const char *name)
+{
+	xmlNode *cur_node;
+
+	for (cur_node = root->children; cur_node; cur_node = cur_node->next)
+	{
+		if (cur_node->type == XML_ELEMENT_NODE &&
+			strcmp((char *)cur_node->name, "service") == 0)
+		{
+			xmlChar *domain = xmlGetProp(cur_node, BAD_CAST "domain");
+			if (domain && strcmp(name, (char *)domain) == 0)
+				return cur_node;
+		}
+	}
+
+	return NULL;
+}
+
 /* Print name=value pairs for a (n XML) node.
  * "ignore" is a string to ignore if present as a property (probably already printed on the main line)
  */
@@ -750,6 +796,56 @@ static void add_clusterfs(xmlNode *root_element, struct option_info *ninfo,
 	xmlAddChild(rs, node);
 }
 
+static void add_clusterfdomain(xmlNode *root_element, struct option_info *ninfo,
+			    int argc, char **argv, int optindex)
+{
+	xmlNode *rm;
+	xmlNode *fdomains;
+	xmlNode *node;
+	xmlNode *cn;
+	int i = 0;
+
+	rm = findnode(root_element, "rm");
+	if (!rm)
+		die("Can't find \"rm\" in %s\n", ninfo->configfile);
+
+	fdomains = findnode(rm, "failoverdomains");
+	if (!fdomains)
+		die("Can't find \"failoverdomains\" %s\n", ninfo->configfile);
+
+	cn = findnode(root_element, "clusternodes");
+	if (!cn)
+		die("Can't find \"clusternodes\" in %s\n", ninfo->configfile);
+
+	/* Check it doesn't already exist */
+	if (find_fdomain_resource(fdomains, ninfo->name))
+		die("failover domain %s already exists\n", ninfo->name);
+
+	/* Check that nodes are defined */
+	while (ninfo->failover_nodes[i]) {
+		if (!find_node(cn, ninfo->failover_nodes[i]))
+			die("Can't find node %s in %s.\n",
+				ninfo->failover_nodes[i], ninfo->configfile);
+		i++;
+	}
+
+	/* Add the new failover domain */
+	node = xmlNewNode(NULL, BAD_CAST "failoverdomain");
+	xmlSetProp(node, BAD_CAST "name", BAD_CAST ninfo->name);
+	_xmlSetIntProp(node, "ordered", ninfo->ordered);
+	_xmlSetIntProp(node, "restricted", ninfo->restricted);
+
+	i = 0;
+	while (ninfo->failover_nodes[i]) {
+		xmlNode *fnode = xmlNewNode(NULL, BAD_CAST "failoverdomainnode");
+		xmlSetProp(fnode, BAD_CAST "name", BAD_CAST ninfo->failover_nodes[i]);
+		_xmlSetIntProp(fnode, "priority", i + 1);
+		xmlAddChild(node, fnode);
+		i++;
+	}
+	xmlAddChild(fdomains, node);
+}
+
 static xmlDoc *open_configfile(struct option_info *ninfo)
 {
 	xmlDoc *doc;
@@ -933,6 +1029,45 @@ static void del_clusterfs(xmlNode *root_element, struct option_info *ninfo)
 	xmlUnlinkNode(node);
 }
 
+static void del_clusterfdomain(xmlNode *root_element, struct option_info *ninfo)
+{
+	xmlNode *rm, *fdomains;
+	xmlNode *node;
+
+	rm = findnode(root_element, "rm");
+	if (!rm)
+	{
+		fprintf(stderr, "Can't find \"rm\" in %s\n", ninfo->configfile);
+		exit(1);
+	}
+
+	fdomains = findnode(rm, "failoverdomains");
+	if (!fdomains)
+	{
+		fprintf(stderr, "Can't find \"failoverdomains\" in %s\n", ninfo->configfile);
+		exit(1);
+	}
+
+	/* Check that not used */
+	node = find_fdomain_ref(rm, ninfo->name);
+	if (node)
+	{
+		fprintf(stderr, "failover domain %s is referenced in service in %s,"
+			" please remove reference first.\n", ninfo->name,
+			ninfo->configfile);
+		exit(1);
+	}
+
+	node = find_fdomain_resource(fdomains, ninfo->name);
+	if (!node)
+	{
+		fprintf(stderr, "failover domain %s does not exist in %s\n", ninfo->name, ninfo->configfile);
+		exit(1);
+	}
+
+	xmlUnlinkNode(node);
+}
+
 struct option addnode_options[] =
 {
       { "votes", required_argument, NULL, 'v'},
@@ -960,6 +1095,17 @@ struct option addfs_options[] =
       { NULL, 0, NULL, 0 },
 };
 
+struct option addfdomain_options[] =
+{
+      { "outputfile", required_argument, NULL, 'o'},
+      { "configfile", required_argument, NULL, 'c'},
+      { "no_ccs", no_argument, NULL, 'C'},
+      { "force_ccs", no_argument, NULL, 'F'},
+      { "ordered", no_argument, NULL, 'p'},
+      { "restricted", no_argument, NULL, 'r'},
+      { NULL, 0, NULL, 0 },
+};
+
 struct option commonw_options[] =
 {
       { "outputfile", required_argument, NULL, 'o'},
@@ -1307,6 +1453,8 @@ void del_node(int argc, char **argv)
 		del_clusterip(root_element, &ninfo);
 	else if (!strcmp(argv[0], "delfs"))
 		del_clusterfs(root_element, &ninfo);
+	else if (!strcmp(argv[0], "delfdomain"))
+		del_clusterfdomain(root_element, &ninfo);
 
 	/* Write it out */
 	save_file(doc, &ninfo);
@@ -1721,6 +1869,73 @@ void add_fs(int argc, char **argv)
 	xmlCleanupParser();
 }
 
+void add_fdomain(int argc, char **argv)
+{
+	struct option_info ninfo;
+	xmlDoc *doc;
+	xmlNode *root_element;
+	int opt, i;
+
+	memset(&ninfo, 0, sizeof(ninfo));
+	ninfo.tell_ccsd = 1;
+
+	while ( (opt = getopt_long(argc, argv, "pro:c:CFh?", addfdomain_options, NULL)) != EOF)
+	{
+		switch(opt)
+		{
+		case 'p':
+			ninfo.ordered = 1;
+			break;
+
+		case 'r':
+			ninfo.restricted = 1;
+			break;
+
+		case 'c':
+			ninfo.configfile = strdup(optarg);
+			break;
+
+		case 'o':
+			ninfo.outputfile = strdup(optarg);
+			break;
+
+		case 'C':
+			ninfo.tell_ccsd = 0;
+			break;
+
+		case 'F':
+			ninfo.force_ccsd = 1;
+			break;
+
+		case '?':
+		default:
+			addfdomain_usage(argv[0]);
+		}
+	}
+
+	if (optind < argc - 1) {
+		ninfo.name = strdup(argv[optind]);
+		ninfo.failover_nodes = (const char **)malloc(sizeof(char *) * (argc - optind));
+		for (i = 0; i < argc - optind - 1; i++)
+			ninfo.failover_nodes[i] = strdup(argv[i + optind + 1]);
+		ninfo.failover_nodes[i] = NULL;
+	} else
+		addfdomain_usage(argv[0]);
+
+	doc = open_configfile(&ninfo);
+
+	root_element = xmlDocGetRootElement(doc);
+
+	increment_version(root_element);
+
+	add_clusterfdomain(root_element, &ninfo, argc, argv, optind);
+
+	/* Write it out */
+	save_file(doc, &ninfo);
+	/* Shutdown libxml */
+	xmlCleanupParser();
+}
+
 void create_skeleton(int argc, char **argv)
 {
 	xmlNode *root_element;
@@ -2095,17 +2310,80 @@ void list_fs(int argc, char **argv)
 						BAD_CAST "mountpoint");
 
 			char f, u, s;
-#define INT_TO_CHAR(x, str) \
-	if (str && atoi((const char *)str)) \
-		x = '*'; \
-	else \
-		x = ' ';
 			INT_TO_CHAR(f, force_fsck)
 			INT_TO_CHAR(u, force_unmount)
 			INT_TO_CHAR(s, self_fence)
-#undef INT_TO_CHAR
 			printf("%-16.16s %-5.5s %c%c%c %-19.19s %s\n", name, type, f, u,
 					s, device, mnt);
 		}
 	}
 }
+
+void list_fdomains(int argc, char **argv)
+{
+	xmlNode *cur_node, *fnode;
+	xmlNode *root_element;
+	xmlNode *rm, *fdomains;
+	xmlDocPtr doc;
+	struct option_info ninfo;
+	int opt;
+	int verbose=0;
+
+	memset(&ninfo, 0, sizeof(ninfo));
+
+	while ( (opt = getopt_long(argc, argv, "c:hv?", list_options, NULL)) != EOF)
+	{
+		switch(opt)
+		{
+		case 'c':
+			ninfo.configfile = strdup(optarg);
+			break;
+		case 'v':
+			verbose++;
+			break;
+		case '?':
+		default:
+			list_usage(argv[0]);
+		}
+	}
+	doc = open_configfile(&ninfo);
+	root_element = xmlDocGetRootElement(doc);
+
+	rm = findnode(root_element, "rm");
+	if (!rm)
+		die("Can't find \"rm\" in %s\n", ninfo.configfile);
+
+	fdomains = findnode(rm, "failoverdomains");
+	if (!fdomains)
+		die("Can't find \"failoverdomains\" in %s\n", ninfo.configfile);
+
+	printf("Name             OR Nodes\n");
+	for (cur_node = fdomains->children; cur_node; cur_node = cur_node->next)
+	{
+		if (cur_node->type == XML_ELEMENT_NODE &&
+			strcmp((char *)cur_node->name, "failoverdomain") == 0)
+		{
+			xmlChar *name  = xmlGetProp(cur_node, BAD_CAST "name");
+			xmlChar *ordered  = xmlGetProp(cur_node, BAD_CAST "ordered");
+			xmlChar *restricted = xmlGetProp(cur_node, BAD_CAST "restricted");
+			char o, r;
+			int first_node = 1;
+
+			INT_TO_CHAR(o, ordered)
+			INT_TO_CHAR(r, restricted)
+			printf("%-16.16s %c%c ", name, o, r);
+			for (fnode = cur_node->children; fnode; fnode = fnode->next)
+				if (fnode->type == XML_ELEMENT_NODE &&
+					strcmp((char *)fnode->name, "failoverdomainnode") == 0)
+				{
+					xmlChar *fname  = xmlGetProp(fnode, BAD_CAST "name");
+					if (first_node) {
+						printf("%s", fname);
+						first_node = 0;
+					} else
+						printf(",%s", fname);
+				}
+			printf("\n");
+		}
+	}
+}
diff --git a/config/tools/ccs_tool/editconf.h b/config/tools/ccs_tool/editconf.h
index 3d1f5c2..7edd52f 100644
--- a/config/tools/ccs_tool/editconf.h
+++ b/config/tools/ccs_tool/editconf.h
@@ -4,6 +4,7 @@ void add_service(int argc, char **argv);
 void add_script(int argc, char **argv);
 void add_ip(int argc, char **argv);
 void add_fs(int argc, char **argv);
+void add_fdomain(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);
@@ -13,4 +14,5 @@ void list_fences(int argc, char **argv);
 void list_scripts(int argc, char **argv);
 void list_ips(int argc, char **argv);
 void list_fs(int argc, char **argv);
+void list_fdomains(int argc, char **argv);
 void create_skeleton(int argc, char **argv);
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Cluster-devel] [PATCH 8/8] Added ability to reference domains from services
  2010-12-10  9:00 [Cluster-devel] [PATCH 0/8] ccs_tool enhancement Dmitry Mishin
                   ` (6 preceding siblings ...)
  2010-12-10  9:00 ` [Cluster-devel] [PATCH 7/8] Added 'failoverdomain' " Dmitry Mishin
@ 2010-12-10  9:00 ` Dmitry Mishin
  2010-12-10  9:12 ` [Cluster-devel] [PATCH 0/8] ccs_tool enhancement Fabio M. Di Nitto
  8 siblings, 0 replies; 13+ messages in thread
From: Dmitry Mishin @ 2010-12-10  9:00 UTC (permalink / raw)
  To: cluster-devel.redhat.com

Signed-off-by: Dmitry Mishin <dim@parallels.com>
---
 config/tools/ccs_tool/editconf.c |   15 ++++++++++++++-
 1 files changed, 14 insertions(+), 1 deletions(-)

diff --git a/config/tools/ccs_tool/editconf.c b/config/tools/ccs_tool/editconf.c
index aae1095..baa6fd3 100644
--- a/config/tools/ccs_tool/editconf.c
+++ b/config/tools/ccs_tool/editconf.c
@@ -46,6 +46,7 @@ struct option_info
 	const char *exclusive;
 	const char *recovery;
 	const char *fs;
+	const char *domain;
 	const char *script;
 	const char *mountpoint;
 	const char *type;
@@ -695,6 +696,7 @@ static void add_clusterservice(xmlNode *root_element, struct option_info *ninfo,
 {
 	xmlNode *rm;
 	xmlNode *rs;
+	xmlNode *fdomains;
 	xmlNode *newnode;
 
 	xmlNode *newfs = NULL;
@@ -711,6 +713,7 @@ static void add_clusterservice(xmlNode *root_element, struct option_info *ninfo,
 				ninfo->configfile);
 
 	rs = findnode(rm, "resources");
+	fdomains = findnode(rm, "failoverdomains");
 	if (ninfo->fs && (!rs || !find_fs_resource(rs, ninfo->fs)))
 		die("fs resource %s doesn't exist in %s\n", ninfo->fs,
 				ninfo->configfile);
@@ -720,11 +723,16 @@ static void add_clusterservice(xmlNode *root_element, struct option_info *ninfo,
 	if (ninfo->ip_addr && (!rs || !find_ip_resource(rs, ninfo->ip_addr)))
 		die("ip resource %s doesn't exist in %s\n", ninfo->ip_addr,
 				ninfo->configfile);
+	if (ninfo->domain && (!fdomains || !find_fdomain_resource(fdomains, ninfo->domain)))
+		die("failover domain %s doesn't exist in %s\n", ninfo->domain,
+				ninfo->configfile);
 
 	/* Add the new service */
 	newnode = xmlNewNode(NULL, BAD_CAST "service");
 	xmlSetProp(newnode, BAD_CAST "name", BAD_CAST ninfo->name);
 	xmlSetProp(newnode, BAD_CAST "autostart", BAD_CAST ninfo->autostart);
+	if (ninfo->domain)
+		xmlSetProp(newnode, BAD_CAST "domain", BAD_CAST ninfo->domain);
 	if (ninfo->exclusive)
 		xmlSetProp(newnode, BAD_CAST "exclusive",
 				BAD_CAST ninfo->exclusive);
@@ -1135,6 +1143,7 @@ struct option list_options[] =
 struct option addservice_options[] =
 {
       { "autostart", required_argument, NULL, 'a'},
+      { "domain", required_argument, NULL, 'd'},
       { "exclusive", required_argument, NULL, 'x'},
       { "recovery", required_argument, NULL, 'r'},
       { "fs", required_argument, NULL, 'f'},
@@ -1553,7 +1562,7 @@ void add_service(int argc, char **argv)
 	ninfo.autostart = "1";
 	ninfo.recovery = "relocate";
 
-	while ( (opt = getopt_long(argc, argv, "a:x:r:f:o:c:s:i:CFh?", addservice_options, NULL)) != EOF)
+	while ( (opt = getopt_long(argc, argv, "a:d:x:r:f:o:c:s:i:CFh?", addservice_options, NULL)) != EOF)
 	{
 		switch(opt)
 		{
@@ -1562,6 +1571,10 @@ void add_service(int argc, char **argv)
 			ninfo.autostart = optarg;
 			break;
 
+		case 'd':
+			ninfo.domain = strdup(optarg);
+			break;
+
 		case 'x':
 			validate_int_arg(opt, optarg);
 			ninfo.exclusive = optarg;
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Cluster-devel] [PATCH 0/8] ccs_tool enhancement
  2010-12-10  9:00 [Cluster-devel] [PATCH 0/8] ccs_tool enhancement Dmitry Mishin
                   ` (7 preceding siblings ...)
  2010-12-10  9:00 ` [Cluster-devel] [PATCH 8/8] Added ability to reference domains from services Dmitry Mishin
@ 2010-12-10  9:12 ` Fabio M. Di Nitto
  2010-12-10  9:37   ` Dmitry Mishin
  8 siblings, 1 reply; 13+ messages in thread
From: Fabio M. Di Nitto @ 2010-12-10  9:12 UTC (permalink / raw)
  To: cluster-devel.redhat.com

On 12/10/2010 10:00 AM, Dmitry Mishin wrote:
> This patchset enhances ccs_tool allowing to create basic cluster configs
> entirely via this tool.
> 
> Thanks,
> Dmitry.
> 

Wow... against what branch is this patch set?

Thanks
Fabio



^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Cluster-devel] [PATCH 0/8] ccs_tool enhancement
  2010-12-10  9:37   ` Dmitry Mishin
@ 2010-12-10  9:36     ` Fabio M. Di Nitto
  0 siblings, 0 replies; 13+ messages in thread
From: Fabio M. Di Nitto @ 2010-12-10  9:36 UTC (permalink / raw)
  To: cluster-devel.redhat.com

Ok,... the patch set looks really nice, just a couple of quirks:

1) the master branch has been obsoleted since eventually cman will
disappear in favor of corosync quorum providers

2) the patchset can still go in the STABLE31 branch since ccs_tool is
still present there.

Would it be possible for you to rebase the patchset on ccs_tool from
STABLE31?

I?d be happy to pull the whole thing in.

thanks!
Fabio

On 12/10/2010 10:37 AM, Dmitry Mishin wrote:
> dim at dim-nb:~/src/cluster> cat .git/config 
> [core]
>         repositoryformatversion = 0
>         filemode = true
>         bare = false
>         logallrefupdates = true
> [remote "origin"]
>         fetch = +refs/heads/*:refs/remotes/origin/*
>         url = git://git.fedorahosted.org/cluster.git
> [branch "master"]
>         remote = origin
>         merge = refs/heads/master
> dim at dim-nb:~/src/cluster> cat .git/ORIG_HEAD 
> 536b9582b9bda33576fe78f6645562acc540f1f4
> 
> On Friday 10 December 2010 12:12:36 Fabio M. Di Nitto wrote:
>> On 12/10/2010 10:00 AM, Dmitry Mishin wrote:
>>> This patchset enhances ccs_tool allowing to create basic cluster configs
>>> entirely via this tool.
>>>
>>> Thanks,
>>> Dmitry.
>>
>> Wow... against what branch is this patch set?
>>
>> Thanks
>> Fabio
> 



^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Cluster-devel] [PATCH 0/8] ccs_tool enhancement
  2010-12-10  9:12 ` [Cluster-devel] [PATCH 0/8] ccs_tool enhancement Fabio M. Di Nitto
@ 2010-12-10  9:37   ` Dmitry Mishin
  2010-12-10  9:36     ` Fabio M. Di Nitto
  0 siblings, 1 reply; 13+ messages in thread
From: Dmitry Mishin @ 2010-12-10  9:37 UTC (permalink / raw)
  To: cluster-devel.redhat.com

dim at dim-nb:~/src/cluster> cat .git/config 
[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
[remote "origin"]
        fetch = +refs/heads/*:refs/remotes/origin/*
        url = git://git.fedorahosted.org/cluster.git
[branch "master"]
        remote = origin
        merge = refs/heads/master
dim at dim-nb:~/src/cluster> cat .git/ORIG_HEAD 
536b9582b9bda33576fe78f6645562acc540f1f4

On Friday 10 December 2010 12:12:36 Fabio M. Di Nitto wrote:
> On 12/10/2010 10:00 AM, Dmitry Mishin wrote:
> > This patchset enhances ccs_tool allowing to create basic cluster configs
> > entirely via this tool.
> > 
> > Thanks,
> > Dmitry.
> 
> Wow... against what branch is this patch set?
> 
> Thanks
> Fabio

-- 
Thanks,
Dmitry.



^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Cluster-devel] [PATCH 8/8] Added ability to reference domains from services
  2010-12-10 13:42 [Cluster-devel] [PATCH 0/8] [STABLE31] sccs_tool enhancement Dmitry Mishin
@ 2010-12-10 13:42 ` Dmitry Mishin
  0 siblings, 0 replies; 13+ messages in thread
From: Dmitry Mishin @ 2010-12-10 13:42 UTC (permalink / raw)
  To: cluster-devel.redhat.com

Signed-off-by: Dmitry Mishin <dim@parallels.com>
---
 config/tools/ccs_tool/editconf.c |   15 ++++++++++++++-
 1 files changed, 14 insertions(+), 1 deletions(-)

diff --git a/config/tools/ccs_tool/editconf.c b/config/tools/ccs_tool/editconf.c
index 516b338..a443831 100644
--- a/config/tools/ccs_tool/editconf.c
+++ b/config/tools/ccs_tool/editconf.c
@@ -44,6 +44,7 @@ struct option_info
 	const char *exclusive;
 	const char *recovery;
 	const char *fs;
+	const char *domain;
 	const char *script;
 	const char *mountpoint;
 	const char *type;
@@ -696,6 +697,7 @@ static void add_clusterservice(xmlNode *root_element, struct option_info *ninfo,
 {
 	xmlNode *rm;
 	xmlNode *rs;
+	xmlNode *fdomains;
 	xmlNode *newnode;
 
 	xmlNode *newfs = NULL;
@@ -712,6 +714,7 @@ static void add_clusterservice(xmlNode *root_element, struct option_info *ninfo,
 				ninfo->configfile);
 
 	rs = findnode(rm, "resources");
+	fdomains = findnode(rm, "failoverdomains");
 	if (ninfo->fs && (!rs || !find_fs_resource(rs, ninfo->fs)))
 		die("fs resource %s doesn't exist in %s\n", ninfo->fs,
 				ninfo->configfile);
@@ -721,11 +724,16 @@ static void add_clusterservice(xmlNode *root_element, struct option_info *ninfo,
 	if (ninfo->ip_addr && (!rs || !find_ip_resource(rs, ninfo->ip_addr)))
 		die("ip resource %s doesn't exist in %s\n", ninfo->ip_addr,
 				ninfo->configfile);
+	if (ninfo->domain && (!fdomains || !find_fdomain_resource(fdomains, ninfo->domain)))
+		die("failover domain %s doesn't exist in %s\n", ninfo->domain,
+				ninfo->configfile);
 
 	/* Add the new service */
 	newnode = xmlNewNode(NULL, BAD_CAST "service");
 	xmlSetProp(newnode, BAD_CAST "name", BAD_CAST ninfo->name);
 	xmlSetProp(newnode, BAD_CAST "autostart", BAD_CAST ninfo->autostart);
+	if (ninfo->domain)
+		xmlSetProp(newnode, BAD_CAST "domain", BAD_CAST ninfo->domain);
 	if (ninfo->exclusive)
 		xmlSetProp(newnode, BAD_CAST "exclusive",
 				BAD_CAST ninfo->exclusive);
@@ -1137,6 +1145,7 @@ struct option create_options[] =
 struct option addservice_options[] =
 {
       { "autostart", required_argument, NULL, 'a'},
+      { "domain", required_argument, NULL, 'd'},
       { "exclusive", required_argument, NULL, 'x'},
       { "recovery", required_argument, NULL, 'r'},
       { "fs", required_argument, NULL, 'f'},
@@ -1530,7 +1539,7 @@ void add_service(int argc, char **argv)
 	ninfo.autostart = "1";
 	ninfo.recovery = "relocate";
 
-	while ( (opt = getopt_long(argc, argv, "a:x:r:f:o:c:s:i:CFh?", addservice_options, NULL)) != EOF)
+	while ( (opt = getopt_long(argc, argv, "a:d:x:r:f:o:c:s:i:CFh?", addservice_options, NULL)) != EOF)
 	{
 		switch(opt)
 		{
@@ -1539,6 +1548,10 @@ void add_service(int argc, char **argv)
 			ninfo.autostart = optarg;
 			break;
 
+		case 'd':
+			ninfo.domain = strdup(optarg);
+			break;
+
 		case 'x':
 			validate_int_arg(opt, optarg);
 			ninfo.exclusive = optarg;
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2010-12-10 13:42 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-12-10  9:00 [Cluster-devel] [PATCH 0/8] ccs_tool enhancement Dmitry Mishin
2010-12-10  9:00 ` [Cluster-devel] [PATCH 1/8] Add "service" object manipulations Dmitry Mishin
2010-12-10  9:00 ` [Cluster-devel] [PATCH 2/8] Unify 'del' functions Dmitry Mishin
2010-12-10  9:00 ` [Cluster-devel] [PATCH 3/8] Add "script" object manipulations Dmitry Mishin
2010-12-10  9:00 ` [Cluster-devel] [PATCH 4/8] Unify parsing of options Dmitry Mishin
2010-12-10  9:00 ` [Cluster-devel] [PATCH 5/8] Added "ip" object manipulations Dmitry Mishin
2010-12-10  9:00 ` [Cluster-devel] [PATCH 6/8] Added 'fs' " Dmitry Mishin
2010-12-10  9:00 ` [Cluster-devel] [PATCH 7/8] Added 'failoverdomain' " Dmitry Mishin
2010-12-10  9:00 ` [Cluster-devel] [PATCH 8/8] Added ability to reference domains from services Dmitry Mishin
2010-12-10  9:12 ` [Cluster-devel] [PATCH 0/8] ccs_tool enhancement Fabio M. Di Nitto
2010-12-10  9:37   ` Dmitry Mishin
2010-12-10  9:36     ` Fabio M. Di Nitto
2010-12-10 13:42 [Cluster-devel] [PATCH 0/8] [STABLE31] sccs_tool enhancement Dmitry Mishin
2010-12-10 13:42 ` [Cluster-devel] [PATCH 8/8] Added ability to reference domains from services Dmitry Mishin

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.