Blob Blame History Raw
From a07ff2945c3d7e80ff8a399439e27c7cfef41cda Mon Sep 17 00:00:00 2001
From: Anuradha Talur <atalur@redhat.com>
Date: Mon, 22 Aug 2016 13:22:03 -0400
Subject: [PATCH 58/86] glusterd : Introduce reset brick

The command basically allows replace brick with src and
dst bricks as same.

Usage:
gluster v reset-brick <volname> <hostname:brick-path> start
This command kills the brick to be reset. Once this command is run,
admin can do other manual operations that they need to do,
like configuring some options for the brick. Once this is done,
resetting the brick can be continued with the following options.

gluster v reset-brick <vname> <hostname:brick> <hostname:brick> commit {force}

Does the job of resetting the brick. 'force' option should be used
when the brick already contains volinfo id.

Problem: On doing a disk-replacement of a brick in a replicate volume
the following 2 scenarios may occur :

a) there is a chance that reads are served from this replaced-disk brick,
which leads to empty reads. b) potential data loss if next writes succeed
only on replaced brick, and heal is done to other bricks from this one.

Solution: After disk-replacement, make sure that reset-brick command is
run for that brick so that pending markers are set for the brick and it
is not chosen as source for reads and heal. But, as of now replace-brick
for the same brick-path is not allowed. In order to fix the above
mentioned problem, same brick-path replace-brick is needed.
With this patch reset-brick commit {force} will be allowed even when
source and destination <hostname:brickpath> are identical as long as
1) destination brick is not alive
2) source and destination brick have the same brick uuid and path.
Also, the destination brick after replace-brick will use the same port
as the source brick.

>Change-Id: I440b9e892ffb781ea4b8563688c3f85c7a7c89de
>BUG: 1266876
>Signed-off-by: Anuradha Talur <atalur@redhat.com>
>Reviewed-on: http://review.gluster.org/12250
>Smoke: Gluster Build System <jenkins@build.gluster.org>
>NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
>CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
>Reviewed-by: Ashish Pandey <aspandey@redhat.com>
>Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>

Change-Id: I440b9e892ffb781ea4b8563688c3f85c7a7c89de
BUG: 1256524
Signed-off-by: Ashish Pandey <aspandey@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/84804
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
---
 cli/src/cli-cmd-parser.c                           |  164 ++++++--
 cli/src/cli-cmd-volume.c                           |   61 +++
 cli/src/cli-rpc-ops.c                              |  224 ++++++++++-
 cli/src/cli-xml-output.c                           |    2 +-
 cli/src/cli.h                                      |    7 +-
 heal/src/glfs-heal.c                               |    2 +-
 rpc/rpc-lib/src/protocol-common.h                  |    1 +
 .../bug-1266876-allow-reset-brick-for-same-path.t  |   54 +++
 xlators/cluster/afr/src/afr-inode-write.c          |    4 +-
 xlators/mgmt/glusterd/src/Makefile.am              |    3 +-
 xlators/mgmt/glusterd/src/glusterd-brick-ops.c     |    2 +-
 xlators/mgmt/glusterd/src/glusterd-handler.c       |    1 +
 xlators/mgmt/glusterd/src/glusterd-hooks.c         |    1 +
 xlators/mgmt/glusterd/src/glusterd-messages.h      |   29 ++-
 xlators/mgmt/glusterd/src/glusterd-mgmt.c          |   33 ++
 xlators/mgmt/glusterd/src/glusterd-mgmt.h          |    6 +
 xlators/mgmt/glusterd/src/glusterd-op-sm.c         |    1 +
 xlators/mgmt/glusterd/src/glusterd-replace-brick.c |  350 ++++------------
 xlators/mgmt/glusterd/src/glusterd-reset-brick.c   |  430 ++++++++++++++++++++
 xlators/mgmt/glusterd/src/glusterd-rpc-ops.c       |    1 +
 xlators/mgmt/glusterd/src/glusterd-syncop.c        |    1 +
 xlators/mgmt/glusterd/src/glusterd-utils.c         |  327 +++++++++++++++-
 xlators/mgmt/glusterd/src/glusterd-utils.h         |   34 ++-
 xlators/mgmt/glusterd/src/glusterd-volume-ops.c    |    2 +-
 xlators/mgmt/glusterd/src/glusterd.c               |    1 +
 xlators/mgmt/glusterd/src/glusterd.h               |    6 +
 26 files changed, 1429 insertions(+), 318 deletions(-)
 create mode 100644 tests/bugs/replicate/bug-1266876-allow-reset-brick-for-same-path.t
 create mode 100644 xlators/mgmt/glusterd/src/glusterd-reset-brick.c

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