diff options
author | vmallika <vmallika@redhat.com> | 2015-04-01 16:56:00 +0530 |
---|---|---|
committer | Vijay Bellur <vbellur@redhat.com> | 2015-04-10 11:21:48 +0000 |
commit | d06e6bac4b5aa6d0fbf1660b92c4100de8f79e68 (patch) | |
tree | 106e47847a88aab96c284b8e3b6aa1c2feffe3e8 | |
parent | fcb55d54a62c8d4a2e8ce4596cd462c471f74dd3 (diff) |
quota/cli: validate quota hard-limit option
Quota hard-limit is supported only upto: 9223372036854775807 (int 64)
In CLI, it is allowed to set the value upto 16384PB (unsigned int 64),
this is not a valid value as the xattrop for quota accounting and
the quota enforcer operates on a signed int64 limit value.
This patches fixes the problem in CLI and allows user to set
the hard-limit value only from range 0 - 9223372036854775807
Change-Id: Ifce6e509e1832ef21d3278bacfa5bd71040c8cba
BUG: 1206432
Signed-off-by: vmallika <vmallika@redhat.com>
Reviewed-on: http://review.gluster.org/10022
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Kaushal M <kaushal@redhat.com>
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
-rw-r--r-- | cli/src/cli-cmd-parser.c | 13 | ||||
-rw-r--r-- | libglusterfs/src/common-utils.c | 68 | ||||
-rw-r--r-- | libglusterfs/src/common-utils.h | 1 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-quota.c | 28 |
4 files changed, 72 insertions, 38 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index da60cde66d9..a8e09a46631 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -906,7 +906,7 @@ cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options) int ret = -1; int i = -1; char key[20] = {0, }; - uint64_t value = 0; + int64_t value = 0; gf_quota_type type = GF_QUOTA_OPTION_TYPE_NONE; char *opwords[] = { "enable", "disable", "limit-usage", "remove", "list", "alert-time", @@ -1004,11 +1004,12 @@ cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options) } if (type == GF_QUOTA_OPTION_TYPE_LIMIT_USAGE) { - ret = gf_string2bytesize_uint64 (words[5], &value); - if (ret != 0) { - if (errno == ERANGE) - cli_err ("Value too large: %s", - words[5]); + ret = gf_string2bytesize_int64 (words[5], &value); + if (ret != 0 || value < 0) { + if (errno == ERANGE || value < 0) + cli_err ("Value out of range " + "(0 - %"PRId64 "): %s", + INT64_MAX, words[5]); else cli_err ("Please enter a correct " "value"); diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c index 6c5f65f6987..b57066d41da 100644 --- a/libglusterfs/src/common-utils.c +++ b/libglusterfs/src/common-utils.c @@ -1450,13 +1450,17 @@ err: int gf_string2bytesize_range (const char *str, uint64_t *n, uint64_t max) { - double value = 0.0; - char *tail = NULL; - int old_errno = 0; - const char *s = NULL; + double value = 0.0; + uint64_t int_value = 0; + uint64_t unit = 0; + char *tail = NULL; + int old_errno = 0; + const char *s = NULL; + gf_boolean_t fraction = _gf_false; if (str == NULL || n == NULL) { - gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid"); + gf_log_callingfn (THIS->name, GF_LOG_WARNING, + "argument invalid"); errno = EINVAL; return -1; } @@ -1469,9 +1473,16 @@ gf_string2bytesize_range (const char *str, uint64_t *n, uint64_t max) break; } + if (strrchr (str, '.')) + fraction = _gf_true; + old_errno = errno; errno = 0; - value = strtod (str, &tail); + if (fraction) + value = strtod (str, &tail); + else + int_value = strtoll (str, &tail, 10); + if (str == tail) errno = EINVAL; @@ -1484,25 +1495,39 @@ gf_string2bytesize_range (const char *str, uint64_t *n, uint64_t max) if (tail[0] != '\0') { if (strcasecmp (tail, GF_UNIT_KB_STRING) == 0) - value *= GF_UNIT_KB; + unit = GF_UNIT_KB; else if (strcasecmp (tail, GF_UNIT_MB_STRING) == 0) - value *= GF_UNIT_MB; + unit = GF_UNIT_MB; else if (strcasecmp (tail, GF_UNIT_GB_STRING) == 0) - value *= GF_UNIT_GB; + unit = GF_UNIT_GB; else if (strcasecmp (tail, GF_UNIT_TB_STRING) == 0) - value *= GF_UNIT_TB; + unit = GF_UNIT_TB; else if (strcasecmp (tail, GF_UNIT_PB_STRING) == 0) - value *= GF_UNIT_PB; + unit = GF_UNIT_PB; else if (strcasecmp (tail, GF_UNIT_B_STRING) != 0) return -1; - } - if ((max - value) < 0) { - errno = ERANGE; - return -1; + if (unit > 0) { + if (fraction) + value *= unit; + else + int_value *= unit; + } } - *n = (uint64_t) value; + if (fraction) { + if ((max - value) < 0) { + errno = ERANGE; + return -1; + } + *n = (uint64_t) value; + } else { + if ((max - int_value) < 0) { + errno = ERANGE; + return -1; + } + *n = int_value; + } return 0; } @@ -1530,6 +1555,17 @@ gf_string2bytesize_uint64 (const char *str, uint64_t *n) } int +gf_string2bytesize_int64 (const char *str, int64_t *n) +{ + uint64_t u64 = 0; + int ret = 0; + + ret = gf_string2bytesize_range(str, &u64, INT64_MAX); + *n = (int64_t) u64; + return ret; +} + +int gf_string2percent_or_bytesize (const char *str, double *n, gf_boolean_t *is_percent) { diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h index ec7e772e6cb..a93c6233a4e 100644 --- a/libglusterfs/src/common-utils.h +++ b/libglusterfs/src/common-utils.h @@ -604,6 +604,7 @@ int gf_string2uint64_base10 (const char *str, uint64_t *n); int gf_string2bytesize (const char *str, uint64_t *n); int gf_string2bytesize_size (const char *str, size_t *n); int gf_string2bytesize_uint64 (const char *str, uint64_t *n); +int gf_string2bytesize_int64 (const char *str, int64_t *n); int gf_string2percent_or_bytesize (const char *str, double *n, gf_boolean_t *is_percent); diff --git a/xlators/mgmt/glusterd/src/glusterd-quota.c b/xlators/mgmt/glusterd/src/glusterd-quota.c index 08e5d97a26b..a137e82b230 100644 --- a/xlators/mgmt/glusterd/src/glusterd-quota.c +++ b/xlators/mgmt/glusterd/src/glusterd-quota.c @@ -500,7 +500,7 @@ glusterd_set_quota_limit (char *volname, char *path, char *hard_limit, new_limit.sl = hton64 (new_limit.sl); - ret = gf_string2bytesize_uint64 (hard_limit, (uint64_t*)&new_limit.hl); + ret = gf_string2bytesize_int64 (hard_limit, &new_limit.hl); if (ret) goto out; @@ -1370,8 +1370,8 @@ glusterd_op_stage_quota (dict_t *dict, char **op_errstr, dict_t *rsp_dict) glusterd_conf_t *priv = NULL; glusterd_volinfo_t *volinfo = NULL; char *hard_limit_str = NULL; - uint64_t hard_limit = 0; - gf_boolean_t get_gfid = _gf_false; + int64_t hard_limit = 0; + gf_boolean_t get_gfid = _gf_false; this = THIS; GF_ASSERT (this); @@ -1460,20 +1460,16 @@ glusterd_op_stage_quota (dict_t *dict, char **op_errstr, dict_t *rsp_dict) "Faild to get hard-limit from dict"); goto out; } - ret = gf_string2bytesize_uint64 (hard_limit_str, &hard_limit); + ret = gf_string2bytesize_int64 (hard_limit_str, &hard_limit); if (ret) { - gf_log (this->name, GF_LOG_ERROR, - "Failed to convert hard-limit string to value"); - goto out; - } - if (hard_limit > UINT64_MAX) { - ret = -1; - ret = gf_asprintf (op_errstr, "Hard-limit %s is greater" - " than %"PRId64"bytes. Please set a " - "smaller limit.", hard_limit_str, - INT64_MAX); - gf_log (this->name, GF_LOG_ERROR, "hard-limit %s " - "greater than INT64_MAX", hard_limit_str); + if (errno == ERANGE || hard_limit < 0) + gf_asprintf (op_errstr, "Hard-limit " + "value out of range (0 - %"PRId64 + "): %s", hard_limit_str); + else + gf_log (this->name, GF_LOG_ERROR, + "Failed to convert hard-limit " + "from string to bytes"); goto out; } get_gfid = _gf_true; |