summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xqa/workunits/cephtool/test.sh2
-rw-r--r--src/common/ceph_argparse.cc54
-rw-r--r--src/common/ceph_argparse.h3
-rw-r--r--src/common/config.cc8
-rw-r--r--src/test/ceph_argparse.cc9
5 files changed, 57 insertions, 19 deletions
diff --git a/qa/workunits/cephtool/test.sh b/qa/workunits/cephtool/test.sh
index 64663fcd702..595fa1a9fa9 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 eff6120df20..791ece79320 100644
--- a/src/common/ceph_argparse.cc
+++ b/src/common/ceph_argparse.cc
@@ -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;
}
@@ -371,14 +375,28 @@ template bool ceph_argparse_witharg<float>(std::vector<const char*> &args,
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
diff --git a/src/common/ceph_argparse.h b/src/common/ceph_argparse.h
index e5845fb32d3..6ad0234df02 100644
--- a/src/common/ceph_argparse.h
+++ b/src/common/ceph_argparse.h
@@ -56,6 +56,9 @@ bool ceph_argparse_double_dash(std::vector<const char*> &args,
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>
bool ceph_argparse_witharg(std::vector<const char*> &args,
diff --git a/src/common/config.cc b/src/common/config.cc
index 1efc1555608..41bb6a85f8c 100644
--- a/src/common/config.cc
+++ b/src/common/config.cc
@@ -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)) &&
diff --git a/src/test/ceph_argparse.cc b/src/test/ceph_argparse.cc
index 49bb962a887..f48f387f9ff 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<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 = "";