From mboxrd@z Thu Jan 1 00:00:00 1970 From: Dmitry Mishin Date: Fri, 10 Dec 2010 12:00:08 +0300 Subject: [Cluster-devel] [PATCH 3/8] Add "script" object manipulations In-Reply-To: <1291971613-13076-1-git-send-email-dim@parallels.com> References: <1291971613-13076-1-git-send-email-dim@parallels.com> Message-ID: <1291971613-13076-4-git-send-email-dim@parallels.com> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 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 --- 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 Add a new fence device\n" " delfence Delete a fence device\n" + " addscript Add a script resource\n" + " delscript 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] \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