summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmar Tumballi <amar@gluster.com>2011-06-21 04:56:41 +0000
committerAnand Avati <avati@gluster.com>2011-06-23 21:30:53 -0700
commitc9854677fcd5a0a68e885cc18b6d9d6d92218f23 (patch)
tree3f54e891e90f05f9e5f7758da355522adfadaf65
parent0d87bfca5c9a95977215599d5800e751ec8f2205 (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.c118
-rw-r--r--rpc/xdr/src/cli1-xdr.h1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.c11
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volgen.c41
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h2
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;