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 16:42:36 +0300 [thread overview]
Message-ID: <1291988557-22348-8-git-send-email-dim@parallels.com> (raw)
In-Reply-To: <1291988557-22348-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 | 281 +++++++++++++++++++++++++++++++++++++-
config/tools/ccs_tool/editconf.h | 2 +
3 files changed, 294 insertions(+), 10 deletions(-)
diff --git a/config/tools/ccs_tool/ccs_tool.c b/config/tools/ccs_tool/ccs_tool.c
index 92a7dac..28bbadc 100644
--- a/config/tools/ccs_tool/ccs_tool.c
+++ b/config/tools/ccs_tool/ccs_tool.c
@@ -257,6 +257,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);
@@ -289,6 +297,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);
@@ -339,9 +351,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 ac522d8..516b338 100644
--- a/config/tools/ccs_tool/editconf.c
+++ b/config/tools/ccs_tool/editconf.c
@@ -25,6 +25,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;
@@ -45,10 +51,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;
};
static void config_usage(int rw)
@@ -170,6 +179,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");
@@ -454,7 +477,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;
}
}
@@ -496,6 +519,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");
@@ -521,6 +549,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)
*/
@@ -751,6 +797,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;
@@ -934,6 +1030,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'},
@@ -957,6 +1092,15 @@ struct option addfs_options[] =
{ NULL, 0, NULL, 0 },
};
+struct option addfdomain_options[] =
+{
+ { "outputfile", required_argument, NULL, 'o'},
+ { "configfile", required_argument, NULL, 'c'},
+ { "ordered", no_argument, NULL, 'p'},
+ { "restricted", no_argument, NULL, 'r'},
+ { NULL, 0, NULL, 0 },
+};
+
struct option commonw_options[] =
{
{ "outputfile", required_argument, NULL, 'o'},
@@ -1287,6 +1431,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);
@@ -1683,6 +1829,64 @@ 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));
+
+ 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 '?':
+ 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)
{
char *fencename = NULL;
@@ -2066,17 +2270,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
next prev parent reply other threads:[~2010-12-10 13:42 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-12-10 13:42 [Cluster-devel] [PATCH 0/8] [STABLE31] sccs_tool enhancement Dmitry Mishin
2010-12-10 13:42 ` [Cluster-devel] [PATCH 1/8] Add "service" object manipulations Dmitry Mishin
2010-12-10 14:49 ` Lon Hohberger
2010-12-10 14:51 ` Lon Hohberger
2010-12-10 13:42 ` [Cluster-devel] [PATCH 2/8] Unify 'del' functions Dmitry Mishin
2010-12-10 13:42 ` [Cluster-devel] [PATCH 3/8] Add "script" object manipulations Dmitry Mishin
2010-12-10 13:42 ` [Cluster-devel] [PATCH 4/8] Unify parsing of options Dmitry Mishin
2010-12-10 13:42 ` [Cluster-devel] [PATCH 5/8] Added "ip" object manipulations Dmitry Mishin
2010-12-10 13:42 ` [Cluster-devel] [PATCH 6/8] Added 'fs' " Dmitry Mishin
2010-12-10 13:42 ` Dmitry Mishin [this message]
2010-12-10 13:42 ` [Cluster-devel] [PATCH 8/8] Added ability to reference domains from services Dmitry Mishin
2010-12-10 14:17 ` [Cluster-devel] [PATCH 0/8] [STABLE31] sccs_tool enhancement Fabio M. Di Nitto
2010-12-15 8:06 ` Fabio M. Di Nitto
-- strict thread matches above, loose matches on Subject: below --
2010-12-10 9:00 [Cluster-devel] [PATCH 0/8] ccs_tool enhancement Dmitry Mishin
2010-12-10 9:00 ` [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=1291988557-22348-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.