3604df
From a07ff2945c3d7e80ff8a399439e27c7cfef41cda Mon Sep 17 00:00:00 2001
3604df
From: Anuradha Talur <atalur@redhat.com>
3604df
Date: Mon, 22 Aug 2016 13:22:03 -0400
3604df
Subject: [PATCH 58/86] glusterd : Introduce reset brick
3604df
3604df
The command basically allows replace brick with src and
3604df
dst bricks as same.
3604df
3604df
Usage:
3604df
gluster v reset-brick <volname> <hostname:brick-path> start
3604df
This command kills the brick to be reset. Once this command is run,
3604df
admin can do other manual operations that they need to do,
3604df
like configuring some options for the brick. Once this is done,
3604df
resetting the brick can be continued with the following options.
3604df
3604df
gluster v reset-brick <vname> <hostname:brick> <hostname:brick> commit {force}
3604df
3604df
Does the job of resetting the brick. 'force' option should be used
3604df
when the brick already contains volinfo id.
3604df
3604df
Problem: On doing a disk-replacement of a brick in a replicate volume
3604df
the following 2 scenarios may occur :
3604df
3604df
a) there is a chance that reads are served from this replaced-disk brick,
3604df
which leads to empty reads. b) potential data loss if next writes succeed
3604df
only on replaced brick, and heal is done to other bricks from this one.
3604df
3604df
Solution: After disk-replacement, make sure that reset-brick command is
3604df
run for that brick so that pending markers are set for the brick and it
3604df
is not chosen as source for reads and heal. But, as of now replace-brick
3604df
for the same brick-path is not allowed. In order to fix the above
3604df
mentioned problem, same brick-path replace-brick is needed.
3604df
With this patch reset-brick commit {force} will be allowed even when
3604df
source and destination <hostname:brickpath> are identical as long as
3604df
1) destination brick is not alive
3604df
2) source and destination brick have the same brick uuid and path.
3604df
Also, the destination brick after replace-brick will use the same port
3604df
as the source brick.
3604df
3604df
>Change-Id: I440b9e892ffb781ea4b8563688c3f85c7a7c89de
3604df
>BUG: 1266876
3604df
>Signed-off-by: Anuradha Talur <atalur@redhat.com>
3604df
>Reviewed-on: http://review.gluster.org/12250
3604df
>Smoke: Gluster Build System <jenkins@build.gluster.org>
3604df
>NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
3604df
>CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
3604df
>Reviewed-by: Ashish Pandey <aspandey@redhat.com>
3604df
>Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
3604df
3604df
Change-Id: I440b9e892ffb781ea4b8563688c3f85c7a7c89de
3604df
BUG: 1256524
3604df
Signed-off-by: Ashish Pandey <aspandey@redhat.com>
3604df
Reviewed-on: https://code.engineering.redhat.com/gerrit/84804
3604df
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
3604df
---
3604df
 cli/src/cli-cmd-parser.c                           |  164 ++++++--
3604df
 cli/src/cli-cmd-volume.c                           |   61 +++
3604df
 cli/src/cli-rpc-ops.c                              |  224 ++++++++++-
3604df
 cli/src/cli-xml-output.c                           |    2 +-
3604df
 cli/src/cli.h                                      |    7 +-
3604df
 heal/src/glfs-heal.c                               |    2 +-
3604df
 rpc/rpc-lib/src/protocol-common.h                  |    1 +
3604df
 .../bug-1266876-allow-reset-brick-for-same-path.t  |   54 +++
3604df
 xlators/cluster/afr/src/afr-inode-write.c          |    4 +-
3604df
 xlators/mgmt/glusterd/src/Makefile.am              |    3 +-
3604df
 xlators/mgmt/glusterd/src/glusterd-brick-ops.c     |    2 +-
3604df
 xlators/mgmt/glusterd/src/glusterd-handler.c       |    1 +
3604df
 xlators/mgmt/glusterd/src/glusterd-hooks.c         |    1 +
3604df
 xlators/mgmt/glusterd/src/glusterd-messages.h      |   29 ++-
3604df
 xlators/mgmt/glusterd/src/glusterd-mgmt.c          |   33 ++
3604df
 xlators/mgmt/glusterd/src/glusterd-mgmt.h          |    6 +
3604df
 xlators/mgmt/glusterd/src/glusterd-op-sm.c         |    1 +
3604df
 xlators/mgmt/glusterd/src/glusterd-replace-brick.c |  350 ++++------------
3604df
 xlators/mgmt/glusterd/src/glusterd-reset-brick.c   |  430 ++++++++++++++++++++
3604df
 xlators/mgmt/glusterd/src/glusterd-rpc-ops.c       |    1 +
3604df
 xlators/mgmt/glusterd/src/glusterd-syncop.c        |    1 +
3604df
 xlators/mgmt/glusterd/src/glusterd-utils.c         |  327 +++++++++++++++-
3604df
 xlators/mgmt/glusterd/src/glusterd-utils.h         |   34 ++-
3604df
 xlators/mgmt/glusterd/src/glusterd-volume-ops.c    |    2 +-
3604df
 xlators/mgmt/glusterd/src/glusterd.c               |    1 +
3604df
 xlators/mgmt/glusterd/src/glusterd.h               |    6 +
3604df
 26 files changed, 1429 insertions(+), 318 deletions(-)
3604df
 create mode 100644 tests/bugs/replicate/bug-1266876-allow-reset-brick-for-same-path.t
3604df
 create mode 100644 xlators/mgmt/glusterd/src/glusterd-reset-brick.c
3604df
3604df
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c
3604df
index 836a464..04c8a22 100644
3604df
--- a/cli/src/cli-cmd-parser.c
3604df
+++ b/cli/src/cli-cmd-parser.c
3604df
@@ -2147,6 +2147,137 @@ out:
3604df
         return ret;
3604df
 }
3604df
 
3604df
+int32_t
3604df
+cli_cmd_brick_op_validate_bricks (const char **words, dict_t *dict,
3604df
+				  int src, int dst)
3604df
+{
3604df
+        int             ret = -1;
3604df
+        char            *delimiter  = NULL;
3604df
+
3604df
+        if (validate_brick_name ((char *)words[src])) {
3604df
+                cli_err ("wrong brick type: %s, use "
3604df
+                         "<HOSTNAME>:<export-dir-abs-path>", words[3]);
3604df
+                ret = -1;
3604df
+                goto out;
3604df
+        } else {
3604df
+                delimiter = strrchr ((char *)words[src], '/');
3604df
+                ret = gf_canonicalize_path (delimiter);
3604df
+                if (ret)
3604df
+                        goto out;
3604df
+        }
3604df
+
3604df
+        ret = dict_set_str (dict, "src-brick", (char *)words[src]);
3604df
+        if (ret)
3604df
+                goto out;
3604df
+
3604df
+        if (dst == -1) {
3604df
+                ret = 0;
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
+        if (validate_brick_name ((char *)words[dst])) {
3604df
+                cli_err ("wrong brick type: %s, use "
3604df
+                         "<HOSTNAME>:<export-dir-abs-path>", words[dst]);
3604df
+                ret = -1;
3604df
+                goto out;
3604df
+        } else {
3604df
+                delimiter = strrchr ((char *)words[dst], '/');
3604df
+                ret = gf_canonicalize_path (delimiter);
3604df
+                if (ret)
3604df
+                        goto out;
3604df
+        }
3604df
+
3604df
+        ret = dict_set_str (dict, "dst-brick", (char *)words[dst]);
3604df
+        if (ret)
3604df
+                goto out;
3604df
+        ret = 0;
3604df
+out:
3604df
+	return ret;
3604df
+}
3604df
+
3604df
+int32_t
3604df
+cli_cmd_volume_reset_brick_parse (const char **words, int wordcount,
3604df
+                                  dict_t **options)
3604df
+{
3604df
+        int                   ret        = -1;
3604df
+        char                 *volname    = NULL;
3604df
+        dict_t               *dict       = NULL;
3604df
+
3604df
+        if (wordcount < 5 || wordcount > 7)
3604df
+                goto out;
3604df
+
3604df
+        dict = dict_new ();
3604df
+
3604df
+        if (!dict)
3604df
+                goto out;
3604df
+
3604df
+        volname = (char *)words[2];
3604df
+
3604df
+        ret = dict_set_str (dict, "volname", volname);
3604df
+        if (ret)
3604df
+                goto out;
3604df
+
3604df
+        if (wordcount == 5) {
3604df
+                if (strcmp (words[4], "start")) {
3604df
+                        cli_err ("Invalid option '%s' for reset-brick. Please "
3604df
+                                 "enter valid reset-brick command", words[4]);
3604df
+                        ret = -1;
3604df
+                        goto out;
3604df
+                }
3604df
+
3604df
+                ret = cli_cmd_brick_op_validate_bricks (words, dict, 3, -1);
3604df
+                if (ret)
3604df
+                        goto out;
3604df
+
3604df
+                ret = dict_set_str (dict, "operation", "GF_RESET_OP_START");
3604df
+                if (ret)
3604df
+                        goto out;
3604df
+        } else if (wordcount == 6) {
3604df
+                if (strcmp (words[5], "commit")) {
3604df
+                        cli_err ("Invalid option '%s' for reset-brick. Please "
3604df
+                                 "enter valid reset-brick command", words[5]);
3604df
+                        ret = -1;
3604df
+                        goto out;
3604df
+                }
3604df
+
3604df
+                ret = cli_cmd_brick_op_validate_bricks (words, dict, 3, 4);
3604df
+                if (ret)
3604df
+                        goto out;
3604df
+
3604df
+                ret = dict_set_str (dict, "operation", "GF_RESET_OP_COMMIT");
3604df
+                if (ret)
3604df
+                        goto out;
3604df
+        } else if (wordcount == 7) {
3604df
+                if (strcmp (words[5], "commit") || strcmp (words[6], "force")) {
3604df
+                        cli_err ("Invalid option '%s %s' for reset-brick. Please "
3604df
+                                 "enter valid reset-brick command",
3604df
+                                  words[5], words[6]);
3604df
+                        ret = -1;
3604df
+                        goto out;
3604df
+                }
3604df
+
3604df
+                ret = cli_cmd_brick_op_validate_bricks (words, dict, 3, 4);
3604df
+                if (ret)
3604df
+                        goto out;
3604df
+
3604df
+                ret = dict_set_str (dict, "operation",
3604df
+                                    "GF_RESET_OP_COMMIT_FORCE");
3604df
+                if (ret)
3604df
+                        goto out;
3604df
+        }
3604df
+
3604df
+        *options = dict;
3604df
+
3604df
+out:
3604df
+        if (ret) {
3604df
+                gf_log ("cli", GF_LOG_ERROR,
3604df
+                        "Unable to parse reset-brick CLI");
3604df
+                if (dict)
3604df
+                        dict_unref (dict);
3604df
+        }
3604df
+
3604df
+        return ret;
3604df
+}
3604df
 
3604df
 int32_t
3604df
 cli_cmd_volume_replace_brick_parse (const char **words, int wordcount,
3604df
@@ -2154,7 +2285,6 @@ cli_cmd_volume_replace_brick_parse (const char **words, int wordcount,
3604df
 {
3604df
         int                   ret        = -1;
3604df
         char                 *volname    = NULL;
3604df
-        char                 *delimiter  = NULL;
3604df
         dict_t               *dict       = NULL;
3604df
 
3604df
         GF_ASSERT (words);
3604df
@@ -2180,35 +2310,7 @@ cli_cmd_volume_replace_brick_parse (const char **words, int wordcount,
3604df
         if (ret)
3604df
                 goto out;
3604df
 
3604df
-        if (validate_brick_name ((char *)words[3])) {
3604df
-                cli_err ("wrong brick type: %s, use "
3604df
-                         "<HOSTNAME>:<export-dir-abs-path>", words[3]);
3604df
-                ret = -1;
3604df
-                goto out;
3604df
-        } else {
3604df
-                delimiter = strrchr ((char *)words[3], ':');
3604df
-                ret = gf_canonicalize_path (delimiter + 1);
3604df
-                if (ret)
3604df
-                        goto out;
3604df
-        }
3604df
-
3604df
-        ret = dict_set_str (dict, "src-brick", (char *)words[3]);
3604df
-        if (ret)
3604df
-                goto out;
3604df
-
3604df
-        if (validate_brick_name ((char *)words[4])) {
3604df
-                cli_err ("wrong brick type: %s, use "
3604df
-                         "<HOSTNAME>:<export-dir-abs-path>", words[4]);
3604df
-                ret = -1;
3604df
-                goto out;
3604df
-        } else {
3604df
-                delimiter = strrchr ((char *)words[4], ':');
3604df
-                ret = gf_canonicalize_path (delimiter + 1);
3604df
-                if (ret)
3604df
-                        goto out;
3604df
-        }
3604df
-
3604df
-        ret = dict_set_str (dict, "dst-brick", (char *)words[4]);
3604df
+        ret = cli_cmd_brick_op_validate_bricks (words, dict, 3, 4);
3604df
         if (ret)
3604df
                 goto out;
3604df
 
3604df
@@ -2229,7 +2331,7 @@ cli_cmd_volume_replace_brick_parse (const char **words, int wordcount,
3604df
 
3604df
 out:
3604df
         if (ret) {
3604df
-                gf_log ("cli", GF_LOG_ERROR, "Unable to parse replace-brick CLI");
3604df
+                gf_log ("cli", GF_LOG_ERROR, "Unable to parse reset-brick CLI");
3604df
                 if (dict)
3604df
                         dict_destroy (dict);
3604df
         }
3604df
diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c
3604df
index 27cb9dd..4b2653b 100644
3604df
--- a/cli/src/cli-cmd-volume.c
3604df
+++ b/cli/src/cli-cmd-volume.c
3604df
@@ -1836,6 +1836,59 @@ out:
3604df
 }
3604df
 
3604df
 int
3604df
+cli_cmd_volume_reset_brick_cbk (struct cli_state *state,
3604df
+                                struct cli_cmd_word *word,
3604df
+                                const char **words,
3604df
+                                int wordcount)
3604df
+{
3604df
+        int                      ret          = -1;
3604df
+        rpc_clnt_procedure_t    *proc         = NULL;
3604df
+        call_frame_t            *frame        = NULL;
3604df
+        dict_t                  *options = NULL;
3604df
+        int                      sent = 0;
3604df
+        int                      parse_error = 0;
3604df
+        cli_local_t             *local = NULL;
3604df
+
3604df
+#ifdef GF_SOLARIS_HOST_OS
3604df
+        cli_out ("Command not supported on Solaris");
3604df
+        goto out;
3604df
+#endif
3604df
+        proc = &cli_rpc_prog->proctable[GLUSTER_CLI_RESET_BRICK];
3604df
+
3604df
+        frame = create_frame (THIS, THIS->ctx->pool);
3604df
+        if (!frame)
3604df
+                goto out;
3604df
+
3604df
+        ret = cli_cmd_volume_reset_brick_parse (words, wordcount, &options);
3604df
+
3604df
+        if (ret) {
3604df
+                cli_usage_out (word->pattern);
3604df
+                parse_error = 1;
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
+        CLI_LOCAL_INIT (local, words, frame, options);
3604df
+
3604df
+        if (proc->fn) {
3604df
+                ret = proc->fn (frame, THIS, options);
3604df
+        }
3604df
+
3604df
+out:
3604df
+        if (ret) {
3604df
+                gf_event (EVENT_BRICK_RESET, "Volume reset-brick failed.");
3604df
+                cli_cmd_sent_status_get (&sent);
3604df
+                if ((sent == 0) && (parse_error == 0))
3604df
+                        cli_out ("Volume reset-brick failed");
3604df
+        } else {
3604df
+                gf_event (EVENT_BRICK_RESET, "Volume reset-brick succeeded.");
3604df
+        }
3604df
+
3604df
+        CLI_STACK_DESTROY (frame);
3604df
+
3604df
+        return ret;
3604df
+}
3604df
+
3604df
+int
3604df
 cli_cmd_volume_replace_brick_cbk (struct cli_state *state,
3604df
                                   struct cli_cmd_word *word,
3604df
                                   const char **words,
3604df
@@ -1875,9 +1928,12 @@ cli_cmd_volume_replace_brick_cbk (struct cli_state *state,
3604df
 
3604df
 out:
3604df
         if (ret) {
3604df
+                gf_event (EVENT_BRICK_REPLACE, "Volume replace-brick failed.");
3604df
                 cli_cmd_sent_status_get (&sent);
3604df
                 if ((sent == 0) && (parse_error == 0))
3604df
                         cli_out ("Volume replace-brick failed");
3604df
+        } else {
3604df
+                gf_event (EVENT_BRICK_RESET, "Volume replace-brick succeeded.");
3604df
         }
3604df
 
3604df
         CLI_STACK_DESTROY (frame);
3604df
@@ -3023,6 +3079,11 @@ struct cli_cmd volume_cmds[] = {
3604df
          "Bitrot translator specific operation. For more information about "
3604df
          "bitrot command type  'man gluster'"
3604df
         },
3604df
+        { "volume reset-brick <VOLNAME> <SOURCE-BRICK> {{start} |"
3604df
+          " {<NEW-BRICK> commit}}",
3604df
+          cli_cmd_volume_reset_brick_cbk,
3604df
+          "reset-brick operations"},
3604df
+
3604df
         { NULL, NULL, NULL }
3604df
 };
3604df
 
3604df
diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c
3604df
index 77a2e24..dcf2a12 100644
3604df
--- a/cli/src/cli-rpc-ops.c
3604df
+++ b/cli/src/cli-rpc-ops.c
3604df
@@ -2967,6 +2967,149 @@ out:
3604df
 }
3604df
 
3604df
 int
3604df
+gf_cli_reset_brick_cbk (struct rpc_req *req, struct iovec *iov,
3604df
+                        int count, void *myframe)
3604df
+{
3604df
+        gf_cli_rsp                       rsp              = {0,};
3604df
+        int                              ret              = -1;
3604df
+        cli_local_t                     *local            = NULL;
3604df
+        call_frame_t                    *frame            = NULL;
3604df
+        char                            *src_brick        = NULL;
3604df
+        char                            *dst_brick        = NULL;
3604df
+        char                            *status_reply     = NULL;
3604df
+        char                            *rb_operation_str = NULL;
3604df
+        dict_t                          *rsp_dict         = NULL;
3604df
+        char                             msg[1024]        = {0,};
3604df
+        char                            *task_id_str      = NULL;
3604df
+        char                            *reset_op         = NULL;
3604df
+
3604df
+        GF_ASSERT (myframe);
3604df
+
3604df
+        if (-1 == req->rpc_status) {
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
+        frame = myframe;
3604df
+
3604df
+        GF_ASSERT (frame->local);
3604df
+
3604df
+        local = frame->local;
3604df
+
3604df
+        ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
3604df
+        if (ret < 0) {
3604df
+                gf_log (frame->this->name, GF_LOG_ERROR,
3604df
+                        "Failed to decode xdr response");
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
+        ret = dict_get_str (local->dict, "operation", &reset_op);
3604df
+        if (ret) {
3604df
+                gf_log (frame->this->name, GF_LOG_ERROR,
3604df
+                        "dict_get on operation failed");
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
+        if (rsp.dict.dict_len) {
3604df
+                /* Unserialize the dictionary */
3604df
+                rsp_dict  = dict_new ();
3604df
+
3604df
+                ret = dict_unserialize (rsp.dict.dict_val,
3604df
+                                rsp.dict.dict_len,
3604df
+                                &rsp_dict);
3604df
+                if (ret < 0) {
3604df
+                        gf_log (frame->this->name, GF_LOG_ERROR, "failed to "
3604df
+                                "unserialize rsp buffer to dictionary");
3604df
+                        goto out;
3604df
+                }
3604df
+        }
3604df
+
3604df
+        if (strcmp (reset_op, "GF_RESET_OP_START") &&
3604df
+            strcmp (reset_op, "GF_RESET_OP_COMMIT") &&
3604df
+            strcmp (reset_op, "GF_RESET_OP_COMMIT_FORCE")) {
3604df
+                rb_operation_str = gf_strdup ("Unknown operation");
3604df
+                ret = -1;
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
+        if (rsp.op_ret && (strcmp (rsp.op_errstr, ""))) {
3604df
+                rb_operation_str = gf_strdup (rsp.op_errstr);
3604df
+        } else {
3604df
+                if (!strcmp (reset_op, "GF_RESET_OP_START")) {
3604df
+                        if (rsp.op_ret)
3604df
+                                rb_operation_str = gf_strdup ("reset-brick "
3604df
+                                                              "start "
3604df
+                                                              "operation "
3604df
+                                                              "failed");
3604df
+                        else
3604df
+                                rb_operation_str = gf_strdup ("reset-brick "
3604df
+                                                              "start "
3604df
+                                                              "operation "
3604df
+                                                              "successful");
3604df
+                } else if (!strcmp (reset_op, "GF_RESET_OP_COMMIT")) {
3604df
+
3604df
+                        if (rsp.op_ret)
3604df
+                                rb_operation_str = gf_strdup ("reset-brick "
3604df
+                                                              "commit "
3604df
+                                                              "operation "
3604df
+                                                              "failed");
3604df
+                        else
3604df
+                                rb_operation_str = gf_strdup ("reset-brick "
3604df
+                                                              "commit "
3604df
+                                                              "operation "
3604df
+                                                              "successful");
3604df
+                } else if (!strcmp (reset_op, "GF_RESET_OP_COMMIT_FORCE")) {
3604df
+
3604df
+                        if (rsp.op_ret)
3604df
+                                rb_operation_str = gf_strdup ("reset-brick "
3604df
+                                                              "commit "
3604df
+                                                              "force operation "
3604df
+                                                              "failed");
3604df
+                        else
3604df
+                                rb_operation_str = gf_strdup ("reset-brick "
3604df
+                                                              "commit "
3604df
+                                                              "force operation "
3604df
+                                                              "successful");
3604df
+                }
3604df
+        }
3604df
+
3604df
+        gf_log ("cli", GF_LOG_INFO, "Received resp to reset brick");
3604df
+        snprintf (msg, sizeof (msg), "%s",
3604df
+                  rb_operation_str ? rb_operation_str : "Unknown operation");
3604df
+
3604df
+        if (global_state->mode & GLUSTER_MODE_XML) {
3604df
+                ret = cli_xml_output_vol_replace_brick (rsp_dict,
3604df
+                                                        rsp.op_ret,
3604df
+                                                        rsp.op_errno, msg);
3604df
+                if (ret)
3604df
+                        gf_log ("cli", GF_LOG_ERROR,
3604df
+                                "Error outputting to xml");
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
+        if (rsp.op_ret)
3604df
+                cli_err ("volume reset-brick: failed: %s", msg);
3604df
+        else
3604df
+                cli_out ("volume reset-brick: success: %s", msg);
3604df
+        ret = rsp.op_ret;
3604df
+
3604df
+out:
3604df
+        if (frame)
3604df
+                frame->local = NULL;
3604df
+
3604df
+        if (local)
3604df
+                cli_local_wipe (local);
3604df
+
3604df
+        if (rb_operation_str)
3604df
+                GF_FREE (rb_operation_str);
3604df
+
3604df
+        cli_cmd_broadcast_response (ret);
3604df
+        free (rsp.dict.dict_val);
3604df
+        if (rsp_dict)
3604df
+                dict_unref (rsp_dict);
3604df
+
3604df
+        return ret;
3604df
+}
3604df
+int
3604df
 gf_cli_replace_brick_cbk (struct rpc_req *req, struct iovec *iov,
3604df
                              int count, void *myframe)
3604df
 {
3604df
@@ -2980,8 +3123,7 @@ gf_cli_replace_brick_cbk (struct rpc_req *req, struct iovec *iov,
3604df
         char                            *rb_operation_str = NULL;
3604df
         dict_t                          *rsp_dict         = NULL;
3604df
         char                             msg[1024]        = {0,};
3604df
-        char                            *task_id_str      = NULL;
3604df
-        char                            *replace_op       = 0;
3604df
+        char                            *replace_op       = NULL;
3604df
 
3604df
         GF_ASSERT (myframe);
3604df
 
3604df
@@ -3023,7 +3165,7 @@ gf_cli_replace_brick_cbk (struct rpc_req *req, struct iovec *iov,
3604df
                 }
3604df
         }
3604df
 
3604df
-        if (!strcmp(replace_op, "GF_REPLACE_OP_COMMIT_FORCE")) {
3604df
+        if (!strcmp (replace_op, "GF_REPLACE_OP_COMMIT_FORCE")) {
3604df
 
3604df
                 if (rsp.op_ret || ret)
3604df
                         rb_operation_str = gf_strdup ("replace-brick commit "
3604df
@@ -3045,7 +3187,7 @@ gf_cli_replace_brick_cbk (struct rpc_req *req, struct iovec *iov,
3604df
                   rb_operation_str ? rb_operation_str : "Unknown operation");
3604df
 
3604df
         if (global_state->mode & GLUSTER_MODE_XML) {
3604df
-                ret = cli_xml_output_vol_replace_brick (replace_op, rsp_dict,
3604df
+                ret = cli_xml_output_vol_replace_brick (rsp_dict,
3604df
                                                         rsp.op_ret,
3604df
                                                         rsp.op_errno, msg);
3604df
                 if (ret)
3604df
@@ -3064,10 +3206,8 @@ out:
3604df
         if (frame)
3604df
                 frame->local = NULL;
3604df
 
3604df
-        if (local) {
3604df
-                dict_unref (local->dict);
3604df
+        if (local)
3604df
                 cli_local_wipe (local);
3604df
-        }
3604df
 
3604df
         if (rb_operation_str)
3604df
                 GF_FREE (rb_operation_str);
3604df
@@ -4903,8 +5043,73 @@ out:
3604df
 }
3604df
 
3604df
 int32_t
3604df
+gf_cli_reset_brick (call_frame_t *frame, xlator_t *this, void *data)
3604df
+{
3604df
+        gf_cli_req                  req        =  { {0,} };
3604df
+        int                         ret        = 0;
3604df
+        dict_t                     *dict       = NULL;
3604df
+        char                       *dst_brick  = NULL;
3604df
+        char                       *src_brick  = NULL;
3604df
+        char                       *volname    = NULL;
3604df
+        char                       *op         = NULL;
3604df
+
3604df
+        if (!frame || !this ||  !data) {
3604df
+                ret = -1;
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
+        dict = data;
3604df
+
3604df
+        ret = dict_get_str (dict, "operation", &op);
3604df
+        if (ret) {
3604df
+                gf_log (this->name, GF_LOG_DEBUG,
3604df
+                        "dict_get on operation failed");
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
+        ret = dict_get_str (dict, "volname", &volname);
3604df
+        if (ret) {
3604df
+                gf_log (this->name, GF_LOG_DEBUG,
3604df
+                        "dict_get on volname failed");
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
+        ret = dict_get_str (dict, "src-brick", &src_brick);
3604df
+        if (ret) {
3604df
+                gf_log (this->name, GF_LOG_DEBUG,
3604df
+                        "dict_get on src-brick failed");
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
+        if (!strcmp (op, "GF_RESET_OP_COMMIT") ||
3604df
+            !strcmp (op, "GF_RESET_OP_COMMIT_FORCE")) {
3604df
+                ret = dict_get_str (dict, "dst-brick", &dst_brick);
3604df
+                if (ret) {
3604df
+                        gf_log (this->name, GF_LOG_DEBUG,
3604df
+                                "dict_get on dst-brick failed");
3604df
+                        goto out;
3604df
+                }
3604df
+        }
3604df
+
3604df
+        gf_log (this->name, GF_LOG_DEBUG,
3604df
+                "Received command reset-brick %s on %s.", op, src_brick);
3604df
+
3604df
+        ret = cli_to_glusterd (&req, frame, gf_cli_reset_brick_cbk,
3604df
+                               (xdrproc_t) xdr_gf_cli_req, dict,
3604df
+                               GLUSTER_CLI_RESET_BRICK, this, cli_rpc_prog,
3604df
+                               NULL);
3604df
+
3604df
+out:
3604df
+        gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
3604df
+
3604df
+        GF_FREE (req.dict.dict_val);
3604df
+
3604df
+        return ret;
3604df
+}
3604df
+
3604df
+int32_t
3604df
 gf_cli_replace_brick (call_frame_t *frame, xlator_t *this,
3604df
-                         void *data)
3604df
+                      void *data)
3604df
 {
3604df
         gf_cli_req                  req        =  {{0,}};
3604df
         int                         ret        = 0;
3604df
@@ -11374,7 +11579,8 @@ struct rpc_clnt_procedure gluster_cli_actors[GLUSTER_CLI_MAXVALUE] = {
3604df
         [GLUSTER_CLI_ATTACH_TIER]      = {"ATTACH_TIER", gf_cli_attach_tier},
3604df
         [GLUSTER_CLI_DETACH_TIER]      = {"DETACH_TIER", gf_cli_detach_tier},
3604df
         [GLUSTER_CLI_TIER]             = {"TIER", gf_cli_tier},
3604df
-        [GLUSTER_CLI_GET_STATE]        = {"GET_STATE", gf_cli_get_state}
3604df
+        [GLUSTER_CLI_GET_STATE]        = {"GET_STATE", gf_cli_get_state},
3604df
+        [GLUSTER_CLI_RESET_BRICK]      = {"RESET_BRICK", gf_cli_reset_brick}
3604df
 };
3604df
 
3604df
 struct rpc_clnt_program cli_prog = {
3604df
diff --git a/cli/src/cli-xml-output.c b/cli/src/cli-xml-output.c
3604df
index 34f85f2..6d1e617 100644
3604df
--- a/cli/src/cli-xml-output.c
3604df
+++ b/cli/src/cli-xml-output.c
3604df
@@ -3865,7 +3865,7 @@ out:
3604df
 }
3604df
 
3604df
 int
3604df
-cli_xml_output_vol_replace_brick (char *op, dict_t *dict,
3604df
+cli_xml_output_vol_replace_brick (dict_t *dict,
3604df
                                   int op_ret, int op_errno, char *op_errstr)
3604df
 {
3604df
 #if (HAVE_LIB_XML)
3604df
diff --git a/cli/src/cli.h b/cli/src/cli.h
3604df
index f9c642e..ba0d845 100644
3604df
--- a/cli/src/cli.h
3604df
+++ b/cli/src/cli.h
3604df
@@ -284,6 +284,10 @@ cli_cmd_volume_replace_brick_parse (const char **words, int wordcount,
3604df
                                    dict_t **options);
3604df
 
3604df
 int32_t
3604df
+cli_cmd_volume_reset_brick_parse (const char **words, int wordcount,
3604df
+                                  dict_t **options);
3604df
+
3604df
+int32_t
3604df
 cli_cmd_log_rotate_parse (const char **words, int wordcount, dict_t **options);
3604df
 int32_t
3604df
 cli_cmd_log_locate_parse (const char **words, int wordcount, dict_t **options);
3604df
@@ -424,7 +428,7 @@ cli_xml_output_vol_remove_brick_detach_tier (gf_boolean_t status_op,
3604df
                                              const char *op);
3604df
 
3604df
 int
3604df
-cli_xml_output_vol_replace_brick (char *op, dict_t *dict, int op_ret,
3604df
+cli_xml_output_vol_replace_brick (dict_t *dict, int op_ret,
3604df
                                   int op_errno, char *op_errstr);
3604df
 
3604df
 int
3604df
@@ -489,5 +493,4 @@ print_quota_list_empty (char *path, int type);
3604df
 
3604df
 int
3604df
 gf_gsync_status_t_comparator (const void *p, const void *q);
3604df
-
3604df
 #endif /* __CLI_H__ */
3604df
diff --git a/heal/src/glfs-heal.c b/heal/src/glfs-heal.c
3604df
index 0a880cb..e885dd9 100644
3604df
--- a/heal/src/glfs-heal.c
3604df
+++ b/heal/src/glfs-heal.c
3604df
@@ -517,7 +517,7 @@ out:
3604df
 
3604df
         (*num_entries)++;
3604df
         glfsh_output->print_heal_status (path ? path :
3604df
-                                                uuid_utoa_r (gfid, gfid_str),
3604df
+                                         uuid_utoa_r (gfid, gfid_str),
3604df
                                          gfid,
3604df
                                          status ? status : "");
3604df
 
3604df
diff --git a/rpc/rpc-lib/src/protocol-common.h b/rpc/rpc-lib/src/protocol-common.h
3604df
index c1a488e..c7c3327 100644
3604df
--- a/rpc/rpc-lib/src/protocol-common.h
3604df
+++ b/rpc/rpc-lib/src/protocol-common.h
3604df
@@ -193,6 +193,7 @@ enum gluster_cli_procnum {
3604df
         GLUSTER_CLI_DETACH_TIER,
3604df
         GLUSTER_CLI_TIER,
3604df
         GLUSTER_CLI_GET_STATE,
3604df
+        GLUSTER_CLI_RESET_BRICK,
3604df
         GLUSTER_CLI_MAXVALUE,
3604df
 };
3604df
 
3604df
diff --git a/tests/bugs/replicate/bug-1266876-allow-reset-brick-for-same-path.t b/tests/bugs/replicate/bug-1266876-allow-reset-brick-for-same-path.t
3604df
new file mode 100644
3604df
index 0000000..884b789
3604df
--- /dev/null
3604df
+++ b/tests/bugs/replicate/bug-1266876-allow-reset-brick-for-same-path.t
3604df
@@ -0,0 +1,54 @@
3604df
+#!/bin/bash
3604df
+. $(dirname $0)/../../include.rc
3604df
+. $(dirname $0)/../../volume.rc
3604df
+cleanup;
3604df
+
3604df
+TEST glusterd
3604df
+TEST pidof glusterd
3604df
+TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}{0,1}
3604df
+TEST $CLI volume start $V0
3604df
+
3604df
+TEST glusterfs --volfile-id=$V0 --volfile-server=$H0 $M0;
3604df
+# Create files
3604df
+for i in {1..5}
3604df
+do
3604df
+        echo $i > $M0/file$i.txt
3604df
+done
3604df
+
3604df
+# Negative case with brick not killed && volume-id xattrs present
3604df
+TEST ! $CLI volume reset-brick $V0 $H0:$B0/${V0}1 $H0:$B0/${V0}1 commit force
3604df
+TEST kill_brick $V0 $H0 $B0/${V0}1
3604df
+
3604df
+# Negative case with brick killed but volume-id xattr present
3604df
+TEST ! $CLI volume reset-brick $V0 $H0:$B0/${V0}1 $H0:$B0/${V0}1 commit
3604df
+
3604df
+TEST $CLI volume reset-brick $V0 $H0:$B0/${V0}1 start
3604df
+# Simulated reset disk
3604df
+for i in {1..5}
3604df
+do
3604df
+        rm -rf $B0/${V0}{1}/file$i.txt
3604df
+done
3604df
+for i in {6..10}
3604df
+do
3604df
+        echo $i > $M0/file$i.txt
3604df
+done
3604df
+
3604df
+# Now reset the brick
3604df
+TEST $CLI volume reset-brick $V0 $H0:$B0/${V0}1 $H0:$B0/${V0}1 commit force
3604df
+
3604df
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 0
3604df
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "1" afr_child_up_status $V0 1
3604df
+
3604df
+EXPECT_WITHIN $PROCESS_UP_TIMEOUT "Y" glustershd_up_status
3604df
+EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 0
3604df
+EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status_in_shd $V0 1
3604df
+
3604df
+TEST $CLI volume heal $V0
3604df
+
3604df
+EXPECT_WITHIN $HEAL_TIMEOUT "0" get_pending_heal_count $V0
3604df
+
3604df
+# Check if entry-heal has happened
3604df
+TEST diff <(ls $B0/${V0}0 | sort) <(ls $B0/${V0}1 | sort)
3604df
+EXPECT "10" echo $(ls $B0/${V0}1 | wc -l)
3604df
+
3604df
+cleanup;
3604df
diff --git a/xlators/cluster/afr/src/afr-inode-write.c b/xlators/cluster/afr/src/afr-inode-write.c
3604df
index ddc257d..24ab52f 100644
3604df
--- a/xlators/cluster/afr/src/afr-inode-write.c
3604df
+++ b/xlators/cluster/afr/src/afr-inode-write.c
3604df
@@ -1235,8 +1235,8 @@ _afr_handle_empty_brick (void *opaque)
3604df
 
3604df
         loc_copy (&local->loc, &data->loc);
3604df
 
3604df
-        gf_msg_debug (this->name, 0, "New brick is : %s",
3604df
-                      priv->children[empty_index]->name);
3604df
+        gf_msg (this->name, GF_LOG_INFO, 0, 0, "New brick is : %s",
3604df
+                priv->children[empty_index]->name);
3604df
 
3604df
         ret = _afr_handle_empty_brick_type (this, frame, &local->loc, empty_index,
3604df
                                           AFR_METADATA_TRANSACTION, op_type);
3604df
diff --git a/xlators/mgmt/glusterd/src/Makefile.am b/xlators/mgmt/glusterd/src/Makefile.am
3604df
index 23840cd..faee862 100644
3604df
--- a/xlators/mgmt/glusterd/src/Makefile.am
3604df
+++ b/xlators/mgmt/glusterd/src/Makefile.am
3604df
@@ -16,7 +16,8 @@ glusterd_la_SOURCES = glusterd.c glusterd-handler.c glusterd-sm.c \
3604df
 	glusterd-proc-mgmt.c glusterd-svc-mgmt.c glusterd-shd-svc.c \
3604df
 	glusterd-nfs-svc.c glusterd-quotad-svc.c glusterd-svc-helper.c \
3604df
 	glusterd-conn-helper.c glusterd-snapd-svc.c glusterd-snapd-svc-helper.c \
3604df
-	glusterd-bitd-svc.c glusterd-scrub-svc.c glusterd-server-quorum.c
3604df
+	glusterd-bitd-svc.c glusterd-scrub-svc.c glusterd-server-quorum.c \
3604df
+	glusterd-reset-brick.c
3604df
 
3604df
 
3604df
 glusterd_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \
3604df
diff --git a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c
3604df
index 7522003..92e6386 100644
3604df
--- a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c
3604df
+++ b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c
3604df
@@ -1830,7 +1830,7 @@ glusterd_op_stage_add_brick (dict_t *dict, char **op_errstr, dict_t *rsp_dict)
3604df
                 brick_alloc = _gf_true;
3604df
 
3604df
                 ret = glusterd_new_brick_validate (brick, brickinfo, msg,
3604df
-                                                   sizeof (msg));
3604df
+                                                   sizeof (msg), NULL);
3604df
                 if (ret) {
3604df
                         *op_errstr = gf_strdup (msg);
3604df
                         ret = -1;
3604df
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
3604df
index b024fdb..d81204e 100644
3604df
--- a/xlators/mgmt/glusterd/src/glusterd-handler.c
3604df
+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c
3604df
@@ -5926,6 +5926,7 @@ rpcsvc_actor_t gd_svc_cli_actors[GLUSTER_CLI_MAXVALUE] = {
3604df
         [GLUSTER_CLI_GET_VOL_OPT]        = {"GET_VOL_OPT",        GLUSTER_CLI_GET_VOL_OPT,      glusterd_handle_get_vol_opt,           NULL, 0, DRC_NA},
3604df
         [GLUSTER_CLI_BITROT]             = {"BITROT",             GLUSTER_CLI_BITROT,           glusterd_handle_bitrot,                NULL, 0, DRC_NA},
3604df
         [GLUSTER_CLI_GET_STATE]          = {"GET_STATE",          GLUSTER_CLI_GET_STATE,        glusterd_handle_get_state,             NULL, 0, DRC_NA},
3604df
+        [GLUSTER_CLI_RESET_BRICK]        = {"RESET_BRICK",        GLUSTER_CLI_RESET_BRICK,      glusterd_handle_reset_brick,           NULL, 0, DRC_NA},
3604df
 };
3604df
 
3604df
 struct rpcsvc_program gd_svc_cli_prog = {
3604df
diff --git a/xlators/mgmt/glusterd/src/glusterd-hooks.c b/xlators/mgmt/glusterd/src/glusterd-hooks.c
3604df
index 45a5912..17beb79 100644
3604df
--- a/xlators/mgmt/glusterd/src/glusterd-hooks.c
3604df
+++ b/xlators/mgmt/glusterd/src/glusterd-hooks.c
3604df
@@ -57,6 +57,7 @@ char glusterd_hook_dirnames[GD_OP_MAX][256] =
3604df
         [GD_OP_LIST_VOLUME]             = EMPTY,
3604df
         [GD_OP_CLEARLOCKS_VOLUME]       = EMPTY,
3604df
         [GD_OP_DEFRAG_BRICK_VOLUME]     = EMPTY,
3604df
+        [GD_OP_RESET_BRICK]             = EMPTY,
3604df
 };
3604df
 #undef EMPTY
3604df
 
3604df
diff --git a/xlators/mgmt/glusterd/src/glusterd-messages.h b/xlators/mgmt/glusterd/src/glusterd-messages.h
3604df
index af492e0..e39fb92 100644
3604df
--- a/xlators/mgmt/glusterd/src/glusterd-messages.h
3604df
+++ b/xlators/mgmt/glusterd/src/glusterd-messages.h
3604df
@@ -41,7 +41,7 @@
3604df
 
3604df
 #define GLUSTERD_COMP_BASE      GLFS_MSGID_GLUSTERD
3604df
 
3604df
-#define GLFS_NUM_MESSAGES       585
3604df
+#define GLFS_NUM_MESSAGES       587
3604df
 
3604df
 #define GLFS_MSGID_END          (GLUSTERD_COMP_BASE + GLFS_NUM_MESSAGES + 1)
3604df
 /* Messaged with message IDs */
3604df
@@ -2837,7 +2837,7 @@
3604df
  * @recommendedaction
3604df
  *
3604df
  */
3604df
-#define GD_MSG_NFS_VOL_FILE_GEN_FAIL             (GLUSTERD_COMP_BASE + 349)
3604df
+#define GD_MSG_GLUSTER_SERVICE_START_FAIL             (GLUSTERD_COMP_BASE + 349)
3604df
 
3604df
 /*!
3604df
  * @messageid
3604df
@@ -2965,7 +2965,7 @@
3604df
  * @recommendedaction
3604df
  *
3604df
  */
3604df
-#define GD_MSG_NFS_SERVER_STOP_FAIL                  (GLUSTERD_COMP_BASE + 365)
3604df
+#define GD_MSG_GLUSTER_SERVICES_STOP_FAIL            (GLUSTERD_COMP_BASE + 365)
3604df
 
3604df
 /*!
3604df
  * @messageid
3604df
@@ -4728,8 +4728,31 @@
3604df
  * @recommendation
3604df
  *
3604df
  */
3604df
+#define GD_MSG_BRICK_CLEANUP_SUCCESS               (GLUSTERD_COMP_BASE + 584)
3604df
+
3604df
+/*!
3604df
+ * @messageid
3604df
+ * @diagnosis
3604df
+ * @recommendation
3604df
+ *
3604df
+ */
3604df
 #define GD_MSG_STATE_STR_GET_FAILED               (GLUSTERD_COMP_BASE + 585)
3604df
 
3604df
+/*!
3604df
+ * @messageid
3604df
+ * @diagnosis
3604df
+ * @recommendedaction
3604df
+ *
3604df
+ */
3604df
+#define GD_MSG_RESET_BRICK_COMMIT_FORCE_REQ_RCVD   (GLUSTERD_COMP_BASE + 586)
3604df
+
3604df
+/*!
3604df
+ * @messageid
3604df
+ * @diagnosis
3604df
+ * @recommendedaction
3604df
+ *
3604df
+ */
3604df
+#define GD_MSG_RESET_BRICK_CMD_FAIL                (GLUSTERD_COMP_BASE + 587)
3604df
 /*------------*/
3604df
 #define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages"
3604df
 #endif /* !_GLUSTERD_MESSAGES_H_ */
3604df
diff --git a/xlators/mgmt/glusterd/src/glusterd-mgmt.c b/xlators/mgmt/glusterd/src/glusterd-mgmt.c
3604df
index 092283a..bac0c6a 100644
3604df
--- a/xlators/mgmt/glusterd/src/glusterd-mgmt.c
3604df
+++ b/xlators/mgmt/glusterd/src/glusterd-mgmt.c
3604df
@@ -200,6 +200,17 @@ gd_mgmt_v3_pre_validate_fn (glusterd_op_t op, dict_t *dict,
3604df
                 }
3604df
                 break;
3604df
 
3604df
+        case GD_OP_RESET_BRICK:
3604df
+               ret = glusterd_reset_brick_prevalidate (dict, op_errstr,
3604df
+                                                       rsp_dict);
3604df
+                if (ret) {
3604df
+                        gf_msg (this->name, GF_LOG_WARNING, 0,
3604df
+                                GD_MSG_PRE_VALIDATION_FAIL,
3604df
+                                "Reset brick prevalidation failed.");
3604df
+                        goto out;
3604df
+                }
3604df
+                break;
3604df
+
3604df
         default:
3604df
                 break;
3604df
         }
3604df
@@ -309,6 +320,17 @@ gd_mgmt_v3_commit_fn (glusterd_op_t op, dict_t *dict,
3604df
                         break;
3604df
 
3604df
                 }
3604df
+                case GD_OP_RESET_BRICK:
3604df
+                {
3604df
+                        ret = glusterd_op_reset_brick (dict, rsp_dict);
3604df
+                        if (ret) {
3604df
+                                gf_msg (this->name, GF_LOG_ERROR, 0,
3604df
+                                        GD_MSG_COMMIT_OP_FAIL,
3604df
+                                        "Reset-brick commit failed.");
3604df
+                                goto out;
3604df
+                        }
3604df
+                        break;
3604df
+                }
3604df
 
3604df
                default:
3604df
                        break;
3604df
@@ -682,6 +704,16 @@ glusterd_pre_validate_aggr_rsp_dict (glusterd_op_t op,
3604df
                         goto out;
3604df
                 }
3604df
                 break;
3604df
+        case GD_OP_RESET_BRICK:
3604df
+                ret = glusterd_rb_use_rsp_dict (aggr, rsp);
3604df
+                if (ret) {
3604df
+                        gf_msg (this->name, GF_LOG_ERROR, 0,
3604df
+                                GD_MSG_PRE_VALIDATION_FAIL,
3604df
+                                "Failed to aggregate prevalidate "
3604df
+                                "response dictionaries.");
3604df
+                        goto out;
3604df
+                }
3604df
+                break;
3604df
         default:
3604df
                 ret = -1;
3604df
                 gf_msg (this->name, GF_LOG_ERROR, EINVAL,
3604df
@@ -985,6 +1017,7 @@ glusterd_mgmt_v3_build_payload (dict_t **req, char **op_errstr, dict_t *dict,
3604df
                 case GD_OP_START_VOLUME:
3604df
                 case GD_OP_ADD_BRICK:
3604df
                 case GD_OP_REPLACE_BRICK:
3604df
+                case GD_OP_RESET_BRICK:
3604df
                 {
3604df
                         ret = dict_get_str (dict, "volname", &volname);
3604df
                         if (ret) {
3604df
diff --git a/xlators/mgmt/glusterd/src/glusterd-mgmt.h b/xlators/mgmt/glusterd/src/glusterd-mgmt.h
3604df
index bf87ec7..2215f17 100644
3604df
--- a/xlators/mgmt/glusterd/src/glusterd-mgmt.h
3604df
+++ b/xlators/mgmt/glusterd/src/glusterd-mgmt.h
3604df
@@ -74,4 +74,10 @@ glusterd_mgmt_v3_release_peer_locks (glusterd_op_t op, dict_t *dict,
3604df
 
3604df
 int32_t
3604df
 glusterd_multiple_mgmt_v3_unlock (dict_t *dict, uuid_t uuid);
3604df
+
3604df
+int
3604df
+glusterd_reset_brick_prevalidate (dict_t *dict, char **op_errstr,
3604df
+                                  dict_t *rsp_dict);
3604df
+int
3604df
+glusterd_op_reset_brick (dict_t *dict, dict_t *rsp_dict);
3604df
 #endif /* _GLUSTERD_MGMT_H_ */
3604df
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
3604df
index 313e3de..0521a9c 100644
3604df
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c
3604df
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
3604df
@@ -4133,6 +4133,7 @@ glusterd_op_build_payload (dict_t **req, char **op_errstr, dict_t *op_ctx)
3604df
                 case GD_OP_BITROT:
3604df
                 case GD_OP_SCRUB_STATUS:
3604df
                 case GD_OP_SCRUB_ONDEMAND:
3604df
+                case GD_OP_RESET_BRICK:
3604df
                         {
3604df
                                 do_common = _gf_true;
3604df
                         }
3604df
diff --git a/xlators/mgmt/glusterd/src/glusterd-replace-brick.c b/xlators/mgmt/glusterd/src/glusterd-replace-brick.c
3604df
index 7bd1de3..7338843 100644
3604df
--- a/xlators/mgmt/glusterd/src/glusterd-replace-brick.c
3604df
+++ b/xlators/mgmt/glusterd/src/glusterd-replace-brick.c
3604df
@@ -27,13 +27,6 @@
3604df
 
3604df
 #include <signal.h>
3604df
 
3604df
-#define GLUSTERD_GET_RB_MNTPT(path, len, volinfo)                           \
3604df
-        snprintf (path, len,                                                \
3604df
-                  DEFAULT_VAR_RUN_DIRECTORY"/%s-"RB_CLIENT_MOUNTPOINT,      \
3604df
-                  volinfo->volname);
3604df
-
3604df
-extern uuid_t global_txn_id;
3604df
-
3604df
 int
3604df
 glusterd_mgmt_v3_initiate_replace_brick_cmd_phases (rpcsvc_request_t *req,
3604df
                                                     glusterd_op_t op,
3604df
@@ -46,15 +39,17 @@ __glusterd_handle_replace_brick (rpcsvc_request_t *req)
3604df
         dict_t                          *dict = NULL;
3604df
         char                            *src_brick = NULL;
3604df
         char                            *dst_brick = NULL;
3604df
-        int32_t                         op = 0;
3604df
-        glusterd_op_t                   cli_op = GD_OP_REPLACE_BRICK;
3604df
+        char                            *cli_op = NULL;
3604df
+        glusterd_op_t                   op = -1;
3604df
         char                            *volname = NULL;
3604df
         char                            msg[2048] = {0,};
3604df
         xlator_t                        *this = NULL;
3604df
+        glusterd_conf_t                 *conf = NULL;
3604df
 
3604df
         GF_ASSERT (req);
3604df
         this = THIS;
3604df
         GF_ASSERT (this);
3604df
+        conf = this->private;
3604df
 
3604df
         ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req);
3604df
         if (ret < 0) {
3604df
@@ -96,7 +91,7 @@ __glusterd_handle_replace_brick (rpcsvc_request_t *req)
3604df
                 goto out;
3604df
         }
3604df
 
3604df
-        ret = dict_get_int32 (dict, "operation", &op);
3604df
+        ret = dict_get_str (dict, "operation", &cli_op);
3604df
         if (ret) {
3604df
                 gf_msg_debug (this->name, 0,
3604df
                         "dict_get on operation failed");
3604df
@@ -104,6 +99,19 @@ __glusterd_handle_replace_brick (rpcsvc_request_t *req)
3604df
                 goto out;
3604df
         }
3604df
 
3604df
+        op = gd_cli_to_gd_op (cli_op);
3604df
+
3604df
+        if (conf->op_version < GD_OP_VERSION_3_9_0 &&
3604df
+            strcmp (cli_op, "GF_REPLACE_OP_COMMIT_FORCE")) {
3604df
+                snprintf (msg, sizeof (msg), "Cannot execute command. The "
3604df
+                          "cluster is operating at version %d. reset-brick "
3604df
+                          "command %s is unavailable in this version.",
3604df
+                          conf->op_version,
3604df
+                          gd_rb_op_to_str (cli_op));
3604df
+                ret = -1;
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
         ret = dict_get_str (dict, "src-brick", &src_brick);
3604df
 
3604df
         if (ret) {
3604df
@@ -115,52 +123,60 @@ __glusterd_handle_replace_brick (rpcsvc_request_t *req)
3604df
         gf_msg_debug (this->name, 0,
3604df
                 "src brick=%s", src_brick);
3604df
 
3604df
-        ret = dict_get_str (dict, "dst-brick", &dst_brick);
3604df
+        if (!strcmp (cli_op, "GF_RESET_OP_COMMIT") ||
3604df
+            !strcmp (cli_op, "GF_RESET_OP_COMMIT_FORCE") ||
3604df
+            !strcmp (cli_op,  "GF_REPLACE_OP_COMMIT_FORCE")) {
3604df
+                ret = dict_get_str (dict, "dst-brick", &dst_brick);
3604df
 
3604df
-        if (ret) {
3604df
-                snprintf (msg, sizeof (msg), "Failed to get dest brick");
3604df
-                gf_msg (this->name, GF_LOG_ERROR, 0,
3604df
-                        GD_MSG_DICT_GET_FAILED, "%s", msg);
3604df
-                goto out;
3604df
+                if (ret) {
3604df
+                        snprintf (msg, sizeof (msg), "Failed to get"
3604df
+                                  "dest brick");
3604df
+                        gf_msg (this->name, GF_LOG_ERROR, 0,
3604df
+                                GD_MSG_DICT_GET_FAILED, "%s", msg);
3604df
+                        goto out;
3604df
+                }
3604df
+
3604df
+                gf_msg_debug (this->name, 0, "dst brick=%s", dst_brick);
3604df
         }
3604df
 
3604df
-        gf_msg_debug (this->name, 0, "dst brick=%s", dst_brick);
3604df
         gf_msg (this->name, GF_LOG_INFO, 0,
3604df
-                GD_MSG_REPLACE_BRK_COMMIT_FORCE_REQ_RCVD,
3604df
-                "Received replace brick commit-force "
3604df
-                "request operation");
3604df
+                (op == GD_OP_REPLACE_BRICK) ?
3604df
+                 GD_MSG_REPLACE_BRK_COMMIT_FORCE_REQ_RCVD :
3604df
+                 GD_MSG_RESET_BRICK_COMMIT_FORCE_REQ_RCVD,
3604df
+                "Received %s request.",
3604df
+                 gd_rb_op_to_str (cli_op));
3604df
+
3604df
+        gf_event ((op == GD_OP_REPLACE_BRICK) ? EVENT_BRICK_REPLACE :
3604df
+                  EVENT_BRICK_RESET, "received %s request. Source bricks %s,"
3604df
+                  "destination brick %s.", gd_rb_op_to_str (cli_op),
3604df
+                  src_brick, (dst_brick) ? dst_brick : "");
3604df
 
3604df
         ret = glusterd_mgmt_v3_initiate_replace_brick_cmd_phases (req,
3604df
-                                            GD_OP_REPLACE_BRICK, dict);
3604df
+                                                                  op, dict);
3604df
 
3604df
 out:
3604df
+        if (ret) {
3604df
+                glusterd_op_send_cli_response (op, ret, 0, req,
3604df
+                                               dict, msg);
3604df
+        }
3604df
+        ret = 0;
3604df
         free (cli_req.dict.dict_val);//malloced by xdr
3604df
 
3604df
         return ret;
3604df
 }
3604df
 
3604df
 int
3604df
-glusterd_handle_replace_brick (rpcsvc_request_t *req)
3604df
+glusterd_handle_reset_brick (rpcsvc_request_t *req)
3604df
 {
3604df
         return glusterd_big_locked_handler (req,
3604df
                                             __glusterd_handle_replace_brick);
3604df
 }
3604df
 
3604df
-static int
3604df
-glusterd_get_rb_dst_brickinfo (glusterd_volinfo_t *volinfo,
3604df
-                               glusterd_brickinfo_t **brickinfo)
3604df
+int
3604df
+glusterd_handle_replace_brick (rpcsvc_request_t *req)
3604df
 {
3604df
-        int32_t                 ret = -1;
3604df
-
3604df
-        if (!volinfo || !brickinfo)
3604df
-                goto out;
3604df
-
3604df
-        *brickinfo = volinfo->rep_brick.dst_brick;
3604df
-
3604df
-        ret = 0;
3604df
-
3604df
-out:
3604df
-        return ret;
3604df
+        return glusterd_big_locked_handler (req,
3604df
+                                            __glusterd_handle_replace_brick);
3604df
 }
3604df
 
3604df
 int
3604df
@@ -172,13 +188,13 @@ glusterd_op_stage_replace_brick (dict_t *dict, char **op_errstr,
3604df
         char                                    *src_brick          = NULL;
3604df
         char                                    *dst_brick          = NULL;
3604df
         char                                    *volname            = NULL;
3604df
-        char                                    *replace_op         = NULL;
3604df
+        char                                    *op                 = NULL;
3604df
+        glusterd_op_t                            gd_op              = -1;
3604df
         glusterd_volinfo_t                      *volinfo            = NULL;
3604df
         glusterd_brickinfo_t                    *src_brickinfo      = NULL;
3604df
         char                                    *host               = NULL;
3604df
         char                                    *path               = NULL;
3604df
         char                                     msg[2048]          = {0};
3604df
-        char                                    *dup_dstbrick       = NULL;
3604df
         glusterd_peerinfo_t                     *peerinfo           = NULL;
3604df
         glusterd_brickinfo_t                    *dst_brickinfo      = NULL;
3604df
         gf_boolean_t                             enabled            = _gf_false;
3604df
@@ -188,8 +204,9 @@ glusterd_op_stage_replace_brick (dict_t *dict, char **op_errstr,
3604df
         char                                    *task_id_str        = NULL;
3604df
         xlator_t                                *this               = NULL;
3604df
         gf_boolean_t                             is_force           = _gf_false;
3604df
-        gsync_status_param_t                     param              = {0,};
3604df
-        char                                    *c                  = NULL;
3604df
+        pid_t                                    pid                = -1;
3604df
+        uuid_t                                   volume_id          = {0,};
3604df
+        char                                    *dup_dstbrick       = NULL;
3604df
 
3604df
         this = THIS;
3604df
         GF_ASSERT (this);
3604df
@@ -197,193 +214,41 @@ glusterd_op_stage_replace_brick (dict_t *dict, char **op_errstr,
3604df
         priv = this->private;
3604df
         GF_ASSERT (priv);
3604df
 
3604df
-        ret = dict_get_str (dict, "src-brick", &src_brick);
3604df
-
3604df
-        if (ret) {
3604df
-                gf_msg (this->name, GF_LOG_ERROR, 0,
3604df
-                        GD_MSG_DICT_GET_FAILED, "Unable to get src brick");
3604df
-                goto out;
3604df
-        }
3604df
-
3604df
-        gf_msg_debug (this->name, 0, "src brick=%s", src_brick);
3604df
-
3604df
-        ret = dict_get_str (dict, "dst-brick", &dst_brick);
3604df
-
3604df
-        if (ret) {
3604df
-                gf_msg (this->name, GF_LOG_ERROR, 0,
3604df
-                        GD_MSG_DICT_GET_FAILED, "Unable to get dest brick");
3604df
-                goto out;
3604df
-        }
3604df
-
3604df
-        gf_msg_debug (this->name, 0, "dst brick=%s", dst_brick);
3604df
-
3604df
-        ret = dict_get_str (dict, "volname", &volname);
3604df
-
3604df
-        if (ret) {
3604df
-                gf_msg (this->name, GF_LOG_ERROR, 0,
3604df
-                        GD_MSG_DICT_GET_FAILED, "Unable to get volume name");
3604df
-                goto out;
3604df
-        }
3604df
-
3604df
-        ret = dict_get_str (dict, "operation", &replace_op);
3604df
-        if (ret) {
3604df
-                gf_msg_debug (this->name, 0,
3604df
-                        "dict get on replace-brick operation failed");
3604df
-                goto out;
3604df
-        }
3604df
-
3604df
-        ret = glusterd_volinfo_find (volname, &volinfo);
3604df
-        if (ret) {
3604df
-                snprintf (msg, sizeof (msg), "volume: %s does not exist",
3604df
-                          volname);
3604df
-                *op_errstr = gf_strdup (msg);
3604df
-                goto out;
3604df
-        }
3604df
-
3604df
-        if (GLUSTERD_STATUS_STARTED != volinfo->status) {
3604df
-                ret = -1;
3604df
-                snprintf (msg, sizeof (msg), "volume: %s is not started",
3604df
-                          volname);
3604df
-                *op_errstr = gf_strdup (msg);
3604df
-                goto out;
3604df
-        }
3604df
-
3604df
-        ret = glusterd_disallow_op_for_tier (volinfo, GD_OP_REPLACE_BRICK, -1);
3604df
-        if (ret) {
3604df
-                snprintf (msg, sizeof (msg), "Replace brick commands are not "
3604df
-                          "supported on tiered volume %s", volname);
3604df
-                *op_errstr = gf_strdup (msg);
3604df
-                goto out;
3604df
-        }
3604df
-
3604df
-        if (!glusterd_store_is_valid_brickpath (volname, dst_brick) ||
3604df
-                !glusterd_is_valid_volfpath (volname, dst_brick)) {
3604df
-                snprintf (msg, sizeof (msg), "brick path %s is too "
3604df
-                          "long.", dst_brick);
3604df
-                gf_msg (this->name, GF_LOG_ERROR, 0,
3604df
-                        GD_MSG_BRKPATH_TOO_LONG, "%s", msg);
3604df
-                *op_errstr = gf_strdup (msg);
3604df
-
3604df
-                ret = -1;
3604df
-                goto out;
3604df
-        }
3604df
-
3604df
-        /* If geo-rep is configured, for this volume, it should be stopped. */
3604df
-        param.volinfo = volinfo;
3604df
-        ret = glusterd_check_geo_rep_running (&param, op_errstr);
3604df
-        if (ret || param.is_active) {
3604df
-                ret = -1;
3604df
+        ret = glusterd_brick_op_prerequisites (dict, &op, &gd_op,
3604df
+                                               &volname, &volinfo,
3604df
+                                               &src_brick, &src_brickinfo,
3604df
+                                               pidfile,
3604df
+                                               op_errstr, rsp_dict);
3604df
+        if (ret)
3604df
                 goto out;
3604df
-        }
3604df
 
3604df
-        if (glusterd_is_defrag_on(volinfo)) {
3604df
-                snprintf (msg, sizeof(msg), "Volume name %s rebalance is in "
3604df
-                          "progress. Please retry after completion", volname);
3604df
-                gf_msg (this->name, GF_LOG_ERROR, 0,
3604df
-                        GD_MSG_OIP_RETRY_LATER, "%s", msg);
3604df
-                *op_errstr = gf_strdup (msg);
3604df
+        if (strcmp (op, "GF_REPLACE_OP_COMMIT_FORCE")) {
3604df
                 ret = -1;
3604df
                 goto out;
3604df
-        }
3604df
-
3604df
-        if (!strcmp(replace_op, "GF_REPLACE_OP_COMMIT_FORCE")) {
3604df
-                is_force = _gf_true;
3604df
         } else {
3604df
-                ret = -1;
3604df
-                goto out;
3604df
-        }
3604df
-
3604df
-        ret = glusterd_volume_brickinfo_get_by_brick (src_brick, volinfo,
3604df
-                                                      &src_brickinfo,
3604df
-                                                      _gf_false);
3604df
-        if (ret) {
3604df
-                snprintf (msg, sizeof (msg), "brick: %s does not exist in "
3604df
-                          "volume: %s", src_brick, volname);
3604df
-                *op_errstr = gf_strdup (msg);
3604df
-                goto out;
3604df
-        }
3604df
-
3604df
-        if (dict) {
3604df
-                if (!glusterd_is_fuse_available ()) {
3604df
-                        gf_msg (this->name, GF_LOG_ERROR, 0,
3604df
-                                GD_MSG_RB_CMD_FAIL, "Unable to open /dev/"
3604df
-                                "fuse (%s), replace-brick command failed",
3604df
-                                strerror (errno));
3604df
-                        snprintf (msg, sizeof(msg), "Fuse unavailable\n "
3604df
-                                "Replace-brick failed");
3604df
-                        *op_errstr = gf_strdup (msg);
3604df
-                        ret = -1;
3604df
-                        goto out;
3604df
-                }
3604df
-        }
3604df
-
3604df
-        if (gf_is_local_addr (src_brickinfo->hostname)) {
3604df
-                gf_msg_debug (this->name, 0,
3604df
-                        "I AM THE SOURCE HOST");
3604df
-                if (src_brickinfo->port && rsp_dict) {
3604df
-                        ret = dict_set_int32 (rsp_dict, "src-brick-port",
3604df
-                                              src_brickinfo->port);
3604df
-                        if (ret) {
3604df
-                                gf_msg_debug (this->name, 0,
3604df
-                                        "Could not set src-brick-port=%d",
3604df
-                                        src_brickinfo->port);
3604df
-                        }
3604df
-                }
3604df
-
3604df
-                GLUSTERD_GET_BRICK_PIDFILE (pidfile, volinfo, src_brickinfo,
3604df
-                                            priv);
3604df
-
3604df
-        }
3604df
-
3604df
-        dup_dstbrick = gf_strdup (dst_brick);
3604df
-        if (!dup_dstbrick) {
3604df
-                ret = -1;
3604df
-                gf_msg (this->name, GF_LOG_ERROR, ENOMEM,
3604df
-                        GD_MSG_NO_MEMORY, "Memory allocation failed");
3604df
-                goto out;
3604df
-        }
3604df
-
3604df
-        /*
3604df
-         * IPv4 address contains '.' and ipv6 addresses contains ':'
3604df
-         * So finding the last occurance of ':' to
3604df
-         * mark the start of brick path
3604df
-         */
3604df
-        c = strrchr(dup_dstbrick, ':');
3604df
-        if (c != NULL) {
3604df
-                c[0] = '\0';
3604df
-                host = dup_dstbrick;
3604df
-                path = c++;
3604df
-        }
3604df
-
3604df
-        if (!host || !path) {
3604df
-                gf_msg (this->name, GF_LOG_ERROR, 0,
3604df
-                        GD_MSG_BAD_FORMAT,
3604df
-                        "dst brick %s is not of form <HOSTNAME>:<export-dir>",
3604df
-                        dst_brick);
3604df
-                ret = -1;
3604df
-                goto out;
3604df
-        }
3604df
+                is_force = _gf_true;
3604df
+	}
3604df
 
3604df
-        ret = glusterd_brickinfo_new_from_brick (dst_brick, &dst_brickinfo,
3604df
-                                                 _gf_true, NULL);
3604df
+	ret = glusterd_get_dst_brick_info (&dst_brick, volname,
3604df
+                                           op_errstr,
3604df
+                                           &dst_brickinfo, &host,
3604df
+                                           dict, &dup_dstbrick);
3604df
         if (ret)
3604df
                 goto out;
3604df
 
3604df
         ret = glusterd_new_brick_validate (dst_brick, dst_brickinfo,
3604df
-                                           msg, sizeof (msg));
3604df
-        if (ret) {
3604df
+                                           msg, sizeof (msg), op);
3604df
+        /* fail if brick being replaced with itself */
3604df
+	if (ret) {
3604df
                 *op_errstr = gf_strdup (msg);
3604df
                 ret = -1;
3604df
                 gf_msg (this->name, GF_LOG_ERROR, 0,
3604df
                         GD_MSG_BRICK_VALIDATE_FAIL, "%s", *op_errstr);
3604df
                 goto out;
3604df
-        }
3604df
+	}
3604df
 
3604df
-        if (!strcmp(replace_op, "GF_REPLACE_OP_COMMIT_FORCE")) {
3604df
-
3604df
-                volinfo->rep_brick.src_brick = src_brickinfo;
3604df
-                volinfo->rep_brick.dst_brick = dst_brickinfo;
3604df
-        }
3604df
+        volinfo->rep_brick.src_brick = src_brickinfo;
3604df
+        volinfo->rep_brick.dst_brick = dst_brickinfo;
3604df
 
3604df
         if (glusterd_rb_check_bricks (volinfo, src_brickinfo, dst_brickinfo)) {
3604df
 
3604df
@@ -489,48 +354,8 @@ rb_kill_destination_brick (glusterd_volinfo_t *volinfo,
3604df
         return glusterd_service_stop ("brick", pidfile, SIGTERM, _gf_true);
3604df
 }
3604df
 
3604df
-static int
3604df
-rb_update_dstbrick_port (glusterd_brickinfo_t *dst_brickinfo, dict_t *rsp_dict,
3604df
-                         dict_t *req_dict, char *replace_op)
3604df
-{
3604df
-        int     ret           = 0;
3604df
-        int     dict_ret      = 0;
3604df
-        int     dst_port      = 0;
3604df
-
3604df
-        dict_ret = dict_get_int32 (req_dict, "dst-brick-port", &dst_port);
3604df
-        if (!dict_ret)
3604df
-                dst_brickinfo->port = dst_port;
3604df
-
3604df
-        if (gf_is_local_addr (dst_brickinfo->hostname)) {
3604df
-                gf_msg ("glusterd", GF_LOG_INFO, 0,
3604df
-                        GD_MSG_BRK_PORT_NO_ADD_INDO,
3604df
-                        "adding dst-brick port no");
3604df
-
3604df
-                if (rsp_dict) {
3604df
-                        ret = dict_set_int32 (rsp_dict, "dst-brick-port",
3604df
-                                              dst_brickinfo->port);
3604df
-                        if (ret) {
3604df
-                                gf_msg_debug ("glusterd", 0,
3604df
-                                        "Could not set dst-brick port no in rsp dict");
3604df
-                                goto out;
3604df
-                        }
3604df
-                }
3604df
-
3604df
-                if (req_dict) {
3604df
-                        ret = dict_set_int32 (req_dict, "dst-brick-port",
3604df
-                                              dst_brickinfo->port);
3604df
-                        if (ret) {
3604df
-                                gf_msg_debug ("glusterd", 0,
3604df
-                                        "Could not set dst-brick port no");
3604df
-                                goto out;
3604df
-                        }
3604df
-                }
3604df
-        }
3604df
-out:
3604df
-        return ret;
3604df
-}
3604df
 
3604df
-static int
3604df
+int
3604df
 glusterd_op_perform_replace_brick (glusterd_volinfo_t  *volinfo,
3604df
                                    char *old_brick, char *new_brick,
3604df
                                    dict_t *dict)
3604df
@@ -568,6 +393,7 @@ glusterd_op_perform_replace_brick (glusterd_volinfo_t  *volinfo,
3604df
 
3604df
         strncpy (new_brickinfo->brick_id, old_brickinfo->brick_id,
3604df
                  sizeof (new_brickinfo->brick_id));
3604df
+        new_brickinfo->port = old_brickinfo->port;
3604df
 
3604df
         /* A bricks mount dir is required only by snapshots which were
3604df
          * introduced in gluster-3.6.0
3604df
@@ -584,8 +410,8 @@ glusterd_op_perform_replace_brick (glusterd_volinfo_t  *volinfo,
3604df
                          sizeof(new_brickinfo->mount_dir));
3604df
         }
3604df
 
3604df
-        cds_list_add_tail (&new_brickinfo->brick_list,
3604df
-                           &old_brickinfo->brick_list);
3604df
+        cds_list_add (&new_brickinfo->brick_list,
3604df
+                      &old_brickinfo->brick_list);
3604df
 
3604df
         volinfo->brick_count++;
3604df
 
3604df
@@ -706,11 +532,11 @@ glusterd_op_replace_brick (dict_t *dict, dict_t *rsp_dict)
3604df
         }
3604df
 
3604df
         ret = rb_update_dstbrick_port (dst_brickinfo, rsp_dict,
3604df
-                                       dict, replace_op);
3604df
+                                       dict);
3604df
         if (ret)
3604df
                 goto out;
3604df
 
3604df
-        if (strcmp(replace_op, "GF_REPLACE_OP_COMMIT_FORCE")) {
3604df
+        if (strcmp (replace_op, "GF_REPLACE_OP_COMMIT_FORCE")) {
3604df
                 ret = -1;
3604df
                 goto out;
3604df
         }
3604df
@@ -729,8 +555,8 @@ glusterd_op_replace_brick (dict_t *dict, dict_t *rsp_dict)
3604df
         ret = glusterd_svcs_stop (volinfo);
3604df
         if (ret) {
3604df
                 gf_msg (this->name, GF_LOG_ERROR, 0,
3604df
-                        GD_MSG_NFS_SERVER_STOP_FAIL,
3604df
-                        "Unable to stop nfs server, ret: %d", ret);
3604df
+                        GD_MSG_GLUSTER_SERVICES_STOP_FAIL,
3604df
+                        "Unable to stop gluster services, ret: %d", ret);
3604df
         }
3604df
 
3604df
         ret = glusterd_op_perform_replace_brick (volinfo, src_brick,
3604df
@@ -739,7 +565,7 @@ glusterd_op_replace_brick (dict_t *dict, dict_t *rsp_dict)
3604df
                 gf_msg (this->name, GF_LOG_CRITICAL, 0,
3604df
                         GD_MSG_BRICK_ADD_FAIL, "Unable to add dst-brick: "
3604df
                         "%s to volume: %s", dst_brick, volinfo->volname);
3604df
-		(void) glusterd_svcs_manager (volinfo);
3604df
+                (void) glusterd_svcs_manager (volinfo);
3604df
                 goto out;
3604df
         }
3604df
 
3604df
@@ -748,8 +574,8 @@ glusterd_op_replace_brick (dict_t *dict, dict_t *rsp_dict)
3604df
         ret = glusterd_svcs_manager (volinfo);
3604df
         if (ret) {
3604df
                 gf_msg (this->name, GF_LOG_CRITICAL, 0,
3604df
-                        GD_MSG_NFS_VOL_FILE_GEN_FAIL,
3604df
-                        "Failed to generate nfs volume file");
3604df
+                        GD_MSG_GLUSTER_SERVICE_START_FAIL,
3604df
+                        "Failed to start one or more gluster services.");
3604df
         }
3604df
 
3604df
 
3604df
@@ -759,7 +585,7 @@ glusterd_op_replace_brick (dict_t *dict, dict_t *rsp_dict)
3604df
         volinfo->rep_brick.dst_brick = NULL;
3604df
 
3604df
         if (!ret)
3604df
-		ret = glusterd_store_volinfo (volinfo,
3604df
+                ret = glusterd_store_volinfo (volinfo,
3604df
                                               GLUSTERD_VOLINFO_VER_AC_INCREMENT);
3604df
         if (ret)
3604df
                 gf_msg (this->name, GF_LOG_ERROR, 0,
3604df
diff --git a/xlators/mgmt/glusterd/src/glusterd-reset-brick.c b/xlators/mgmt/glusterd/src/glusterd-reset-brick.c
3604df
new file mode 100644
3604df
index 0000000..d1efe06
3604df
--- /dev/null
3604df
+++ b/xlators/mgmt/glusterd/src/glusterd-reset-brick.c
3604df
@@ -0,0 +1,430 @@
3604df
+/*
3604df
+   Copyright (c) 2016 Red Hat, Inc. <http://www.redhat.com>
3604df
+   This file is part of GlusterFS.
3604df
+
3604df
+   This file is licensed to you under your choice of the GNU Lesser
3604df
+   General Public License, version 3 or any later version (LGPLv3 or
3604df
+   later), or the GNU General Public License, version 2 (GPLv2), in all
3604df
+   cases as published by the Free Software Foundation.
3604df
+*/
3604df
+#include "common-utils.h"
3604df
+#include "cli1-xdr.h"
3604df
+#include "xdr-generic.h"
3604df
+#include "glusterfs.h"
3604df
+#include "glusterd.h"
3604df
+#include "glusterd-op-sm.h"
3604df
+#include "glusterd-geo-rep.h"
3604df
+#include "glusterd-store.h"
3604df
+#include "glusterd-utils.h"
3604df
+#include "glusterd-svc-mgmt.h"
3604df
+#include "glusterd-svc-helper.h"
3604df
+#include "glusterd-nfs-svc.h"
3604df
+#include "glusterd-volgen.h"
3604df
+#include "glusterd-messages.h"
3604df
+#include "glusterd-mgmt.h"
3604df
+#include "run.h"
3604df
+#include "syscall.h"
3604df
+
3604df
+#include <signal.h>
3604df
+
3604df
+int
3604df
+glusterd_reset_brick_prevalidate (dict_t *dict, char **op_errstr,
3604df
+                                  dict_t *rsp_dict)
3604df
+{
3604df
+        int                                      ret                = 0;
3604df
+        int32_t                                  port               = 0;
3604df
+        char                                    *src_brick          = NULL;
3604df
+        char                                    *dst_brick          = NULL;
3604df
+        char                                    *volname            = NULL;
3604df
+        char                                    *op                 = NULL;
3604df
+        glusterd_op_t                            gd_op              = -1;
3604df
+        glusterd_volinfo_t                      *volinfo            = NULL;
3604df
+        glusterd_brickinfo_t                    *src_brickinfo      = NULL;
3604df
+        char                                    *host               = NULL;
3604df
+        char                                     msg[2048]          = {0};
3604df
+        glusterd_peerinfo_t                     *peerinfo           = NULL;
3604df
+        glusterd_brickinfo_t                    *dst_brickinfo      = NULL;
3604df
+        gf_boolean_t                             enabled            = _gf_false;
3604df
+        glusterd_conf_t                         *priv               = NULL;
3604df
+        char                                    *savetok            = NULL;
3604df
+        char                                     pidfile[PATH_MAX]  = {0};
3604df
+        char                                    *task_id_str        = NULL;
3604df
+        xlator_t                                *this               = NULL;
3604df
+        gf_boolean_t                             is_force           = _gf_false;
3604df
+        gsync_status_param_t                     param              = {0,};
3604df
+        pid_t                                    pid                = -1;
3604df
+        uuid_t                                   volume_id          = {0,};
3604df
+        char                                    *dup_dstbrick       = NULL;
3604df
+
3604df
+        this = THIS;
3604df
+        GF_ASSERT (this);
3604df
+
3604df
+        priv = this->private;
3604df
+        GF_ASSERT (priv);
3604df
+
3604df
+        ret = glusterd_brick_op_prerequisites (dict, &op, &gd_op,
3604df
+                                               &volname, &volinfo,
3604df
+                                               &src_brick, &src_brickinfo,
3604df
+                                               pidfile,
3604df
+                                               op_errstr, rsp_dict);
3604df
+        if (ret)
3604df
+                goto out;
3604df
+
3604df
+        if (!strcmp (op, "GF_RESET_OP_START"))
3604df
+                goto done;
3604df
+
3604df
+        if (!strcmp (op, "GF_RESET_OP_COMMIT_FORCE"))
3604df
+                is_force = _gf_true;
3604df
+
3604df
+	ret = glusterd_get_dst_brick_info (&dst_brick, volname,
3604df
+					   op_errstr,
3604df
+					   &dst_brickinfo, &host,
3604df
+                                           dict, &dup_dstbrick);
3604df
+        if (ret)
3604df
+                goto out;
3604df
+
3604df
+        ret = glusterd_new_brick_validate (dst_brick, dst_brickinfo,
3604df
+                                           msg, sizeof (msg), op);
3604df
+        /* if bricks are not same and reset brick was used, fail command.
3604df
+         * Only replace brick should be used to replace with new bricks
3604df
+         * to the volume.
3604df
+         */
3604df
+        if (ret == 0) {
3604df
+                if (!gf_uuid_compare (MY_UUID, dst_brickinfo->uuid)) {
3604df
+                        ret = -1;
3604df
+                        *op_errstr = gf_strdup
3604df
+                                        ("When destination brick is new,"
3604df
+                                         " please use"
3604df
+                                         " gluster volume "
3604df
+                                         "replace-brick <volname> "
3604df
+                                         "<src-brick> <dst-brick> "
3604df
+                                         "commit force");
3604df
+                        if (*op_errstr)
3604df
+                                gf_msg (this->name,
3604df
+                                   GF_LOG_ERROR,
3604df
+                                   EPERM,
3604df
+                                   GD_MSG_BRICK_VALIDATE_FAIL,
3604df
+                                   "%s", *op_errstr);
3604df
+                        goto out;
3604df
+                }
3604df
+        } else if (ret == 1) {
3604df
+                if (gf_is_service_running (pidfile, &pid)) {
3604df
+                        ret = -1;
3604df
+                        *op_errstr = gf_strdup
3604df
+                                        ("Source brick"
3604df
+                                         " must be stopped."
3604df
+                                         " Please use "
3604df
+                                         "gluster volume "
3604df
+                                         "reset-brick <volname> "
3604df
+                                         "<dst-brick> start.");
3604df
+                        if (*op_errstr)
3604df
+                                gf_msg (this->name,
3604df
+                                   GF_LOG_ERROR,
3604df
+                                   EPERM,
3604df
+                                   GD_MSG_BRICK_VALIDATE_FAIL,
3604df
+                                   "%s", *op_errstr);
3604df
+                        goto out;
3604df
+                }
3604df
+                ret = sys_lgetxattr (dst_brickinfo->path,
3604df
+                                     GF_XATTR_VOL_ID_KEY,
3604df
+                                     volume_id, 16);
3604df
+                if (gf_uuid_compare (dst_brickinfo->uuid,
3604df
+                                     src_brickinfo->uuid) ||
3604df
+                    (ret >= 0 && is_force == _gf_false)) {
3604df
+                        ret = -1;
3604df
+                        *op_errstr = gf_strdup ("Brick not available."
3604df
+                                                "It may be containing "
3604df
+                                                "or be contained "
3604df
+                                                "by an existing brick."
3604df
+                                                "Use 'force' option to "
3604df
+                                                "override this.");
3604df
+                        if (*op_errstr)
3604df
+                                gf_msg (this->name,
3604df
+                                    GF_LOG_ERROR,
3604df
+                                    EPERM,
3604df
+                                    GD_MSG_BRICK_VALIDATE_FAIL,
3604df
+                                    "%s", *op_errstr);
3604df
+                        goto out;
3604df
+                }
3604df
+                ret = 0;
3604df
+        } else {
3604df
+                *op_errstr = gf_strdup (msg);
3604df
+                ret = -1;
3604df
+                gf_msg (this->name, GF_LOG_ERROR, 0,
3604df
+                        GD_MSG_BRICK_VALIDATE_FAIL, "%s", *op_errstr);
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
+        volinfo->rep_brick.src_brick = src_brickinfo;
3604df
+        volinfo->rep_brick.dst_brick = dst_brickinfo;
3604df
+
3604df
+        if (gf_is_local_addr (host)) {
3604df
+                ret = glusterd_validate_and_create_brickpath
3604df
+                                                  (dst_brickinfo,
3604df
+                                                  volinfo->volume_id,
3604df
+                                                  op_errstr, is_force);
3604df
+                if (ret)
3604df
+                        goto out;
3604df
+        } else {
3604df
+                rcu_read_lock ();
3604df
+
3604df
+                peerinfo = glusterd_peerinfo_find (NULL, host);
3604df
+                if (peerinfo == NULL) {
3604df
+                        ret = -1;
3604df
+                        snprintf (msg, sizeof (msg),
3604df
+                                  "%s, is not a friend.",
3604df
+                                  host);
3604df
+                        *op_errstr = gf_strdup (msg);
3604df
+
3604df
+                } else if (!peerinfo->connected) {
3604df
+                        snprintf (msg, sizeof (msg), "%s,"
3604df
+                                  "is not connected at "
3604df
+                                  "the moment.", host);
3604df
+                        *op_errstr = gf_strdup (msg);
3604df
+                        ret = -1;
3604df
+
3604df
+                } else if (GD_FRIEND_STATE_BEFRIENDED !=
3604df
+                                peerinfo->state.state) {
3604df
+                        snprintf (msg, sizeof (msg),
3604df
+                                  "%s, is not befriended "
3604df
+                                  "at the moment.", host);
3604df
+                        *op_errstr = gf_strdup (msg);
3604df
+                        ret = -1;
3604df
+                }
3604df
+                rcu_read_unlock ();
3604df
+
3604df
+                if (ret)
3604df
+                        goto out;
3604df
+
3604df
+        }
3604df
+
3604df
+        ret = glusterd_get_brick_mount_dir
3604df
+                        (dst_brickinfo->path,
3604df
+                         dst_brickinfo->hostname,
3604df
+                         dst_brickinfo->mount_dir);
3604df
+        if (ret) {
3604df
+                gf_msg (this->name, GF_LOG_ERROR, 0,
3604df
+                        GD_MSG_BRICK_MOUNTDIR_GET_FAIL,
3604df
+                        "Failed to get brick mount_dir.");
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
+        ret = dict_set_dynstr_with_alloc (rsp_dict,
3604df
+                                  "brick1.mount_dir",
3604df
+                                   dst_brickinfo->mount_dir);
3604df
+        if (ret) {
3604df
+                gf_msg (this->name, GF_LOG_ERROR, 0,
3604df
+                        GD_MSG_DICT_SET_FAILED,
3604df
+                        "Failed to set brick1.mount_dir");
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
+        ret = dict_set_int32 (rsp_dict, "brick_count", 1);
3604df
+        if (ret) {
3604df
+                gf_msg (this->name, GF_LOG_ERROR, 0,
3604df
+                        GD_MSG_DICT_SET_FAILED,
3604df
+                        "Failed to set local_brick_count.");
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
+done:
3604df
+        ret = 0;
3604df
+out:
3604df
+        GF_FREE (dup_dstbrick);
3604df
+        gf_msg_debug (this->name, 0, "Returning %d.", ret);
3604df
+
3604df
+        return ret;
3604df
+}
3604df
+
3604df
+int
3604df
+glusterd_op_reset_brick (dict_t *dict, dict_t *rsp_dict)
3604df
+{
3604df
+        int                                      ret           = 0;
3604df
+        dict_t                                  *ctx           = NULL;
3604df
+        char                                    *op            = NULL;
3604df
+        glusterd_volinfo_t                      *volinfo       = NULL;
3604df
+        char                                    *volname       = NULL;
3604df
+        xlator_t                                *this          = NULL;
3604df
+        glusterd_conf_t                         *priv          = NULL;
3604df
+        char                                    *src_brick     = NULL;
3604df
+        char                                    *dst_brick     = NULL;
3604df
+        glusterd_brickinfo_t                    *src_brickinfo = NULL;
3604df
+        glusterd_brickinfo_t                    *dst_brickinfo = NULL;
3604df
+        char                                    *task_id_str   = NULL;
3604df
+        char                                    pidfile[PATH_MAX] = {0,};
3604df
+
3604df
+        this = THIS;
3604df
+        GF_ASSERT (this);
3604df
+
3604df
+        priv = this->private;
3604df
+        GF_ASSERT (priv);
3604df
+
3604df
+        ret = dict_get_str (dict, "operation", &op);
3604df
+        if (ret) {
3604df
+                gf_msg_debug (this->name, 0,
3604df
+                        "dict_get on operation failed");
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
+        ret = dict_get_str (dict, "volname", &volname);
3604df
+        if (ret) {
3604df
+                gf_msg (this->name, GF_LOG_ERROR, 0,
3604df
+                        GD_MSG_DICT_GET_FAILED, "Unable to get volume name");
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
+        ret = glusterd_volinfo_find (volname, &volinfo);
3604df
+        if (ret)
3604df
+                goto out;
3604df
+
3604df
+        ret = dict_get_str (dict, "src-brick", &src_brick);
3604df
+        if (ret) {
3604df
+                gf_msg (this->name, GF_LOG_ERROR, 0,
3604df
+                        GD_MSG_DICT_GET_FAILED, "Unable to get src brick");
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
+        gf_msg_debug (this->name, 0, "src brick=%s", src_brick);
3604df
+
3604df
+        ret = glusterd_volume_brickinfo_get_by_brick (src_brick, volinfo,
3604df
+                                                      &src_brickinfo,
3604df
+                                                      _gf_false);
3604df
+        if (ret) {
3604df
+                gf_msg_debug (this->name, 0,
3604df
+                        "Unable to get src-brickinfo");
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
+        if (!strcmp (op, "GF_RESET_OP_START")) {
3604df
+                (void) glusterd_brick_disconnect (src_brickinfo);
3604df
+                GLUSTERD_GET_BRICK_PIDFILE (pidfile, volinfo,
3604df
+                                            src_brickinfo, priv);
3604df
+                ret = glusterd_service_stop ("brick", pidfile,
3604df
+                                             SIGTERM, _gf_false);
3604df
+                if (ret == 0) {
3604df
+                        glusterd_set_brick_status (src_brickinfo,
3604df
+                                                GF_BRICK_STOPPED);
3604df
+                        (void) glusterd_brick_unlink_socket_file
3604df
+                                        (volinfo, src_brickinfo);
3604df
+                        gf_msg (this->name, GF_LOG_INFO, 0,
3604df
+                        GD_MSG_BRICK_CLEANUP_SUCCESS,
3604df
+                        "Brick cleanup successful.");
3604df
+                } else {
3604df
+                        gf_msg (this->name, GF_LOG_CRITICAL, 0,
3604df
+                                GD_MSG_BRK_CLEANUP_FAIL,
3604df
+                                "Unable to cleanup src brick");
3604df
+                        goto out;
3604df
+                }
3604df
+                goto out;
3604df
+        } else if (!strcmp (op, "GF_RESET_OP_COMMIT") ||
3604df
+                   !strcmp (op, "GF_RESET_OP_COMMIT_FORCE")) {
3604df
+                ret = dict_get_str (dict, "dst-brick", &dst_brick);
3604df
+                if (ret) {
3604df
+                        gf_msg (this->name, GF_LOG_ERROR, 0,
3604df
+                                GD_MSG_DICT_GET_FAILED,
3604df
+                                "Unable to get dst brick");
3604df
+                        goto out;
3604df
+                }
3604df
+
3604df
+                gf_msg_debug (this->name, 0, "dst brick=%s", dst_brick);
3604df
+
3604df
+                ret = glusterd_get_rb_dst_brickinfo (volinfo,
3604df
+                                                &dst_brickinfo);
3604df
+                if (ret) {
3604df
+                        gf_msg (this->name, GF_LOG_ERROR, 0,
3604df
+                                GD_MSG_RB_BRICKINFO_GET_FAIL,
3604df
+                                "Unable to get "
3604df
+                                "reset brick "
3604df
+                                "destination brickinfo");
3604df
+                        goto out;
3604df
+                }
3604df
+
3604df
+                ret = glusterd_resolve_brick (dst_brickinfo);
3604df
+                if (ret) {
3604df
+                        gf_msg_debug (this->name, 0,
3604df
+                                "Unable to resolve dst-brickinfo");
3604df
+                        goto out;
3604df
+                }
3604df
+
3604df
+                ret = rb_update_dstbrick_port (dst_brickinfo, rsp_dict,
3604df
+                                               dict);
3604df
+                if (ret)
3604df
+                        goto out;
3604df
+
3604df
+                if (gf_is_local_addr (dst_brickinfo->hostname)) {
3604df
+                        gf_msg_debug (this->name, 0, "I AM THE DESTINATION HOST");
3604df
+                        (void) glusterd_brick_disconnect (src_brickinfo);
3604df
+                        GLUSTERD_GET_BRICK_PIDFILE (pidfile, volinfo,
3604df
+                                                    src_brickinfo, priv);
3604df
+                        ret = glusterd_service_stop ("brick", pidfile,
3604df
+                                                     SIGTERM, _gf_false);
3604df
+                        if (ret == 0) {
3604df
+                                glusterd_set_brick_status
3604df
+                                        (src_brickinfo, GF_BRICK_STOPPED);
3604df
+                                (void) glusterd_brick_unlink_socket_file
3604df
+                                                (volinfo, src_brickinfo);
3604df
+                                gf_msg (this->name, GF_LOG_INFO, 0,
3604df
+                                GD_MSG_BRICK_CLEANUP_SUCCESS,
3604df
+                                "Brick cleanup successful.");
3604df
+                        } else {
3604df
+                                gf_msg (this->name, GF_LOG_CRITICAL, 0,
3604df
+                                        GD_MSG_BRK_CLEANUP_FAIL,
3604df
+                                        "Unable to cleanup src brick");
3604df
+                                goto out;
3604df
+                        }
3604df
+                }
3604df
+
3604df
+                ret = glusterd_svcs_stop (volinfo);
3604df
+                if (ret) {
3604df
+                        gf_msg (this->name, GF_LOG_ERROR, 0,
3604df
+                                GD_MSG_GLUSTER_SERVICES_STOP_FAIL,
3604df
+                                "Unable to stop gluster services, ret: %d",
3604df
+                                ret);
3604df
+                        goto out;
3604df
+                }
3604df
+                ret = glusterd_op_perform_replace_brick (volinfo, src_brick,
3604df
+                                                         dst_brick, dict);
3604df
+                if (ret) {
3604df
+                        gf_msg (this->name, GF_LOG_CRITICAL, 0,
3604df
+                                GD_MSG_BRICK_ADD_FAIL,
3604df
+                                "Unable to add dst-brick: "
3604df
+                                "%s to volume: %s", dst_brick,
3604df
+                                volinfo->volname);
3604df
+                        (void) glusterd_svcs_manager (volinfo);
3604df
+                        goto out;
3604df
+                }
3604df
+
3604df
+                volinfo->rebal.defrag_status = 0;
3604df
+
3604df
+                ret = glusterd_svcs_manager (volinfo);
3604df
+                if (ret) {
3604df
+                        gf_msg (this->name, GF_LOG_CRITICAL, 0,
3604df
+                                GD_MSG_GLUSTER_SERVICE_START_FAIL,
3604df
+                                "Failed to start one or more gluster services.");
3604df
+                }
3604df
+
3604df
+
3604df
+                ret = glusterd_fetchspec_notify (THIS);
3604df
+                glusterd_brickinfo_delete (volinfo->rep_brick.dst_brick);
3604df
+                volinfo->rep_brick.src_brick = NULL;
3604df
+                volinfo->rep_brick.dst_brick = NULL;
3604df
+
3604df
+                if (!ret)
3604df
+                        ret = glusterd_store_volinfo (volinfo,
3604df
+                              GLUSTERD_VOLINFO_VER_AC_INCREMENT);
3604df
+                if (ret) {
3604df
+                        gf_msg (this->name, GF_LOG_ERROR, 0,
3604df
+                                GD_MSG_RBOP_STATE_STORE_FAIL,
3604df
+                                "Couldn't store"
3604df
+                                " reset brick operation's state.");
3604df
+
3604df
+                }
3604df
+        } else {
3604df
+                ret = -1;
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
+
3604df
+out:
3604df
+        return ret;
3604df
+}
3604df
diff --git a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c
3604df
index c87a6da..51deeff 100644
3604df
--- a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c
3604df
+++ b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c
3604df
@@ -144,6 +144,7 @@ glusterd_op_send_cli_response (glusterd_op_t op, int32_t op_ret,
3604df
         case GD_OP_BITROT:
3604df
         case GD_OP_SCRUB_STATUS:
3604df
         case GD_OP_SCRUB_ONDEMAND:
3604df
+        case GD_OP_RESET_BRICK:
3604df
         {
3604df
                 /*nothing specific to be done*/
3604df
                 break;
3604df
diff --git a/xlators/mgmt/glusterd/src/glusterd-syncop.c b/xlators/mgmt/glusterd/src/glusterd-syncop.c
3604df
index 64a0aeb..47100c1 100644
3604df
--- a/xlators/mgmt/glusterd/src/glusterd-syncop.c
3604df
+++ b/xlators/mgmt/glusterd/src/glusterd-syncop.c
3604df
@@ -248,6 +248,7 @@ glusterd_syncop_aggr_rsp_dict (glusterd_op_t op, dict_t *aggr, dict_t *rsp)
3604df
         break;
3604df
 
3604df
         case GD_OP_REPLACE_BRICK:
3604df
+        case GD_OP_RESET_BRICK:
3604df
                 ret = glusterd_rb_use_rsp_dict (aggr, rsp);
3604df
                 if (ret)
3604df
                         goto out;
3604df
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
3604df
index 6b18d17..375b965 100644
3604df
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
3604df
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
3604df
@@ -6002,7 +6002,7 @@ glusterd_is_defrag_on (glusterd_volinfo_t *volinfo)
3604df
 
3604df
 int
3604df
 glusterd_new_brick_validate (char *brick, glusterd_brickinfo_t *brickinfo,
3604df
-                             char *op_errstr, size_t len)
3604df
+                             char *op_errstr, size_t len, char *op)
3604df
 {
3604df
         glusterd_brickinfo_t    *newbrickinfo = NULL;
3604df
         int                     ret = -1;
3604df
@@ -6043,8 +6043,12 @@ glusterd_new_brick_validate (char *brick, glusterd_brickinfo_t *brickinfo,
3604df
                                                       newbrickinfo->path)) {
3604df
                         snprintf(op_errstr, len, "Brick: %s not available."
3604df
                                  " Brick may be containing or be contained "
3604df
-                                 "by an existing brick", brick);
3604df
-                        ret = -1;
3604df
+                                 "by an existing brick.", brick);
3604df
+                        if (op && (!strcmp (op, "GF_RESET_OP_COMMIT") ||
3604df
+                            !strcmp (op, "GF_RESET_OP_COMMIT_FORCE")))
3604df
+                                ret = 1;
3604df
+                        else
3604df
+                                ret = -1;
3604df
                         goto out;
3604df
                 }
3604df
 
3604df
@@ -11490,6 +11494,7 @@ glusterd_disallow_op_for_tier (glusterd_volinfo_t *volinfo, glusterd_op_t op,
3604df
         switch (op) {
3604df
         case GD_OP_ADD_BRICK:
3604df
         case GD_OP_REPLACE_BRICK:
3604df
+	case GD_OP_RESET_BRICK:
3604df
                 ret = -1;
3604df
                 gf_msg_debug (this->name, 0, "Operation not "
3604df
                         "permitted on tiered volume %s",
3604df
@@ -11739,3 +11744,319 @@ get_last_brick_of_brick_group (glusterd_volinfo_t *volinfo,
3604df
 
3604df
         return last;
3604df
 }
3604df
+
3604df
+int
3604df
+glusterd_get_rb_dst_brickinfo (glusterd_volinfo_t *volinfo,
3604df
+                               glusterd_brickinfo_t **brickinfo)
3604df
+{
3604df
+        int32_t                 ret = -1;
3604df
+
3604df
+        if (!volinfo || !brickinfo)
3604df
+                goto out;
3604df
+
3604df
+        *brickinfo = volinfo->rep_brick.dst_brick;
3604df
+
3604df
+        ret = 0;
3604df
+
3604df
+out:
3604df
+        return ret;
3604df
+}
3604df
+
3604df
+int
3604df
+rb_update_dstbrick_port (glusterd_brickinfo_t *dst_brickinfo, dict_t *rsp_dict,
3604df
+                         dict_t *req_dict)
3604df
+{
3604df
+        int     ret           = 0;
3604df
+        int     dict_ret      = 0;
3604df
+        int     dst_port      = 0;
3604df
+
3604df
+        dict_ret = dict_get_int32 (req_dict, "dst-brick-port", &dst_port);
3604df
+        if (!dict_ret)
3604df
+                dst_brickinfo->port = dst_port;
3604df
+
3604df
+        if (gf_is_local_addr (dst_brickinfo->hostname)) {
3604df
+                gf_msg ("glusterd", GF_LOG_INFO, 0,
3604df
+                        GD_MSG_BRK_PORT_NO_ADD_INDO,
3604df
+                        "adding dst-brick port no %d", dst_port);
3604df
+
3604df
+                if (rsp_dict) {
3604df
+                        ret = dict_set_int32 (rsp_dict, "dst-brick-port",
3604df
+                                              dst_brickinfo->port);
3604df
+                        if (ret) {
3604df
+                                gf_msg_debug ("glusterd", 0,
3604df
+                                        "Could not set dst-brick port no in rsp dict");
3604df
+                                goto out;
3604df
+                        }
3604df
+                }
3604df
+
3604df
+                if (req_dict && !dict_ret) {
3604df
+                        ret = dict_set_int32 (req_dict, "dst-brick-port",
3604df
+                                              dst_brickinfo->port);
3604df
+                        if (ret) {
3604df
+                                gf_msg_debug ("glusterd", 0,
3604df
+                                        "Could not set dst-brick port no");
3604df
+                                goto out;
3604df
+                        }
3604df
+                }
3604df
+        }
3604df
+out:
3604df
+        return ret;
3604df
+}
3604df
+
3604df
+int
3604df
+glusterd_brick_op_prerequisites (dict_t *dict,
3604df
+                                 char **op,
3604df
+                                 glusterd_op_t *gd_op, char **volname,
3604df
+                                 glusterd_volinfo_t **volinfo,
3604df
+                                 char **src_brick, glusterd_brickinfo_t
3604df
+                                 **src_brickinfo, char *pidfile,
3604df
+                                 char **op_errstr, dict_t *rsp_dict)
3604df
+{
3604df
+        int                                      ret                = 0;
3604df
+        char                                     msg[2048]          = {0};
3604df
+        gsync_status_param_t                     param              = {0,};
3604df
+        xlator_t                                *this               = NULL;
3604df
+        glusterd_conf_t                         *priv               = NULL;
3604df
+        glusterd_volinfo_t                      *v                  = NULL;
3604df
+        glusterd_brickinfo_t                    *b                  = NULL;
3604df
+
3604df
+        this = THIS;
3604df
+        GF_ASSERT (this);
3604df
+
3604df
+        priv = this->private;
3604df
+        GF_ASSERT (priv);
3604df
+
3604df
+        ret = dict_get_str (dict, "operation", op);
3604df
+        if (ret) {
3604df
+                gf_msg_debug (this->name, 0,
3604df
+                        "dict get on operation type failed");
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
+        *gd_op = gd_cli_to_gd_op (*op);
3604df
+        if (*gd_op < 0)
3604df
+                goto out;
3604df
+
3604df
+        ret = dict_get_str (dict, "volname", volname);
3604df
+
3604df
+        if (ret) {
3604df
+                gf_msg (this->name, GF_LOG_ERROR, 0,
3604df
+                        GD_MSG_DICT_GET_FAILED, "Unable to get volume name");
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
+        ret = glusterd_volinfo_find (*volname, volinfo);
3604df
+        if (ret) {
3604df
+                snprintf (msg, sizeof (msg), "volume: %s does not exist",
3604df
+                          *volname);
3604df
+                *op_errstr = gf_strdup (msg);
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
+        if (GLUSTERD_STATUS_STARTED != (*volinfo)->status) {
3604df
+                ret = -1;
3604df
+                snprintf (msg, sizeof (msg), "volume: %s is not started",
3604df
+                          *volname);
3604df
+                *op_errstr = gf_strdup (msg);
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
+        ret = glusterd_disallow_op_for_tier (*volinfo, *gd_op, -1);
3604df
+        if (ret) {
3604df
+                snprintf (msg, sizeof (msg), "%sbrick commands are not "
3604df
+                          "supported on tiered volume %s",
3604df
+                          (*gd_op == GD_OP_REPLACE_BRICK) ? "replace-" :
3604df
+                          "reset-",
3604df
+                           *volname);
3604df
+                *op_errstr = gf_strdup (msg);
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
+        /* If geo-rep is configured, for this volume, it should be stopped. */
3604df
+        param.volinfo = *volinfo;
3604df
+        ret = glusterd_check_geo_rep_running (&param, op_errstr);
3604df
+        if (ret || param.is_active) {
3604df
+                ret = -1;
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
+        if (glusterd_is_defrag_on(*volinfo)) {
3604df
+                snprintf (msg, sizeof(msg), "Volume name %s rebalance is in "
3604df
+                          "progress. Please retry after completion", *volname);
3604df
+                gf_msg (this->name, GF_LOG_ERROR, 0,
3604df
+                        GD_MSG_OIP_RETRY_LATER, "%s", msg);
3604df
+                *op_errstr = gf_strdup (msg);
3604df
+                ret = -1;
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
+        if (dict) {
3604df
+                if (!glusterd_is_fuse_available ()) {
3604df
+                        gf_msg (this->name, GF_LOG_ERROR, 0,
3604df
+                                (*gd_op == GD_OP_REPLACE_BRICK) ?
3604df
+                                GD_MSG_RB_CMD_FAIL :
3604df
+                                GD_MSG_RESET_BRICK_CMD_FAIL,
3604df
+                                "Unable to open /dev/"
3604df
+                                "fuse (%s), %s command failed",
3604df
+                                strerror (errno), gd_rb_op_to_str (*op));
3604df
+                        snprintf (msg, sizeof(msg), "Fuse unavailable\n "
3604df
+                                "%s failed", gd_rb_op_to_str (*op));
3604df
+                        *op_errstr = gf_strdup (msg);
3604df
+                        ret = -1;
3604df
+                        goto out;
3604df
+                }
3604df
+        }
3604df
+
3604df
+        ret = dict_get_str (dict, "src-brick", src_brick);
3604df
+
3604df
+        if (ret) {
3604df
+                gf_msg (this->name, GF_LOG_ERROR, 0,
3604df
+                        GD_MSG_DICT_GET_FAILED, "Unable to get src brick");
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
+        gf_msg_debug (this->name, 0, "src brick=%s", *src_brick);
3604df
+
3604df
+        ret = glusterd_volume_brickinfo_get_by_brick (*src_brick, *volinfo,
3604df
+                                                      src_brickinfo,
3604df
+                                                      _gf_false);
3604df
+        if (ret) {
3604df
+                snprintf (msg, sizeof (msg), "brick: %s does not exist in "
3604df
+                          "volume: %s", *src_brick, *volname);
3604df
+                *op_errstr = gf_strdup (msg);
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
+        if (gf_is_local_addr ((*src_brickinfo)->hostname)) {
3604df
+                gf_msg_debug (this->name, 0,
3604df
+                        "I AM THE SOURCE HOST");
3604df
+                if ((*src_brickinfo)->port && rsp_dict) {
3604df
+                        ret = dict_set_int32 (rsp_dict, "src-brick-port",
3604df
+                                              (*src_brickinfo)->port);
3604df
+                        if (ret) {
3604df
+                                gf_msg_debug (this->name, 0,
3604df
+                                        "Could not set src-brick-port=%d",
3604df
+                                        (*src_brickinfo)->port);
3604df
+                        }
3604df
+                }
3604df
+
3604df
+                v = *volinfo;
3604df
+                b = *src_brickinfo;
3604df
+                GLUSTERD_GET_BRICK_PIDFILE (pidfile, v, b,
3604df
+                                            priv);
3604df
+        }
3604df
+
3604df
+        ret = 0;
3604df
+out:
3604df
+        return ret;
3604df
+}
3604df
+
3604df
+int
3604df
+glusterd_get_dst_brick_info (char **dst_brick, char *volname, char **op_errstr,
3604df
+                             glusterd_brickinfo_t **dst_brickinfo, char **host,
3604df
+                             dict_t *dict, char **dup_dstbrick)
3604df
+{
3604df
+
3604df
+        char                                    *path               = NULL;
3604df
+        char                                    *c                  = NULL;
3604df
+        char                                     msg[2048]          = {0};
3604df
+        xlator_t                                *this               = NULL;
3604df
+        glusterd_conf_t                         *priv               = NULL;
3604df
+        int                                      ret                = 0;
3604df
+
3604df
+        this = THIS;
3604df
+        GF_ASSERT (this);
3604df
+
3604df
+        priv = this->private;
3604df
+        GF_ASSERT (priv);
3604df
+
3604df
+        ret = dict_get_str (dict, "dst-brick", dst_brick);
3604df
+
3604df
+        if (ret) {
3604df
+                gf_msg (this->name, GF_LOG_ERROR, 0,
3604df
+                        GD_MSG_DICT_GET_FAILED,
3604df
+                        "Unable to get dest brick.");
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
+        gf_msg_debug (this->name, 0, "dst brick=%s", *dst_brick);
3604df
+
3604df
+        if (!glusterd_store_is_valid_brickpath (volname, *dst_brick) ||
3604df
+                !glusterd_is_valid_volfpath (volname, *dst_brick)) {
3604df
+                snprintf (msg, sizeof (msg), "brick path %s is too "
3604df
+                          "long.", *dst_brick);
3604df
+                gf_msg (this->name, GF_LOG_ERROR, 0,
3604df
+                        GD_MSG_BRKPATH_TOO_LONG, "%s", msg);
3604df
+                *op_errstr = gf_strdup (msg);
3604df
+
3604df
+                ret = -1;
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
+        *dup_dstbrick = gf_strdup (*dst_brick);
3604df
+        if (!*dup_dstbrick) {
3604df
+                ret = -1;
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
+        /*
3604df
+         * IPv4 address contains '.' and ipv6 addresses contains ':'
3604df
+         * So finding the last occurance of ':' to
3604df
+         * mark the start of brick path
3604df
+         */
3604df
+        c = strrchr(*dup_dstbrick, ':');
3604df
+        if (c != NULL) {
3604df
+                c[0] = '\0';
3604df
+                *host = *dup_dstbrick;
3604df
+                path = c++;
3604df
+        }
3604df
+
3604df
+        if (!host || !path) {
3604df
+                gf_msg (this->name, GF_LOG_ERROR, 0,
3604df
+                        GD_MSG_BAD_FORMAT,
3604df
+                        "dst brick %s is not of "
3604df
+                        "form <HOSTNAME>:<export-dir>",
3604df
+                        *dst_brick);
3604df
+                ret = -1;
3604df
+                goto out;
3604df
+        }
3604df
+
3604df
+        ret = glusterd_brickinfo_new_from_brick (*dst_brick,
3604df
+                                                 dst_brickinfo,
3604df
+                                                 _gf_true, NULL);
3604df
+        if (ret)
3604df
+                goto out;
3604df
+
3604df
+        ret = 0;
3604df
+out:
3604df
+        return ret;
3604df
+}
3604df
+
3604df
+glusterd_op_t
3604df
+gd_cli_to_gd_op (char *cli_op)
3604df
+{
3604df
+        if (!strcmp (cli_op, "GF_RESET_OP_START") ||
3604df
+            !strcmp(cli_op, "GF_RESET_OP_COMMIT") ||
3604df
+            !strcmp (cli_op, "GF_RESET_OP_COMMIT_FORCE")) {
3604df
+                return GD_OP_RESET_BRICK;
3604df
+        }
3604df
+
3604df
+        if (!strcmp (cli_op, "GF_REPLACE_OP_COMMIT_FORCE"))
3604df
+                return GD_OP_REPLACE_BRICK;
3604df
+
3604df
+        return -1;
3604df
+}
3604df
+
3604df
+char *
3604df
+gd_rb_op_to_str (char *op)
3604df
+{
3604df
+        if (!strcmp (op, "GF_RESET_OP_START"))
3604df
+                return "reset-brick start";
3604df
+        if (!strcmp (op, "GF_RESET_OP_COMMIT"))
3604df
+                return "reset-brick commit";
3604df
+        if (!strcmp (op, "GF_RESET_OP_COMMIT_FORCE"))
3604df
+                return "reset-brick commit force";
3604df
+        if (!strcmp (op, "GF_REPLACE_OP_COMMIT_FORCE"))
3604df
+                return "replace-brick commit force";
3604df
+        return NULL;
3604df
+}
3604df
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h
3604df
index ca07efd..419ab48 100644
3604df
--- a/xlators/mgmt/glusterd/src/glusterd-utils.h
3604df
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.h
3604df
@@ -242,7 +242,7 @@ glusterd_volinfo_bricks_delete (glusterd_volinfo_t *volinfo);
3604df
 
3604df
 int
3604df
 glusterd_new_brick_validate (char *brick, glusterd_brickinfo_t *brickinfo,
3604df
-                             char *op_errstr, size_t len);
3604df
+                             char *op_errstr, size_t len, char *op);
3604df
 int32_t
3604df
 glusterd_volume_brickinfos_delete (glusterd_volinfo_t *volinfo);
3604df
 
3604df
@@ -741,4 +741,36 @@ assign_brick_groups (glusterd_volinfo_t *volinfo);
3604df
 glusterd_brickinfo_t*
3604df
 get_last_brick_of_brick_group (glusterd_volinfo_t *volinfo,
3604df
                                glusterd_brickinfo_t *brickinfo);
3604df
+int
3604df
+glusterd_get_rb_dst_brickinfo (glusterd_volinfo_t *volinfo,
3604df
+                               glusterd_brickinfo_t **brickinfo);
3604df
+int
3604df
+rb_update_dstbrick_port (glusterd_brickinfo_t *dst_brickinfo, dict_t *rsp_dict,
3604df
+                         dict_t *req_dict);
3604df
+int
3604df
+glusterd_op_perform_replace_brick (glusterd_volinfo_t  *volinfo,
3604df
+                                   char *old_brick, char *new_brick,
3604df
+                                   dict_t *dict);
3604df
+int32_t
3604df
+glusterd_brick_unlink_socket_file (glusterd_volinfo_t *volinfo,
3604df
+                                   glusterd_brickinfo_t *brickinfo);
3604df
+char *
3604df
+gd_rb_op_to_str (char *op);
3604df
+
3604df
+glusterd_op_t
3604df
+gd_cli_to_gd_op (char *cli_op);
3604df
+
3604df
+int
3604df
+glusterd_get_dst_brick_info (char **dst_brick, char *volname, char **op_errstr,
3604df
+                             glusterd_brickinfo_t **dst_brickinfo, char **host,
3604df
+                             dict_t *dict, char **dup_dstbrick);
3604df
+
3604df
+int
3604df
+glusterd_brick_op_prerequisites (dict_t *dict,
3604df
+                                 char **op,
3604df
+                                 glusterd_op_t *gd_op, char **volname,
3604df
+                                 glusterd_volinfo_t **volinfo,
3604df
+                                 char **src_brick, glusterd_brickinfo_t
3604df
+                                 **src_brickinfo, char *pidfile,
3604df
+                                 char **op_errstr, dict_t *rsp_dict);
3604df
 #endif
3604df
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
3604df
index 2b1c50a..204ea3f 100644
3604df
--- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
3604df
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
3604df
@@ -1253,7 +1253,7 @@ glusterd_op_stage_create_volume (dict_t *dict, char **op_errstr,
3604df
                         goto out;
3604df
 
3604df
                 ret = glusterd_new_brick_validate (brick, brick_info, msg,
3604df
-                                                   sizeof (msg));
3604df
+                                                   sizeof (msg), NULL);
3604df
                 if (ret)
3604df
                         goto out;
3604df
 
3604df
diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c
3604df
index 7d39637..498672b 100644
3604df
--- a/xlators/mgmt/glusterd/src/glusterd.c
3604df
+++ b/xlators/mgmt/glusterd/src/glusterd.c
3604df
@@ -123,6 +123,7 @@ const char *gd_op_list[GD_OP_MAX + 1] = {
3604df
         [GD_OP_SYS_EXEC]                = "Execute system commands",
3604df
         [GD_OP_GSYNC_CREATE]            = "Geo-replication Create",
3604df
         [GD_OP_SNAP]                    = "Snapshot",
3604df
+        [GD_OP_RESET_BRICK]             = "Reset Brick",
3604df
         [GD_OP_MAX]                     = "Invalid op"
3604df
 };
3604df
 
3604df
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
3604df
index 7ca589c..8013c58 100644
3604df
--- a/xlators/mgmt/glusterd/src/glusterd.h
3604df
+++ b/xlators/mgmt/glusterd/src/glusterd.h
3604df
@@ -119,6 +119,7 @@ typedef enum glusterd_op_ {
3604df
         GD_OP_TIER_MIGRATE,
3604df
         GD_OP_SCRUB_STATUS,
3604df
         GD_OP_SCRUB_ONDEMAND,
3604df
+        GD_OP_RESET_BRICK,
3604df
         GD_OP_MAX,
3604df
 } glusterd_op_t;
3604df
 
3604df
@@ -950,6 +951,9 @@ int
3604df
 glusterd_handle_fsm_log (rpcsvc_request_t *req);
3604df
 
3604df
 int
3604df
+glusterd_handle_reset_brick (rpcsvc_request_t *req);
3604df
+
3604df
+int
3604df
 glusterd_xfer_cli_deprobe_resp (rpcsvc_request_t *req, int32_t op_ret,
3604df
                                 int32_t op_errno, char *op_errstr,
3604df
                                 char *hostname, dict_t *dict);
3604df
@@ -1192,4 +1196,6 @@ int
3604df
 glusterd_remove_brick_migrate_cbk (glusterd_volinfo_t *volinfo,
3604df
                                    gf_defrag_status_t status);
3604df
 
3604df
+int
3604df
+__glusterd_handle_reset_brick (rpcsvc_request_t *req);
3604df
 #endif
3604df
-- 
3604df
1.7.1
3604df