diff options
| author | Amar Tumballi <amar@gluster.com> | 2011-06-21 04:56:41 +0000 | 
|---|---|---|
| committer | Anand Avati <avati@gluster.com> | 2011-06-23 21:30:53 -0700 | 
| commit | c9854677fcd5a0a68e885cc18b6d9d6d92218f23 (patch) | |
| tree | 3f54e891e90f05f9e5f7758da355522adfadaf65 | |
| parent | 0d87bfca5c9a95977215599d5800e751ec8f2205 (diff) | |
gluster volume create: option for stripe + replicate volume
So RAID01 like option is a possibility
Signed-off-by: Amar Tumballi <amar@gluster.com>
Signed-off-by: Anand Avati <avati@gluster.com>
BUG: 3040 (need a way to create volumes with 'stripe+replicate' setup..)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=3040
| -rw-r--r-- | cli/src/cli-cmd-parser.c | 118 | ||||
| -rw-r--r-- | rpc/xdr/src/cli1-xdr.h | 1 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.c | 11 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volgen.c | 41 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.h | 2 | 
5 files changed, 149 insertions, 24 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index 3e331848d1b..2c1897550ec 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -158,6 +158,7 @@ cli_cmd_volume_create_parse (const char **words, int wordcount, dict_t **options          int     ret = -1;          gf1_cluster_type type = GF_CLUSTER_TYPE_NONE;          int     count = 1; +        int     sub_count = 1;          int     brick_index = 0;          int     i = 0;          char    *trans_type = NULL; @@ -204,19 +205,23 @@ cli_cmd_volume_create_parse (const char **words, int wordcount, dict_t **options                                  goto out;          } - -        ret = dict_set_str (dict, "volname", volname); -        if (ret) -                goto out; -          if (wordcount < 4) {                  ret = -1;                  goto out;          } + +        if (wordcount < 6) { +                /* seems no options are given, go directly to the parse_brick */ +                brick_index = 3; +                type = GF_CLUSTER_TYPE_NONE; +                trans_type = gf_strdup ("tcp"); +                goto parse_bricks; +        } +          w = str_getunamb (words[3], opwords_cl);          if (!w) {                  type = GF_CLUSTER_TYPE_NONE; -                brick_index = 3; +                index = 3;          } else if ((strcmp (w, "replica")) == 0) {                  type = GF_CLUSTER_TYPE_REPLICATE;                  if (wordcount < 5) { @@ -232,7 +237,7 @@ cli_cmd_volume_create_parse (const char **words, int wordcount, dict_t **options                  ret = dict_set_int32 (dict, "replica-count", count);                  if (ret)                          goto out; -                brick_index = 5; +                index = 5;          } else if ((strcmp (w, "stripe")) == 0) {                  type = GF_CLUSTER_TYPE_STRIPE;                  if (wordcount < 5) { @@ -248,24 +253,78 @@ cli_cmd_volume_create_parse (const char **words, int wordcount, dict_t **options                  ret = dict_set_int32 (dict, "stripe-count", count);                  if (ret)                          goto out; -                brick_index = 5; -        } else +                index = 5; +        } else {                  GF_ASSERT (!"opword mismatch"); - -        ret = dict_set_int32 (dict, "type", type); -        if (ret) +                ret = -1;                  goto out; +        } -        if (type) -                index = 5; -        else -                index = 3; +        /* Ie, how many bricks together forms a subvolume of distribute */ +        sub_count = count; +        /* reset the count value now */ +        count = 1; + +        /* It can be a 'stripe x replicate' (ie, RAID01) type of volume */ +        w = str_getunamb (words[5], opwords_cl); +        if (w && ((strcmp (w, "replica")) == 0)) { +                if (type == GF_CLUSTER_TYPE_REPLICATE) { +                        cli_out ("'replica' option is already given"); +                        ret = -1; +                        goto out; +                } +                /* The previous one should have been 'stripe' option */ +                type = GF_CLUSTER_TYPE_STRIPE_REPLICATE; -        if (wordcount < (index + 1)) { +                if (wordcount < 7) { +                        ret = -1; +                        goto out; +                } +                count = strtol (words[6], NULL, 0); +                if (!count || (count < 2)) { +                        cli_out ("replica count should be greater than 1"); +                        ret = -1; +                        goto out; +                } + +                ret = dict_set_int32 (dict, "replica-count", count); +                if (ret) +                        goto out; +                index = 7; +        } else if (w && ((strcmp (w, "stripe")) == 0)) { +                if (type == GF_CLUSTER_TYPE_STRIPE) { +                        cli_out ("'stripe' option is already given"); +                        ret = -1; +                        goto out; +                } + +                /* The previous one should have been 'replica' option */ +                type = GF_CLUSTER_TYPE_STRIPE_REPLICATE; + +                if (wordcount < 7) { +                        ret = -1; +                        goto out; +                } +                count = strtol (words[6], NULL, 0); +                if (!count || (count < 2)) { +                        cli_out ("stripe count should be greater than 1"); +                        ret = -1; +                        goto out; +                } +                ret = dict_set_int32 (dict, "stripe-count", count); +                if (ret) +                        goto out; +                index = 7; +        } else if (w) { +                GF_ASSERT (!"opword mismatch");                  ret = -1;                  goto out;          } +        sub_count *= count; + +        brick_index = index; +          if (str_getunamb (words[index], opwords_tr)) {                  brick_index = index+2;                  if (wordcount < (index + 2)) { @@ -290,10 +349,7 @@ cli_cmd_volume_create_parse (const char **words, int wordcount, dict_t **options                  trans_type = gf_strdup ("tcp");          } -        ret = dict_set_dynstr (dict, "transport", trans_type); -        if (ret) -                goto out; - +parse_bricks:          ret = cli_cmd_bricks_parse (words, wordcount, brick_index, &bricks,                                      &brick_count);          if (ret) @@ -307,17 +363,35 @@ cli_cmd_volume_create_parse (const char **words, int wordcount, dict_t **options                  goto out;          } -        if (brick_count % count) { +        if (brick_count % sub_count) {                  if (type == GF_CLUSTER_TYPE_STRIPE)                          cli_out ("number of bricks is not a multiple of "                                   "stripe count");                  else if (type == GF_CLUSTER_TYPE_REPLICATE)                          cli_out ("number of bricks is not a multiple of "                                   "replica count"); +                else +                        cli_out ("number of bricks given doesn't match " +                                 "required count"); +                  ret = -1;                  goto out;          } +        /* Everything if parsed fine. start setting info in dict */ +        ret = dict_set_str (dict, "volname", volname); +        if (ret) +                goto out; + +        ret = dict_set_int32 (dict, "type", type); +        if (ret) +                goto out; + +        ret = dict_set_dynstr (dict, "transport", trans_type); +        if (ret) +                goto out; + +          ret = dict_set_dynstr (dict, "bricks", bricks);          if (ret)                  goto out; diff --git a/rpc/xdr/src/cli1-xdr.h b/rpc/xdr/src/cli1-xdr.h index 80a2b4633ec..01b4e461ce0 100644 --- a/rpc/xdr/src/cli1-xdr.h +++ b/rpc/xdr/src/cli1-xdr.h @@ -37,6 +37,7 @@ enum gf1_cluster_type {  	GF_CLUSTER_TYPE_NONE = 0,  	GF_CLUSTER_TYPE_STRIPE = 0 + 1,  	GF_CLUSTER_TYPE_REPLICATE = 0 + 2, +	GF_CLUSTER_TYPE_STRIPE_REPLICATE = 0 + 3,  };  typedef enum gf1_cluster_type gf1_cluster_type; diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index 0cf94171c89..47f2c73c9eb 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -2707,6 +2707,17 @@ glusterd_op_create_volume (dict_t *dict, char **op_errstr)                                        &sub_count);                  if (ret)                          goto out; +        } else if (GF_CLUSTER_TYPE_STRIPE_REPLICATE == volinfo->type) { +                ret = dict_get_int32 (dict, "stripe-count", +                                      &volinfo->stripe_count); +                if (ret) +                        goto out; +                ret = dict_get_int32 (dict, "replica-count", +                                      &volinfo->replica_count); +                if (ret) +                        goto out; + +                sub_count = volinfo->stripe_count * volinfo->replica_count;          }          ret = dict_get_str (dict, "transport", &trans_type); diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c index a090f46debd..607fe1dafae 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volgen.c +++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c @@ -1506,6 +1506,7 @@ static int  client_graph_builder (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,                        dict_t *set_dict, void *param)  { +        int                      sub_count          = 0;          int                      dist_count         = 0;          char                     transt[16]         = {0,};          char                    *volname            = NULL; @@ -1576,7 +1577,8 @@ client_graph_builder (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,                  return -1;          } -        if (volinfo->sub_count > 1) { +        sub_count = volinfo->sub_count; +        if (sub_count > 1) {                  switch (volinfo->type) {                  case GF_CLUSTER_TYPE_REPLICATE:                          cluster_args = replicate_args; @@ -1584,6 +1586,11 @@ client_graph_builder (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,                  case GF_CLUSTER_TYPE_STRIPE:                          cluster_args = stripe_args;                          break; +                case GF_CLUSTER_TYPE_STRIPE_REPLICATE: +                        /* Replicate after the clients, then stripe */ +                        sub_count = volinfo->replica_count; +                        cluster_args = replicate_args; +                        break;                  default:                          gf_log ("", GF_LOG_ERROR, "volume inconsistency: "                                  "unrecognized clustering type"); @@ -1595,7 +1602,7 @@ client_graph_builder (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,                  txl = first_of (graph);                  for (trav = txl; trav->next; trav = trav->next);                  for (;; trav = trav->prev) { -                        if (i % volinfo->sub_count == 0) { +                        if (i % sub_count == 0) {                                  xl = volgen_graph_add_nolink (graph,                                                                cluster_args[0],                                                                cluster_args[1], @@ -1613,8 +1620,38 @@ client_graph_builder (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,                                  break;                          i++;                  } + +                if (GF_CLUSTER_TYPE_STRIPE_REPLICATE == volinfo->type) { +                        sub_count = volinfo->stripe_count; +                        cluster_args = stripe_args; + +                        i = 0; +                        txl = first_of (graph); +                        for (trav = txl; --j; trav = trav->next); +                        for (;; trav = trav->prev) { +                                if (i % sub_count == 0) { +                                        xl = volgen_graph_add_nolink (graph, +                                                                      cluster_args[0], +                                                                      cluster_args[1], +                                                                      volname, j); +                                        if (!xl) +                                                return -1; +                                        j++; +                                } + +                                ret = volgen_xlator_link (xl, trav); +                                if (ret) +                                        return -1; + +                                if (trav == txl) +                                        break; +                                i++; +                        } + +                }          } +          if (volinfo->sub_count)                  dist_count = volinfo->brick_count / volinfo->sub_count;          else diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index b1027c1714c..7cbb4bc56b6 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -187,6 +187,8 @@ struct glusterd_volinfo_ {          struct list_head        bricks;          glusterd_volume_status  status;          int                     sub_count; +        int                     stripe_count; +        int                     replica_count;          int                     port;          glusterd_store_handle_t *shandle;  | 
