From c770722983f73aa838b5985755999050c746550a Mon Sep 17 00:00:00 2001 From: Amar Tumballi Date: Tue, 11 Oct 2011 16:33:24 +0530 Subject: changing of the volume types after volume is created. with this patch, one can do all the below operations: on a simple distribute volume 'test' with bricks A,B, add bricks C and D: bash# gluster volume add-brick test replica 2 C D now the volume 'test' becomes distribute-replicate, with pairs A-C, B-D. same holds good for stripe. and now, one can change the replica count 2 on volume 'test' to 4 like below: bash# gluster volume add-brick test replica 4 E F G H now, volume has 'replica' count 4, with pairs being 'A-C-E-F' and 'B-D-G-H'. after this, if user wants to reduce the replica count, he can do bash# gluster volume remove-brick test replica 3 C H # (one from each pair) This should work to reduce the replica count Change-Id: I4f109141a9ba7be4a92a5f5810a4163baeb92973 BUG: 3305 Reviewed-on: http://review.gluster.com/158 Tested-by: Gluster Build System Reviewed-by: Vijay Bellur --- cli/src/cli-cmd-parser.c | 91 ++++++++++++++++++++++++++++++++++++++++++++---- cli/src/cli-cmd-volume.c | 4 +-- 2 files changed, 86 insertions(+), 9 deletions(-) (limited to 'cli') diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index e09db1ce6..eaeb3f1ae 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -726,6 +726,11 @@ cli_cmd_volume_add_brick_parse (const char **words, int wordcount, int ret = -1; int brick_count = 0, brick_index = 0; char *bricks = NULL; + char *opwords_cl[] = { "replica", "stripe", NULL }; + gf1_cluster_type type = GF_CLUSTER_TYPE_NONE; + int count = 1; + char *w = NULL; + int index; GF_ASSERT (words); GF_ASSERT (options); @@ -751,8 +756,58 @@ cli_cmd_volume_add_brick_parse (const char **words, int wordcount, 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; + goto parse_bricks; + } - brick_index = 3; + w = str_getunamb (words[3], opwords_cl); + if (!w) { + type = GF_CLUSTER_TYPE_NONE; + index = 3; + } else if ((strcmp (w, "replica")) == 0) { + type = GF_CLUSTER_TYPE_REPLICATE; + if (wordcount < 5) { + ret = -1; + goto out; + } + count = strtol (words[4], 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 = 5; + } else if ((strcmp (w, "stripe")) == 0) { + type = GF_CLUSTER_TYPE_STRIPE; + if (wordcount < 5) { + ret = -1; + goto out; + } + count = strtol (words[4], 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 = 5; + } else { + GF_ASSERT (!"opword mismatch"); + ret = -1; + goto out; + } + + brick_index = index; + +parse_bricks: ret = cli_cmd_bricks_parse (words, wordcount, brick_index, &bricks, &brick_count); if (ret) @@ -794,20 +849,21 @@ cli_cmd_volume_remove_brick_parse (const char **words, int wordcount, int32_t j = 0; char *tmp_brick = NULL; char *tmp_brick1 = NULL; + char *type_opword[] = { "replica", NULL }; char *opwords[] = { "start", "commit", "pause", "abort", "status", "force", NULL }; char *w = NULL; int32_t command = GF_OP_CMD_NONE; + long count = 0; GF_ASSERT (words); GF_ASSERT (options); - dict = dict_new (); - - if (!dict) + if (wordcount < 4) goto out; - if (wordcount < 3) + dict = dict_new (); + if (!dict) goto out; volname = (char *)words[2]; @@ -818,6 +874,29 @@ cli_cmd_volume_remove_brick_parse (const char **words, int wordcount, if (ret) goto out; + brick_index = 3; + w = str_getunamb (words[3], type_opword); + if (w && !strcmp ("replica", w)) { + if (wordcount < 5) { + ret = -1; + goto out; + } + count = strtol (words[4], NULL, 0); + if (count < 1) { + cli_out ("replica count should be greater than 0 in " + "case of remove-brick"); + ret = -1; + goto out; + } + + ret = dict_set_int32 (dict, "replica-count", count); + if (ret) + goto out; + brick_index = 5; + } else if (w) { + GF_ASSERT (!"opword mismatch"); + } + w = str_getunamb (words[wordcount - 1], opwords); if (!w) { /* Should be default 'force' */ @@ -861,8 +940,6 @@ cli_cmd_volume_remove_brick_parse (const char **words, int wordcount, command); - brick_index = 3; - tmp_index = brick_index; tmp_brick = GF_MALLOC(2048 * sizeof(*tmp_brick), gf_common_mt_char); diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index 425840f7f..36e4c659c 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -1601,11 +1601,11 @@ struct cli_cmd volume_cmds[] = { cli_cmd_volume_rename_cbk, "rename volume to "},*/ - { "volume add-brick ...", + { "volume add-brick [ ] ...", cli_cmd_volume_add_brick_cbk, "add brick to volume "}, - { "volume remove-brick ... {start|pause|abort|status|commit|force}", + { "volume remove-brick [replica ] ... {start|pause|abort|status|commit|force}", cli_cmd_volume_remove_brick_cbk, "remove brick from volume "}, -- cgit