diff options
-rw-r--r-- | cli/src/cli-cmd-parser.c | 245 | ||||
-rw-r--r-- | cli/src/cli-cmd-volume.c | 2 | ||||
-rw-r--r-- | tests/basic/glusterd/disperse-create.t | 81 |
3 files changed, 226 insertions, 102 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index d7c1ddeb041..9c887fa78a5 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -177,24 +177,58 @@ out: } int32_t -cli_cmd_create_disperse_check(struct cli_state * state, int * disperse, - int * redundancy, int count) +cli_cmd_create_disperse_check (struct cli_state *state, int *disperse, + int *redundancy, int *data, int count) { int i = 0; int tmp = 0; gf_answer_t answer = GF_ANSWER_NO; char question[128]; - const char * question1 = "There isn't an optimal redundancy value " - "for this configuration. Do you want to " - "create the volume with redundancy 1 ?"; + const char *question1 = "There isn't an optimal redundancy value " + "for this configuration. Do you want to " + "create the volume with redundancy 1 ?"; - const char * question2 = "The optimal redundancy for this " - "configuration is %d. Do you want to create " - "the volume with this value ?"; + const char *question2 = "The optimal redundancy for this " + "configuration is %d. Do you want to create " + "the volume with this value ?"; - const char * question3 = "This configuration is not optimal on most " - "workloads. Do you want to use it ?"; + const char *question3 = "This configuration is not optimal on most " + "workloads. Do you want to use it ?"; + + const char *question4 = "Redundancy for this configuration is %d. " + "Do you want to create " + "the volume with this value ?"; + + if (*data > 0) { + if (*disperse > 0 && *redundancy > 0) { + if (*disperse != (*data + *redundancy)) { + cli_err ("Disperse count(%d) should be equal " + "to sum of disperse-data count(%d) and " + "redundancy count(%d)", *disperse, + *data, *redundancy); + return -1; + } + } else if (*redundancy > 0) { + *disperse = *data + *redundancy; + } else if (*disperse > 0) { + *redundancy = *disperse - *data; + } else { + if ((count - *data) >= *data) { + cli_err ("Please provide redundancy count " + "along with disperse-data count"); + return -1; + } else { + sprintf (question, question4, count - *data); + answer = cli_cmd_get_confirmation (state, + question); + if (answer == GF_ANSWER_NO) + return -1; + *redundancy = count - *data; + *disperse = count; + } + } + } if (*disperse <= 0) { if (count < 3) { @@ -206,7 +240,7 @@ cli_cmd_create_disperse_check(struct cli_state * state, int * disperse, *disperse = count; } - if (*redundancy == 0) { + if (*redundancy == -1) { tmp = *disperse - 1; for (i = tmp / 2; (i > 0) && ((tmp & -tmp) != tmp); @@ -232,8 +266,7 @@ cli_cmd_create_disperse_check(struct cli_state * state, int * disperse, } tmp = 0; - } - else { + } else { tmp = *disperse - *redundancy; } @@ -254,6 +287,87 @@ cli_cmd_create_disperse_check(struct cli_state * state, int * disperse, return 0; } +static int32_t +cli_validate_disperse_volume (char *word, gf1_cluster_type type, + const char **words, int32_t wordcount, + int32_t index, int32_t *disperse_count, + int32_t *redundancy_count, + int32_t *data_count) +{ + int ret = -1; + + switch (type) { + case GF_CLUSTER_TYPE_NONE: + case GF_CLUSTER_TYPE_DISPERSE: + if (strcmp (word, "disperse") == 0) { + if (*disperse_count >= 0) { + cli_err ("disperse option given twice"); + goto out; + } + if (wordcount < (index+2)) { + goto out; + } + ret = gf_string2int (words[index + 1], disperse_count); + if (ret == -1 && errno == EINVAL) { + *disperse_count = 0; + ret = 1; + } else if (ret == -1) { + goto out; + } else { + if (*disperse_count < 3) { + cli_err ("disperse count must " + "be greater than 2"); + goto out; + } + ret = 2; + } + } else if (strcmp (word, "disperse-data") == 0) { + if (*data_count >= 0) { + cli_err ("disperse-data option given twice"); + goto out; + } + if (wordcount < (index+2)) { + goto out; + } + ret = gf_string2int (words[index+1], data_count); + if (ret == -1 || *data_count < 2) { + cli_err ("disperse-data must be greater than 1"); + goto out; + } + ret = 2; + } else if (strcmp (word, "redundancy") == 0) { + if (*redundancy_count >= 0) { + cli_err ("redundancy option given twice"); + goto out; + } + if (wordcount < (index+2)) { + goto out; + } + ret = gf_string2int (words[index+1], redundancy_count); + if (ret == -1 || *redundancy_count < 1) { + cli_err ("redundancy must be greater than 0"); + goto out; + } + ret = 2; + } + break; + case GF_CLUSTER_TYPE_STRIPE_REPLICATE: + cli_err ("striped-replicated-dispersed volume " + "is not supported"); + goto out; + case GF_CLUSTER_TYPE_STRIPE: + cli_err ("striped-dispersed volume is not " + "supported"); + goto out; + case GF_CLUSTER_TYPE_REPLICATE: + cli_err ("replicated-dispersed volume is not " + "supported"); + goto out; + } +out: + return ret; +} + int32_t cli_cmd_volume_create_parse (struct cli_state *state, const char **words, int wordcount, dict_t **options) @@ -271,7 +385,7 @@ cli_cmd_volume_create_parse (struct cli_state *state, const char **words, char *bricks = NULL; int32_t brick_count = 0; char *opwords[] = { "replica", "stripe", "transport", "disperse", - "redundancy", NULL }; + "redundancy", "disperse-data", NULL }; char *invalid_volnames[] = {"volume", "type", "subvolumes", "option", "end-volume", "all", "volume_not_in_ring", @@ -285,7 +399,8 @@ cli_cmd_volume_create_parse (struct cli_state *state, const char **words, int32_t replica_count = 1; int32_t stripe_count = 1; int32_t disperse_count = -1; - int32_t redundancy_count = 0; + int32_t redundancy_count = -1; + int32_t disperse_data_count = -1; gf_boolean_t is_force = _gf_false; int wc = wordcount; @@ -440,90 +555,17 @@ cli_cmd_volume_create_parse (struct cli_state *state, const char **words, } index += 2; - } else if ((strcmp (w, "disperse")) == 0) { - switch (type) { - case GF_CLUSTER_TYPE_DISPERSE: - if (disperse_count >= 0) { - cli_err ("disperse option given " - "twice"); - goto out; - } - break; - case GF_CLUSTER_TYPE_NONE: - type = GF_CLUSTER_TYPE_DISPERSE; - break; - case GF_CLUSTER_TYPE_STRIPE_REPLICATE: - cli_err ("striped-replicated-dispersed volume " - "is not supported"); - goto out; - case GF_CLUSTER_TYPE_STRIPE: - cli_err ("striped-dispersed volume is not " - "supported"); - goto out; - case GF_CLUSTER_TYPE_REPLICATE: - cli_err ("replicated-dispersed volume is not " - "supported"); - goto out; - } - - if (wordcount >= (index+2)) { - disperse_count = strtol (words[index + 1], - &ptr, 0); - if (*ptr != 0) - disperse_count = 0; - else { - if (disperse_count < 3) { - cli_err ("disperse count must " - "be greater than 2"); - ret = -1; - goto out; - } - index++; - } - } - - index++; - - } else if ((strcmp (w, "redundancy")) == 0) { - switch (type) { - case GF_CLUSTER_TYPE_NONE: - type = GF_CLUSTER_TYPE_DISPERSE; - break; - case GF_CLUSTER_TYPE_DISPERSE: - if (redundancy_count > 0) { - cli_err ("redundancy option given " - "twice"); - goto out; - } - break; - case GF_CLUSTER_TYPE_STRIPE_REPLICATE: - cli_err ("striped-replicated-dispersed volume " - "is not supported"); - goto out; - case GF_CLUSTER_TYPE_STRIPE: - cli_err ("striped-dispersed volume is not " - "supported"); - goto out; - case GF_CLUSTER_TYPE_REPLICATE: - cli_err ("replicated-dispersed volume is not " - "supported"); - goto out; - } - - if (wordcount < (index+2)) { - ret = -1; - goto out; - } - redundancy_count = strtol (words[index+1], NULL, 0); - if (redundancy_count < 1) { - cli_err ("redundancy must be greater than 0"); - ret = -1; + } else if ((strcmp (w, "disperse") == 0) || + (strcmp (w, "redundancy") == 0) || + (strcmp (w, "disperse-data") == 0)) { + ret = cli_validate_disperse_volume (w, type, words, + wordcount, index, &disperse_count, + &redundancy_count, &disperse_data_count); + if (ret < 0) goto out; - } - - index += 2; - - } else { + index += ret; + type = GF_CLUSTER_TYPE_DISPERSE; + } else { GF_ASSERT (!"opword mismatch"); ret = -1; goto out; @@ -563,9 +605,10 @@ cli_cmd_volume_create_parse (struct cli_state *state, const char **words, } if (type == GF_CLUSTER_TYPE_DISPERSE) { - ret = cli_cmd_create_disperse_check(state, &disperse_count, - &redundancy_count, - brick_count); + ret = cli_cmd_create_disperse_check (state, &disperse_count, + &redundancy_count, + &disperse_data_count, + brick_count); if (!ret) ret = dict_set_int32 (dict, "disperse-count", disperse_count); diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index f87e6e24e7e..1b235bade6f 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -2305,7 +2305,7 @@ struct cli_cmd volume_cmds[] = { "list information of all volumes"}, { "volume create <NEW-VOLNAME> [stripe <COUNT>] [replica <COUNT>] " - "[disperse [<COUNT>]] [redundancy <COUNT>] " + "[disperse [<COUNT>]] [disperse-data <COUNT>] [redundancy <COUNT>] " "[transport <tcp|rdma|tcp,rdma>] <NEW-BRICK>" #ifdef HAVE_BD_XLATOR "?<vg_name>" diff --git a/tests/basic/glusterd/disperse-create.t b/tests/basic/glusterd/disperse-create.t new file mode 100644 index 00000000000..e5ce74c12b2 --- /dev/null +++ b/tests/basic/glusterd/disperse-create.t @@ -0,0 +1,81 @@ +#!/bin/bash + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc + +# This command tests the volume create command validation for disperse volumes. + +cleanup; +TEST glusterd +TEST pidof glusterd +TEST $CLI volume create $V0 disperse $H0:$B0/b1 $H0:$B0/b2 $H0:$B0/b3 +EXPECT "1 x \(2 \+ 1\) = 3" volinfo_field $V0 "Number of Bricks" + +TEST $CLI volume delete $V0 +TEST $CLI volume create $V0 disperse 3 $H0:$B0/b4 $H0:$B0/b5 $H0:$B0/b6 +EXPECT "1 x \(2 \+ 1\) = 3" volinfo_field $V0 "Number of Bricks" + +TEST $CLI volume delete $V0 +TEST $CLI volume create $V0 disperse 3 redundancy 1 $H0:$B0/b7 $H0:$B0/b8 $H0:$B0/b9 +EXPECT "1 x \(2 \+ 1\) = 3" volinfo_field $V0 "Number of Bricks" + +TEST $CLI volume delete $V0 +TEST $CLI volume create $V0 redundancy 1 $H0:$B0/b10 $H0:$B0/b11 $H0:$B0/b12 +EXPECT "1 x \(2 \+ 1\) = 3" volinfo_field $V0 "Number of Bricks" + +TEST $CLI volume delete $V0 +TEST $CLI volume create $V0 disperse-data 2 redundancy 1 $H0:$B0/b11 $H0:$B0/b12 $H0:$B0/b13 +EXPECT "1 x \(2 \+ 1\) = 3" volinfo_field $V0 "Number of Bricks" + +TEST $CLI volume delete $V0 +TEST $CLI volume create $V0 disperse-data 2 redundancy 1 $H0:$B0/b11 $H0:$B0/b12 $H0:$B0/b13 +EXPECT "1 x \(2 \+ 1\) = 3" volinfo_field $V0 "Number of Bricks" + +TEST $CLI volume delete $V0 +TEST $CLI volume create $V0 disperse 3 disperse-data 2 $H0:$B0/b14 $H0:$B0/b15 $H0:$B0/b16 +EXPECT "1 x \(2 \+ 1\) = 3" volinfo_field $V0 "Number of Bricks" + +TEST $CLI volume delete $V0 +TEST $CLI volume create $V0 disperse 3 disperse-data 2 redundancy 1 $H0:$B0/b17 $H0:$B0/b18 $H0:$B0/b19 +EXPECT "1 x \(2 \+ 1\) = 3" volinfo_field $V0 "Number of Bricks" + +# -ve test cases +#Key-words appearing more than once +TEST ! $CLI volume create $V0 disperse 3 disperse 3 $H0:$B0/b20 $H0:$B0/b21 $H0:$B0/b22 +TEST ! $CLI volume create $V0 disperse-data 2 disperse-data 2 $H0:$B0/b20 $H0:$B0/b21 $H0:$B0/b22 +TEST ! $CLI volume create $V0 redundancy 1 redundancy 1 $H0:$B0/b20 $H0:$B0/b21 $H0:$B0/b22 + +#Minimum counts test +TEST ! $CLI volume create $V0 disperse 2 $H0:$B0/b20 $H0:$B0/b22 +TEST ! $CLI volume create $V0 disperse-data 1 redundancy 0 $H0:$B0/b20 $H0:$B0/b22 +TEST ! $CLI volume create $V0 redundancy 0 $H0:$B0/b20 $H0:$B0/b22 + +#Wrong count n != k+m +TEST ! $CLI volume create $V0 disperse 4 disperse-data 4 redundancy 2 $H0:$B0/b20 $H0:$B0/b21 $H0:$B0/b22 +#Num bricks is not multiple of disperse count +TEST ! $CLI volume create $V0 disperse 6 disperse-data 4 $H0:$B0/b20 $H0:$B0/b21 $H0:$B0/b22 +#Redundancy > data +TEST ! $CLI volume create $V0 disperse 6 disperse-data 2 redundancy 4 $H0:$B0/b20 $H0:$B0/b21 $H0:$B0/b22 +TEST ! $CLI volume create $V0 disperse 4 disperse-data 2 redundancy 2 $H0:$B0/b20 $H0:$B0/b21 $H0:$B0/b22 +#Replica + Disperse +TEST ! $CLI volume create $V0 disperse 4 replica 2 $H0:$B0/b20 $H0:$B0/b21 $H0:$B0/b22 +TEST ! $CLI volume create $V0 disperse-data 2 replica 2 $H0:$B0/b20 $H0:$B0/b21 $H0:$B0/b22 $H0:$B0/b23 +TEST ! $CLI volume create $V0 redundancy 2 replica 2 $H0:$B0/b20 $H0:$B0/b21 $H0:$B0/b22 +TEST ! $CLI volume create $V0 replica 2 disperse 4 $H0:$B0/b20 $H0:$B0/b21 $H0:$B0/b22 +TEST ! $CLI volume create $V0 replica 2 disperse-data 2 $H0:$B0/b20 $H0:$B0/b21 $H0:$B0/b22 $H0:$B0/b23 +TEST ! $CLI volume create $V0 replica 2 redundancy 2 $H0:$B0/b20 $H0:$B0/b21 $H0:$B0/b22 +#Stripe + Disperse +TEST ! $CLI volume create $V0 disperse 4 stripe 2 $H0:$B0/b20 $H0:$B0/b21 $H0:$B0/b22 +TEST ! $CLI volume create $V0 disperse-data 2 stripe 2 $H0:$B0/b20 $H0:$B0/b21 $H0:$B0/b22 $H0:$B0/b23 +TEST ! $CLI volume create $V0 redundancy 2 stripe 2 $H0:$B0/b20 $H0:$B0/b21 $H0:$B0/b22 +TEST ! $CLI volume create $V0 stripe 2 disperse 4 $H0:$B0/b20 $H0:$B0/b21 $H0:$B0/b22 +TEST ! $CLI volume create $V0 stripe 2 disperse-data 2 $H0:$B0/b20 $H0:$B0/b21 $H0:$B0/b22 $H0:$B0/b23 +TEST ! $CLI volume create $V0 stripe 2 redundancy 2 $H0:$B0/b20 $H0:$B0/b21 $H0:$B0/b22 +#Stripe + Replicate + Disperse, It is failing with striped-dispersed volume. +TEST ! $CLI volume create $V0 disperse 4 stripe 2 replica 2 $H0:$B0/b20 $H0:$B0/b21 $H0:$B0/b22 +TEST ! $CLI volume create $V0 disperse-data 2 stripe 2 replica 2 $H0:$B0/b20 $H0:$B0/b21 $H0:$B0/b22 $H0:$B0/b23 +TEST ! $CLI volume create $V0 redundancy 2 stripe 2 replica 2 $H0:$B0/b20 $H0:$B0/b21 $H0:$B0/b22 +TEST ! $CLI volume create $V0 stripe 2 disperse 4 replica 2 $H0:$B0/b20 $H0:$B0/b21 $H0:$B0/b22 +TEST ! $CLI volume create $V0 stripe 2 disperse-data 2 replica 2 $H0:$B0/b20 $H0:$B0/b21 $H0:$B0/b22 $H0:$B0/b23 +TEST ! $CLI volume create $V0 stripe 2 redundancy 2 replica 2 $H0:$B0/b20 $H0:$B0/b21 $H0:$B0/b22 +cleanup |