cb8e9e
From 9bcb02bdc78fdc960004cfef77062bd74b891acf Mon Sep 17 00:00:00 2001
cb8e9e
From: Anuradha <atalur@redhat.com>
cb8e9e
Date: Fri, 5 Jun 2015 16:46:39 +0530
cb8e9e
Subject: [PATCH 111/129] glusterd/ afr : set afr pending xattrs on replace brick
cb8e9e
cb8e9e
This patch is part one change to prevent data loss
cb8e9e
in a replicate volume on doing a replace-brick commit
cb8e9e
force operation.
cb8e9e
cb8e9e
Problem: After doing replace-brick commit force, there is a
cb8e9e
chance that self heal happens from the replaced (sink) brick
cb8e9e
rather than the source brick leading to data loss.
cb8e9e
cb8e9e
Solution: During the commit phase of replace brick, after old
cb8e9e
brick is brought down, create a temporary mount and perform
cb8e9e
setfattr operation (on virtual xattr) indicating AFR to mark
cb8e9e
the replaced brick as sink.
cb8e9e
cb8e9e
As a part of this change replace-brick command is being changed
cb8e9e
to use mgmt_v3 framework rather than op-state-machine framework.
cb8e9e
cb8e9e
Many thanks to Krishnan Parthasarathi for helping me out on this.
cb8e9e
cb8e9e
Upstream links:
cb8e9e
master : http://review.gluster.org/10076/
cb8e9e
3.7    : http://review.gluster.org/11253/
cb8e9e
cb8e9e
Change-Id: If0d51b5b3cef5b34d5672d46ea12eaa9d35fd894
cb8e9e
BUG: 1140649
cb8e9e
Signed-off-by: Anuradha Talur <atalur@redhat.com>
cb8e9e
Reviewed-on: https://code.engineering.redhat.com/gerrit/51017
cb8e9e
Reviewed-by: Ravishankar Narayanankutty <ravishankar@redhat.com>
cb8e9e
Tested-by: Ravishankar Narayanankutty <ravishankar@redhat.com>
cb8e9e
---
cb8e9e
 libglusterfs/src/glusterfs.h                       |    2 +
cb8e9e
 xlators/mgmt/glusterd/src/glusterd-mgmt.c          |   52 ++++
cb8e9e
 xlators/mgmt/glusterd/src/glusterd-mgmt.h          |   29 ++
cb8e9e
 xlators/mgmt/glusterd/src/glusterd-op-sm.c         |    2 +-
cb8e9e
 xlators/mgmt/glusterd/src/glusterd-op-sm.h         |    6 +-
cb8e9e
 xlators/mgmt/glusterd/src/glusterd-replace-brick.c |  298 ++++++++++++--------
cb8e9e
 xlators/mgmt/glusterd/src/glusterd.h               |    1 -
cb8e9e
 7 files changed, 272 insertions(+), 118 deletions(-)
cb8e9e
cb8e9e
diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h
cb8e9e
index 6f20185..c00bf55 100644
cb8e9e
--- a/libglusterfs/src/glusterfs.h
cb8e9e
+++ b/libglusterfs/src/glusterfs.h
cb8e9e
@@ -169,6 +169,8 @@
cb8e9e
 #define GF_AFR_SBRAIN_CHOICE "replica.split-brain-choice"
cb8e9e
 #define GF_AFR_SPB_CHOICE_TIMEOUT "replica.split-brain-choice-timeout"
cb8e9e
 #define GF_AFR_SBRAIN_RESOLVE "replica.split-brain-heal-finalize"
cb8e9e
+#define GF_AFR_REPLACE_BRICK "trusted.replace-brick"
cb8e9e
+#define GF_AFR_DIRTY "trusted.afr.dirty"
cb8e9e
 
cb8e9e
 #define GF_GFIDLESS_LOOKUP "gfidless-lookup"
cb8e9e
 /* replace-brick and pump related internal xattrs */
cb8e9e
diff --git a/xlators/mgmt/glusterd/src/glusterd-mgmt.c b/xlators/mgmt/glusterd/src/glusterd-mgmt.c
cb8e9e
index 41e6391..607d2c5 100644
cb8e9e
--- a/xlators/mgmt/glusterd/src/glusterd-mgmt.c
cb8e9e
+++ b/xlators/mgmt/glusterd/src/glusterd-mgmt.c
cb8e9e
@@ -169,6 +169,16 @@ gd_mgmt_v3_pre_validate_fn (glusterd_op_t op, dict_t *dict,
cb8e9e
 
cb8e9e
                 break;
cb8e9e
 
cb8e9e
+        case GD_OP_REPLACE_BRICK:
cb8e9e
+                ret = glusterd_op_stage_replace_brick (dict, op_errstr,
cb8e9e
+                                                       rsp_dict);
cb8e9e
+                if (ret) {
cb8e9e
+                        gf_log (this->name, GF_LOG_WARNING,
cb8e9e
+                                "Replace-brick prevalidation failed.");
cb8e9e
+                        goto out;
cb8e9e
+                }
cb8e9e
+                break;
cb8e9e
+
cb8e9e
         default:
cb8e9e
                 break;
cb8e9e
         }
cb8e9e
@@ -242,6 +252,17 @@ gd_mgmt_v3_commit_fn (glusterd_op_t op, dict_t *dict,
cb8e9e
                        }
cb8e9e
                        break;
cb8e9e
                }
cb8e9e
+                case GD_OP_REPLACE_BRICK:
cb8e9e
+                {
cb8e9e
+                        ret = glusterd_op_replace_brick (dict, rsp_dict);
cb8e9e
+                        if (ret) {
cb8e9e
+                                gf_msg (this->name, GF_LOG_ERROR, 0,
cb8e9e
+                                        GD_MSG_COMMIT_OP_FAIL,
cb8e9e
+                                        "Replace-brick commit failed.");
cb8e9e
+                                goto out;
cb8e9e
+                        }
cb8e9e
+                        break;
cb8e9e
+                }
cb8e9e
                default:
cb8e9e
                        break;
cb8e9e
         }
cb8e9e
@@ -527,6 +548,16 @@ glusterd_pre_validate_aggr_rsp_dict (glusterd_op_t op,
cb8e9e
                         goto out;
cb8e9e
                 }
cb8e9e
                 break;
cb8e9e
+        case GD_OP_REPLACE_BRICK:
cb8e9e
+                ret = glusterd_rb_use_rsp_dict (aggr, rsp);
cb8e9e
+                if (ret) {
cb8e9e
+                        gf_msg (this->name, GF_LOG_ERROR, 0,
cb8e9e
+                                GD_MSG_PRE_VALIDATION_FAIL,
cb8e9e
+                                "Failed to aggregate prevalidate "
cb8e9e
+                                "response dictionaries.");
cb8e9e
+                        goto out;
cb8e9e
+                }
cb8e9e
+                break;
cb8e9e
         default:
cb8e9e
                 ret = -1;
cb8e9e
                 gf_msg (this->name, GF_LOG_ERROR, EINVAL,
cb8e9e
@@ -809,6 +840,7 @@ glusterd_mgmt_v3_build_payload (dict_t **req, char **op_errstr, dict_t *dict,
cb8e9e
         int32_t                 ret      = -1;
cb8e9e
         dict_t                 *req_dict = NULL;
cb8e9e
         xlator_t               *this     = NULL;
cb8e9e
+        char                   *volname  = NULL;
cb8e9e
 
cb8e9e
         this = THIS;
cb8e9e
         GF_ASSERT (this);
cb8e9e
@@ -824,6 +856,26 @@ glusterd_mgmt_v3_build_payload (dict_t **req, char **op_errstr, dict_t *dict,
cb8e9e
                 case GD_OP_SNAP:
cb8e9e
                         dict_copy (dict, req_dict);
cb8e9e
                         break;
cb8e9e
+                case GD_OP_REPLACE_BRICK:
cb8e9e
+                {
cb8e9e
+                        ret = dict_get_str (dict, "volname", &volname);
cb8e9e
+                        if (ret) {
cb8e9e
+                                gf_log (this->name, GF_LOG_CRITICAL,
cb8e9e
+                                        "volname is not present in "
cb8e9e
+                                        "operation ctx");
cb8e9e
+                                goto out;
cb8e9e
+                        }
cb8e9e
+
cb8e9e
+                        if (strcasecmp (volname, "all")) {
cb8e9e
+                                ret = glusterd_dict_set_volid (dict,
cb8e9e
+                                                               volname,
cb8e9e
+                                                             op_errstr);
cb8e9e
+                                if (ret)
cb8e9e
+                                        goto out;
cb8e9e
+                        }
cb8e9e
+                        dict_copy (dict, req_dict);
cb8e9e
+                }
cb8e9e
+                        break;
cb8e9e
                 default:
cb8e9e
                         break;
cb8e9e
         }
cb8e9e
diff --git a/xlators/mgmt/glusterd/src/glusterd-mgmt.h b/xlators/mgmt/glusterd/src/glusterd-mgmt.h
cb8e9e
index a9812a4..b49137f 100644
cb8e9e
--- a/xlators/mgmt/glusterd/src/glusterd-mgmt.h
cb8e9e
+++ b/xlators/mgmt/glusterd/src/glusterd-mgmt.h
cb8e9e
@@ -50,4 +50,33 @@ glusterd_snap_pre_validate_use_rsp_dict (dict_t *dst, dict_t *src);
cb8e9e
 
cb8e9e
 int32_t
cb8e9e
 glusterd_set_barrier_value (dict_t *dict, char *option);
cb8e9e
+int
cb8e9e
+
cb8e9e
+glusterd_mgmt_v3_initiate_lockdown (glusterd_op_t op, dict_t *dict,
cb8e9e
+                                    char **op_errstr, uint32_t *op_errno,
cb8e9e
+                                    gf_boolean_t  *is_acquired,
cb8e9e
+                                    uint32_t txn_generation);
cb8e9e
+
cb8e9e
+int
cb8e9e
+glusterd_mgmt_v3_build_payload (dict_t **req, char **op_errstr, dict_t *dict,
cb8e9e
+                                glusterd_op_t op);
cb8e9e
+
cb8e9e
+int
cb8e9e
+glusterd_mgmt_v3_pre_validate (glusterd_op_t op, dict_t *req_dict,
cb8e9e
+                               char **op_errstr, uint32_t *op_errno,
cb8e9e
+                               uint32_t txn_generation);
cb8e9e
+
cb8e9e
+int
cb8e9e
+glusterd_mgmt_v3_commit (glusterd_op_t op, dict_t *op_ctx, dict_t *req_dict,
cb8e9e
+                         char **op_errstr, uint32_t *op_errno,
cb8e9e
+                         uint32_t txn_generation);
cb8e9e
+
cb8e9e
+int
cb8e9e
+glusterd_mgmt_v3_release_peer_locks (glusterd_op_t op, dict_t *dict,
cb8e9e
+                                     int32_t op_ret, char **op_errstr,
cb8e9e
+                                     gf_boolean_t  is_acquired,
cb8e9e
+                                     uint32_t txn_generation);
cb8e9e
+
cb8e9e
+int32_t
cb8e9e
+glusterd_multiple_mgmt_v3_unlock (dict_t *dict, uuid_t uuid);
cb8e9e
 #endif /* _GLUSTERD_MGMT_H_ */
cb8e9e
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
cb8e9e
index 8fca680..8e5c4bb 100644
cb8e9e
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c
cb8e9e
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
cb8e9e
@@ -3665,7 +3665,7 @@ out:
cb8e9e
         return ret;
cb8e9e
 }
cb8e9e
 
cb8e9e
-static int
cb8e9e
+int
cb8e9e
 glusterd_dict_set_volid (dict_t *dict, char *volname, char **op_errstr)
cb8e9e
 {
cb8e9e
         int                     ret = -1;
cb8e9e
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.h b/xlators/mgmt/glusterd/src/glusterd-op-sm.h
cb8e9e
index 368bb04..1b64419 100644
cb8e9e
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.h
cb8e9e
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.h
cb8e9e
@@ -234,9 +234,6 @@ glusterd_check_option_exists(char *optstring, char **completion);
cb8e9e
 int
cb8e9e
 set_xlator_option (dict_t *dict, char *key, char *value);
cb8e9e
 
cb8e9e
-void
cb8e9e
-glusterd_do_replace_brick (void *data);
cb8e9e
-
cb8e9e
 char*
cb8e9e
 glusterd_op_sm_state_name_get (int state);
cb8e9e
 
cb8e9e
@@ -298,4 +295,7 @@ glusterd_generate_txn_id (dict_t *dict, uuid_t **txn_id);
cb8e9e
 
cb8e9e
 void
cb8e9e
 glusterd_set_opinfo (char *errstr, int32_t op_errno, int32_t op_ret);
cb8e9e
+
cb8e9e
+int
cb8e9e
+glusterd_dict_set_volid (dict_t *dict, char *volname, char **op_errstr);
cb8e9e
 #endif
cb8e9e
diff --git a/xlators/mgmt/glusterd/src/glusterd-replace-brick.c b/xlators/mgmt/glusterd/src/glusterd-replace-brick.c
cb8e9e
index db9b36c..b063284 100644
cb8e9e
--- a/xlators/mgmt/glusterd/src/glusterd-replace-brick.c
cb8e9e
+++ b/xlators/mgmt/glusterd/src/glusterd-replace-brick.c
cb8e9e
@@ -26,6 +26,7 @@
cb8e9e
 #include "glusterd-nfs-svc.h"
cb8e9e
 #include "glusterd-volgen.h"
cb8e9e
 #include "glusterd-messages.h"
cb8e9e
+#include "glusterd-mgmt.h"
cb8e9e
 #include "run.h"
cb8e9e
 #include "syscall.h"
cb8e9e
 
cb8e9e
@@ -39,6 +40,79 @@
cb8e9e
 extern uuid_t global_txn_id;
cb8e9e
 
cb8e9e
 int
cb8e9e
+glusterd_mgmt_v3_initiate_replace_brick_cmd_phases (rpcsvc_request_t *req,
cb8e9e
+                                                    glusterd_op_t op,
cb8e9e
+                                                    dict_t *dict);
cb8e9e
+int
cb8e9e
+glusterd_handle_replicate_replace_brick (glusterd_volinfo_t *volinfo,
cb8e9e
+                                         glusterd_brickinfo_t *brickinfo)
cb8e9e
+{
cb8e9e
+        int32_t                    ret               = -1;
cb8e9e
+        char                       tmpmount[]        = "/tmp/mntXXXXXX";
cb8e9e
+        char                       logfile[PATH_MAX] = {0,};
cb8e9e
+        int                        dirty[3]          = {0,};
cb8e9e
+        runner_t                   runner            = {0};
cb8e9e
+        glusterd_conf_t           *priv              = NULL;
cb8e9e
+        char                      *pid               = NULL;
cb8e9e
+
cb8e9e
+        priv = THIS->private;
cb8e9e
+
cb8e9e
+        dirty[2] = hton32(1);
cb8e9e
+
cb8e9e
+        ret = sys_lsetxattr (brickinfo->path, GF_AFR_DIRTY, dirty,
cb8e9e
+                             sizeof (dirty), 0);
cb8e9e
+        if (ret == -1) {
cb8e9e
+                gf_log (THIS->name, GF_LOG_ERROR, "Failed to set extended"
cb8e9e
+                        " attribute %s : %s.", GF_AFR_DIRTY, strerror (errno));
cb8e9e
+                goto out;
cb8e9e
+        }
cb8e9e
+
cb8e9e
+        if (mkdtemp (tmpmount) == NULL) {
cb8e9e
+                gf_log (THIS->name, GF_LOG_ERROR,
cb8e9e
+                        "failed to create a temporary mount directory.");
cb8e9e
+                ret = -1;
cb8e9e
+                goto out;
cb8e9e
+        }
cb8e9e
+        snprintf (logfile, sizeof (logfile),
cb8e9e
+                  DEFAULT_LOG_FILE_DIRECTORY"/%s-replace-brick-mount.log",
cb8e9e
+                  volinfo->volname);
cb8e9e
+
cb8e9e
+        ret = gf_asprintf (&pid, "%d", GF_CLIENT_PID_AFR_SELF_HEALD);
cb8e9e
+        if (ret < 0)
cb8e9e
+                goto out;
cb8e9e
+
cb8e9e
+        runinit (&runner);
cb8e9e
+        runner_add_args (&runner, SBIN_DIR"/glusterfs",
cb8e9e
+                         "-s", "localhost",
cb8e9e
+                         "--volfile-id", volinfo->volname,
cb8e9e
+                         "--client-pid", pid,
cb8e9e
+                         "-l", logfile, tmpmount, NULL);
cb8e9e
+        synclock_unlock (&priv->big_lock);
cb8e9e
+        ret = runner_run (&runner);
cb8e9e
+
cb8e9e
+        if (ret) {
cb8e9e
+                runner_log (&runner, THIS->name, GF_LOG_ERROR, "mount command"
cb8e9e
+                            "failed.");
cb8e9e
+                goto lock;
cb8e9e
+        }
cb8e9e
+        ret = sys_lsetxattr (tmpmount, GF_AFR_REPLACE_BRICK,
cb8e9e
+                             brickinfo->brick_id, sizeof (brickinfo->brick_id),
cb8e9e
+                             0);
cb8e9e
+        if (ret == -1)
cb8e9e
+                gf_log (THIS->name, GF_LOG_ERROR, "Failed to set extended"
cb8e9e
+                        " attribute %s : %s", GF_AFR_REPLACE_BRICK,
cb8e9e
+                        strerror (errno));
cb8e9e
+        gf_umount_lazy (THIS->name, tmpmount, 1);
cb8e9e
+lock:
cb8e9e
+        synclock_lock (&priv->big_lock);
cb8e9e
+out:
cb8e9e
+        if (pid)
cb8e9e
+                GF_FREE (pid);
cb8e9e
+        gf_log ("", GF_LOG_DEBUG, "Returning with ret");
cb8e9e
+        return ret;
cb8e9e
+}
cb8e9e
+
cb8e9e
+int
cb8e9e
 __glusterd_handle_replace_brick (rpcsvc_request_t *req)
cb8e9e
 {
cb8e9e
         int32_t                         ret = -1;
cb8e9e
@@ -126,22 +200,12 @@ __glusterd_handle_replace_brick (rpcsvc_request_t *req)
cb8e9e
         gf_log (this->name, GF_LOG_INFO, "Received replace brick commit-force "
cb8e9e
                 "request operation");
cb8e9e
 
cb8e9e
-        ret = glusterd_op_begin (req, GD_OP_REPLACE_BRICK, dict,
cb8e9e
-                                 msg, sizeof (msg));
cb8e9e
+        ret = glusterd_mgmt_v3_initiate_replace_brick_cmd_phases (req,
cb8e9e
+                                            GD_OP_REPLACE_BRICK, dict);
cb8e9e
 
cb8e9e
 out:
cb8e9e
         free (cli_req.dict.dict_val);//malloced by xdr
cb8e9e
 
cb8e9e
-        glusterd_friend_sm ();
cb8e9e
-        glusterd_op_sm ();
cb8e9e
-
cb8e9e
-        if (ret) {
cb8e9e
-                if (msg[0] == '\0')
cb8e9e
-                        snprintf (msg, sizeof (msg), "Operation failed");
cb8e9e
-                ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
cb8e9e
-                                                     dict, msg);
cb8e9e
-        }
cb8e9e
-
cb8e9e
         return ret;
cb8e9e
 }
cb8e9e
 
cb8e9e
@@ -188,7 +252,6 @@ glusterd_op_stage_replace_brick (dict_t *dict, char **op_errstr,
cb8e9e
         glusterd_peerinfo_t                     *peerinfo           = NULL;
cb8e9e
         glusterd_brickinfo_t                    *dst_brickinfo      = NULL;
cb8e9e
         gf_boolean_t                             enabled            = _gf_false;
cb8e9e
-        dict_t                                  *ctx                = NULL;
cb8e9e
         glusterd_conf_t                         *priv               = NULL;
cb8e9e
         char                                    *savetok            = NULL;
cb8e9e
         char                                     pidfile[PATH_MAX]  = {0};
cb8e9e
@@ -292,8 +355,6 @@ glusterd_op_stage_replace_brick (dict_t *dict, char **op_errstr,
cb8e9e
                 goto out;
cb8e9e
         }
cb8e9e
 
cb8e9e
-        ctx = glusterd_op_get_ctx();
cb8e9e
-
cb8e9e
         if (!strcmp(replace_op, "GF_REPLACE_OP_COMMIT_FORCE")) {
cb8e9e
                 is_force = _gf_true;
cb8e9e
         } else {
cb8e9e
@@ -310,7 +371,7 @@ glusterd_op_stage_replace_brick (dict_t *dict, char **op_errstr,
cb8e9e
                 goto out;
cb8e9e
         }
cb8e9e
 
cb8e9e
-        if (ctx) {
cb8e9e
+        if (dict) {
cb8e9e
                 if (!glusterd_is_fuse_available ()) {
cb8e9e
                         gf_msg (this->name, GF_LOG_ERROR, 0,
cb8e9e
                                 GD_MSG_RB_CMD_FAIL, "Unable to open /dev/"
cb8e9e
@@ -493,7 +554,6 @@ rb_update_srcbrick_port (glusterd_volinfo_t *volinfo,
cb8e9e
                          dict_t *rsp_dict, dict_t *req_dict, char *replace_op)
cb8e9e
 {
cb8e9e
         xlator_t *this                  = NULL;
cb8e9e
-        dict_t   *ctx                   = NULL;
cb8e9e
         int       ret                   = 0;
cb8e9e
         int       dict_ret              = 0;
cb8e9e
         int       src_port              = 0;
cb8e9e
@@ -536,9 +596,8 @@ rb_update_srcbrick_port (glusterd_volinfo_t *volinfo,
cb8e9e
                         }
cb8e9e
                 }
cb8e9e
 
cb8e9e
-                ctx = glusterd_op_get_ctx ();
cb8e9e
-                if (ctx) {
cb8e9e
-                        ret = dict_set_int32 (ctx, "src-brick-port",
cb8e9e
+                if (req_dict) {
cb8e9e
+                        ret = dict_set_int32 (req_dict, "src-brick-port",
cb8e9e
                                               src_brickinfo->port);
cb8e9e
                         if (ret) {
cb8e9e
                                 gf_log (this->name, GF_LOG_DEBUG,
cb8e9e
@@ -558,7 +617,6 @@ static int
cb8e9e
 rb_update_dstbrick_port (glusterd_brickinfo_t *dst_brickinfo, dict_t *rsp_dict,
cb8e9e
                          dict_t *req_dict, char *replace_op)
cb8e9e
 {
cb8e9e
-        dict_t *ctx           = NULL;
cb8e9e
         int     ret           = 0;
cb8e9e
         int     dict_ret      = 0;
cb8e9e
         int     dst_port      = 0;
cb8e9e
@@ -581,9 +639,8 @@ rb_update_dstbrick_port (glusterd_brickinfo_t *dst_brickinfo, dict_t *rsp_dict,
cb8e9e
                         }
cb8e9e
                 }
cb8e9e
 
cb8e9e
-                ctx = glusterd_op_get_ctx ();
cb8e9e
-                if (ctx) {
cb8e9e
-                        ret = dict_set_int32 (ctx, "dst-brick-port",
cb8e9e
+                if (req_dict) {
cb8e9e
+                        ret = dict_set_int32 (req_dict, "dst-brick-port",
cb8e9e
                                               dst_brickinfo->port);
cb8e9e
                         if (ret) {
cb8e9e
                                 gf_log ("", GF_LOG_DEBUG,
cb8e9e
@@ -658,6 +715,16 @@ glusterd_op_perform_replace_brick (glusterd_volinfo_t  *volinfo,
cb8e9e
         if (ret)
cb8e9e
                 goto out;
cb8e9e
 
cb8e9e
+        /* if the volume is a replicate volume, do: */
cb8e9e
+        if (glusterd_is_volume_replicate (volinfo)) {
cb8e9e
+                if (!gf_uuid_compare (new_brickinfo->uuid, MY_UUID)) {
cb8e9e
+                        ret = glusterd_handle_replicate_replace_brick
cb8e9e
+                                  (volinfo, new_brickinfo);
cb8e9e
+                        if (ret < 0)
cb8e9e
+                                goto out;
cb8e9e
+                }
cb8e9e
+        }
cb8e9e
+
cb8e9e
         ret = glusterd_create_volfiles_and_notify_services (volinfo);
cb8e9e
         if (ret)
cb8e9e
                 goto out;
cb8e9e
@@ -764,17 +831,6 @@ glusterd_op_replace_brick (dict_t *dict, dict_t *rsp_dict)
cb8e9e
         if (ret)
cb8e9e
                 goto out;
cb8e9e
 
cb8e9e
-                /* Set task-id, if available, in op_ctx dict for*/
cb8e9e
-        if (is_origin_glusterd (dict)) {
cb8e9e
-                ctx = glusterd_op_get_ctx();
cb8e9e
-                if (!ctx) {
cb8e9e
-                        gf_msg (this->name, GF_LOG_ERROR, 0,
cb8e9e
-                                GD_MSG_OPCTX_GET_FAIL, "Failed to "
cb8e9e
-                                "get op_ctx");
cb8e9e
-                        ret = -1;
cb8e9e
-                        goto out;
cb8e9e
-                }
cb8e9e
-        }
cb8e9e
         ret = rb_update_dstbrick_port (dst_brickinfo, rsp_dict,
cb8e9e
                                        dict, replace_op);
cb8e9e
         if (ret)
cb8e9e
@@ -839,119 +895,135 @@ out:
cb8e9e
         return ret;
cb8e9e
 }
cb8e9e
 
cb8e9e
-void
cb8e9e
-glusterd_do_replace_brick (void *data)
cb8e9e
+int
cb8e9e
+glusterd_mgmt_v3_initiate_replace_brick_cmd_phases (rpcsvc_request_t *req,
cb8e9e
+                                                    glusterd_op_t op,
cb8e9e
+                                                    dict_t *dict)
cb8e9e
 {
cb8e9e
-        glusterd_volinfo_t     *volinfo = NULL;
cb8e9e
-        int32_t                 src_port = 0;
cb8e9e
-        int32_t                 dst_port = 0;
cb8e9e
-        int32_t                 ret      = 0;
cb8e9e
-        dict_t                 *dict    = NULL;
cb8e9e
-        char                   *src_brick = NULL;
cb8e9e
-        char                   *dst_brick = NULL;
cb8e9e
-        char                   *volname   = NULL;
cb8e9e
-        glusterd_brickinfo_t   *src_brickinfo = NULL;
cb8e9e
-        glusterd_brickinfo_t   *dst_brickinfo = NULL;
cb8e9e
-	glusterd_conf_t	       *priv = NULL;
cb8e9e
-        uuid_t                 *txn_id = NULL;
cb8e9e
-        xlator_t               *this = NULL;
cb8e9e
+        int32_t                     ret              = -1;
cb8e9e
+        int32_t                     op_ret           = -1;
cb8e9e
+        uint32_t                    txn_generation   = 0;
cb8e9e
+        uint32_t                    op_errno         = 0;
cb8e9e
+        char                        *cli_errstr      = NULL;
cb8e9e
+        char                        *op_errstr       = NULL;
cb8e9e
+        dict_t                      *req_dict        = NULL;
cb8e9e
+        dict_t                      *tmp_dict        = NULL;
cb8e9e
+        uuid_t                      *originator_uuid = NULL;
cb8e9e
+        xlator_t                    *this            = NULL;
cb8e9e
+        glusterd_conf_t             *conf            = NULL;
cb8e9e
+        gf_boolean_t                success          = _gf_false;
cb8e9e
+        gf_boolean_t                is_acquired      = _gf_false;
cb8e9e
 
cb8e9e
         this = THIS;
cb8e9e
-	GF_ASSERT (this);
cb8e9e
-	priv = this->private;
cb8e9e
-        GF_ASSERT (priv);
cb8e9e
-        GF_ASSERT (data);
cb8e9e
-
cb8e9e
-        txn_id = &priv->global_txn_id;
cb8e9e
-        dict = data;
cb8e9e
-
cb8e9e
-	if (priv->timer) {
cb8e9e
-		gf_timer_call_cancel (THIS->ctx, priv->timer);
cb8e9e
-		priv->timer = NULL;
cb8e9e
-                gf_msg_debug ("", 0,
cb8e9e
-                        "Cancelling timer thread");
cb8e9e
-	}
cb8e9e
-
cb8e9e
-        gf_msg_debug (this->name, 0,
cb8e9e
-                "Replace brick operation detected");
cb8e9e
-
cb8e9e
-        ret = dict_get_bin (dict, "transaction_id", (void **)&txn_id);
cb8e9e
-        gf_msg_debug (this->name, 0, "transaction ID = %s",
cb8e9e
-                uuid_utoa (*txn_id));
cb8e9e
+        GF_ASSERT (this);
cb8e9e
+        GF_ASSERT (req);
cb8e9e
+        GF_ASSERT (dict);
cb8e9e
+        conf = this->private;
cb8e9e
+        GF_ASSERT (conf);
cb8e9e
 
cb8e9e
-        ret = dict_get_str (dict, "src-brick", &src_brick);
cb8e9e
-        if (ret) {
cb8e9e
-                gf_msg ("", GF_LOG_ERROR, 0,
cb8e9e
-                        GD_MSG_DICT_GET_FAILED, "Unable to get src brick");
cb8e9e
+        txn_generation = conf->generation;
cb8e9e
+        originator_uuid = GF_CALLOC (1, sizeof(uuid_t),
cb8e9e
+                                     gf_common_mt_uuid_t);
cb8e9e
+        if (!originator_uuid) {
cb8e9e
+                ret = -1;
cb8e9e
                 goto out;
cb8e9e
         }
cb8e9e
 
cb8e9e
-        gf_msg_debug (this->name, 0,
cb8e9e
-                "src brick=%s", src_brick);
cb8e9e
-
cb8e9e
-        ret = dict_get_str (dict, "dst-brick", &dst_brick);
cb8e9e
+        gf_uuid_copy (*originator_uuid, MY_UUID);
cb8e9e
+        ret = dict_set_bin (dict, "originator_uuid",
cb8e9e
+                            originator_uuid, sizeof (uuid_t));
cb8e9e
         if (ret) {
cb8e9e
-                gf_msg ("", GF_LOG_ERROR, 0,
cb8e9e
-                        GD_MSG_DICT_GET_FAILED, "Unable to get dst brick");
cb8e9e
+                gf_msg (this->name, GF_LOG_ERROR, 0,
cb8e9e
+                        GD_MSG_DICT_SET_FAILED,
cb8e9e
+                        "Failed to set originator_uuid.");
cb8e9e
                 goto out;
cb8e9e
         }
cb8e9e
 
cb8e9e
-        gf_msg_debug (this->name, 0,
cb8e9e
-                "dst brick=%s", dst_brick);
cb8e9e
-
cb8e9e
-        ret = glusterd_volinfo_find (volname, &volinfo);
cb8e9e
+        ret = dict_set_int32 (dict, "is_synctasked", _gf_true);
cb8e9e
         if (ret) {
cb8e9e
-                gf_msg (this->name, GF_LOG_ERROR, EINVAL,
cb8e9e
-                        GD_MSG_VOLINFO_GET_FAIL, "Unable to find volinfo");
cb8e9e
+                gf_msg (this->name, GF_LOG_ERROR, 0,
cb8e9e
+                        GD_MSG_DICT_SET_FAILED,
cb8e9e
+                        "Failed to set synctasked flag to true.");
cb8e9e
                 goto out;
cb8e9e
         }
cb8e9e
 
cb8e9e
-        ret = glusterd_volume_brickinfo_get_by_brick (src_brick, volinfo,
cb8e9e
-                                                      &src_brickinfo);
cb8e9e
-        if (ret) {
cb8e9e
-                gf_msg_debug (this->name, 0, "Unable to get src-brickinfo");
cb8e9e
+        tmp_dict = dict_new();
cb8e9e
+        if (!tmp_dict) {
cb8e9e
+                gf_msg (this->name, GF_LOG_ERROR, 0,
cb8e9e
+                        GD_MSG_DICT_CREATE_FAIL, "Unable to create dict");
cb8e9e
                 goto out;
cb8e9e
         }
cb8e9e
+        dict_copy (dict, tmp_dict);
cb8e9e
 
cb8e9e
-        ret = glusterd_get_rb_dst_brickinfo (volinfo, &dst_brickinfo);
cb8e9e
-        if (!dst_brickinfo) {
cb8e9e
-                gf_msg_debug (this->name, 0, "Unable to get dst-brickinfo");
cb8e9e
+        ret = glusterd_mgmt_v3_initiate_lockdown (op, dict, &op_errstr,
cb8e9e
+                                                  &op_errno, &is_acquired,
cb8e9e
+                                                  txn_generation);
cb8e9e
+        if (ret) {
cb8e9e
+                gf_msg (this->name, GF_LOG_ERROR, 0,
cb8e9e
+                        GD_MSG_MGMTV3_LOCKDOWN_FAIL,
cb8e9e
+                        "mgmt_v3 lockdown failed.");
cb8e9e
                 goto out;
cb8e9e
         }
cb8e9e
 
cb8e9e
-        ret = glusterd_resolve_brick (dst_brickinfo);
cb8e9e
+        ret = glusterd_mgmt_v3_build_payload (&req_dict, &op_errstr, dict, op);
cb8e9e
         if (ret) {
cb8e9e
-                gf_msg_debug (this->name, 0, "Unable to resolve dst-brickinfo");
cb8e9e
+                gf_msg (this->name, GF_LOG_ERROR, 0,
cb8e9e
+                        GD_MSG_MGMTV3_PAYLOAD_BUILD_FAIL, LOGSTR_BUILD_PAYLOAD,
cb8e9e
+                        gd_op_list[op]);
cb8e9e
+                if (op_errstr == NULL)
cb8e9e
+                        gf_asprintf (&op_errstr, OPERRSTR_BUILD_PAYLOAD);
cb8e9e
                 goto out;
cb8e9e
         }
cb8e9e
 
cb8e9e
-        ret = dict_get_int32 (dict, "src-brick-port", &src_port);
cb8e9e
+        ret = glusterd_mgmt_v3_pre_validate (op, req_dict, &op_errstr,
cb8e9e
+                                             &op_errno, txn_generation);
cb8e9e
         if (ret) {
cb8e9e
                 gf_msg (this->name, GF_LOG_ERROR, 0,
cb8e9e
-                        GD_MSG_DICT_GET_FAILED, "Unable to get src-brick port");
cb8e9e
+                        GD_MSG_PRE_VALIDATION_FAIL, "Pre Validation Failed");
cb8e9e
                 goto out;
cb8e9e
         }
cb8e9e
 
cb8e9e
-        ret = dict_get_int32 (dict, "dst-brick-port", &dst_port);
cb8e9e
+        ret = glusterd_mgmt_v3_commit (op, dict, req_dict, &op_errstr,
cb8e9e
+                                       &op_errno, txn_generation);
cb8e9e
         if (ret) {
cb8e9e
-                gf_msg (this->name, GF_LOG_ERROR, errno,
cb8e9e
-                        GD_MSG_DICT_GET_FAILED, "Unable to get dst-brick port");
cb8e9e
+                gf_msg (this->name, GF_LOG_ERROR, 0,
cb8e9e
+                        GD_MSG_COMMIT_OP_FAIL, "Commit Op Failed");
cb8e9e
+                goto out;
cb8e9e
         }
cb8e9e
 
cb8e9e
-        dst_brickinfo->port = dst_port;
cb8e9e
-        src_brickinfo->port = src_port;
cb8e9e
+        ret = 0;
cb8e9e
 
cb8e9e
 out:
cb8e9e
-        if (ret)
cb8e9e
-                ret = glusterd_op_sm_inject_event (GD_OP_EVENT_RCVD_RJT,
cb8e9e
-                                                   txn_id, NULL);
cb8e9e
-        else
cb8e9e
-                ret = glusterd_op_sm_inject_event (GD_OP_EVENT_COMMIT_ACC,
cb8e9e
-                                                   txn_id, NULL);
cb8e9e
+        op_ret = ret;
cb8e9e
 
cb8e9e
-        synclock_lock (&priv->big_lock);
cb8e9e
-        {
cb8e9e
-                glusterd_op_sm ();
cb8e9e
+        (void) glusterd_mgmt_v3_release_peer_locks (op, dict, op_ret,
cb8e9e
+                                                    &op_errstr, is_acquired,
cb8e9e
+                                                    txn_generation);
cb8e9e
+
cb8e9e
+        if (is_acquired) {
cb8e9e
+                ret = glusterd_multiple_mgmt_v3_unlock (tmp_dict, MY_UUID);
cb8e9e
+                if (ret) {
cb8e9e
+                        gf_msg (this->name, GF_LOG_ERROR, 0,
cb8e9e
+                                GD_MSG_MGMTV3_UNLOCK_FAIL,
cb8e9e
+                                "Failed to release mgmt_v3 locks on "
cb8e9e
+                                "localhost.");
cb8e9e
+                        op_ret = ret;
cb8e9e
+                }
cb8e9e
         }
cb8e9e
-        synclock_unlock (&priv->big_lock);
cb8e9e
+        /* SEND CLI RESPONSE */
cb8e9e
+        glusterd_op_send_cli_response (op, op_ret, op_errno, req,
cb8e9e
+                                       dict, op_errstr);
cb8e9e
+
cb8e9e
+        if (req_dict)
cb8e9e
+                dict_unref (req_dict);
cb8e9e
+
cb8e9e
+        if (tmp_dict)
cb8e9e
+                dict_unref (tmp_dict);
cb8e9e
+
cb8e9e
+        if (op_errstr) {
cb8e9e
+                GF_FREE (op_errstr);
cb8e9e
+                op_errstr = NULL;
cb8e9e
+        }
cb8e9e
+
cb8e9e
+        return 0;
cb8e9e
 }
cb8e9e
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
cb8e9e
index 59234bc..cfe7a7b 100644
cb8e9e
--- a/xlators/mgmt/glusterd/src/glusterd.h
cb8e9e
+++ b/xlators/mgmt/glusterd/src/glusterd.h
cb8e9e
@@ -1044,7 +1044,6 @@ int glusterd_op_stage_barrier (dict_t *dict, char **op_errstr);
cb8e9e
 int glusterd_op_barrier (dict_t *dict, char **op_errstr);
cb8e9e
 
cb8e9e
 /* misc */
cb8e9e
-void glusterd_do_replace_brick (void *data);
cb8e9e
 int glusterd_op_perform_remove_brick (glusterd_volinfo_t  *volinfo, char *brick,
cb8e9e
                                       int force, int *need_migrate);
cb8e9e
 int glusterd_op_stop_volume_args_get (dict_t *dict, char** volname, int *flags);
cb8e9e
-- 
cb8e9e
1.7.1
cb8e9e