diff options
| author | Pranith Kumar K <pkarampu@redhat.com> | 2015-02-09 14:20:28 +0530 | 
|---|---|---|
| committer | Krishnan Parthasarathi <kparthas@redhat.com> | 2015-02-23 04:34:24 -0800 | 
| commit | a671b9a575b89c263af161293e78e49484859ec7 (patch) | |
| tree | 19edf8bb5a25b6b7435306d60e24bd12d4b011e4 | |
| parent | 2b821b114836901bf1e661fc6c4e212298c9768d (diff) | |
cli: Provide CLI to create disperse volume with data, redundancy counts
Change-Id: Iba44be565c895e26b19b5ff85a886873f6b53e5c
BUG: 1177601
Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
Reviewed-on: http://review.gluster.org/9616
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Krishnan Parthasarathi <kparthas@redhat.com>
Tested-by: Krishnan Parthasarathi <kparthas@redhat.com>
| -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  | 
