summaryrefslogtreecommitdiffstats
path: root/cli/src/cli-cmd-parser.c
diff options
context:
space:
mode:
authorAnuradha Talur <atalur@redhat.com>2016-08-22 13:22:03 -0400
committerPranith Kumar Karampuri <pkarampu@redhat.com>2016-08-29 19:55:53 -0700
commit936f8aeac3252951e7fa0cdaa5d260fad3bd5ea0 (patch)
tree66240b8ef55d55ca9535a21f73a5f71c9ff6ade4 /cli/src/cli-cmd-parser.c
parentc204f452dfd9907a0d32f35294a0805701a6d993 (diff)
glusterd : Introduce reset brick
The command basically allows replace brick with src and dst bricks as same. Usage: gluster v reset-brick <volname> <hostname:brick-path> start This command kills the brick to be reset. Once this command is run, admin can do other manual operations that they need to do, like configuring some options for the brick. Once this is done, resetting the brick can be continued with the following options. gluster v reset-brick <vname> <hostname:brick> <hostname:brick> commit {force} Does the job of resetting the brick. 'force' option should be used when the brick already contains volinfo id. Problem: On doing a disk-replacement of a brick in a replicate volume the following 2 scenarios may occur : a) there is a chance that reads are served from this replaced-disk brick, which leads to empty reads. b) potential data loss if next writes succeed only on replaced brick, and heal is done to other bricks from this one. Solution: After disk-replacement, make sure that reset-brick command is run for that brick so that pending markers are set for the brick and it is not chosen as source for reads and heal. But, as of now replace-brick for the same brick-path is not allowed. In order to fix the above mentioned problem, same brick-path replace-brick is needed. With this patch reset-brick commit {force} will be allowed even when source and destination <hostname:brickpath> are identical as long as 1) destination brick is not alive 2) source and destination brick have the same brick uuid and path. Also, the destination brick after replace-brick will use the same port as the source brick. Change-Id: I440b9e892ffb781ea4b8563688c3f85c7a7c89de BUG: 1266876 Signed-off-by: Anuradha Talur <atalur@redhat.com> Reviewed-on: http://review.gluster.org/12250 Smoke: Gluster Build System <jenkins@build.gluster.org> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.org> Reviewed-by: Ashish Pandey <aspandey@redhat.com> Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
Diffstat (limited to 'cli/src/cli-cmd-parser.c')
-rw-r--r--cli/src/cli-cmd-parser.c164
1 files changed, 133 insertions, 31 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c
index be0a8e756d5..86b02877159 100644
--- a/cli/src/cli-cmd-parser.c
+++ b/cli/src/cli-cmd-parser.c
@@ -2134,6 +2134,137 @@ out:
return ret;
}
+int32_t
+cli_cmd_brick_op_validate_bricks (const char **words, dict_t *dict,
+ int src, int dst)
+{
+ int ret = -1;
+ char *delimiter = NULL;
+
+ if (validate_brick_name ((char *)words[src])) {
+ cli_err ("wrong brick type: %s, use "
+ "<HOSTNAME>:<export-dir-abs-path>", words[3]);
+ ret = -1;
+ goto out;
+ } else {
+ delimiter = strrchr ((char *)words[src], '/');
+ ret = gf_canonicalize_path (delimiter);
+ if (ret)
+ goto out;
+ }
+
+ ret = dict_set_str (dict, "src-brick", (char *)words[src]);
+ if (ret)
+ goto out;
+
+ if (dst == -1) {
+ ret = 0;
+ goto out;
+ }
+
+ if (validate_brick_name ((char *)words[dst])) {
+ cli_err ("wrong brick type: %s, use "
+ "<HOSTNAME>:<export-dir-abs-path>", words[dst]);
+ ret = -1;
+ goto out;
+ } else {
+ delimiter = strrchr ((char *)words[dst], '/');
+ ret = gf_canonicalize_path (delimiter);
+ if (ret)
+ goto out;
+ }
+
+ ret = dict_set_str (dict, "dst-brick", (char *)words[dst]);
+ if (ret)
+ goto out;
+ ret = 0;
+out:
+ return ret;
+}
+
+int32_t
+cli_cmd_volume_reset_brick_parse (const char **words, int wordcount,
+ dict_t **options)
+{
+ int ret = -1;
+ char *volname = NULL;
+ dict_t *dict = NULL;
+
+ if (wordcount < 5 || wordcount > 7)
+ goto out;
+
+ dict = dict_new ();
+
+ if (!dict)
+ goto out;
+
+ volname = (char *)words[2];
+
+ ret = dict_set_str (dict, "volname", volname);
+ if (ret)
+ goto out;
+
+ if (wordcount == 5) {
+ if (strcmp (words[4], "start")) {
+ cli_err ("Invalid option '%s' for reset-brick. Please "
+ "enter valid reset-brick command", words[4]);
+ ret = -1;
+ goto out;
+ }
+
+ ret = cli_cmd_brick_op_validate_bricks (words, dict, 3, -1);
+ if (ret)
+ goto out;
+
+ ret = dict_set_str (dict, "operation", "GF_RESET_OP_START");
+ if (ret)
+ goto out;
+ } else if (wordcount == 6) {
+ if (strcmp (words[5], "commit")) {
+ cli_err ("Invalid option '%s' for reset-brick. Please "
+ "enter valid reset-brick command", words[5]);
+ ret = -1;
+ goto out;
+ }
+
+ ret = cli_cmd_brick_op_validate_bricks (words, dict, 3, 4);
+ if (ret)
+ goto out;
+
+ ret = dict_set_str (dict, "operation", "GF_RESET_OP_COMMIT");
+ if (ret)
+ goto out;
+ } else if (wordcount == 7) {
+ if (strcmp (words[5], "commit") || strcmp (words[6], "force")) {
+ cli_err ("Invalid option '%s %s' for reset-brick. Please "
+ "enter valid reset-brick command",
+ words[5], words[6]);
+ ret = -1;
+ goto out;
+ }
+
+ ret = cli_cmd_brick_op_validate_bricks (words, dict, 3, 4);
+ if (ret)
+ goto out;
+
+ ret = dict_set_str (dict, "operation",
+ "GF_RESET_OP_COMMIT_FORCE");
+ if (ret)
+ goto out;
+ }
+
+ *options = dict;
+
+out:
+ if (ret) {
+ gf_log ("cli", GF_LOG_ERROR,
+ "Unable to parse reset-brick CLI");
+ if (dict)
+ dict_unref (dict);
+ }
+
+ return ret;
+}
int32_t
cli_cmd_volume_replace_brick_parse (const char **words, int wordcount,
@@ -2141,7 +2272,6 @@ cli_cmd_volume_replace_brick_parse (const char **words, int wordcount,
{
int ret = -1;
char *volname = NULL;
- char *delimiter = NULL;
dict_t *dict = NULL;
GF_ASSERT (words);
@@ -2167,35 +2297,7 @@ cli_cmd_volume_replace_brick_parse (const char **words, int wordcount,
if (ret)
goto out;
- if (validate_brick_name ((char *)words[3])) {
- cli_err ("wrong brick type: %s, use "
- "<HOSTNAME>:<export-dir-abs-path>", words[3]);
- ret = -1;
- goto out;
- } else {
- delimiter = strrchr ((char *)words[3], ':');
- ret = gf_canonicalize_path (delimiter + 1);
- if (ret)
- goto out;
- }
-
- ret = dict_set_str (dict, "src-brick", (char *)words[3]);
- if (ret)
- goto out;
-
- if (validate_brick_name ((char *)words[4])) {
- cli_err ("wrong brick type: %s, use "
- "<HOSTNAME>:<export-dir-abs-path>", words[4]);
- ret = -1;
- goto out;
- } else {
- delimiter = strrchr ((char *)words[4], ':');
- ret = gf_canonicalize_path (delimiter + 1);
- if (ret)
- goto out;
- }
-
- ret = dict_set_str (dict, "dst-brick", (char *)words[4]);
+ ret = cli_cmd_brick_op_validate_bricks (words, dict, 3, 4);
if (ret)
goto out;
@@ -2216,7 +2318,7 @@ cli_cmd_volume_replace_brick_parse (const char **words, int wordcount,
out:
if (ret) {
- gf_log ("cli", GF_LOG_ERROR, "Unable to parse replace-brick CLI");
+ gf_log ("cli", GF_LOG_ERROR, "Unable to parse reset-brick CLI");
if (dict)
dict_unref (dict);
}