diff options
-rw-r--r-- | libglusterfs/src/common-utils.c | 57 | ||||
-rw-r--r-- | libglusterfs/src/common-utils.h | 4 | ||||
-rw-r--r-- | libglusterfs/src/options.c | 118 |
3 files changed, 97 insertions, 82 deletions
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c index 068bd8460..952af10cf 100644 --- a/libglusterfs/src/common-utils.c +++ b/libglusterfs/src/common-utils.c @@ -1267,6 +1267,63 @@ gf_string2bytesize (const char *str, uint64_t *n) return 0; } +int +gf_string2percent_or_bytesize (const char *str, + uint64_t *n, + gf_boolean_t *is_percent) +{ + uint64_t value = 0ULL; + char *tail = NULL; + int old_errno = 0; + const char *s = NULL; + + if (str == NULL || n == NULL) { + gf_log_callingfn (THIS->name, GF_LOG_WARNING, + "argument invalid"); + errno = EINVAL; + return -1; + } + + for (s = str; *s != '\0'; s++) { + if (isspace (*s)) + continue; + if (*s == '-') + return -1; + break; + } + + old_errno = errno; + errno = 0; + value = strtoull (str, &tail, 10); + + if (errno == ERANGE || errno == EINVAL) + return -1; + + if (errno == 0) + errno = old_errno; + + if (tail[0] != '\0') { + if (strcasecmp (tail, GF_UNIT_KB_STRING) == 0) + value *= GF_UNIT_KB; + else if (strcasecmp (tail, GF_UNIT_MB_STRING) == 0) + value *= GF_UNIT_MB; + else if (strcasecmp (tail, GF_UNIT_GB_STRING) == 0) + value *= GF_UNIT_GB; + else if (strcasecmp (tail, GF_UNIT_TB_STRING) == 0) + value *= GF_UNIT_TB; + else if (strcasecmp (tail, GF_UNIT_PB_STRING) == 0) + value *= GF_UNIT_PB; + else if (strcasecmp (tail, GF_UNIT_PERCENT_STRING) == 0) + *is_percent = _gf_true; + else + return -1; + } + + *n = value; + + return 0; +} + int64_t gf_str_to_long_long (const char *number) { diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h index 63566fb53..67ad5ac8e 100644 --- a/libglusterfs/src/common-utils.h +++ b/libglusterfs/src/common-utils.h @@ -69,6 +69,8 @@ void trap (void); #define GF_UNIT_TB_STRING "TB" #define GF_UNIT_PB_STRING "PB" +#define GF_UNIT_PERCENT_STRING "%" + #define GEOREP "geo-replication" #define GHADOOP "glusterfs-hadoop" @@ -421,6 +423,8 @@ int gf_string2uint32_base10 (const char *str, uint32_t *n); int gf_string2uint64_base10 (const char *str, uint64_t *n); int gf_string2bytesize (const char *str, uint64_t *n); +int gf_string2percent_or_bytesize (const char *str, uint64_t *n, + gf_boolean_t *is_percent); int gf_string2boolean (const char *str, gf_boolean_t *b); int gf_string2percent (const char *str, uint32_t *n); diff --git a/libglusterfs/src/options.c b/libglusterfs/src/options.c index b8d3b6ae5..39844461a 100644 --- a/libglusterfs/src/options.c +++ b/libglusterfs/src/options.c @@ -319,8 +319,6 @@ out: return ret; } - -/* TODO: clean this up */ static int xlator_option_validate_percent_or_sizet (xlator_t *xl, const char *key, const char *value, @@ -328,88 +326,44 @@ xlator_option_validate_percent_or_sizet (xlator_t *xl, const char *key, { int ret = -1; char errstr[256]; - uint32_t percent = 0; uint64_t size = 0; + gf_boolean_t is_percent = _gf_false; + + if (gf_string2percent_or_bytesize (value, &size, &is_percent) == 0) { + if (is_percent) { + ret = 0; + goto out; + } + /* Check the range */ + if ((opt->min == 0) && (opt->max == 0)) { + gf_log (xl->name, GF_LOG_DEBUG, + "no range check required for " + "'option %s %s'", + key, value); + ret = 0; + goto out; + } + if ((size < opt->min) || (size > opt->max)) { + snprintf (errstr, 256, + "'%"PRId64"' in 'option %s %s'" + " is out of range [%"PRId64" -" + " %"PRId64"]", + size, key, value, opt->min, opt->max); + gf_log (xl->name, GF_LOG_ERROR, "%s", errstr); + goto out; + } + ret = 0; + goto out; + } + + /* If control reaches here, invalid argument */ + + snprintf (errstr, 256, + "invalid number format \"%s\" in \"option %s\"", + value, key); + gf_log (xl->name, GF_LOG_ERROR, "%s", errstr); - /* Check if the value is valid percentage */ - if (gf_string2percent (value, &percent) == 0) { - if (percent > 100) { - gf_log (xl->name, GF_LOG_DEBUG, - "value given was greater than 100, " - "assuming this is actually a size"); - if (gf_string2bytesize (value, &size) == 0) { - /* Check the range */ - if ((opt->min == 0) && (opt->max == 0)) { - gf_log (xl->name, GF_LOG_DEBUG, - "no range check rquired for " - "'option %s %s'", - key, value); - // It is a size - ret = 0; - goto out; - } - if ((size < opt->min) || (size > opt->max)) { - snprintf (errstr, 256, - "'%"PRId64"' in 'option %s %s' " - "is out of range [%"PRId64" - " - "%"PRId64"]", - size, key, value, - opt->min, opt->max); - gf_log (xl->name, GF_LOG_ERROR, "%s", - errstr); - goto out; - } - // It is a size - ret = 0; - goto out; - } else { - // It's not a percent or size - snprintf (errstr, 256, - "invalid number format \"%s\" " - "in \"option %s\"", - value, key); - gf_log (xl->name, GF_LOG_ERROR, "%s", errstr); - goto out; - } - } - // It is a percent - ret = 0; - goto out; - } else { - if (gf_string2bytesize (value, &size) == 0) { - /* Check the range */ - if ((opt->min == 0) && (opt->max == 0)) { - gf_log (xl->name, GF_LOG_DEBUG, - "no range check required for " - "'option %s %s'", - key, value); - // It is a size - ret = 0; - goto out; - } - if ((size < opt->min) || (size > opt->max)) { - snprintf (errstr, 256, - "'%"PRId64"' in 'option %s %s'" - " is out of range [%"PRId64" -" - " %"PRId64"]", - size, key, value, opt->min, opt->max); - gf_log (xl->name, GF_LOG_ERROR, "%s", errstr); - goto out; - } - } else { - // It's not a percent or size - snprintf (errstr, 256, - "invalid number format \"%s\" in \"option %s\"", - value, key); - gf_log (xl->name, GF_LOG_ERROR, "%s", errstr); - goto out; - } - //It is a size - ret = 0; - goto out; - } - ret = 0; out: if (ret && op_errstr) *op_errstr = gf_strdup (errstr); @@ -425,7 +379,7 @@ xlator_option_validate_time (xlator_t *xl, const char *key, const char *value, char errstr[256]; uint32_t input_time = 0; - /* Check if the value is valid percentage */ + /* Check if the value is valid time */ if (gf_string2time (value, &input_time) != 0) { snprintf (errstr, 256, "invalid time format \"%s\" in " |