Merge remote-tracking branch 'origin/wip-2862'

Reviewed-by: Josh Durgin <jdurgin@redhat.com>

Conflicts:
	src/common/ceph_argparse.cc
	src/rbd.cc
This commit is contained in:
Josh Durgin 2015-04-08 13:51:31 -07:00
commit 94ceeb94ba
4 changed files with 85 additions and 32 deletions

View File

@ -151,6 +151,44 @@ void vec_to_argv(const char *argv0, std::vector<const char*>& args,
(*argv)[(*argc)++] = args[i];
}
void ceph_arg_value_type(const char * nextargstr, bool *bool_option, bool *bool_numeric)
{
bool is_numeric = true;
bool is_option;
if (nextargstr == NULL) {
return;
}
if (strlen(nextargstr) < 2) {
is_option = false;
} else {
is_option = (nextargstr[0] == '-') && (nextargstr[1] == '-');
}
for (unsigned int i = 0; i < strlen(nextargstr); i++) {
if (!(nextargstr[i] >= '0' && nextargstr[i] <= '9')) {
// May be negative numeral value
if ((i == 0) && (strlen(nextargstr) >= 2)) {
if (nextargstr[0] == '-')
continue;
}
is_numeric = false;
break;
}
}
// -<option>
if (nextargstr[0] == '-' && is_numeric == false) {
is_option = true;
}
*bool_option = is_option;
*bool_numeric = is_numeric;
return;
}
bool parse_ip_port_vec(const char *s, vector<entity_addr_t>& vec)
{
const char *p = s;
@ -343,21 +381,34 @@ bool ceph_argparse_witharg(std::vector<const char*> &args,
{
int r;
va_list ap;
bool is_option = false;
bool is_numeric = true;
std::string str;
va_start(ap, oss);
r = va_ceph_argparse_witharg(args, i, &str, oss, ap);
va_end(ap);
if (r == 0) {
return false;
} else if (r < 0) {
return true;
}
if (r == 1) {
std::string err;
T myret = strict_str_convert(str.c_str(), &err);
*ret = myret;
if (!err.empty()) {
oss << err;
ceph_arg_value_type(str.c_str(), &is_option, &is_numeric);
if ((is_option == true) || (is_numeric == false)) {
*ret = EXIT_FAILURE;
if (is_option == true) {
oss << "Missing option value";
} else {
oss << "The option value '" << str << "' is invalid";
}
return true;
}
std::string err;
T myret = strict_str_convert(str.c_str(), &err);
*ret = myret;
if (!err.empty()) {
oss << err;
}
return true;
}

View File

@ -26,26 +26,32 @@ using std::ostringstream;
long long strict_strtoll(const char *str, int base, std::string *err)
{
char *endptr;
std::string errStr;
errno = 0; /* To distinguish success/failure after call (see man page) */
long long ret = strtoll(str, &endptr, base);
if ((errno == ERANGE && (ret == LLONG_MAX || ret == LLONG_MIN))
|| (errno != 0 && ret == 0)) {
ostringstream oss;
oss << "strict_strtoll: integer underflow or overflow parsing '" << str << "'";
*err = oss.str();
errStr = "The option value '";
errStr.append(str);
errStr.append("'");
errStr.append(" seems to be invalid");
*err = errStr;
return 0;
}
if (endptr == str) {
ostringstream oss;
oss << "strict_strtoll: expected integer, got: '" << str << "'";
*err = oss.str();
errStr = "Expected option value to be integer, got '";
errStr.append(str);
errStr.append("'");
*err = errStr;
return 0;
}
if (*endptr != '\0') {
ostringstream oss;
oss << "strict_strtoll: garbage at end of string. got: '" << str << "'";
*err = oss.str();
errStr = "The option value '";
errStr.append(str);
errStr.append("'");
errStr.append(" seems to be invalid");
*err = errStr;
return 0;
}
*err = "";
@ -54,19 +60,16 @@ long long strict_strtoll(const char *str, int base, std::string *err)
int strict_strtol(const char *str, int base, std::string *err)
{
std::string errStr;
long long ret = strict_strtoll(str, base, err);
if (!err->empty())
return 0;
if (ret <= INT_MIN) {
ostringstream oss;
oss << "strict_strtol: integer underflow parsing '" << str << "'";
*err = oss.str();
return 0;
}
if (ret >= INT_MAX) {
ostringstream oss;
oss << "strict_strtol: integer overflow parsing '" << str << "'";
*err = oss.str();
if ((ret <= INT_MIN) || (ret >= INT_MAX)) {
errStr = "The option value '";
errStr.append(str);
errStr.append("'");
errStr.append(" seems to be invalid");
*err = errStr;
return 0;
}
return static_cast<int>(ret);

View File

@ -2799,6 +2799,10 @@ int main(int argc, const char **argv)
cerr << "rbd: " << err.str() << std::endl;
return EXIT_FAILURE;
}
if ((order <= 0) || (order < 12) || (order > 25)) {
cerr << "rbd: order must be between 12 (4 KB) and 25 (32 MB)" << std::endl;
return EXIT_FAILURE;
}
} else if (ceph_argparse_witharg(args, i, &bench_io_size, err, "--io-size", (char*)NULL)) {
if (!err.str().empty()) {
cerr << "rbd: " << err.str() << std::endl;
@ -3308,11 +3312,6 @@ if (!set_conf_param(v, p1, p2, p3)) { \
}
if (opt_cmd == OPT_CREATE || opt_cmd == OPT_CLONE || opt_cmd == OPT_IMPORT) {
if (order && (order < 12 || order > 25)) {
cerr << "rbd: order must be between 12 (4 KB) and 25 (32 MB)"
<< std::endl;
return EINVAL;
}
if ((stripe_unit && !stripe_count) || (!stripe_unit && stripe_count)) {
cerr << "must specify both (or neither) of stripe-unit and stripe-count"
<< std::endl;

View File

@ -10,7 +10,7 @@
[1]
$ osdmaptool myosdmap --test-map-object foo --pool bar
strict_strtoll: expected integer, got: 'bar'
The option value 'bar' is invalid
[1]
$ osdmaptool myosdmap --test-map-object foo --pool 123
@ -35,7 +35,7 @@
[1]
$ osdmaptool myosdmap --test-map-pgs --pool baz
strict_strtoll: expected integer, got: 'baz'
The option value 'baz' is invalid
[1]
$ osdmaptool myosdmap --test-map-pgs --pool 123