diff --git a/tools/crm_verify.c b/tools/crm_verify.c index 1db394ab10..01b4f2add1 100644 --- a/tools/crm_verify.c +++ b/tools/crm_verify.c @@ -1,323 +1,295 @@ /* * Copyright (C) 2004 Andrew Beekhof * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include -#define OPTARGS "V?X:x:pLS:" +#define OPTARGS "" #ifdef HAVE_GETOPT_H # include #endif #include #include gboolean USE_LIVE_CIB = FALSE; char *cib_save = NULL; void usage(const char *cmd, int exit_status); extern gboolean stage0(pe_working_set_t *data_set); extern void cleanup_alloc_calculations(pe_working_set_t *data_set); extern xmlNode * do_calculations( pe_working_set_t *data_set, xmlNode *xml_input, ha_time_t *now); +static struct crm_option long_options[] = { + /* Top-level Options */ + {"help", 0, 0, '?', "This text"}, + {"version", 0, 0, 'v', "Version information" }, + {"verbose", 0, 0, 'V', "Increase debug output\n"}, + + {F_CRM_DATA, 1, 0, 'X', NULL, 1}, /* legacy */ + {"xml-text", 1, 0, 'X', "Check the configuration in the supplied string"}, + {"xml-file", 1, 0, 'x', "Check the configuration in the named file"}, + {"xml-pipe", 0, 0, 'p', "\tCheck the configuration piped in via stdin"}, + {"live-check", 0, 0, 'L', "Check the configuration used by the running cluster\n"}, + + {"save-xml", 1, 0, 'S'}, + + {0, 0, 0, 0} +}; + int main(int argc, char **argv) { xmlNode *cib_object = NULL; xmlNode *status = NULL; int argerr = 0; int flag; + int option_index = 0; pe_working_set_t data_set; cib_t * cib_conn = NULL; int rc = cib_ok; gboolean xml_stdin = FALSE; const char *xml_tag = NULL; const char *xml_file = NULL; const char *xml_string = NULL; g_log_set_handler(NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG | G_LOG_FLAG_RECURSION | G_LOG_FLAG_FATAL, cl_glib_msg_handler, NULL); /* and for good measure... - this enum is a bit field (!) */ g_log_set_always_fatal((GLogLevelFlags)0); /*value out of range*/ crm_log_init(basename(argv[0]), LOG_ERR, FALSE, TRUE, 0, NULL); + crm_set_options("V?X:x:pLS:v", NULL, long_options, + "Check a (complete) confiuration for syntax and common conceptual errors.\n" + " Checks the well-formedness of an XML configuration, its conformance to the configured DTD/schema and for the presence of common misconfigurations.\n"); while (1) { -#ifdef HAVE_GETOPT_H - int option_index = 0; - static struct option long_options[] = { - /* Top-level Options */ - {F_CRM_DATA, 1, 0, 'X'}, /* legacy */ - {"xml-text", 1, 0, 'X'}, - {"xml-file", 1, 0, 'x'}, - {"xml-pipe", 0, 0, 'p'}, - {"save-xml", 1, 0, 'S'}, - {"live-check", 0, 0, 'L'}, - {"help", 0, 0, '?'}, - - {0, 0, 0, 0} - }; -#endif - -#ifdef HAVE_GETOPT_H - flag = getopt_long(argc, argv, OPTARGS, - long_options, &option_index); -#else - flag = getopt(argc, argv, OPTARGS); -#endif + flag = crm_get_option(argc, argv, &option_index); if (flag == -1) break; switch(flag) { #ifdef HAVE_GETOPT_H case 0: printf("option %s", long_options[option_index].name); if (optarg) printf(" with arg %s", optarg); printf("\n"); break; #endif case 'X': crm_debug_2("Option %c => %s", flag, optarg); xml_string = crm_strdup(optarg); break; case 'x': crm_debug_2("Option %c => %s", flag, optarg); xml_file = crm_strdup(optarg); break; case 'p': xml_stdin = TRUE; break; case 'S': cib_save = crm_strdup(optarg); break; case 'V': alter_debug(DEBUG_INC); break; case 'L': USE_LIVE_CIB = TRUE; break; case '?': - usage(crm_system_name, LSB_EXIT_OK); + case 'v': + crm_help(flag, LSB_EXIT_OK); break; default: printf("?? getopt returned character code 0%o ??\n", flag); ++argerr; break; } } if (optind < argc) { printf("non-option ARGV-elements: "); while (optind < argc) { printf("%s ", argv[optind++]); } printf("\n"); } if (optind > argc) { ++argerr; } if (argerr) { crm_err("%d errors in option parsing", argerr); - usage(crm_system_name, LSB_EXIT_GENERIC); + crm_help(flag, LSB_EXIT_GENERIC); } crm_info("=#=#=#=#= Getting XML =#=#=#=#="); if(USE_LIVE_CIB) { cib_conn = cib_new(); rc = cib_conn->cmds->signon(cib_conn, crm_system_name, cib_command); } if(USE_LIVE_CIB) { if(rc == cib_ok) { int options = cib_scope_local|cib_sync_call; crm_info("Reading XML from: live cluster"); rc = cib_conn->cmds->query( cib_conn, NULL, &cib_object, options); } if(rc != cib_ok) { fprintf(stderr, "Live CIB query failed: %s\n", cib_error2string(rc)); return 3; } if(cib_object == NULL) { fprintf(stderr, "Live CIB query failed: empty result\n"); return 3; } } else if(xml_file != NULL) { cib_object = filename2xml(xml_file); if(cib_object == NULL) { fprintf(stderr, "Couldn't parse input file: %s\n", xml_file); return 4; } } else if(xml_string != NULL) { cib_object = string2xml(xml_string); if(cib_object == NULL) { fprintf(stderr, "Couldn't parse input string: %s\n", xml_string); return 4; } } else if(xml_stdin) { cib_object = stdin2xml(); if(cib_object == NULL) { fprintf(stderr, "Couldn't parse input from STDIN.\n"); return 4; } } else { fprintf(stderr, "No configuration source specified." " Use --help for usage information.\n"); return 5; } xml_tag = crm_element_name(cib_object); if(safe_str_neq(xml_tag, XML_TAG_CIB)) { fprintf(stderr, "This tool can only check complete configurations (ie. those starting with ).\n"); return 6; } if(cib_save != NULL) { write_xml_file(cib_object, cib_save, FALSE); } status = get_object_root(XML_CIB_TAG_STATUS, cib_object); if(status == NULL) { create_xml_node(cib_object, XML_CIB_TAG_STATUS); } #if CRM_DEPRECATED_SINCE_2_0_4 xml_child_iter_filter(status, node_state, XML_CIB_TAG_STATE, xml_remove_prop(node_state, XML_CIB_TAG_LRM); ); #endif if(validate_xml(cib_object, NULL, FALSE) == FALSE) { crm_config_err("CIB did not pass DTD/schema validation"); free_xml(cib_object); cib_object = NULL; } else if(cli_config_update(&cib_object, NULL) == FALSE) { crm_config_error = TRUE; free_xml(cib_object); cib_object = NULL; fprintf(stderr, "The cluster will NOT be able to use this configuration.\n"); fprintf(stderr, "Please manually update the configuration to conform to the %s syntax.\n", LATEST_SCHEMA_VERSION); } if(cib_object == NULL) { } else if(USE_LIVE_CIB) { /* we will always have a status section and can do a full simulation */ do_calculations(&data_set, cib_object, NULL); cleanup_alloc_calculations(&data_set); } else { set_working_set_defaults(&data_set); data_set.now = new_ha_date(TRUE); data_set.input = cib_object; stage0(&data_set); cleanup_alloc_calculations(&data_set); } if(crm_config_error) { fprintf(stderr, "Errors found during check: config not valid\n"); if(crm_log_level < LOG_WARNING) { fprintf(stderr, " -V may provide more details\n"); } rc = 2; } else if(crm_config_warning) { fprintf(stderr, "Warnings found during check: config may not be valid\n"); if(crm_log_level < LOG_WARNING) { fprintf(stderr, " Use -V for more details\n"); } rc = 1; } if(USE_LIVE_CIB) { cib_conn->cmds->signoff(cib_conn); cib_delete(cib_conn); } return rc; } - - -void -usage(const char *cmd, int exit_status) -{ - FILE *stream; - - stream = exit_status ? stderr : stdout; - fprintf(stream, "%s -- Check a (complete) confiuration for syntax and common conceptual errors.\n" - " Checks the well-formedness of an XML configuration, its conformance to the specified DTD or schema and for the presence of common misconfigurations.\n\n", - cmd); - fprintf(stream, "usage: %s [-V] [-D] -(?|L|X|x|p)\n", cmd); - - fprintf(stream, "\t--%s (-%c)\t: this help message\n", "help", '?'); - fprintf(stream, "\t--%s (-%c)\t: " - "turn on debug info. additional instances increase verbosity\n", - "verbose", 'V'); - fprintf(stream, "\t--%s (-%c)\t: Connect to the running cluster\n", - "live-check", 'L'); - fprintf(stream, "\t--%s (-%c) \t: Use the configuration in the supplied string\n", - F_CRM_DATA, 'X'); - fprintf(stream, "\t--%s (-%c) \t: Use the configuration in the named file\n", - "xml-file", 'x'); - fprintf(stream, "\t--%s (-%c) \t: Use the configuration piped in via stdin\n", - "xml-pipe", 'p'); - fflush(stream); - - exit(exit_status); -}