From 93022c0cc6c22b3a30ded3e109a3fe0a0dce8ca0 Mon Sep 17 00:00:00 2001 From: Kaushal M Date: Wed, 7 Mar 2012 13:06:38 +0530 Subject: mgmt/glusterd : volume set validation fixes This is the new version of the patch by Kaushik at review.gluster.com/699 The following new option types have been introduced: * GF_OPTION_TYPE_INTERNET_ADDRESS_LIST * GF_OPTION_TYPE_PRIORITY_LIST * GF_OPTION_TYPE_SIZE_LIST and option types of several options in translators have been updated to use the new types. valid_internet_address(), valid_ipv4_address() & valid_ipv6_address() functions has been updated for * wildcard matching. Previously used standalone wildcard address checking functions have been removed. Changes have been done to stripe translator to correctly set, update and use stripe-blocksize. Also minimum value for block-size has been set to 16KB. Change-Id: I2aa484ff695f6a915a8fc9a9f965cf0344f41d59 BUG: 765248 Signed-off-by: Kaushal M Reviewed-on: http://review.gluster.com/2899 Tested-by: Gluster Build System Reviewed-by: Shishir Gowda Reviewed-by: Anand Avati --- cli/src/cli-cmd-parser.c | 101 ++++--------- cli/src/cli-cmd-peer.c | 2 +- libglusterfs/src/common-utils.c | 219 +++++++++++----------------- libglusterfs/src/common-utils.h | 6 +- libglusterfs/src/options.c | 183 ++++++++++++++++++++++- libglusterfs/src/options.h | 3 + xlators/cluster/stripe/src/stripe.c | 210 +++++++++++++++++++------- xlators/features/quota/src/quota.c | 2 + xlators/mgmt/glusterd/src/glusterd-volgen.c | 8 +- xlators/nfs/server/src/nfs.c | 14 +- xlators/performance/io-cache/src/io-cache.c | 2 +- xlators/protocol/auth/addr/src/addr.c | 6 +- xlators/protocol/server/src/server.c | 16 +- 13 files changed, 481 insertions(+), 291 deletions(-) diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index d41493b6c..4c86ab488 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -115,9 +115,9 @@ cli_cmd_bricks_parse (const char **words, int wordcount, int brick_index, GF_FREE (tmp_host); goto out; } - if (!valid_internet_address (host_name)) { - cli_out ("internet address '%s' does not comform to " - "standards", host_name); + if (!valid_internet_address (host_name, _gf_false)) { + cli_out ("internet address '%s' does not conform to " + "standards", host_name); } GF_FREE (tmp_host); tmp_list = gf_strdup (brick_list + 1); @@ -634,54 +634,17 @@ out: return ret; } -int32_t -cli_cmd_valid_ip_list (char *iplist) -{ - int ret = 0; - char *duplist = NULL; - char *addr = NULL; - char *saveptr = NULL; - - GF_ASSERT (iplist); - duplist = gf_strdup (iplist); - - if (!duplist) { - ret = -1; - goto out; - } - - addr = strtok_r (duplist, ",", &saveptr); - if (!addr) { - ret = -1; - goto out; - } - while (addr) { - if (!valid_internet_address (addr) && - !valid_wildcard_internet_address (addr)) { - cli_out ("Invalid ip or wildcard : %s", addr); - ret= -1; - goto out; - } - addr = strtok_r (NULL, ",", &saveptr); - } -out: - if (duplist) - GF_FREE (duplist); - gf_log ("cli", GF_LOG_INFO, "Returning %d", ret); - return ret; -} - int32_t cli_cmd_volume_set_parse (const char **words, int wordcount, dict_t **options) { - dict_t *dict = NULL; - char *volname = NULL; - int ret = -1; - int count = 0; - char *key = NULL; - char *value = NULL; - int i = 0; - char str[50] = {0,}; + dict_t *dict = NULL; + char *volname = NULL; + int ret = -1; + int count = 0; + char *key = NULL; + char *value = NULL; + int i = 0; + char str[50] = {0,}; GF_ASSERT (words); GF_ASSERT (options); @@ -703,42 +666,28 @@ cli_cmd_volume_set_parse (const char **words, int wordcount, dict_t **options) if (ret) goto out; - if (wordcount == 3) { - if (!strcmp (volname, "help")) { - ret = dict_set_str (dict, "help", volname); - if (ret) - goto out; - } else if (!strcmp (volname, "help-xml")) { - ret = dict_set_str (dict, "help-xml", volname); - if (ret) - goto out; - } else { - ret = -1; + if ((!strcmp (volname, "help") || !strcmp (volname, "help-xml")) + && wordcount == 3 ) { + ret = dict_set_str (dict, volname, volname); + if (ret) goto out; - } + } else if (wordcount < 5) { + ret = -1; + goto out; } - for (i = 3; i < wordcount; i+=2) { - key = (char *) words[i]; - value = (char *) words[i+1]; + key = (char *) words[i]; + value = (char *) words[i+1]; - if ( !key || !value) { - ret = -1; - goto out; - } + if ( !key || !value) { + ret = -1; + goto out; + } count++; - if (!strncmp ("auth.allow", key, sizeof (key)) || - !strncmp ("auth.reject", key, sizeof (key))) { - ret = cli_cmd_valid_ip_list (value); - if (ret) { - gf_log ("cli", GF_LOG_ERROR, - "invalid ips given"); - goto out; - } - } + sprintf (str, "key%d", count); ret = dict_set_str (dict, str, key); if (ret) diff --git a/cli/src/cli-cmd-peer.c b/cli/src/cli-cmd-peer.c index cad520dfc..7f0d28f6d 100644 --- a/cli/src/cli-cmd-peer.c +++ b/cli/src/cli-cmd-peer.c @@ -72,7 +72,7 @@ cli_cmd_peer_probe_cbk (struct cli_state *state, struct cli_cmd_word *word, if (ret) goto out; - ret = valid_internet_address ((char *) words[2]); + ret = valid_internet_address ((char *) words[2], _gf_false); if (ret == 1) { ret = 0; } else { diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c index 952af10cf..f26d2bdc3 100644 --- a/libglusterfs/src/common-utils.c +++ b/libglusterfs/src/common-utils.c @@ -1586,47 +1586,79 @@ get_nth_word (const char *str, int n) } /* RFC 1123 & 952 */ - -/* The functions below validate given internet addresses and - * wildcard internet address for correctness. - * All return 1 on success and 0 on failure - */ - +/* Syntax formed combining RFC 1123 & 952 * + ::= *["."] * + ::= <[*[]] + ::= [*[]] */ char valid_host_name (char *address, int length) { - int i = 0; - char ret = 0; - int flag = 0; + int i = 0; + int str_len = 0; + char ret = 1; + char *dup_addr = NULL; + char *temp_str = NULL; + char *save_ptr = NULL; - if ((length > 255) || (length == 1)) + if ((length > _POSIX_HOST_NAME_MAX) || (length == 1)) { + ret = 0; goto out; + } - if (!isalnum (address[length - 1])) + dup_addr = gf_strdup (address); + if (!dup_addr) { + ret = 0; goto out; + } + temp_str = strtok_r (dup_addr,".", &save_ptr); - for (i = 0; i < length; i++) { - if (!isalnum (address[i]) && (address[i] != '.') - && (address[i] != '-')) + /* first-name */ + if (!temp_str || + !isalnum(temp_str[0]) || + !isalnum (temp_str[strlen(temp_str)-1])) { + ret = 0; + goto out; + } + for (i = 1; i < (strlen (temp_str) - 1); i++) { + if (!isalnum (temp_str[i]) && (temp_str[i] != '-')) { + ret = 0; goto out; + } + } - if (isalpha(address[i])) - flag = 1; + /* gen-name */ + while ((temp_str = strtok_r (NULL, ".", &save_ptr))) { + str_len = strlen (temp_str); + + if (!isalpha (temp_str[0]) || + !isalnum (temp_str[str_len-1])) { + ret = 0; + goto out; + } + for (i = 1; i < str_len; i++) { + if (!isalnum (temp_str[i]) && (temp_str[i] != '-')) { + ret = 0; + goto out; + } + } } - if (flag) - ret = 1; out: + if (dup_addr) + GF_FREE (dup_addr); return ret; } +/* Matches all ipv4 address, if wildcard_acc is true '*' wildcard pattern for* + subnets is considerd as valid strings as well */ char -valid_ipv4_address (char *address, int length) +valid_ipv4_address (char *address, int length, gf_boolean_t wildcard_acc) { int octets = 0; int value = 0; char *tmp = NULL, *ptr = NULL, *prev = NULL, *endptr = NULL; - char ret = 0; + char ret = 1; + int is_wildcard = 0; tmp = gf_strdup (address); prev = tmp; @@ -1634,15 +1666,22 @@ valid_ipv4_address (char *address, int length) while (prev != NULL) { octets++; - value = strtol (prev, &endptr, 10); - if ((value > 255) || (value < 0) || - (endptr != NULL && *endptr != '\0')) - goto out; + if (wildcard_acc && !strcmp (prev, "*")) { + is_wildcard = 1; + } else { + value = strtol (prev, &endptr, 10); + if ((value > 255) || (value < 0) || + (endptr != NULL && *endptr != '\0')) { + ret = 0; + goto out; + } + } prev = strtok_r (NULL, ".", &ptr); } - if (octets == 4) - ret = 1; + if ((octets > 4) || (octets < 4 && !is_wildcard)) { + ret = 0; + } out: GF_FREE (tmp); @@ -1650,27 +1689,35 @@ out: } char -valid_ipv6_address (char *address, int length) +valid_ipv6_address (char *address, int length, gf_boolean_t wildcard_acc) { int hex_numbers = 0; int value = 0; char *tmp = NULL, *ptr = NULL, *prev = NULL, *endptr = NULL; - char ret = 0; + char ret = 1; + int is_wildcard = 0; tmp = gf_strdup (address); prev = strtok_r (tmp, ":", &ptr); while (prev != NULL) { hex_numbers++; - value = strtol (prev, &endptr, 16); - if ((value > 0xffff) || (value < 0) - || (endptr != NULL && *endptr != '\0')) - goto out; + if (wildcard_acc && !strcmp (prev, "*")) { + is_wildcard = 1; + } else { + value = strtol (prev, &endptr, 16); + if ((value > 0xffff) || (value < 0) + || (endptr != NULL && *endptr != '\0')) { + ret = 0; + goto out; + } + } prev = strtok_r (NULL, ":", &ptr); } - if (hex_numbers <= 8) - ret = 1; + if ((hex_numbers > 8) || (hex_numbers < 8 && !is_wildcard)) { + ret = 0; + } out: GF_FREE (tmp); @@ -1678,7 +1725,7 @@ out: } char -valid_internet_address (char *address) +valid_internet_address (char *address, gf_boolean_t wildcard_acc) { char ret = 0; int length = 0; @@ -1692,8 +1739,8 @@ valid_internet_address (char *address) if (length == 0) goto out; - if (valid_ipv4_address (address, length) - || valid_ipv6_address (address, length) + if (valid_ipv4_address (address, length, wildcard_acc) + || valid_ipv6_address (address, length, wildcard_acc) || valid_host_name (address, length)) ret = 1; @@ -1701,104 +1748,6 @@ out: return ret; } -char -valid_ipv4_wildcard_check (char *address) -{ - char ret = 0; - int octets = 0; - char *tmp = NULL; - char *prev = NULL; - char *endptr = NULL; - int value = 0; - int is_wildcard = 0; - - tmp = gf_strdup (address); - prev = strtok (tmp, "."); - - while (prev != NULL) { - octets++; - - if (!strcmp (prev, "*")) { - is_wildcard = 1; - } else { - value = strtol (prev, &endptr, 10); - - if ((value > 255) || (value < 0) || - (endptr != NULL && *endptr != '\0')) - goto out; - } - prev = strtok (NULL, "."); - } - - if (is_wildcard && (octets <= 4)) - ret = 1; - -out: - if (tmp) - GF_FREE (tmp); - return ret; - -} - -char -valid_ipv6_wildcard_check (char *address) -{ - char ret = 0; - int hex_numbers = 0; - int value = 0; - char *tmp = NULL; - char *prev = NULL; - char *endptr = NULL; - int is_wildcard = 0; - - tmp = gf_strdup (address); - prev = strtok (tmp, ":"); - - while (prev != NULL) { - hex_numbers++; - - if (!strcmp (prev, "*")) { - is_wildcard = 1; - } else { - value = strtol (prev, &endptr, 16); - - if ((value > 0xffff) || (value < 0) || - (endptr != NULL && *endptr != '\0')) - goto out; - } - prev = strtok (NULL, ":"); - } - - if (is_wildcard && (hex_numbers <= 8)) - ret = 1; -out: - if (tmp) - GF_FREE (tmp); - return ret; -} - -char -valid_wildcard_internet_address (char *address) -{ - char ret = 0; - - if (address == NULL) { - gf_log_callingfn (THIS->name, GF_LOG_WARNING, - "argument invalid"); - goto out; - } - - if (strlen (address) == 0) - goto out; - - if (valid_ipv4_wildcard_check (address) || - valid_ipv6_wildcard_check (address)) - ret = 1; - -out: - return ret; -} - /*Thread safe conversion function*/ char * uuid_utoa (uuid_t uuid) diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h index 8c9b26f76..335517799 100644 --- a/libglusterfs/src/common-utils.h +++ b/libglusterfs/src/common-utils.h @@ -465,9 +465,9 @@ void skip_word (char **str); char *get_nth_word (const char *str, int n); char valid_host_name (char *address, int length); -char valid_ipv4_address (char *address, int length); -char valid_ipv6_address (char *address, int length); -char valid_internet_address (char *address); +char valid_ipv4_address (char *address, int length, gf_boolean_t wildcard_acc); +char valid_ipv6_address (char *address, int length, gf_boolean_t wildcard_acc); +char valid_internet_address (char *address, gf_boolean_t wildcard_acc); char valid_ipv4_wildcard_check (char *address); char valid_ipv6_wildcard_check (char *address); char valid_wildcard_internet_address (char *address); diff --git a/libglusterfs/src/options.c b/libglusterfs/src/options.c index 39844461a..6da68fd99 100644 --- a/libglusterfs/src/options.c +++ b/libglusterfs/src/options.c @@ -464,10 +464,11 @@ xlator_option_validate_addr (xlator_t *xl, const char *key, const char *value, int ret = -1; char errstr[256]; - if (!valid_internet_address ((char *)value)) { + if (!valid_internet_address ((char *)value, _gf_false)) { snprintf (errstr, 256, - "internet address '%s' does not conform to standards.", - value); + "option %s %s: '%s' is not a valid internet-address," + " it does not conform to standards.", + key, value, value); gf_log (xl->name, GF_LOG_ERROR, "%s", errstr); if (op_errstr) *op_errstr = gf_strdup (errstr); @@ -478,6 +479,176 @@ xlator_option_validate_addr (xlator_t *xl, const char *key, const char *value, return ret; } +static int +xlator_option_validate_addr_list (xlator_t *xl, const char *key, + const char *value, volume_option_t *opt, + char **op_errstr) +{ + int ret = -1; + char *dup_val = NULL; + char *addr_tok = NULL; + char *save_ptr = NULL; + char errstr[256]; + + dup_val = gf_strdup (value); + if (!dup_val) { + ret = -1; + snprintf (errstr, 256, "internal error, out of memory."); + goto out; + } + + addr_tok = strtok_r (dup_val, ",", &save_ptr); + 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; + 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); + + return ret; +} + +/*XXX: the rules to validate are as per block-size required for stripe xlator */ +static int +gf_validate_size (const char *sizestr, volume_option_t *opt) +{ + uint64_t value = 0; + int ret = 0; + + GF_ASSERT (opt); + + if (gf_string2bytesize (sizestr, &value) != 0 || + value < opt->min || + value % 512) { + ret = -1; + goto out; + } + + out: + gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret); + return ret; +} + +static int +gf_validate_number (const char *numstr, volume_option_t *opt) +{ + int32_t value; + return gf_string2int32 (numstr, &value); +} + +/* Parses the string to be of the form :,:... * + * takes two optional validaters key_validator and value_validator */ +static int +validate_list_elements (const char *string, volume_option_t *opt, + int (key_validator)( const char *), + int (value_validator)( const char *, volume_option_t *)) +{ + + char *dup_string = NULL; + char *str_sav = NULL; + char *substr_sav = NULL; + char *str_ptr = NULL; + char *key = NULL; + char *value = NULL; + int ret = 0; + + GF_ASSERT (string); + + dup_string = gf_strdup (string); + if (NULL == dup_string) + goto out; + + str_ptr = strtok_r (dup_string, ",", &str_sav); + while (str_ptr) { + + key = strtok_r (str_ptr, ":", &substr_sav); + if (!key || + (key_validator && key_validator(key))) { + ret = -1; + gf_log (THIS->name, GF_LOG_WARNING, + "invalid list '%s', key '%s' not valid.", + string, key); + goto out; + } + + value = strtok_r (NULL, ":", &substr_sav); + if (!value || + (value_validator && value_validator(value, opt))) { + ret = -1; + gf_log (THIS->name, GF_LOG_WARNING, + "invalid list '%s', value '%s' not valid.", + string, key); + goto out; + } + + str_ptr = strtok_r (NULL, ",", &str_sav); + substr_sav = NULL; + } + out: + if (dup_string) + GF_FREE (dup_string); + gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret); + return ret; +} + +static int +xlator_option_validate_priority_list (xlator_t *xl, const char *key, + const char *value, volume_option_t *opt, + char **op_errstr) +{ + int ret =0; + char errstr[1024] = {0, }; + + GF_ASSERT (value); + + ret = validate_list_elements (value, opt, NULL, &gf_validate_number); + if (ret) { + snprintf (errstr, 1024, + "option %s %s: '%s' is not a valid " + "priority-list", key, value, value); + *op_errstr = gf_strdup (errstr); + } + + return ret; +} + +static int +xlator_option_validate_size_list (xlator_t *xl, const char *key, + const char *value, volume_option_t *opt, + char **op_errstr) +{ + + int ret = 0; + char errstr[1024] = {0, }; + + GF_ASSERT (value); + + ret = gf_validate_size (value, opt); + if (ret) + ret = validate_list_elements (value, opt, NULL, &gf_validate_size); + + if (ret) { + snprintf (errstr, 1024, + "option %s %s: '%s' is not a valid " + "size-list", key, value, value); + *op_errstr = gf_strdup (errstr); + } + + return ret; + +} static int xlator_option_validate_any (xlator_t *xl, const char *key, const char *value, @@ -486,7 +657,6 @@ xlator_option_validate_any (xlator_t *xl, const char *key, const char *value, return 0; } - typedef int (xlator_option_validator_t) (xlator_t *xl, const char *key, const char *value, volume_option_t *opt, char **operrstr); @@ -510,6 +680,11 @@ xlator_option_validate (xlator_t *xl, char *key, char *value, [GF_OPTION_TYPE_TIME] = xlator_option_validate_time, [GF_OPTION_TYPE_DOUBLE] = xlator_option_validate_double, [GF_OPTION_TYPE_INTERNET_ADDRESS] = xlator_option_validate_addr, + [GF_OPTION_TYPE_INTERNET_ADDRESS_LIST] = + xlator_option_validate_addr_list, + [GF_OPTION_TYPE_PRIORITY_LIST] = + xlator_option_validate_priority_list, + [GF_OPTION_TYPE_SIZE_LIST] = xlator_option_validate_size_list, [GF_OPTION_TYPE_ANY] = xlator_option_validate_any, [GF_OPTION_TYPE_MAX] = NULL, }; diff --git a/libglusterfs/src/options.h b/libglusterfs/src/options.h index 40089ac63..722cc3b7a 100644 --- a/libglusterfs/src/options.h +++ b/libglusterfs/src/options.h @@ -44,6 +44,9 @@ typedef enum { GF_OPTION_TYPE_TIME, GF_OPTION_TYPE_DOUBLE, GF_OPTION_TYPE_INTERNET_ADDRESS, + GF_OPTION_TYPE_INTERNET_ADDRESS_LIST, + GF_OPTION_TYPE_PRIORITY_LIST, + GF_OPTION_TYPE_SIZE_LIST, GF_OPTION_TYPE_MAX, } volume_option_type_t; diff --git a/xlators/cluster/stripe/src/stripe.c b/xlators/cluster/stripe/src/stripe.c index 464ffb930..6762d9adc 100644 --- a/xlators/cluster/stripe/src/stripe.c +++ b/xlators/cluster/stripe/src/stripe.c @@ -39,6 +39,8 @@ #include "byte-order.h" #include "statedump.h" +#define STRIPE_MIN_BLOCK_SIZE 16*GF_UNIT_KB + struct volume_options options[]; void @@ -70,33 +72,27 @@ out: * stripe_get_matching_bs - Get the matching block size for the given path. */ int32_t -stripe_get_matching_bs (const char *path, struct stripe_options *opts, - uint64_t default_bs) +stripe_get_matching_bs (const char *path, stripe_private_t *priv) { struct stripe_options *trav = NULL; - char *pathname = NULL; uint64_t block_size = 0; - block_size = default_bs; - - if (!path || !opts) - goto out; - - /* FIXME: is a strdup really necessary? */ - pathname = gf_strdup (path); - if (!pathname) - goto out; + GF_VALIDATE_OR_GOTO ("stripe", priv, out); + GF_VALIDATE_OR_GOTO ("stripe", path, out); - trav = opts; - while (trav) { - if (!fnmatch (trav->path_pattern, pathname, FNM_NOESCAPE)) { - block_size = trav->block_size; - break; + LOCK (&priv->lock); + { + block_size = priv->block_size; + trav = priv->pattern; + while (trav) { + if (!fnmatch (trav->path_pattern, path, FNM_NOESCAPE)) { + block_size = trav->block_size; + break; + } + trav = trav->next; } - trav = trav->next; } - - GF_FREE (pathname); + UNLOCK (&priv->lock); out: return block_size; @@ -1883,9 +1879,7 @@ stripe_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, } local->op_ret = -1; local->op_errno = ENOTCONN; - local->stripe_size = stripe_get_matching_bs (loc->path, - priv->pattern, - priv->block_size); + local->stripe_size = stripe_get_matching_bs (loc->path, priv); frame->local = local; local->inode = inode_ref (loc->inode); loc_copy (&local->loc, loc); @@ -2546,9 +2540,7 @@ stripe_create (call_frame_t *frame, xlator_t *this, loc_t *loc, } local->op_ret = -1; local->op_errno = ENOTCONN; - local->stripe_size = stripe_get_matching_bs (loc->path, - priv->pattern, - priv->block_size); + local->stripe_size = stripe_get_matching_bs (loc->path, priv); frame->local = local; local->inode = inode_ref (loc->inode); loc_copy (&local->loc, loc); @@ -2689,9 +2681,7 @@ stripe_open (call_frame_t *frame, xlator_t *this, loc_t *loc, /* Striped files */ local->flags = flags; local->call_count = priv->child_count; - local->stripe_size = stripe_get_matching_bs (loc->path, - priv->pattern, - priv->block_size); + local->stripe_size = stripe_get_matching_bs (loc->path, priv); while (trav) { STACK_WIND (frame, stripe_open_cbk, trav->xlator, @@ -3889,6 +3879,30 @@ notify (xlator_t *this, int32_t event, void *data, ...) return 0; } +static int +set_default_block_size (stripe_private_t *priv, char *num) +{ + + int ret = -1; + GF_VALIDATE_OR_GOTO ("stripe", THIS, out); + GF_VALIDATE_OR_GOTO (THIS->name, priv, out); + GF_VALIDATE_OR_GOTO (THIS->name, num, out); + + + if (gf_string2bytesize (num, &priv->block_size) != 0) { + gf_log (THIS->name, GF_LOG_ERROR, + "invalid number format \"%s\"", num); + goto out; + } + + ret = 0; + + out: + return ret; + +} + + int set_stripe_block_size (xlator_t *this, stripe_private_t *priv, char *data) { @@ -3910,7 +3924,8 @@ set_stripe_block_size (xlator_t *this, stripe_private_t *priv, char *data) stripe_str = strtok_r (data, ",", &tmp_str); while (stripe_str) { dup_str = gf_strdup (stripe_str); - stripe_opt = CALLOC (1, sizeof (struct stripe_options)); + stripe_opt = GF_CALLOC (1, sizeof (struct stripe_options), + gf_stripe_mt_stripe_options); if (!stripe_opt) { GF_FREE (dup_str); goto out; @@ -3921,6 +3936,9 @@ set_stripe_block_size (xlator_t *this, stripe_private_t *priv, char *data) if (!num) { num = pattern; pattern = "*"; + ret = set_default_block_size (priv, num); + if (ret) + goto out; } if (gf_string2bytesize (num, &stripe_opt->block_size) != 0) { gf_log (this->name, GF_LOG_ERROR, @@ -3928,7 +3946,7 @@ set_stripe_block_size (xlator_t *this, stripe_private_t *priv, char *data) goto out; } - if (stripe_opt->block_size < 512) { + if (stripe_opt->block_size < STRIPE_MIN_BLOCK_SIZE) { gf_log (this->name, GF_LOG_ERROR, "Invalid Block-size: " "%s. Should be atleast 512 bytes", num); goto out; @@ -3945,14 +3963,13 @@ set_stripe_block_size (xlator_t *this, stripe_private_t *priv, char *data) "block-size : pattern %s : size %"PRId64, stripe_opt->path_pattern, stripe_opt->block_size); - if (!priv->pattern) { - priv->pattern = stripe_opt; - } else { + if (priv->pattern) + temp_stripeopt = NULL; + else temp_stripeopt = priv->pattern; - while (temp_stripeopt->next) - temp_stripeopt = temp_stripeopt->next; - temp_stripeopt->next = stripe_opt; - } + priv->pattern = stripe_opt; + stripe_opt->next = temp_stripeopt; + stripe_str = strtok_r (NULL, ",", &tmp_str); GF_FREE (dup_str); } @@ -4397,21 +4414,83 @@ out: return ret; } +static int +clear_pattern_list (stripe_private_t *priv) +{ + struct stripe_options *prev = NULL; + struct stripe_options *trav = NULL; + int ret = -1; + + GF_VALIDATE_OR_GOTO ("stripe", priv, out); + + trav = priv->pattern; + priv->pattern = NULL; + while (trav) { + prev = trav; + trav = trav->next; + GF_FREE (prev); + } + + ret = 0; + out: + return ret; + + +} + int reconfigure (xlator_t *this, dict_t *options) { - stripe_private_t *priv = NULL; - int ret = -1; + stripe_private_t *priv = NULL; + data_t *data = NULL; + int ret = -1; + volume_option_t *opt = NULL; + + GF_ASSERT (this); + GF_ASSERT (this->private); - priv = this->private; + priv = this->private; - GF_OPTION_RECONF ("block-size", priv->block_size, options, size, out); ret = 0; -out: - return ret; + LOCK (&priv->lock); + { + ret = clear_pattern_list (priv); + if (ret) + goto unlock; + + data = dict_get (options, "block-size"); + if (data) { + ret = set_stripe_block_size (this, priv, data->data); + if (ret) + goto unlock; + } else { + opt = xlator_volume_option_get (this, "block-size"); + if (!opt) { + gf_log (this->name, GF_LOG_WARNING, + "option 'block-size' not found"); + ret = -1; + goto unlock; + } + + if (gf_string2bytesize (opt->default_value, &priv->block_size)){ + gf_log (this->name, GF_LOG_ERROR, + "Unable to set default block-size "); + ret = -1; + goto unlock; + } + } + } + unlock: + UNLOCK (&priv->lock); + if (ret) + goto out; + + ret = 0; + out: + return ret; } @@ -4424,6 +4503,7 @@ int32_t init (xlator_t *this) { stripe_private_t *priv = NULL; + volume_option_t *opt = NULL; xlator_list_t *trav = NULL; data_t *data = NULL; int32_t count = 0; @@ -4489,19 +4569,36 @@ init (xlator_t *this) goto out; } - - GF_OPTION_INIT ("block-size", priv->block_size, size, out); - - /* option stripe-pattern *avi:1GB,*pdf:4096 */ - data = dict_get (this->options, "block-size"); - if (data) { - ret = set_stripe_block_size (this, priv, data->data); - if (ret) - goto out; + ret = 0; + LOCK (&priv->lock); + { + opt = xlator_volume_option_get (this, "block-size"); + if (!opt) { + gf_log (this->name, GF_LOG_WARNING, + "option 'block-size' not found"); + ret = -1; + goto unlock; + } + if (gf_string2bytesize (opt->default_value, &priv->block_size)){ + gf_log (this->name, GF_LOG_ERROR, + "Unable to set default block-size "); + ret = -1; + goto unlock; + } + /* option stripe-pattern *avi:1GB,*pdf:16K */ + data = dict_get (this->options, "block-size"); + if (data) { + ret = set_stripe_block_size (this, priv, data->data); + if (ret) + goto unlock; + } } + unlock: + UNLOCK (&priv->lock); + if (ret) + goto out; GF_OPTION_INIT ("use-xattr", priv->xattr_supported, bool, out); - /* notify related */ priv->nodes_down = priv->child_count; @@ -4551,7 +4648,7 @@ fini (xlator_t *this) while (trav) { prev = trav; trav = trav->next; - FREE (prev); + GF_FREE (prev); } LOCK_DESTROY (&priv->lock); GF_FREE (priv); @@ -5072,8 +5169,9 @@ struct xlator_dumpops dumpops = { struct volume_options options[] = { { .key = {"block-size"}, - .type = GF_OPTION_TYPE_ANY, + .type = GF_OPTION_TYPE_SIZE_LIST, .default_value = "128KB", + .min = STRIPE_MIN_BLOCK_SIZE, .description = "Size of the stripe unit that would be read " "from or written to the striped servers." }, diff --git a/xlators/features/quota/src/quota.c b/xlators/features/quota/src/quota.c index 753882f0d..349489b64 100644 --- a/xlators/features/quota/src/quota.c +++ b/xlators/features/quota/src/quota.c @@ -3155,6 +3155,8 @@ struct volume_options options[] = { {.key = {"limit-set"}}, {.key = {"timeout"}, .type = GF_OPTION_TYPE_SIZET, + .min = 1, + .max = 60, .default_value = "0", .description = "quota caches the directory sizes on client. Timeout " "indicates the timeout for the cache to be revalidated." diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c index 85691e681..63e26009a 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volgen.c +++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c @@ -186,7 +186,7 @@ static struct volopt_map_entry glusterd_volopt_map[] = { {"nfs.port", "nfs/server", "nfs.port", NULL, GLOBAL_DOC, 0}, {"nfs.rpc-auth-unix", "nfs/server", "!rpc-auth.auth-unix.*", NULL, DOC, 0}, - {"nfs.rpc-auth-null", "nfs/server", "!rpc-auth.auth.null.*", NULL, DOC, 0}, + {"nfs.rpc-auth-null", "nfs/server", "!rpc-auth.auth-null.*", NULL, DOC, 0}, {"nfs.rpc-auth-allow", "nfs/server", "!rpc-auth.addr.*.allow", NULL, DOC, 0}, {"nfs.rpc-auth-reject", "nfs/server", "!rpc-auth.addr.*.reject", NULL, DOC, 0}, {"nfs.ports-insecure", "nfs/server", "!rpc-auth.ports.*.insecure", NULL, DOC, 0}, @@ -2539,7 +2539,7 @@ nfs_option_handler (volgen_graph_t *graph, } if (! strcmp (vme->option, "!rpc-auth.auth-unix.*")) { - ret = gf_asprintf (&aa, "rpc-auth.auth.unix.%s", + ret = gf_asprintf (&aa, "rpc-auth.auth-unix.%s", volinfo->volname); if (ret != -1) { @@ -2550,8 +2550,8 @@ nfs_option_handler (volgen_graph_t *graph, if (ret) return -1; } - if (! strcmp (vme->option, "!rpc-auth.auth.null.*")) { - ret = gf_asprintf (&aa, "rpc-auth.auth.null.%s", + if (! strcmp (vme->option, "!rpc-auth.auth-null.*")) { + ret = gf_asprintf (&aa, "rpc-auth.auth-null.%s", volinfo->volname); if (ret != -1) { diff --git a/xlators/nfs/server/src/nfs.c b/xlators/nfs/server/src/nfs.c index 9a44c009a..f2c690994 100644 --- a/xlators/nfs/server/src/nfs.c +++ b/xlators/nfs/server/src/nfs.c @@ -1040,28 +1040,28 @@ struct volume_options options[] = { "unrecognized option warnings." }, { .key = {"rpc-auth.addr.allow"}, - .type = GF_OPTION_TYPE_STR, + .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST, .description = "Allow a comma separated list of addresses and/or" " hostnames to connect to the server. By default, all" " connections are allowed. This allows users to " "define a general rule for all exported volumes." }, { .key = {"rpc-auth.addr.reject"}, - .type = GF_OPTION_TYPE_STR, + .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST, .description = "Reject a comma separated list of addresses and/or" " hostnames from connecting to the server. By default," " all connections are allowed. This allows users to" "define a general rule for all exported volumes." }, { .key = {"rpc-auth.addr.*.allow"}, - .type = GF_OPTION_TYPE_STR, + .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST, .description = "Allow a comma separated list of addresses and/or" " hostnames to connect to the server. By default, all" " connections are allowed. This allows users to " "define a rule for a specific exported volume." }, { .key = {"rpc-auth.addr.*.reject"}, - .type = GF_OPTION_TYPE_STR, + .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST, .description = "Reject a comma separated list of addresses and/or" " hostnames from connecting to the server. By default," " all connections are allowed. This allows users to" @@ -1123,12 +1123,16 @@ struct volume_options options[] = { }, { .key = {"nfs.port"}, .type = GF_OPTION_TYPE_INT, + .min = 1, + .max = 0xffff, .description = "Use this option on systems that need Gluster NFS to " "be associated with a non-default port number." }, { .key = {"nfs.mem-factor"}, .type = GF_OPTION_TYPE_INT, - .description = "Use this option to make NFS faster on systems by " + .min = 1, + .max = 1024, + .description = "Use this option to make NFS be faster on systems by " "using more memory. This option specifies a multiple " "that determines the total amount of memory used. " "Default value is 15. Increase to use more memory in " diff --git a/xlators/performance/io-cache/src/io-cache.c b/xlators/performance/io-cache/src/io-cache.c index 2af50f962..a50fa872e 100644 --- a/xlators/performance/io-cache/src/io-cache.c +++ b/xlators/performance/io-cache/src/io-cache.c @@ -1984,7 +1984,7 @@ struct xlator_cbks cbks = { struct volume_options options[] = { { .key = {"priority"}, - .type = GF_OPTION_TYPE_ANY, + .type = GF_OPTION_TYPE_PRIORITY_LIST, .default_value = "", .description = "Assigns priority to filenames with specific " "patterns so that when a page needs to be ejected " diff --git a/xlators/protocol/auth/addr/src/addr.c b/xlators/protocol/auth/addr/src/addr.c index 0209dd353..2bc604de8 100644 --- a/xlators/protocol/auth/addr/src/addr.c +++ b/xlators/protocol/auth/addr/src/addr.c @@ -226,14 +226,14 @@ out: struct volume_options options[] = { { .key = {"auth.addr.*.allow"}, - .type = GF_OPTION_TYPE_ANY + .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST }, { .key = {"auth.addr.*.reject"}, - .type = GF_OPTION_TYPE_ANY + .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST }, /* Backword compatibility */ { .key = {"auth.ip.*.allow"}, - .type = GF_OPTION_TYPE_ANY + .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST }, { .key = {NULL} } }; diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c index f87e371f1..33889fd9b 100644 --- a/xlators/protocol/server/src/server.c +++ b/xlators/protocol/server/src/server.c @@ -558,9 +558,8 @@ validate_auth_options (xlator_t *this, dict_t *dict) while (addr) { - if (valid_internet_address (addr) || - valid_wildcard_internet_address (addr)) - { + if (valid_internet_address + (addr, _gf_true)) { error = 0; } else { error = -1; @@ -1140,5 +1139,16 @@ struct volume_options options[] = { .min = GF_MIN_SOCKET_WINDOW_SIZE, .max = GF_MAX_SOCKET_WINDOW_SIZE }, + + /* The following two options are defined in addr.c, redifined here * + * for the sake of validation during volume set from cli */ + + { .key = {"auth.addr.*.allow"}, + .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST + }, + { .key = {"auth.addr.*.reject"}, + .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST + }, + { .key = {NULL} }, }; -- cgit