FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Redhat > Cluster Development

 
 
LinkBack Thread Tools
 
Old 12-10-2010, 08:00 AM
Dmitry Mishin
 
Default Add "service" object manipulations

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
"
" delnode <node> Delete a node
"
" lsnode List nodes
"
+ " addservice <name> Add a service
"
+ " delservice <name> Delete a service
"
+ " lsservice List services
"
" lsfence List fence devices
"
" addfence <fencedev> Add a new fence device
"
" delfence <fencedev> Delete a fence device
"
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>
", 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.
");
@@ -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>
", 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
", ninfo->configfile);
+
+ /* Don't allow duplicate service names */
+ if (find_service(rm, ninfo->name))
+ die("service %s already exists in %s
", 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
", ninfo->fs,
+ ninfo->configfile);
+ if (ninfo->script && (!rs || !find_script_resource(rs, ninfo->script)))
+ die("script resource %s doesn't exist in %s
", 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
", 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
", ninfo->configfile);
+ exit(1);
+ }
+
+ oldnode = find_service(rm, ninfo->name);
+ if (!oldnode)
+ {
+ fprintf(stderr, "service %s does not exist in %s
", 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: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("
Cluster name: %s, config_version: %s

",
+ (char *)cluster_name(root_element),
+ (char *)find_version(root_element));
+
+ rm = findnode(root_element, "rm");
+ if (!rm)
+ die("Can't find "rm" in %s
", ninfo.configfile);
+
+ printf("Name Autostart Exclusive Recovery
");
+ 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
", 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
 
Old 12-10-2010, 12:42 PM
Dmitry Mishin
 
Default Add "service" object manipulations

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 | 364 +++++++++++++++++++++++++++++++++++++-
config/tools/ccs_tool/editconf.h | 3 +
3 files changed, 378 insertions(+), 4 deletions(-)

diff --git a/config/tools/ccs_tool/ccs_tool.c b/config/tools/ccs_tool/ccs_tool.c
index 34805be..2fe6f78 100644
--- a/config/tools/ccs_tool/ccs_tool.c
+++ b/config/tools/ccs_tool/ccs_tool.c
@@ -225,6 +225,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);
@@ -237,6 +245,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);
@@ -279,6 +291,9 @@ static void tool_print_usage(FILE *stream){
" addnode <node> Add a node
"
" delnode <node> Delete a node
"
" lsnode List nodes
"
+ " addservice <name> Add a service
"
+ " delservice <name> Delete a service
"
+ " lsservice List services
"
" lsfence List fence devices
"
" addfence <fencedev> Add a new fence device
"
" delfence <fencedev> Delete a fence device
"
diff --git a/config/tools/ccs_tool/editconf.c b/config/tools/ccs_tool/editconf.c
index a0371b4..d63dc37 100644
--- a/config/tools/ccs_tool/editconf.c
+++ b/config/tools/ccs_tool/editconf.c
@@ -32,7 +32,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;
@@ -121,6 +128,15 @@ static void delnode_usage(const char *name)
exit(0);
}

+static void delservice_usage(const char *name)
+{
+ fprintf(stderr, "Usage: %s %s [options] <name>
", 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.
");
@@ -160,6 +176,15 @@ static void addnode_usage(const char *name)
exit(0);
}

+static void addservice_usage(const char *name)
+{
+ fprintf(stderr, "Usage: %s %s [options] <servicename>
", 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.
@@ -378,15 +403,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;
}
@@ -394,6 +421,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)
*/
@@ -518,6 +570,79 @@ static void add_clusternode(xmlNode *root_element, struct option_info *ninfo,
}
}

+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
", ninfo->configfile);
+
+ /* Don't allow duplicate service names */
+ if (find_service(rm, ninfo->name))
+ die("service %s already exists in %s
", 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
", ninfo->fs,
+ ninfo->configfile);
+ if (ninfo->script && (!rs || !find_script_resource(rs, ninfo->script)))
+ die("script resource %s doesn't exist in %s
", 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
", 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;
@@ -562,6 +687,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
", ninfo->configfile);
+ exit(1);
+ }
+
+ oldnode = find_service(rm, ninfo->name);
+ if (!oldnode)
+ {
+ fprintf(stderr, "service %s does not exist in %s
", ninfo->name, ninfo->configfile);
+ exit(1);
+ }
+
+ xmlUnlinkNode(oldnode);
+}
+
struct option addnode_options[] =
{
{ "votes", required_argument, NULL, 'v'},
@@ -613,6 +760,25 @@ struct option create_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'},
+ { NULL, 0, NULL, 0 },
+};
+
+struct option delservice_options[] =
+{
+ { "outputfile", required_argument, NULL, 'o'},
+ { "configfile", required_argument, NULL, 'c'},
+ { NULL, 0, NULL, 0 },
+};

static int next_nodeid(int startid, int *nodeids, int nodecount)
{
@@ -966,6 +1132,196 @@ 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.autostart = "1";
+ ninfo.recovery = "relocate";
+
+ while ( (opt = getopt_long(argc, argv, "a:x:r:f: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 '?':
+ 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));
+
+ 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 '?':
+ 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("
Cluster name: %s, config_version: %s

",
+ (char *)cluster_name(root_element),
+ (char *)find_version(root_element));
+
+ rm = findnode(root_element, "rm");
+ if (!rm)
+ die("Can't find "rm" in %s
", ninfo.configfile);
+
+ printf("Name Autostart Exclusive Recovery
");
+ 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
", name,
+ atoi((char *)autostart), atoi((char *)exclusive),
+ (char *)recovery);
+ }
+}
+
void create_skeleton(int argc, char **argv)
{
char *fencename = NULL;
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
 
Old 12-10-2010, 01:49 PM
Lon Hohberger
 
Default Add "service" object manipulations

On Fri, 2010-12-10 at 16:42 +0300, Dmitry Mishin wrote:
> +static xmlNode *find_ip_resource(xmlNode *root, const char *name)
> +{
> + return do_find_node(root, name, "ip", "name");
> +}
> +

should be

return do_find_node(root, name, "ip", "address");

IP resources don't have names; the primary attribute is the address
field. Adding a "name" will break configuration validation without
patches to ip.sh and cluster.rng.

(this might happen in other patches too)

-- Lon
 
Old 12-10-2010, 01:51 PM
Lon Hohberger
 
Default Add "service" object manipulations

On Fri, 2010-12-10 at 09:49 -0500, Lon Hohberger wrote:
> On Fri, 2010-12-10 at 16:42 +0300, Dmitry Mishin wrote:
> > +static xmlNode *find_ip_resource(xmlNode *root, const char *name)
> > +{
> > + return do_find_node(root, name, "ip", "name");
> > +}
> > +
>
> should be
>
> return do_find_node(root, name, "ip", "address");
>
> IP resources don't have names; the primary attribute is the address
> field. Adding a "name" will break configuration validation without
> patches to ip.sh and cluster.rng.
>
> (this might happen in other patches too)

Scratch that, you fixed it in patch 5.

-- Lon
 

Thread Tools




All times are GMT. The time now is 09:15 PM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org