summaryrefslogtreecommitdiffstats
path: root/libglusterfs/src/options.c
diff options
context:
space:
mode:
Diffstat (limited to 'libglusterfs/src/options.c')
-rw-r--r--libglusterfs/src/options.c273
1 files changed, 171 insertions, 102 deletions
diff --git a/libglusterfs/src/options.c b/libglusterfs/src/options.c
index 0cec59fdb..842b6413a 100644
--- a/libglusterfs/src/options.c
+++ b/libglusterfs/src/options.c
@@ -53,7 +53,6 @@ out:
return ret;
}
-
static int
xlator_option_validate_int (xlator_t *xl, const char *key, const char *value,
volume_option_t *opt, char **op_errstr)
@@ -71,7 +70,8 @@ xlator_option_validate_int (xlator_t *xl, const char *key, const char *value,
goto out;
}
- if ((opt->min == 0) && (opt->max == 0)) {
+ if ((opt->min == 0) && (opt->max == 0) &&
+ (opt->validate == GF_OPT_VALIDATE_BOTH)) {
gf_log (xl->name, GF_LOG_TRACE,
"no range check required for 'option %s %s'",
key, value);
@@ -79,10 +79,28 @@ xlator_option_validate_int (xlator_t *xl, const char *key, const char *value,
goto out;
}
- if ((inputll < opt->min) || (inputll > opt->max)) {
+ if ((opt->validate == GF_OPT_VALIDATE_MIN)) {
+ if (inputll < opt->min) {
+ snprintf (errstr, 256,
+ "'%lld' in 'option %s %s' is smaller than "
+ "minimum value '%.0f'", inputll, key,
+ value, opt->min);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+ } else if ((opt->validate == GF_OPT_VALIDATE_MAX)) {
+ if ((inputll > opt->max)) {
+ snprintf (errstr, 256,
+ "'%lld' in 'option %s %s' is greater than "
+ "maximum value '%.0f'", inputll, key,
+ value, opt->max);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+ } else if ((inputll < opt->min) || (inputll > opt->max)) {
snprintf (errstr, 256,
"'%lld' in 'option %s %s' is out of range "
- "[%"PRId64" - %"PRId64"]",
+ "[%.0f - %.0f]",
inputll, key, value, opt->min, opt->max);
gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
goto out;
@@ -101,7 +119,7 @@ xlator_option_validate_sizet (xlator_t *xl, const char *key, const char *value,
volume_option_t *opt, char **op_errstr)
{
uint64_t size = 0;
- int ret = -1;
+ int ret = 0;
char errstr[256];
/* Check the range */
@@ -110,6 +128,7 @@ xlator_option_validate_sizet (xlator_t *xl, const char *key, const char *value,
"invalid number format \"%s\" in option \"%s\"",
value, key);
gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ ret = -1;
goto out;
}
@@ -117,30 +136,26 @@ xlator_option_validate_sizet (xlator_t *xl, const char *key, const char *value,
gf_log (xl->name, GF_LOG_TRACE,
"no range check required for 'option %s %s'",
key, value);
- ret = 0;
goto out;
}
if ((size < opt->min) || (size > opt->max)) {
- if (strncmp (key, "cache-size", 10) == 0) {
+ if ((strncmp (key, "cache-size", 10) == 0) &&
+ (size > opt->max)) {
snprintf (errstr, 256, "Cache size %"PRId64" is out of "
- "range [%"PRId64" - %"PRId64"]",
+ "range [%.0f - %.0f]",
size, opt->min, opt->max);
- //*op_errstr = gf_strdup (errstr);
gf_log (xl->name, GF_LOG_WARNING, "%s", errstr);
- ret = 0;
- goto out;
} else {
snprintf (errstr, 256,
"'%"PRId64"' in 'option %s %s' "
- "is out of range [%"PRId64" - %"PRId64"]",
+ "is out of range [%.0f - %.0f]",
size, key, value, opt->min, opt->max);
gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
- goto out;
+ ret = -1;
}
}
- ret = 0;
out:
if (ret && op_errstr)
*op_errstr = gf_strdup (errstr);
@@ -213,6 +228,46 @@ out:
return ret;
}
+void
+set_error_str (char *errstr, size_t len, volume_option_t *opt, const char *key,
+ const char *value)
+{
+ int i = 0;
+ char given_array[4096] = {0,};
+
+ for (i = 0; (i < ZR_OPTION_MAX_ARRAY_SIZE) && opt->value[i];) {
+ strcat (given_array, opt->value[i]);
+ if (((++i) < ZR_OPTION_MAX_ARRAY_SIZE) &&
+ (opt->value[i]))
+ strcat (given_array, ", ");
+ else
+ strcat (given_array, ".");
+ }
+ snprintf (errstr, len, "option %s %s: '%s' is not valid "
+ "(possible options are %s)", key, value, value, given_array);
+ return;
+}
+
+int
+is_all_whitespaces (const char *value)
+{
+ int i = 0;
+ size_t len = 0;
+
+ if (value == NULL)
+ return -1;
+
+ len = strlen (value);
+
+ for (i = 0; i < len; i++) {
+ if (value[i] == ' ')
+ continue;
+ else
+ return 0;
+ }
+
+ return 1;
+}
static int
xlator_option_validate_str (xlator_t *xl, const char *key, const char *value,
@@ -220,8 +275,7 @@ xlator_option_validate_str (xlator_t *xl, const char *key, const char *value,
{
int ret = -1;
int i = 0;
- char errstr[256];
- char given_array[4096] = {0,};
+ char errstr[4096] = {0,};
/* Check if the '*str' is valid */
if (GF_OPTION_LIST_EMPTY(opt)) {
@@ -229,6 +283,9 @@ xlator_option_validate_str (xlator_t *xl, const char *key, const char *value,
goto out;
}
+ if (is_all_whitespaces (value) == 1)
+ goto out;
+
for (i = 0; (i < ZR_OPTION_MAX_ARRAY_SIZE) && opt->value[i]; i++) {
#ifdef GF_DARWIN_HOST_OS
if (fnmatch (opt->value[i], value, 0) == 0) {
@@ -243,8 +300,8 @@ xlator_option_validate_str (xlator_t *xl, const char *key, const char *value,
#endif
}
- if (((i < ZR_OPTION_MAX_ARRAY_SIZE) && (!opt->value[i])) ||
- (i == ZR_OPTION_MAX_ARRAY_SIZE)) {
+ if ((i == ZR_OPTION_MAX_ARRAY_SIZE) || (!opt->value[i]))
+ goto out;
/* enter here only if
* 1. reached end of opt->value array and haven't
* validated input
@@ -254,26 +311,15 @@ xlator_option_validate_str (xlator_t *xl, const char *key, const char *value,
* matched all possible input values.
*/
- for (i = 0; (i < ZR_OPTION_MAX_ARRAY_SIZE) && opt->value[i];) {
- strcat (given_array, opt->value[i]);
- if (((++i) < ZR_OPTION_MAX_ARRAY_SIZE) &&
- (opt->value[i]))
- strcat (given_array, ", ");
- else
- strcat (given_array, ".");
- }
- snprintf (errstr, 256,
- "option %s %s: '%s' is not valid "
- "(possible options are %s)",
- key, value, value, given_array);
- gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
- goto out;
- }
-
ret = 0;
+
out:
- if (ret && op_errstr)
- *op_errstr = gf_strdup (errstr);
+ if (ret) {
+ set_error_str (errstr, sizeof (errstr), opt, key, value);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ if (op_errstr)
+ *op_errstr = gf_strdup (errstr);
+ }
return ret;
}
@@ -282,10 +328,9 @@ static int
xlator_option_validate_percent (xlator_t *xl, const char *key, const char *value,
volume_option_t *opt, char **op_errstr)
{
- int ret = -1;
- char errstr[256];
- uint32_t percent = 0;
-
+ double percent = 0;
+ int ret = -1;
+ char errstr[256];
/* Check if the value is valid percentage */
if (gf_string2percent (value, &percent) != 0) {
@@ -296,9 +341,9 @@ xlator_option_validate_percent (xlator_t *xl, const char *key, const char *value
goto out;
}
- if ((percent < 0) || (percent > 100)) {
+ if ((percent < 0.0) || (percent > 100.0)) {
snprintf (errstr, 256,
- "'%d' in 'option %s %s' is out of range [0 - 100]",
+ "'%lf' in 'option %s %s' is out of range [0 - 100]",
percent, key, value);
gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
goto out;
@@ -338,8 +383,7 @@ xlator_option_validate_percent_or_sizet (xlator_t *xl, const char *key,
if ((size < opt->min) || (size > opt->max)) {
snprintf (errstr, 256,
"'%"PRId64"' in 'option %s %s'"
- " is out of range [%"PRId64" -"
- " %"PRId64"]",
+ " is out of range [%.0f - %.0f]",
size, key, value, opt->min, opt->max);
gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
goto out;
@@ -393,7 +437,7 @@ xlator_option_validate_time (xlator_t *xl, const char *key, const char *value,
if ((input_time < opt->min) || (input_time > opt->max)) {
snprintf (errstr, 256,
"'%"PRIu32"' in 'option %s %s' is "
- "out of range [%"PRId64" - %"PRId64"]",
+ "out of range [%.0f - %.0f]",
input_time, key, value,
opt->min, opt->max);
gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
@@ -412,28 +456,21 @@ static int
xlator_option_validate_double (xlator_t *xl, const char *key, const char *value,
volume_option_t *opt, char **op_errstr)
{
- int ret = -1;
- char errstr[256];
- double val = 0.0;
-
- /* Check if the value is valid double */
- if (gf_string2double (value, &val) != 0) {
- snprintf (errstr, 256,
- "invalid double \"%s\" in \"option %s\"",
- value, key);
- gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
- goto out;
- }
+ double input = 0.0;
+ int ret = -1;
+ char errstr[256];
- if (val < 0.0) {
+ /* Check the range */
+ if (gf_string2double (value, &input) != 0) {
snprintf (errstr, 256,
- "invalid double \"%s\" in \"option %s\"",
+ "invalid number format \"%s\" in option \"%s\"",
value, key);
gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
goto out;
}
- if ((opt->min == 0) && (opt->max == 0)) {
+ if ((opt->min == 0) && (opt->max == 0) &&
+ (opt->validate == GF_OPT_VALIDATE_BOTH)) {
gf_log (xl->name, GF_LOG_TRACE,
"no range check required for 'option %s %s'",
key, value);
@@ -441,6 +478,33 @@ xlator_option_validate_double (xlator_t *xl, const char *key, const char *value,
goto out;
}
+ if ((opt->validate == GF_OPT_VALIDATE_MIN)) {
+ if (input < opt->min) {
+ snprintf (errstr, 256,
+ "'%f' in 'option %s %s' is smaller than "
+ "minimum value '%f'", input, key,
+ value, opt->min);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+ } else if ((opt->validate == GF_OPT_VALIDATE_MAX)) {
+ if ((input > opt->max)) {
+ snprintf (errstr, 256,
+ "'%f' in 'option %s %s' is greater than "
+ "maximum value '%f'", input, key,
+ value, opt->max);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+ } else if ((input < opt->min) || (input > opt->max)) {
+ snprintf (errstr, 256,
+ "'%f' in 'option %s %s' is out of range "
+ "[%f - %f]",
+ input, key, value, opt->min, opt->max);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ goto out;
+ }
+
ret = 0;
out:
if (ret && op_errstr)
@@ -480,34 +544,32 @@ xlator_option_validate_addr_list (xlator_t *xl, const char *key,
char *dup_val = NULL;
char *addr_tok = NULL;
char *save_ptr = NULL;
- char errstr[256];
+ char errstr[4096] = {0,};
dup_val = gf_strdup (value);
- if (!dup_val) {
- ret = -1;
- snprintf (errstr, 256, "internal error, out of memory.");
+ if (!dup_val)
goto out;
- }
addr_tok = strtok_r (dup_val, ",", &save_ptr);
+ if (addr_tok == NULL)
+ goto out;
while (addr_tok) {
- if (!valid_internet_address (addr_tok, _gf_true)) {
- snprintf (errstr, 256,
- "option %s %s: '%s' is not a valid "
- "internet-address-list",
- key, value, value);
- gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
- ret = -1;
+ if (!valid_internet_address (addr_tok, _gf_true))
goto out;
- }
+
addr_tok = strtok_r (NULL, ",", &save_ptr);
}
ret = 0;
- out:
- if (op_errstr && ret)
- *op_errstr = gf_strdup (errstr);
- if (dup_val)
- GF_FREE (dup_val);
+
+out:
+ if (ret) {
+ snprintf (errstr, sizeof (errstr), "option %s %s: '%s' is not "
+ "a valid internet-address-list", key, value, value);
+ gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);
+ if (op_errstr)
+ *op_errstr = gf_strdup (errstr);
+ }
+ GF_FREE (dup_val);
return ret;
}
@@ -563,6 +625,10 @@ validate_list_elements (const char *string, volume_option_t *opt,
goto out;
str_ptr = strtok_r (dup_string, ",", &str_sav);
+ if (str_ptr == NULL) {
+ ret = -1;
+ goto out;
+ }
while (str_ptr) {
key = strtok_r (str_ptr, ":", &substr_sav);
@@ -588,9 +654,9 @@ validate_list_elements (const char *string, volume_option_t *opt,
str_ptr = strtok_r (NULL, ",", &str_sav);
substr_sav = NULL;
}
+
out:
- if (dup_string)
- GF_FREE (dup_string);
+ GF_FREE (dup_string);
gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
return ret;
}
@@ -695,7 +761,7 @@ out:
}
-static volume_option_t *
+volume_option_t *
xlator_volume_option_get_list (volume_opt_list_t *vol_list, const char *key)
{
volume_option_t *opt = NULL;
@@ -744,7 +810,7 @@ xlator_volume_option_get (xlator_t *xl, const char *key)
}
-static void
+static int
xl_opt_validate (dict_t *dict, char *key, data_t *value, void *data)
{
xlator_t *xl = NULL;
@@ -765,7 +831,7 @@ xl_opt_validate (dict_t *dict, char *key, data_t *value, void *data)
opt = xlator_volume_option_get_list (vol_opt, key);
if (!opt)
- return;
+ return 0;
ret = xlator_option_validate (xl, key, value->data, opt, &errstr);
if (ret)
@@ -783,7 +849,7 @@ xl_opt_validate (dict_t *dict, char *key, data_t *value, void *data)
dict_set (dict, opt->key[0], value);
dict_del (dict, key);
}
- return;
+ return 0;
}
@@ -988,11 +1054,8 @@ out:
static int
-not_null (char *in, char **out)
+pass (char *in, char **out)
{
- if (!in || !out)
- return -1;
-
*out = in;
return 0;
}
@@ -1013,46 +1076,52 @@ xl_by_name (char *in, xlator_t **out)
static int
-pc_or_size (char *in, uint64_t *out)
+pc_or_size (char *in, double *out)
{
- uint32_t pc = 0;
+ double pc = 0;
int ret = 0;
+ uint64_t size = 0;
if (gf_string2percent (in, &pc) == 0) {
- if (pc > 100) {
- ret = gf_string2bytesize (in, out);
+ if (pc > 100.0) {
+ ret = gf_string2bytesize (in, &size);
+ if (!ret)
+ *out = size;
} else {
*out = pc;
}
} else {
- ret = gf_string2bytesize (in, out);
+ ret = gf_string2bytesize (in, &size);
+ if (!ret)
+ *out = size;
}
return ret;
}
-
-DEFINE_INIT_OPT(char *, str, not_null);
+DEFINE_INIT_OPT(char *, str, pass);
DEFINE_INIT_OPT(uint64_t, uint64, gf_string2uint64);
DEFINE_INIT_OPT(int64_t, int64, gf_string2int64);
DEFINE_INIT_OPT(uint32_t, uint32, gf_string2uint32);
DEFINE_INIT_OPT(int32_t, int32, gf_string2int32);
DEFINE_INIT_OPT(uint64_t, size, gf_string2bytesize);
-DEFINE_INIT_OPT(uint32_t, percent, gf_string2percent);
-DEFINE_INIT_OPT(uint64_t, percent_or_size, pc_or_size);
+DEFINE_INIT_OPT(double, percent, gf_string2percent);
+DEFINE_INIT_OPT(double, percent_or_size, pc_or_size);
DEFINE_INIT_OPT(gf_boolean_t, bool, gf_string2boolean);
DEFINE_INIT_OPT(xlator_t *, xlator, xl_by_name);
-DEFINE_INIT_OPT(char *, path, not_null);
+DEFINE_INIT_OPT(char *, path, pass);
+DEFINE_INIT_OPT(double, double, gf_string2double);
-DEFINE_RECONF_OPT(char *, str, not_null);
+DEFINE_RECONF_OPT(char *, str, pass);
DEFINE_RECONF_OPT(uint64_t, uint64, gf_string2uint64);
DEFINE_RECONF_OPT(int64_t, int64, gf_string2int64);
DEFINE_RECONF_OPT(uint32_t, uint32, gf_string2uint32);
DEFINE_RECONF_OPT(int32_t, int32, gf_string2int32);
DEFINE_RECONF_OPT(uint64_t, size, gf_string2bytesize);
-DEFINE_RECONF_OPT(uint32_t, percent, gf_string2percent);
-DEFINE_RECONF_OPT(uint64_t, percent_or_size, pc_or_size);
+DEFINE_RECONF_OPT(double, percent, gf_string2percent);
+DEFINE_RECONF_OPT(double, percent_or_size, pc_or_size);
DEFINE_RECONF_OPT(gf_boolean_t, bool, gf_string2boolean);
DEFINE_RECONF_OPT(xlator_t *, xlator, xl_by_name);
-DEFINE_RECONF_OPT(char *, path, not_null);
+DEFINE_RECONF_OPT(char *, path, pass);
+DEFINE_RECONF_OPT(double, double, gf_string2double);