All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dmitry Mishin <dim@parallels.com>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] [PATCH 7/8] Added 'failoverdomain' object manipulations
Date: Fri, 10 Dec 2010 12:00:12 +0300	[thread overview]
Message-ID: <1291971613-13076-8-git-send-email-dim@parallels.com> (raw)
In-Reply-To: <1291971613-13076-1-git-send-email-dim@parallels.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



  parent reply	other threads:[~2010-12-10  9:00 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 ` Dmitry Mishin [this message]
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
  -- strict thread matches above, loose matches on Subject: below --
2010-12-10 13:42 [Cluster-devel] [PATCH 0/8] [STABLE31] sccs_tool enhancement Dmitry Mishin
2010-12-10 13:42 ` [Cluster-devel] [PATCH 7/8] Added 'failoverdomain' object manipulations Dmitry Mishin

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=1291971613-13076-8-git-send-email-dim@parallels.com \
    --to=dim@parallels.com \
    /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.