e7a346
From 783c36e573a9c937422e63af038bb35648483b9e Mon Sep 17 00:00:00 2001
e7a346
From: Sanju Rakonde <srakonde@redhat.com>
e7a346
Date: Fri, 30 Nov 2018 16:16:55 +0530
e7a346
Subject: [PATCH 490/493] glusterd: migrating rebalance commands to mgmt_v3
e7a346
 framework
e7a346
e7a346
Current rebalance commands use the op_state machine framework.
e7a346
Porting it to use the mgmt_v3 framework.
e7a346
e7a346
> Change-Id: I6faf4a6335c2e2f3d54bbde79908a7749e4613e7
e7a346
> fixes: bz#1655827
e7a346
> Signed-off-by: Sanju Rakonde <srakonde@redhat.com>
e7a346
e7a346
upstream patch: https://review.gluster.org/#/c/glusterfs/+/21762/
e7a346
e7a346
Change-Id: I6faf4a6335c2e2f3d54bbde79908a7749e4613e7
e7a346
BUG: 1652466
e7a346
Signed-off-by: Sanju Rakonde <srakonde@redhat.com>
e7a346
Reviewed-on: https://code.engineering.redhat.com/gerrit/158917
e7a346
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
e7a346
Tested-by: RHGS Build Bot <nigelb@redhat.com>
e7a346
---
e7a346
 libglusterfs/src/globals.h                     |   2 +
e7a346
 xlators/mgmt/glusterd/src/glusterd-handler.c   |   4 +-
e7a346
 xlators/mgmt/glusterd/src/glusterd-mgmt.c      | 128 ++++++-
e7a346
 xlators/mgmt/glusterd/src/glusterd-mgmt.h      |   5 +-
e7a346
 xlators/mgmt/glusterd/src/glusterd-op-sm.h     |   3 +
e7a346
 xlators/mgmt/glusterd/src/glusterd-rebalance.c | 495 ++++++++++++++++++++++++-
e7a346
 xlators/mgmt/glusterd/src/glusterd-syncop.c    |   9 +
e7a346
 xlators/mgmt/glusterd/src/glusterd-utils.c     |   4 +-
e7a346
 xlators/mgmt/glusterd/src/glusterd.h           |   9 +
e7a346
 9 files changed, 637 insertions(+), 22 deletions(-)
e7a346
e7a346
diff --git a/libglusterfs/src/globals.h b/libglusterfs/src/globals.h
e7a346
index 343263c..5e3b180 100644
e7a346
--- a/libglusterfs/src/globals.h
e7a346
+++ b/libglusterfs/src/globals.h
e7a346
@@ -111,6 +111,8 @@
e7a346
 
e7a346
 #define GD_OP_VERSION_3_13_3   31303 /* Op-version for GlusterFS 3.13.3 */
e7a346
 
e7a346
+#define GD_OP_VERSION_6_0      60000 /* Op-version for GlusterFS 6.0 */
e7a346
+
e7a346
 /* Downstream only change */
e7a346
 #define GD_OP_VERSION_3_11_2   31102 /* Op-version for RHGS 3.3.1-async */
e7a346
 #define GD_OP_VERSION_3_13_3   31303 /* Op-version for RHGS-3.4-Batch Update-1*/
e7a346
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
e7a346
index d40de89..d8e3335 100644
e7a346
--- a/xlators/mgmt/glusterd/src/glusterd-handler.c
e7a346
+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c
e7a346
@@ -3120,7 +3120,9 @@ __glusterd_handle_cli_profile_volume (rpcsvc_request_t *req)
e7a346
                 glusterd_friend_sm();
e7a346
                 glusterd_op_sm();
e7a346
         } else {
e7a346
-                ret = glusterd_mgmt_v3_initiate_profile_phases(req, cli_op, dict);
e7a346
+                ret = glusterd_mgmt_v3_initiate_all_phases_with_brickop_phase(req,
e7a346
+                                                                              cli_op,
e7a346
+                                                                              dict);
e7a346
         }
e7a346
 
e7a346
 out:
e7a346
diff --git a/xlators/mgmt/glusterd/src/glusterd-mgmt.c b/xlators/mgmt/glusterd/src/glusterd-mgmt.c
e7a346
index d98c6bc..ef8a2d9 100644
e7a346
--- a/xlators/mgmt/glusterd/src/glusterd-mgmt.c
e7a346
+++ b/xlators/mgmt/glusterd/src/glusterd-mgmt.c
e7a346
@@ -224,6 +224,16 @@ gd_mgmt_v3_pre_validate_fn (glusterd_op_t op, dict_t *dict,
e7a346
                 }
e7a346
                 break;
e7a346
 
e7a346
+        case GD_OP_REBALANCE:
e7a346
+        case GD_OP_DEFRAG_BRICK_VOLUME:
e7a346
+                ret = glusterd_mgmt_v3_op_stage_rebalance(dict, op_errstr);
e7a346
+                if (ret) {
e7a346
+                        gf_log(this->name, GF_LOG_WARNING,
e7a346
+                               "Rebalance Prevalidate Failed");
e7a346
+                        goto out;
e7a346
+                }
e7a346
+                break;
e7a346
+
e7a346
         case GD_OP_MAX_OPVERSION:
e7a346
                 ret = 0;
e7a346
                 break;
e7a346
@@ -264,6 +274,8 @@ gd_mgmt_v3_brick_op_fn (glusterd_op_t op, dict_t *dict,
e7a346
                 break;
e7a346
         }
e7a346
         case GD_OP_PROFILE_VOLUME:
e7a346
+        case GD_OP_REBALANCE:
e7a346
+        case GD_OP_DEFRAG_BRICK_VOLUME:
e7a346
         {
e7a346
                 ret = gd_brick_op_phase(op, rsp_dict, dict, op_errstr);
e7a346
                 if (ret) {
e7a346
@@ -438,6 +450,19 @@ gd_mgmt_v3_commit_fn (glusterd_op_t op, dict_t *dict,
e7a346
                         }
e7a346
                         break;
e7a346
                 }
e7a346
+                case GD_OP_REBALANCE:
e7a346
+                case GD_OP_DEFRAG_BRICK_VOLUME:
e7a346
+                {
e7a346
+                        ret = glusterd_mgmt_v3_op_rebalance(dict, op_errstr,
e7a346
+                                                            rsp_dict);
e7a346
+                        if (ret) {
e7a346
+                                gf_msg(this->name, GF_LOG_ERROR, 0,
e7a346
+                                       GD_MSG_COMMIT_OP_FAIL,
e7a346
+                                       "Rebalance Commit Failed");
e7a346
+                                goto out;
e7a346
+                        }
e7a346
+                        break;
e7a346
+                }
e7a346
 
e7a346
                default:
e7a346
                        break;
e7a346
@@ -880,6 +905,8 @@ glusterd_pre_validate_aggr_rsp_dict (glusterd_op_t op,
e7a346
         case GD_OP_TIER_START_STOP:
e7a346
         case GD_OP_REMOVE_TIER_BRICK:
e7a346
         case GD_OP_PROFILE_VOLUME:
e7a346
+        case GD_OP_DEFRAG_BRICK_VOLUME:
e7a346
+        case GD_OP_REBALANCE:
e7a346
                 break;
e7a346
         case GD_OP_MAX_OPVERSION:
e7a346
                 break;
e7a346
@@ -1197,6 +1224,7 @@ glusterd_mgmt_v3_build_payload (dict_t **req, char **op_errstr, dict_t *dict,
e7a346
                 break;
e7a346
         case GD_OP_START_VOLUME:
e7a346
         case GD_OP_ADD_BRICK:
e7a346
+        case GD_OP_DEFRAG_BRICK_VOLUME:
e7a346
         case GD_OP_REPLACE_BRICK:
e7a346
         case GD_OP_RESET_BRICK:
e7a346
         case GD_OP_ADD_TIER_BRICK:
e7a346
@@ -1221,6 +1249,30 @@ glusterd_mgmt_v3_build_payload (dict_t **req, char **op_errstr, dict_t *dict,
e7a346
                         dict_copy (dict, req_dict);
e7a346
                 }
e7a346
                         break;
e7a346
+
e7a346
+        case GD_OP_REBALANCE: {
e7a346
+                if (gd_set_commit_hash(dict) != 0) {
e7a346
+                        ret = -1;
e7a346
+                        goto out;
e7a346
+                }
e7a346
+                ret = dict_get_str (dict, "volname", &volname);
e7a346
+                if (ret) {
e7a346
+                        gf_msg(this->name, GF_LOG_CRITICAL, errno,
e7a346
+                               GD_MSG_DICT_GET_FAILED,
e7a346
+                               "volname is not present in "
e7a346
+                               "operation ctx");
e7a346
+                        goto out;
e7a346
+                }
e7a346
+
e7a346
+                if (strcasecmp(volname, "all")) {
e7a346
+                        ret = glusterd_dict_set_volid(dict, volname, op_errstr);
e7a346
+                        if (ret)
e7a346
+                                goto out;
e7a346
+                }
e7a346
+                dict_copy(dict, req_dict);
e7a346
+        }
e7a346
+                break;
e7a346
+
e7a346
         case GD_OP_TIER_START_STOP:
e7a346
         case GD_OP_REMOVE_TIER_BRICK:
e7a346
         case GD_OP_DETACH_TIER_STATUS:
e7a346
@@ -1247,6 +1299,7 @@ gd_mgmt_v3_brick_op_cbk_fn (struct rpc_req *req, struct iovec *iov,
e7a346
         call_frame_t               *frame         = NULL;
e7a346
         int32_t                     op_ret        = -1;
e7a346
         int32_t                     op_errno      = -1;
e7a346
+        dict_t                     *rsp_dict      = NULL;
e7a346
         xlator_t                   *this          = NULL;
e7a346
         uuid_t                     *peerid        = NULL;
e7a346
 
e7a346
@@ -1278,10 +1331,45 @@ gd_mgmt_v3_brick_op_cbk_fn (struct rpc_req *req, struct iovec *iov,
e7a346
         if (ret < 0)
e7a346
                 goto out;
e7a346
 
e7a346
+        if (rsp.dict.dict_len) {
e7a346
+                /* Unserialize the dictionary */
e7a346
+                rsp_dict  = dict_new ();
e7a346
+
e7a346
+                ret = dict_unserialize (rsp.dict.dict_val,
e7a346
+                                        rsp.dict.dict_len,
e7a346
+                                        &rsp_dict);
e7a346
+                if (ret < 0) {
e7a346
+                        free (rsp.dict.dict_val);
e7a346
+                        goto out;
e7a346
+                } else {
e7a346
+                        rsp_dict->extra_stdfree = rsp.dict.dict_val;
e7a346
+                }
e7a346
+        }
e7a346
+
e7a346
         gf_uuid_copy (args->uuid, rsp.uuid);
e7a346
+        pthread_mutex_lock (&args->lock_dict);
e7a346
+        {
e7a346
+                if (rsp.op == GD_OP_DEFRAG_BRICK_VOLUME)
e7a346
+                        ret = glusterd_syncop_aggr_rsp_dict (rsp.op, args->dict,
e7a346
+                                                             rsp_dict);
e7a346
+        }
e7a346
+        pthread_mutex_unlock (&args->lock_dict);
e7a346
 
e7a346
-        op_ret = rsp.op_ret;
e7a346
-        op_errno = rsp.op_errno;
e7a346
+        if (ret) {
e7a346
+                gf_msg (this->name, GF_LOG_ERROR, 0,
e7a346
+                        GD_MSG_RESP_AGGR_FAIL, "%s",
e7a346
+                        "Failed to aggregate response from "
e7a346
+                        " node/brick");
e7a346
+                if (!rsp.op_ret)
e7a346
+                        op_ret = ret;
e7a346
+                else {
e7a346
+                        op_ret = rsp.op_ret;
e7a346
+                        op_errno = rsp.op_errno;
e7a346
+                }
e7a346
+        } else {
e7a346
+                op_ret = rsp.op_ret;
e7a346
+                op_errno = rsp.op_errno;
e7a346
+        }
e7a346
 
e7a346
 out:
e7a346
         gd_mgmt_v3_collate_errors (args, op_ret, op_errno, rsp.op_errstr,
e7a346
@@ -1353,11 +1441,12 @@ out:
e7a346
 }
e7a346
 
e7a346
 int
e7a346
-glusterd_mgmt_v3_brick_op (glusterd_op_t op, dict_t *rsp_dict, dict_t *req_dict,
e7a346
+glusterd_mgmt_v3_brick_op (glusterd_op_t op, dict_t *op_ctx, dict_t *req_dict,
e7a346
                            char **op_errstr, uint32_t txn_generation)
e7a346
 {
e7a346
         int32_t              ret        = -1;
e7a346
         int32_t              peer_cnt   = 0;
e7a346
+        dict_t              *rsp_dict   = NULL;
e7a346
         glusterd_peerinfo_t *peerinfo   = NULL;
e7a346
         struct syncargs      args       = {0};
e7a346
         uuid_t               peer_uuid  = {0};
e7a346
@@ -1372,6 +1461,13 @@ glusterd_mgmt_v3_brick_op (glusterd_op_t op, dict_t *rsp_dict, dict_t *req_dict,
e7a346
         GF_ASSERT (req_dict);
e7a346
         GF_ASSERT (op_errstr);
e7a346
 
e7a346
+        rsp_dict = dict_new();
e7a346
+        if (!rsp_dict) {
e7a346
+                gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_CREATE_FAIL,
e7a346
+                       "Failed to create response dictionary");
e7a346
+                goto out;
e7a346
+        }
e7a346
+
e7a346
         /* Perform brick op on local node */
e7a346
         ret = gd_mgmt_v3_brick_op_fn (op, req_dict, op_errstr,
e7a346
                                      rsp_dict);
e7a346
@@ -1395,9 +1491,21 @@ glusterd_mgmt_v3_brick_op (glusterd_op_t op, dict_t *rsp_dict, dict_t *req_dict,
e7a346
                 }
e7a346
                 goto out;
e7a346
         }
e7a346
+        if (op == GD_OP_DEFRAG_BRICK_VOLUME || op == GD_OP_PROFILE_VOLUME) {
e7a346
+                ret = glusterd_syncop_aggr_rsp_dict(op, op_ctx, rsp_dict);
e7a346
+                if (ret) {
e7a346
+                        gf_log(this->name, GF_LOG_ERROR, "%s",
e7a346
+                               "Failed to aggregate response from "
e7a346
+                               " node/brick");
e7a346
+                        goto out;
e7a346
+                }
e7a346
+        }
e7a346
+
e7a346
+        dict_unref(rsp_dict);
e7a346
+        rsp_dict = NULL;
e7a346
 
e7a346
         /* Sending brick op req to other nodes in the cluster */
e7a346
-        gd_syncargs_init (&args, rsp_dict);
e7a346
+        gd_syncargs_init (&args, op_ctx);
e7a346
         synctask_barrier_init((&args));
e7a346
         peer_cnt = 0;
e7a346
 
e7a346
@@ -1616,6 +1724,13 @@ glusterd_mgmt_v3_commit (glusterd_op_t op, dict_t *op_ctx, dict_t *req_dict,
e7a346
         GF_ASSERT (op_errstr);
e7a346
         GF_VALIDATE_OR_GOTO (this->name, op_errno, out);
e7a346
 
e7a346
+        if (op == GD_OP_REBALANCE || op == GD_OP_DEFRAG_BRICK_VOLUME) {
e7a346
+                ret = glusterd_set_rebalance_id_in_rsp_dict(req_dict, op_ctx);
e7a346
+                if (ret) {
e7a346
+                        gf_log(this->name, GF_LOG_WARNING,
e7a346
+                               "Failed to set rebalance id in dict.");
e7a346
+                }
e7a346
+        }
e7a346
         rsp_dict = dict_new ();
e7a346
         if (!rsp_dict) {
e7a346
                 gf_msg (this->name, GF_LOG_ERROR, 0,
e7a346
@@ -2140,8 +2255,9 @@ out:
e7a346
 }
e7a346
 
e7a346
 int32_t
e7a346
-glusterd_mgmt_v3_initiate_profile_phases (rpcsvc_request_t *req,
e7a346
-                                          glusterd_op_t op, dict_t *dict)
e7a346
+glusterd_mgmt_v3_initiate_all_phases_with_brickop_phase (rpcsvc_request_t *req,
e7a346
+                                                         glusterd_op_t op,
e7a346
+                                                         dict_t *dict)
e7a346
 {
e7a346
         int32_t                     ret              = -1;
e7a346
         int32_t                     op_ret           = -1;
e7a346
diff --git a/xlators/mgmt/glusterd/src/glusterd-mgmt.h b/xlators/mgmt/glusterd/src/glusterd-mgmt.h
e7a346
index eff070d..ef0fe10 100644
e7a346
--- a/xlators/mgmt/glusterd/src/glusterd-mgmt.h
e7a346
+++ b/xlators/mgmt/glusterd/src/glusterd-mgmt.h
e7a346
@@ -37,8 +37,9 @@ glusterd_mgmt_v3_initiate_all_phases (rpcsvc_request_t *req, glusterd_op_t op,
e7a346
                                      dict_t *dict);
e7a346
 
e7a346
 int32_t
e7a346
-glusterd_mgmt_v3_initiate_profile_phases(rpcsvc_request_t *req,
e7a346
-                                         glusterd_op_t op, dict_t *dict);
e7a346
+glusterd_mgmt_v3_initiate_all_phases_with_brickop_phase(rpcsvc_request_t *req,
e7a346
+                                                        glusterd_op_t op,
e7a346
+                                                        dict_t *dict);
e7a346
 
e7a346
 int32_t
e7a346
 glusterd_mgmt_v3_initiate_snap_phases(rpcsvc_request_t *req, glusterd_op_t op,
e7a346
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.h b/xlators/mgmt/glusterd/src/glusterd-op-sm.h
e7a346
index e64d368..cf1e61c 100644
e7a346
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.h
e7a346
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.h
e7a346
@@ -318,4 +318,7 @@ glusterd_op_stats_volume (dict_t *dict, char **op_errstr, dict_t *rsp_dict);
e7a346
 
e7a346
 int
e7a346
 glusterd_op_stage_stats_volume (dict_t *dict, char **op_errstr);
e7a346
+
e7a346
+int
e7a346
+gd_set_commit_hash(dict_t *dict);
e7a346
 #endif
e7a346
diff --git a/xlators/mgmt/glusterd/src/glusterd-rebalance.c b/xlators/mgmt/glusterd/src/glusterd-rebalance.c
e7a346
index 5ab828c..7ba5f65 100644
e7a346
--- a/xlators/mgmt/glusterd/src/glusterd-rebalance.c
e7a346
+++ b/xlators/mgmt/glusterd/src/glusterd-rebalance.c
e7a346
@@ -23,6 +23,7 @@
e7a346
 #include "glusterd.h"
e7a346
 #include "glusterd-sm.h"
e7a346
 #include "glusterd-op-sm.h"
e7a346
+#include "glusterd-mgmt.h"
e7a346
 #include "glusterd-utils.h"
e7a346
 #include "glusterd-messages.h"
e7a346
 #include "glusterd-store.h"
e7a346
@@ -501,6 +502,7 @@ __glusterd_handle_defrag_volume (rpcsvc_request_t *req)
e7a346
         int32_t                 ret       = -1;
e7a346
         gf_cli_req              cli_req   = {{0,}};
e7a346
         glusterd_conf_t        *priv      = NULL;
e7a346
+        int32_t                 op        = GD_OP_NONE;
e7a346
         dict_t                 *dict      = NULL;
e7a346
         char                   *volname   = NULL;
e7a346
         gf_cli_defrag_type      cmd       = 0;
e7a346
@@ -563,17 +565,25 @@ __glusterd_handle_defrag_volume (rpcsvc_request_t *req)
e7a346
             (cmd == GF_DEFRAG_CMD_STOP_DETACH_TIER) ||
e7a346
             (cmd == GF_DEFRAG_CMD_STOP) ||
e7a346
             (cmd == GF_DEFRAG_CMD_DETACH_STATUS)) {
e7a346
-                ret = glusterd_op_begin (req, GD_OP_DEFRAG_BRICK_VOLUME,
e7a346
-                                         dict, msg, sizeof (msg));
e7a346
+                op = GD_OP_DEFRAG_BRICK_VOLUME;
e7a346
         } else
e7a346
-                ret = glusterd_op_begin (req, GD_OP_REBALANCE, dict,
e7a346
-                                         msg, sizeof (msg));
e7a346
-
e7a346
+                op =  GD_OP_REBALANCE;
e7a346
+
e7a346
+        if (priv->op_version < GD_OP_VERSION_6_0) {
e7a346
+                gf_msg_debug(this->name, 0,
e7a346
+                             "The cluster is operating at "
e7a346
+                             "version less than %d. Falling back "
e7a346
+                             "to op-sm framework.",
e7a346
+                             GD_OP_VERSION_6_0);
e7a346
+                ret = glusterd_op_begin(req, op, dict, msg, sizeof(msg));
e7a346
+                glusterd_friend_sm();
e7a346
+                glusterd_op_sm();
e7a346
+        } else {
e7a346
+                ret = glusterd_mgmt_v3_initiate_all_phases_with_brickop_phase(req,
e7a346
+                                                                              op,
e7a346
+                                                                              dict);
e7a346
+        }
e7a346
 out:
e7a346
-
e7a346
-        glusterd_friend_sm ();
e7a346
-        glusterd_op_sm ();
e7a346
-
e7a346
         if (ret) {
e7a346
                 if (msg[0] == '\0')
e7a346
                         snprintf (msg, sizeof (msg), "Operation failed");
e7a346
@@ -583,8 +593,8 @@ out:
e7a346
         }
e7a346
 
e7a346
         free (cli_req.dict.dict_val);//malloced by xdr
e7a346
-
e7a346
-        return 0;
e7a346
+        gf_msg_debug(this->name, 0, "Returning %d", ret);
e7a346
+        return ret;
e7a346
 }
e7a346
 
e7a346
 int
e7a346
@@ -628,6 +638,469 @@ glusterd_brick_validation  (dict_t *dict, char *key, data_t *value,
e7a346
 }
e7a346
 
e7a346
 int
e7a346
+glusterd_set_rebalance_id_in_rsp_dict(dict_t *req_dict, dict_t *rsp_dict)
e7a346
+{
e7a346
+        int                    ret         = -1;
e7a346
+        int32_t                cmd         = 0;
e7a346
+        char                  *volname     = NULL;
e7a346
+        glusterd_volinfo_t    *volinfo     = NULL;
e7a346
+        char                   msg[2048]   = {0};
e7a346
+        char                  *task_id_str = NULL;
e7a346
+        xlator_t              *this        = NULL;
e7a346
+
e7a346
+        this = THIS;
e7a346
+        GF_ASSERT(this);
e7a346
+
e7a346
+        GF_ASSERT(rsp_dict);
e7a346
+        GF_ASSERT(req_dict);
e7a346
+
e7a346
+        ret = dict_get_str(rsp_dict, "volname", &volname);
e7a346
+        if (ret) {
e7a346
+                gf_msg_debug(this->name, 0, "volname not found");
e7a346
+                goto out;
e7a346
+        }
e7a346
+
e7a346
+        ret = dict_get_int32(rsp_dict, "rebalance-command", &cmd);
e7a346
+        if (ret) {
e7a346
+                gf_msg_debug(this->name, 0, "cmd not found");
e7a346
+                goto out;
e7a346
+        }
e7a346
+
e7a346
+        ret = glusterd_rebalance_cmd_validate(cmd, volname, &volinfo, msg,
e7a346
+                                              sizeof(msg));
e7a346
+        if (ret) {
e7a346
+                gf_msg_debug(this->name, 0, "failed to validate");
e7a346
+                goto out;
e7a346
+        }
e7a346
+
e7a346
+        /* reblance id is generted in glusterd_mgmt_v3_op_stage_rebalance(), but
e7a346
+         * rsp_dict is unavailable there. So copying it to rsp_dict from req_dict
e7a346
+         * here. So that cli can display the rebalance id.*/
e7a346
+        if ((cmd == GF_DEFRAG_CMD_START) ||
e7a346
+            (cmd == GF_DEFRAG_CMD_START_LAYOUT_FIX) ||
e7a346
+            (cmd == GF_DEFRAG_CMD_START_FORCE) ||
e7a346
+            (cmd == GF_DEFRAG_CMD_START_TIER)) {
e7a346
+                if (is_origin_glusterd(rsp_dict)) {
e7a346
+                        ret = dict_get_str(req_dict, GF_REBALANCE_TID_KEY,
e7a346
+                                           &task_id_str);
e7a346
+                        if (ret) {
e7a346
+                                snprintf(msg, sizeof(msg), "Missing rebalance-id");
e7a346
+                                gf_msg(this->name, GF_LOG_WARNING, 0,
e7a346
+                                       GD_MSG_REBALANCE_ID_MISSING, "%s", msg);
e7a346
+                                ret = 0;
e7a346
+                        } else {
e7a346
+                                gf_uuid_parse(task_id_str,
e7a346
+                                              volinfo->rebal.rebalance_id);
e7a346
+                                ret = glusterd_copy_uuid_to_dict(
e7a346
+                                      volinfo->rebal.rebalance_id, rsp_dict,
e7a346
+                                      GF_REBALANCE_TID_KEY);
e7a346
+                                if (ret) {
e7a346
+                                        snprintf(msg, sizeof(msg),
e7a346
+                                                 "Failed to set rebalance id for volume %s",
e7a346
+                                                 volname);
e7a346
+                                        gf_msg(this->name, GF_LOG_WARNING, 0,
e7a346
+                                               GD_MSG_DICT_SET_FAILED, "%s",
e7a346
+                                               msg);
e7a346
+                                }
e7a346
+                        }
e7a346
+                }
e7a346
+        }
e7a346
+
e7a346
+        /* Set task-id, if available, in rsp_dict for operations other than
e7a346
+         * start. This is needed when we want rebalance id in xml output
e7a346
+         */
e7a346
+        if (cmd == GF_DEFRAG_CMD_STATUS || cmd == GF_DEFRAG_CMD_STOP ||
e7a346
+            cmd == GF_DEFRAG_CMD_STATUS_TIER) {
e7a346
+                if (!gf_uuid_is_null(volinfo->rebal.rebalance_id)) {
e7a346
+                        if (GD_OP_REMOVE_BRICK == volinfo->rebal.op)
e7a346
+                                ret = glusterd_copy_uuid_to_dict(
e7a346
+                                      volinfo->rebal.rebalance_id, rsp_dict,
e7a346
+                                      GF_REMOVE_BRICK_TID_KEY);
e7a346
+                        else
e7a346
+                                ret = glusterd_copy_uuid_to_dict(
e7a346
+                                      volinfo->rebal.rebalance_id,
e7a346
+                                      rsp_dict, GF_REBALANCE_TID_KEY);
e7a346
+                        if (ret) {
e7a346
+                                gf_msg(this->name, GF_LOG_ERROR, 0,
e7a346
+                                       GD_MSG_DICT_SET_FAILED,
e7a346
+                                       "Failed to set task-id for volume %s",
e7a346
+                                       volname);
e7a346
+                                goto out;
e7a346
+                        }
e7a346
+                }
e7a346
+        }
e7a346
+out:
e7a346
+        return ret;
e7a346
+}
e7a346
+
e7a346
+int
e7a346
+glusterd_mgmt_v3_op_stage_rebalance(dict_t *dict, char **op_errstr)
e7a346
+{
e7a346
+        char               *volname     = NULL;
e7a346
+        char               *cmd_str     = NULL;
e7a346
+        int                 ret         = 0;
e7a346
+        int32_t             cmd         = 0;
e7a346
+        char                msg[2048]   = {0};
e7a346
+        glusterd_volinfo_t *volinfo     = NULL;
e7a346
+        char               *task_id_str = NULL;
e7a346
+        xlator_t           *this        = 0;
e7a346
+        int32_t             is_force    = 0;
e7a346
+
e7a346
+        this = THIS;
e7a346
+        GF_ASSERT(this);
e7a346
+
e7a346
+        ret = dict_get_str (dict, "volname", &volname);
e7a346
+        if (ret) {
e7a346
+                gf_msg_debug(this->name, 0, "volname not found");
e7a346
+                goto out;
e7a346
+        }
e7a346
+
e7a346
+        ret = dict_get_int32 (dict, "rebalance-command", &cmd);
e7a346
+        if (ret) {
e7a346
+                gf_msg_debug(this->name, 0, "cmd not found");
e7a346
+                goto out;
e7a346
+        }
e7a346
+
e7a346
+        ret = glusterd_rebalance_cmd_validate(cmd, volname, &volinfo, msg,
e7a346
+                                              sizeof(msg));
e7a346
+        if (ret) {
e7a346
+                gf_msg_debug(this->name, 0, "failed to validate");
e7a346
+                goto out;
e7a346
+        }
e7a346
+        switch (cmd) {
e7a346
+        case GF_DEFRAG_CMD_START_TIER:
e7a346
+                ret = dict_get_int32 (dict, "force", &is_force);
e7a346
+                if (ret)
e7a346
+                        is_force = 0;
e7a346
+
e7a346
+                if (volinfo->type != GF_CLUSTER_TYPE_TIER) {
e7a346
+                        gf_asprintf(op_errstr,
e7a346
+                                    "volume %s is not a tier "
e7a346
+                                    "volume.",
e7a346
+                                    volinfo->volname);
e7a346
+                        ret = -1;
e7a346
+                        goto out;
e7a346
+                }
e7a346
+                if ((!is_force) && glusterd_is_tier_daemon_running(volinfo)) {
e7a346
+                        ret = gf_asprintf(op_errstr,
e7a346
+                                          "A Tier daemon is "
e7a346
+                                          "already running on volume %s",
e7a346
+                                          volname);
e7a346
+                        ret = -1;
e7a346
+                        goto out;
e7a346
+                }
e7a346
+                /* Fall through */
e7a346
+        case GF_DEFRAG_CMD_START:
e7a346
+        case GF_DEFRAG_CMD_START_LAYOUT_FIX:
e7a346
+                /* Check if the connected clients are all of version
e7a346
+                 * glusterfs-3.6 and higher. This is needed to prevent some data
e7a346
+                 * loss issues that could occur when older clients are connected
e7a346
+                 * when rebalance is run. This check can be bypassed by using
e7a346
+                 * 'force'
e7a346
+                 */
e7a346
+                ret = glusterd_check_client_op_version_support(volname,
e7a346
+                                                               GD_OP_VERSION_RHS_3_0,
e7a346
+                                                               NULL);
e7a346
+                if (ret) {
e7a346
+                        ret = gf_asprintf(op_errstr,
e7a346
+                                          "Volume %s has one or "
e7a346
+                                          "more connected clients of a version"
e7a346
+                                          " lower than GlusterFS-v3.6.0. "
e7a346
+                                          "Starting rebalance in this state "
e7a346
+                                          "could lead to data loss.\nPlease "
e7a346
+                                          "disconnect those clients before "
e7a346
+                                          "attempting this command again.",
e7a346
+                                          volname);
e7a346
+                        goto out;
e7a346
+                }
e7a346
+                /* Fall through */
e7a346
+        case GF_DEFRAG_CMD_START_FORCE:
e7a346
+                if (is_origin_glusterd(dict)) {
e7a346
+                        ret = glusterd_generate_and_set_task_id(dict,
e7a346
+                                                                GF_REBALANCE_TID_KEY);
e7a346
+                        if (ret) {
e7a346
+                                gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_TASKID_GEN_FAIL,
e7a346
+                                       "Failed to generate task-id");
e7a346
+                                goto out;
e7a346
+                        }
e7a346
+                } else {
e7a346
+                        ret = dict_get_str(dict, GF_REBALANCE_TID_KEY, &task_id_str);
e7a346
+                        if (ret) {
e7a346
+                                snprintf(msg, sizeof(msg), "Missing rebalance-id");
e7a346
+                                gf_msg(this->name, GF_LOG_WARNING, 0,
e7a346
+                                       GD_MSG_REBALANCE_ID_MISSING, "%s", msg);
e7a346
+                                ret = 0;
e7a346
+                        }
e7a346
+                }
e7a346
+                ret = glusterd_defrag_start_validate(volinfo, msg, sizeof(msg),
e7a346
+                                                     GD_OP_REBALANCE);
e7a346
+                if (ret) {
e7a346
+                        gf_msg_debug(this->name, 0,
e7a346
+                                     "defrag start validate "
e7a346
+                                     "failed for volume %s.",
e7a346
+                                     volinfo->volname);
e7a346
+                        goto out;
e7a346
+                }
e7a346
+                break;
e7a346
+        case GF_DEFRAG_CMD_STATUS_TIER:
e7a346
+        case GF_DEFRAG_CMD_STATUS:
e7a346
+        case GF_DEFRAG_CMD_STOP:
e7a346
+
e7a346
+                ret = dict_get_str(dict, "cmd-str", &cmd_str);
e7a346
+                if (ret) {
e7a346
+                        gf_msg(this->name, GF_LOG_ERROR, 0, GD_MSG_DICT_GET_FAILED,
e7a346
+                               "Failed to get "
e7a346
+                               "command string");
e7a346
+                        ret = -1;
e7a346
+                        goto out;
e7a346
+                }
e7a346
+                if ((strstr(cmd_str, "rebalance") != NULL) &&
e7a346
+                    (volinfo->rebal.op != GD_OP_REBALANCE)) {
e7a346
+                        snprintf(msg, sizeof(msg),
e7a346
+                                 "Rebalance not started "
e7a346
+                                 "for volume %s.", volinfo->volname);
e7a346
+                        ret = -1;
e7a346
+                        goto out;
e7a346
+                }
e7a346
+
e7a346
+                if (strstr(cmd_str, "remove-brick") != NULL) {
e7a346
+                        if (volinfo->rebal.op != GD_OP_REMOVE_BRICK) {
e7a346
+                                snprintf(msg, sizeof(msg),
e7a346
+                                         "remove-brick not "
e7a346
+                                         "started for volume %s.",
e7a346
+                                         volinfo->volname);
e7a346
+                                ret = -1;
e7a346
+                                goto out;
e7a346
+                        }
e7a346
+
e7a346
+                        /* For remove-brick status/stop command check whether
e7a346
+                         * given input brick is part of volume or not.*/
e7a346
+
e7a346
+                        ret = dict_foreach_fnmatch(dict, "brick*",
e7a346
+                                                   glusterd_brick_validation, volinfo);
e7a346
+                        if (ret == -1) {
e7a346
+                                snprintf(msg, sizeof(msg),
e7a346
+                                         "Incorrect brick for volume %s",
e7a346
+                                         volinfo->volname);
e7a346
+                                goto out;
e7a346
+                        }
e7a346
+                }
e7a346
+                if (cmd == GF_DEFRAG_CMD_STATUS_TIER) {
e7a346
+                        if (volinfo->type != GF_CLUSTER_TYPE_TIER) {
e7a346
+                                snprintf(msg, sizeof(msg),
e7a346
+                                         "volume %s is not "
e7a346
+                                         "a tier volume.",
e7a346
+                                         volinfo->volname);
e7a346
+                                ret = -1;
e7a346
+                                goto out;
e7a346
+                        }
e7a346
+                }
e7a346
+
e7a346
+                break;
e7a346
+
e7a346
+        case GF_DEFRAG_CMD_STOP_DETACH_TIER:
e7a346
+        case GF_DEFRAG_CMD_DETACH_STATUS:
e7a346
+                if (volinfo->type != GF_CLUSTER_TYPE_TIER) {
e7a346
+                        snprintf(msg, sizeof(msg),
e7a346
+                                 "volume %s is not "
e7a346
+                                 "a tier volume.",
e7a346
+                                 volinfo->volname);
e7a346
+                        ret = -1;
e7a346
+                        goto out;
e7a346
+                }
e7a346
+
e7a346
+                if (volinfo->rebal.op != GD_OP_REMOVE_BRICK) {
e7a346
+                        snprintf(msg, sizeof(msg),
e7a346
+                                 "Detach-tier "
e7a346
+                                 "not started");
e7a346
+                        ret = -1;
e7a346
+                        goto out;
e7a346
+                }
e7a346
+                break;
e7a346
+        default:
e7a346
+                break;
e7a346
+        }
e7a346
+
e7a346
+        ret = 0;
e7a346
+out:
e7a346
+        if (ret && op_errstr && msg[0])
e7a346
+                *op_errstr = gf_strdup(msg);
e7a346
+
e7a346
+        return ret;
e7a346
+}
e7a346
+
e7a346
+int
e7a346
+glusterd_mgmt_v3_op_rebalance(dict_t *dict, char **op_errstr, dict_t *rsp_dict)
e7a346
+{
e7a346
+        char                 *volname        = NULL;
e7a346
+        int                   ret            = 0;
e7a346
+        int32_t               cmd            = 0;
e7a346
+        char                  msg[2048]      = {0};
e7a346
+        glusterd_volinfo_t   *volinfo        = NULL;
e7a346
+        glusterd_brickinfo_t *brickinfo      = NULL;
e7a346
+        glusterd_brickinfo_t *tmp            = NULL;
e7a346
+        gf_boolean_t          volfile_update = _gf_false;
e7a346
+        char                 *task_id_str    = NULL;
e7a346
+        xlator_t             *this           = NULL;
e7a346
+        uint32_t              commit_hash;
e7a346
+        int32_t               is_force       = 0;
e7a346
+
e7a346
+        this = THIS;
e7a346
+        GF_ASSERT(this);
e7a346
+
e7a346
+        ret = dict_get_str(dict, "volname", &volname);
e7a346
+        if (ret) {
e7a346
+                gf_msg_debug(this->name, 0, "volname not given");
e7a346
+                goto out;
e7a346
+        }
e7a346
+
e7a346
+        ret = dict_get_int32(dict, "rebalance-command", &cmd);
e7a346
+        if (ret) {
e7a346
+                gf_msg_debug(this->name, 0, "command not given");
e7a346
+                goto out;
e7a346
+        }
e7a346
+
e7a346
+        ret = glusterd_rebalance_cmd_validate(cmd, volname, &volinfo, msg,
e7a346
+                                              sizeof(msg));
e7a346
+        if (ret) {
e7a346
+                gf_msg_debug(this->name, 0, "cmd validate failed");
e7a346
+                goto out;
e7a346
+        }
e7a346
+
e7a346
+        switch (cmd) {
e7a346
+        case GF_DEFRAG_CMD_START:
e7a346
+        case GF_DEFRAG_CMD_START_LAYOUT_FIX:
e7a346
+        case GF_DEFRAG_CMD_START_FORCE:
e7a346
+        case GF_DEFRAG_CMD_START_TIER:
e7a346
+
e7a346
+                ret = dict_get_int32(dict, "force", &is_force);
e7a346
+                if (ret)
e7a346
+                        is_force = 0;
e7a346
+                if (!is_force) {
e7a346
+                        /* Reset defrag status to 'NOT STARTED' whenever a
e7a346
+                         * remove-brick/rebalance command is issued to remove
e7a346
+                         * stale information from previous run.
e7a346
+                         */
e7a346
+                        volinfo->rebal.defrag_status = GF_DEFRAG_STATUS_NOT_STARTED;
e7a346
+
e7a346
+                        ret = dict_get_str(dict, GF_REBALANCE_TID_KEY, &task_id_str);
e7a346
+                        if (ret) {
e7a346
+                                gf_msg_debug(this->name, 0,
e7a346
+                                             "Missing rebalance id");
e7a346
+                                ret = 0;
e7a346
+                        } else {
e7a346
+                                gf_uuid_parse(task_id_str, volinfo->rebal.rebalance_id);
e7a346
+                                volinfo->rebal.op = GD_OP_REBALANCE;
e7a346
+                        }
e7a346
+                        if (!gd_should_i_start_rebalance(volinfo)) {
e7a346
+                                /* Store the rebalance-id and rebalance command
e7a346
+                                 * even if the peer isn't starting a rebalance
e7a346
+                                 * process. On peers where a rebalance process
e7a346
+                                 * is started, glusterd_handle_defrag_start
e7a346
+                                 * performs the storing.
e7a346
+                                 * Storing this is needed for having
e7a346
+                                 * 'volume status' work correctly.
e7a346
+                                 */
e7a346
+                                glusterd_store_perform_node_state_store(volinfo);
e7a346
+                                break;
e7a346
+                        }
e7a346
+                        if (dict_get_uint32(dict, "commit-hash", &commit_hash) == 0) {
e7a346
+                                volinfo->rebal.commit_hash = commit_hash;
e7a346
+                        }
e7a346
+                        ret = glusterd_handle_defrag_start(volinfo, msg, sizeof(msg),
e7a346
+                                                           cmd, NULL, GD_OP_REBALANCE);
e7a346
+                        break;
e7a346
+                } else {
e7a346
+                        /* Reset defrag status to 'STARTED' so that the
e7a346
+                         * pid is checked and restarted accordingly.
e7a346
+                         * If the pid is not running it executes the
e7a346
+                         * "NOT_STARTED" case and restarts the process
e7a346
+                         */
e7a346
+                        volinfo->rebal.defrag_status = GF_DEFRAG_STATUS_STARTED;
e7a346
+                        volinfo->rebal.defrag_cmd = cmd;
e7a346
+                        volinfo->rebal.op = GD_OP_REBALANCE;
e7a346
+
e7a346
+                        ret = dict_get_str(dict, GF_REBALANCE_TID_KEY, &task_id_str);
e7a346
+                        if (ret) {
e7a346
+                                gf_msg_debug(this->name, 0,
e7a346
+                                             "Missing rebalance id");
e7a346
+                                ret = 0;
e7a346
+                        } else {
e7a346
+                                gf_uuid_parse(task_id_str, volinfo->rebal.rebalance_id);
e7a346
+                                volinfo->rebal.op = GD_OP_REBALANCE;
e7a346
+                        }
e7a346
+                        if (dict_get_uint32(dict, "commit-hash", &commit_hash) == 0) {
e7a346
+                                volinfo->rebal.commit_hash = commit_hash;
e7a346
+                        }
e7a346
+                        ret = glusterd_restart_rebalance_for_volume(volinfo);
e7a346
+                        break;
e7a346
+                }
e7a346
+        case GF_DEFRAG_CMD_STOP:
e7a346
+        case GF_DEFRAG_CMD_STOP_DETACH_TIER:
e7a346
+                /* Clear task-id only on explicitly stopping rebalance.
e7a346
+                 * Also clear the stored operation, so it doesn't cause trouble
e7a346
+                 * with future rebalance/remove-brick starts
e7a346
+                 */
e7a346
+                gf_uuid_clear(volinfo->rebal.rebalance_id);
e7a346
+                volinfo->rebal.op = GD_OP_NONE;
e7a346
+
e7a346
+                /* Fall back to the old volume file in case of decommission*/
e7a346
+                cds_list_for_each_entry_safe(brickinfo, tmp, &volinfo->bricks,
e7a346
+                                             brick_list)
e7a346
+                {
e7a346
+                        if (!brickinfo->decommissioned)
e7a346
+                            continue;
e7a346
+                        brickinfo->decommissioned = 0;
e7a346
+                        volfile_update = _gf_true;
e7a346
+                }
e7a346
+
e7a346
+                if (volfile_update == _gf_false) {
e7a346
+                        ret = 0;
e7a346
+                        break;
e7a346
+                }
e7a346
+
e7a346
+                ret = glusterd_create_volfiles_and_notify_services(volinfo);
e7a346
+                if (ret) {
e7a346
+                        gf_msg(this->name, GF_LOG_WARNING, 0,
e7a346
+                               GD_MSG_VOLFILE_CREATE_FAIL, "failed to create volfiles");
e7a346
+                        goto out;
e7a346
+                }
e7a346
+
e7a346
+                ret = glusterd_store_volinfo(volinfo,
e7a346
+                                             GLUSTERD_VOLINFO_VER_AC_INCREMENT);
e7a346
+                if (ret) {
e7a346
+                        gf_msg(this->name, GF_LOG_WARNING, 0, GD_MSG_VOLINFO_SET_FAIL,
e7a346
+                               "failed to store volinfo");
e7a346
+                        goto out;
e7a346
+                }
e7a346
+
e7a346
+                if (volinfo->type == GF_CLUSTER_TYPE_TIER &&
e7a346
+                    cmd == GF_OP_CMD_STOP_DETACH_TIER) {
e7a346
+                        glusterd_defrag_info_set(volinfo, dict,
e7a346
+                                                 GF_DEFRAG_CMD_START_TIER,
e7a346
+                                                 GF_DEFRAG_CMD_START, GD_OP_REBALANCE);
e7a346
+                        glusterd_restart_rebalance_for_volume(volinfo);
e7a346
+                }
e7a346
+
e7a346
+                ret = 0;
e7a346
+                break;
e7a346
+
e7a346
+        case GF_DEFRAG_CMD_START_DETACH_TIER:
e7a346
+        case GF_DEFRAG_CMD_STATUS:
e7a346
+        case GF_DEFRAG_CMD_STATUS_TIER:
e7a346
+                break;
e7a346
+        default:
e7a346
+                break;
e7a346
+        }
e7a346
+
e7a346
+out:
e7a346
+        if (ret && op_errstr && msg[0])
e7a346
+                *op_errstr = gf_strdup(msg);
e7a346
+
e7a346
+        return ret;
e7a346
+}
e7a346
+
e7a346
+int
e7a346
 glusterd_op_stage_rebalance (dict_t *dict, char **op_errstr)
e7a346
 {
e7a346
         char                    *volname     = NULL;
e7a346
diff --git a/xlators/mgmt/glusterd/src/glusterd-syncop.c b/xlators/mgmt/glusterd/src/glusterd-syncop.c
e7a346
index 9a67d1c..7baef64 100644
e7a346
--- a/xlators/mgmt/glusterd/src/glusterd-syncop.c
e7a346
+++ b/xlators/mgmt/glusterd/src/glusterd-syncop.c
e7a346
@@ -317,6 +317,15 @@ glusterd_syncop_aggr_rsp_dict (glusterd_op_t op, dict_t *aggr, dict_t *rsp)
e7a346
                 ret = glusterd_max_opversion_use_rsp_dict (aggr, rsp);
e7a346
         break;
e7a346
 
e7a346
+        case GD_OP_PROFILE_VOLUME:
e7a346
+                ret = glusterd_profile_volume_use_rsp_dict(aggr, rsp);
e7a346
+                break;
e7a346
+
e7a346
+        case GD_OP_REBALANCE:
e7a346
+        case GD_OP_DEFRAG_BRICK_VOLUME:
e7a346
+                ret = glusterd_volume_rebalance_use_rsp_dict(aggr, rsp);
e7a346
+                break;
e7a346
+
e7a346
         case GD_OP_TIER_STATUS:
e7a346
         case GD_OP_DETACH_TIER_STATUS:
e7a346
         case GD_OP_REMOVE_TIER_BRICK:
e7a346
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
e7a346
index 6468ecb..0fe56eb 100644
e7a346
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
e7a346
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
e7a346
@@ -10884,7 +10884,7 @@ glusterd_volume_rebalance_use_rsp_dict (dict_t *aggr, dict_t *rsp_dict)
e7a346
         int                  ret           = 0;
e7a346
         int32_t              index         = 0;
e7a346
         int32_t              count         = 0;
e7a346
-        int32_t              current_index = 2;
e7a346
+        int32_t              current_index = 1;
e7a346
         int32_t              value32       = 0;
e7a346
         uint64_t             value         = 0;
e7a346
         char                *peer_uuid_str = NULL;
e7a346
@@ -10925,7 +10925,7 @@ glusterd_volume_rebalance_use_rsp_dict (dict_t *aggr, dict_t *rsp_dict)
e7a346
         if (ret)
e7a346
                 gf_msg ("glusterd", GF_LOG_ERROR, 0,
e7a346
                         GD_MSG_DICT_GET_FAILED,
e7a346
-                        "failed to get index");
e7a346
+                        "failed to get index from rsp dict");
e7a346
 
e7a346
         memset (key, 0, 256);
e7a346
         snprintf (key, 256, "node-uuid-%d", index);
e7a346
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
e7a346
index 42c8821..f1e41be 100644
e7a346
--- a/xlators/mgmt/glusterd/src/glusterd.h
e7a346
+++ b/xlators/mgmt/glusterd/src/glusterd.h
e7a346
@@ -1223,6 +1223,15 @@ int glusterd_op_stage_add_brick (dict_t *dict, char **op_errstr,
e7a346
                                  dict_t *rsp_dict);
e7a346
 int glusterd_op_stage_remove_brick (dict_t *dict, char **op_errstr);
e7a346
 
e7a346
+int
e7a346
+glusterd_set_rebalance_id_in_rsp_dict(dict_t *req_dict, dict_t *rsp_dict);
e7a346
+
e7a346
+int
e7a346
+glusterd_mgmt_v3_op_stage_rebalance(dict_t *dict, char **op_errstr);
e7a346
+
e7a346
+int
e7a346
+glusterd_mgmt_v3_op_rebalance(dict_t *dict, char **op_errstr, dict_t *rsp_dict);
e7a346
+
e7a346
 int glusterd_op_stage_rebalance (dict_t *dict, char **op_errstr);
e7a346
 int glusterd_op_rebalance (dict_t *dict, char **op_errstr, dict_t *rsp_dict);
e7a346
 
e7a346
-- 
e7a346
1.8.3.1
e7a346