summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvmallika <vmallika@redhat.com>2015-04-01 16:56:00 +0530
committerVijay Bellur <vbellur@redhat.com>2015-04-10 11:21:48 +0000
commitd06e6bac4b5aa6d0fbf1660b92c4100de8f79e68 (patch)
tree106e47847a88aab96c284b8e3b6aa1c2feffe3e8
parentfcb55d54a62c8d4a2e8ce4596cd462c471f74dd3 (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.c13
-rw-r--r--libglusterfs/src/common-utils.c68
-rw-r--r--libglusterfs/src/common-utils.h1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-quota.c28
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;