From: Colin Patrick McCabe Date: Tue, 23 Aug 2011 22:43:52 +0000 (-0700) Subject: injectargs: binary flags only consume 1 token X-Git-Tag: v0.35~252 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=18ec5655feb805c1c113410d49f92516e8a9c3aa;p=ceph.git injectargs: binary flags only consume 1 token Never consume more than one token when parsing a binary flag. Basically, your choices are --foo=false, --foo=true, and just --foo. However, only 1 token will ever be examined. Signed-off-by: Colin McCabe --- diff --git a/src/common/ceph_argparse.cc b/src/common/ceph_argparse.cc index 7481f91a93ef..d0570d425f21 100644 --- a/src/common/ceph_argparse.cc +++ b/src/common/ceph_argparse.cc @@ -24,10 +24,12 @@ #include "msg/msg_types.h" #include +#include #include #include #include #include +#include #include /* @@ -276,6 +278,55 @@ bool ceph_argparse_flag(std::vector &args, } } +bool ceph_argparse_binary_flag(std::vector &args, + std::vector::iterator &i, int *ret, + std::ostringstream *oss, ...) +{ + const char *first = *i; + char tmp[strlen(first)+1]; + dashes_to_underscores(first, tmp); + first = tmp; + const char *a; + va_list ap; + int strlen_a; + + // does this argument match any of the possibilities? + va_start(ap, oss); + while (1) { + a = va_arg(ap, char*); + if (a == NULL) + return false; + strlen_a = strlen(a); + char a2[strlen_a+1]; + dashes_to_underscores(a, a2); + if (strncmp(a2, first, strlen(a2)) == 0) { + if (first[strlen_a] == '=') { + i = args.erase(i); + const char *val = first + strlen_a + 1; + if (strcmp(val, "true") == 0) { + *ret = 1; + return true; + } + else if (strcmp(val, "false") == 0) { + *ret = 0; + return true; + } + if (oss) { + (*oss) << "Parse error parsing binary flag " << a + << ". Expected true or false, but got '" << val << "'\n"; + } + *ret = -EINVAL; + return true; + } + else if (first[strlen_a] == '\0') { + i = args.erase(i); + *ret = 1; + return true; + } + } + } +} + bool ceph_argparse_witharg(std::vector &args, std::vector::iterator &i, std::string *ret, ...) { diff --git a/src/common/ceph_argparse.h b/src/common/ceph_argparse.h index 91f9981b908f..01098188f753 100644 --- a/src/common/ceph_argparse.h +++ b/src/common/ceph_argparse.h @@ -96,6 +96,9 @@ bool ceph_argparse_flag(std::vector &args, std::vector::iterator &i, ...); bool ceph_argparse_witharg(std::vector &args, std::vector::iterator &i, std::string *ret, ...); +bool ceph_argparse_binary_flag(std::vector &args, + std::vector::iterator &i, int *ret, + std::ostringstream *oss, ...); extern CephInitParameters ceph_argparse_early_args (std::vector& args, uint32_t module_type, int flags, std::string *conf_file_list); diff --git a/src/common/config.cc b/src/common/config.cc index 52021e4949b3..e97e7fc34474 100644 --- a/src/common/config.cc +++ b/src/common/config.cc @@ -46,6 +46,7 @@ using std::map; using std::multimap; +using std::ostringstream; using std::pair; using std::set; using std::string; @@ -679,10 +680,18 @@ int md_config_t::parse_injectargs(std::vector& args, const config_option *opt = config_optionsp + o; std::string as_option("--"); as_option += opt->name; - if ((opt->type == OPT_BOOL) && - ceph_argparse_flag(args, i, as_option.c_str(), (char*)NULL)) { - set_val_impl("true", opt); - break; + if (opt->type == OPT_BOOL) { + int res; + if (ceph_argparse_binary_flag(args, i, &res, oss, as_option.c_str(), + (char*)NULL)) { + if (res == 0) + set_val_impl("false", opt); + else if (res == 1) + set_val_impl("true", opt); + else + ret = res; + break; + } } else if (ceph_argparse_witharg(args, i, &val, as_option.c_str(), (char*)NULL)) { diff --git a/src/test/daemon_config.cc b/src/test/daemon_config.cc index ffc48d67b73d..288c643dbbaf 100644 --- a/src/test/daemon_config.cc +++ b/src/test/daemon_config.cc @@ -175,7 +175,7 @@ TEST(DaemonConfig, InjectArgsBooleans) { // parse error std::ostringstream chat4; - injection = "--debug 1 --log_to_syslog=falsey --debug-ms 40"; + injection = "--debug 1 --log_to_syslog=falsey --debug-ms 42"; ret = g_ceph_context->_conf->injectargs(injection, &chat3); ASSERT_EQ(ret, -EINVAL); @@ -184,6 +184,12 @@ TEST(DaemonConfig, InjectArgsBooleans) { ret = g_ceph_context->_conf->get_val("log_to_syslog", &tmp, sizeof(buf)); ASSERT_EQ(ret, 0); ASSERT_EQ(string("true"), string(buf)); + + // debug-ms should still become 42... + memset(buf, 0, sizeof(buf)); + ret = g_ceph_context->_conf->get_val("debug_ms", &tmp, sizeof(buf)); + ASSERT_EQ(ret, 0); + ASSERT_EQ(string("42"), string(buf)); } TEST(DaemonConfig, InjectArgsLogfile) {