From: Mykola Golub Date: Tue, 31 Mar 2015 10:24:39 +0000 (+0300) Subject: ceph_argparse: don't die when called by injectargs X-Git-Tag: v9.0.0~16^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=46103b2c3bc9a0bc1d0aea005cae3146fe334836;p=ceph.git ceph_argparse: don't die when called by injectargs Fixes: #11261 Signed-off-by: Mykola Golub --- diff --git a/qa/workunits/cephtool/test.sh b/qa/workunits/cephtool/test.sh index 64663fcd702f..595fa1a9fa94 100755 --- a/qa/workunits/cephtool/test.sh +++ b/qa/workunits/cephtool/test.sh @@ -204,6 +204,8 @@ function test_mon_injectargs() check_response "osd_debug_op_order = 'true'" ceph tell osd.0 injectargs -- '--osd_debug_op_order --osd_failsafe_full_ratio .98' >& $TMPFILE || return 1 check_response "osd_debug_op_order = 'true' osd_failsafe_full_ratio = '0.98'" + ceph tell osd.0 injectargs -- '--osd_failsafe_full_ratio' >& $TMPFILE || return 1 + check_response "Option --osd_failsafe_full_ratio requires an argument" } function test_mon_injectargs_SI() diff --git a/src/common/ceph_argparse.cc b/src/common/ceph_argparse.cc index eff6120df201..791ece793203 100644 --- a/src/common/ceph_argparse.cc +++ b/src/common/ceph_argparse.cc @@ -297,8 +297,9 @@ bool ceph_argparse_binary_flag(std::vector &args, return r; } -static bool va_ceph_argparse_witharg(std::vector &args, - std::vector::iterator &i, std::string *ret, va_list ap) +static int va_ceph_argparse_witharg(std::vector &args, + std::vector::iterator &i, std::string *ret, + std::ostream &oss, va_list ap) { const char *first = *i; char tmp[strlen(first)+1]; @@ -309,7 +310,7 @@ static bool va_ceph_argparse_witharg(std::vector &args, while (1) { const char *a = va_arg(ap, char*); if (a == NULL) - return false; + return 0; int strlen_a = strlen(a); char a2[strlen_a+1]; dashes_to_underscores(a, a2); @@ -317,18 +318,19 @@ static bool va_ceph_argparse_witharg(std::vector &args, if (first[strlen_a] == '=') { *ret = first + strlen_a + 1; i = args.erase(i); - return true; + return 1; } else if (first[strlen_a] == '\0') { // find second part (or not) if (i+1 == args.end()) { - cerr << "Option " << *i << " requires an argument." << std::endl; - _exit(1); + oss << "Option " << *i << " requires an argument."; + i = args.erase(i); + return -EINVAL; } i = args.erase(i); *ret = *i; i = args.erase(i); - return true; + return 1; } } } @@ -339,21 +341,23 @@ bool ceph_argparse_witharg(std::vector &args, std::vector::iterator &i, T *ret, std::ostream &oss, ...) { - bool r; + int r; va_list ap; std::string str; va_start(ap, oss); - r = va_ceph_argparse_witharg(args, i, &str, ap); + r = va_ceph_argparse_witharg(args, i, &str, oss, ap); va_end(ap); - if (!r) { + if (r == 0) { return false; } - std::string err; - T myret = strict_str_convert(str.c_str(), &err); - *ret = myret; - if (!err.empty()) { - oss << err; + if (r == 1) { + std::string err; + T myret = strict_str_convert(str.c_str(), &err); + *ret = myret; + if (!err.empty()) { + oss << err; + } } return true; } @@ -370,15 +374,29 @@ template bool ceph_argparse_witharg(std::vector &args, std::vector::iterator &i, float *ret, std::ostream &oss, ...); +bool ceph_argparse_witharg(std::vector &args, + std::vector::iterator &i, std::string *ret, + std::ostream &oss, ...) +{ + int r; + va_list ap; + va_start(ap, oss); + r = va_ceph_argparse_witharg(args, i, ret, oss, ap); + va_end(ap); + return r != 0; +} + bool ceph_argparse_witharg(std::vector &args, std::vector::iterator &i, std::string *ret, ...) { - bool r; + int r; va_list ap; va_start(ap, ret); - r = va_ceph_argparse_witharg(args, i, ret, ap); + r = va_ceph_argparse_witharg(args, i, ret, cerr, ap); va_end(ap); - return r; + if (r < 0) + _exit(1); + return r != 0; } CephInitParameters ceph_argparse_early_args diff --git a/src/common/ceph_argparse.h b/src/common/ceph_argparse.h index e5845fb32d34..6ad0234df027 100644 --- a/src/common/ceph_argparse.h +++ b/src/common/ceph_argparse.h @@ -55,6 +55,9 @@ bool ceph_argparse_double_dash(std::vector &args, std::vector::iterator &i); 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, + std::ostream &oss, ...); bool ceph_argparse_witharg(std::vector &args, std::vector::iterator &i, std::string *ret, ...); template diff --git a/src/common/config.cc b/src/common/config.cc index 1efc15556084..41bb6a85f8c0 100644 --- a/src/common/config.cc +++ b/src/common/config.cc @@ -486,6 +486,7 @@ int md_config_t::parse_option(std::vector& args, } for (o = 0; o < NUM_CONFIG_OPTIONS; ++o) { + ostringstream err; const config_option *opt = config_optionsp + o; std::string as_option("--"); as_option += opt->name; @@ -509,8 +510,13 @@ int md_config_t::parse_option(std::vector& args, } } } - else if (ceph_argparse_witharg(args, i, &val, + else if (ceph_argparse_witharg(args, i, &val, err, as_option.c_str(), (char*)NULL)) { + if (!err.str().empty()) { + *oss << err.str(); + ret = -EINVAL; + break; + } if (oss && ( ((opt->type == OPT_STR) || (opt->type == OPT_ADDR) || (opt->type == OPT_UUID)) && diff --git a/src/test/ceph_argparse.cc b/src/test/ceph_argparse.cc index 49bb962a8870..f48f387f9ffb 100644 --- a/src/test/ceph_argparse.cc +++ b/src/test/ceph_argparse.cc @@ -74,7 +74,10 @@ TEST(CephArgParse, SimpleArgParse) { found_foo = false; found_bar = ""; + bool baz_found = false; + std::string found_baz = ""; VectorContainer foo(FOO); + ostringstream err; for (std::vector::iterator i = foo.arr.begin(); i != foo.arr.end(); ) { @@ -83,11 +86,17 @@ TEST(CephArgParse, SimpleArgParse) { } else if (ceph_argparse_witharg(foo.arr, i, &found_bar, "--bar", (char*)NULL)) { } + else if (ceph_argparse_witharg(foo.arr, i, &found_baz, err, "--baz", (char*)NULL)) { + ASSERT_NE(string(""), err.str()); + baz_found = true; + } else ++i; } ASSERT_EQ(found_foo, true); ASSERT_EQ(found_bar, ""); + ASSERT_EQ(baz_found, true); + ASSERT_EQ(found_baz, ""); found_foo = false; found_bar = "";