]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
ceph_argparse: don't die when called by injectargs 4210/head
authorMykola Golub <mgolub@mirantis.com>
Tue, 31 Mar 2015 10:24:39 +0000 (13:24 +0300)
committerMykola Golub <mgolub@mirantis.com>
Sat, 4 Apr 2015 07:55:04 +0000 (10:55 +0300)
Fixes: #11261
Signed-off-by: Mykola Golub <mgolub@mirantis.com>
qa/workunits/cephtool/test.sh
src/common/ceph_argparse.cc
src/common/ceph_argparse.h
src/common/config.cc
src/test/ceph_argparse.cc

index 64663fcd702f84474a0835b83cf23b49eb23f308..595fa1a9fa94e37aa41b58b8e34af64871f36494 100755 (executable)
@@ -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()
index eff6120df201eb911cb2f8387323b6ea70b79498..791ece793203f0ec19fb09b79bd82cda79be4d5b 100644 (file)
@@ -297,8 +297,9 @@ bool ceph_argparse_binary_flag(std::vector<const char*> &args,
   return r;
 }
 
-static bool va_ceph_argparse_witharg(std::vector<const char*> &args,
-       std::vector<const char*>::iterator &i, std::string *ret, va_list ap)
+static int va_ceph_argparse_witharg(std::vector<const char*> &args,
+       std::vector<const char*>::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<const char*> &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<const char*> &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<const char*> &args,
        std::vector<const char*>::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<float>(std::vector<const char*> &args,
        std::vector<const char*>::iterator &i, float *ret,
        std::ostream &oss, ...);
 
+bool ceph_argparse_witharg(std::vector<const char*> &args,
+       std::vector<const char*>::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<const char*> &args,
        std::vector<const char*>::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
index e5845fb32d34aa42c6e52a3acd6d01eff77a9346..6ad0234df0274ca27ef62d6b4a178e77905646cb 100644 (file)
@@ -55,6 +55,9 @@ bool ceph_argparse_double_dash(std::vector<const char*> &args,
        std::vector<const char*>::iterator &i);
 bool ceph_argparse_flag(std::vector<const char*> &args,
        std::vector<const char*>::iterator &i, ...);
+bool ceph_argparse_witharg(std::vector<const char*> &args,
+       std::vector<const char*>::iterator &i, std::string *ret,
+       std::ostream &oss, ...);
 bool ceph_argparse_witharg(std::vector<const char*> &args,
        std::vector<const char*>::iterator &i, std::string *ret, ...);
 template<class T>
index 1efc15556084ea1c1125aef2c1485c69ebe79252..41bb6a85f8c0db291bea1a09c7b68ad03d550b99 100644 (file)
@@ -486,6 +486,7 @@ int md_config_t::parse_option(std::vector<const char*>& 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<const char*>& 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)) &&
index 49bb962a88706ea4b166ed93dd2ba338e0ce5f42..f48f387f9ffb6d872f04e03e86ff27e0d05ba7c9 100644 (file)
@@ -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<const char*>::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 = "";