diff options
| -rw-r--r-- | cli/src/cli-cmd-parser.c | 60 | ||||
| -rw-r--r-- | cli/src/cli-cmd-volume.c | 17 | ||||
| -rw-r--r-- | cli/src/cli-rpc-ops.c | 33 | ||||
| -rw-r--r-- | cli/src/cli.h | 4 | ||||
| -rw-r--r-- | rpc/xdr/src/cli1-xdr.x | 8 | ||||
| -rwxr-xr-x | tests/basic/tier/tier.t | 22 | ||||
| -rw-r--r-- | xlators/cluster/dht/src/dht-common.c | 2 | ||||
| -rw-r--r-- | xlators/cluster/dht/src/dht-common.h | 6 | ||||
| -rw-r--r-- | xlators/cluster/dht/src/dht-rebalance.c | 24 | ||||
| -rw-r--r-- | xlators/cluster/dht/src/tier.c | 38 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-brick-ops.c | 36 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.c | 20 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-rebalance.c | 6 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-store.c | 9 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-syncop.c | 17 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 12 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.h | 3 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volgen.c | 17 | 
18 files changed, 259 insertions, 75 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index a8e09a46631..a1648a9c527 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -1565,6 +1565,66 @@ out:          return ret;  } +int32_t +cli_cmd_volume_detach_tier_parse (const char **words, int wordcount, +                                  dict_t **options) +{ +        int      ret = -1; +        char    *word = NULL; +        dict_t  *dict = NULL; +        int32_t  command = GF_OP_CMD_NONE; +        int      force = 0; + +        if (!((wordcount == 4) || (wordcount == 5))) +                goto out; + +        dict = dict_new (); +        if (!dict) +                goto out; + +        ret = dict_set_str (dict, "volname", (char *)words[2]); +        if (ret) +                goto out; + +        if (wordcount == 5) { +                word = (char *)words[4]; +                if (!strcmp(word, "force")) +                        force = 1; +        } + +        word = (char *)words[3]; + +        ret = -1; + +        if (!strcmp(word, "start")) { +                command = GF_OP_CMD_DETACH_START; +        } else if (!strcmp(word, "commit")) { +                if (force) +                        command = GF_OP_CMD_DETACH_COMMIT_FORCE; +                else +                        command = GF_OP_CMD_DETACH_COMMIT; +        } else if (!strcmp(word, "stop")) +                command = GF_DEFRAG_CMD_STOP_DETACH_TIER; +        else if (!strcmp(word, "status")) +                command = GF_DEFRAG_CMD_STATUS; +        else +                goto out; + +        ret = dict_set_int32 (dict, "command", command); +        if (ret) +                goto out; + +        *options = dict; +        ret = 0; +out: +        if (ret) { +                gf_log ("cli", GF_LOG_ERROR, "Unable to parse detach-tier CLI"); +                if (dict) +                        dict_unref (dict); +        } + +        return ret; +}  int32_t  cli_cmd_volume_remove_brick_parse (const char **words, int wordcount, diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index ae091b3182e..8b73c2e7840 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -915,26 +915,16 @@ cli_cmd_volume_detach_tier_cbk (struct cli_state *state,          const char *question = "Removing tier can result in data loss. "                                 "Do you want to Continue?"; -        if (wordcount != 3) -                goto out; -          frame = create_frame (THIS, THIS->ctx->pool);          if (!frame)                  goto out; -        options = dict_new (); -        if (!options) -                goto out; +        ret = cli_cmd_volume_detach_tier_parse(words, wordcount, &options); -        ret = dict_set_int32 (options, "force", 1);          if (ret)                  goto out; -        ret = dict_set_int32 (options, "command", GF_OP_CMD_DETACH); -        if (ret) -                goto out; - -        ret = dict_set_str (options, "volname", (char *)words[2]); +        ret = dict_set_int32 (options, "force", 1);          if (ret)                  goto out; @@ -2563,7 +2553,8 @@ struct cli_cmd volume_cmds[] = {            cli_cmd_volume_attach_tier_cbk,            "attach tier to volume <VOLNAME>"}, -        { "volume detach-tier <VOLNAME>", +        { "volume detach-tier <VOLNAME> " +          " <start|stop|status|commit|[force]>",            cli_cmd_volume_detach_tier_cbk,            "detach tier from volume <VOLNAME>"}, diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index 7c5743af741..e8a81cd6523 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -56,6 +56,10 @@ extern rpc_clnt_prog_t *cli_rpc_prog;  extern int              cli_op_ret;  extern int              connected; +int32_t +gf_cli_remove_brick (call_frame_t *frame, xlator_t *this, +                     void *data); +  char *cli_vol_type_str[] = {"Distribute",                              "Stripe",                              "Replicate", @@ -1355,11 +1359,14 @@ gf_cli_print_rebalance_status (dict_t *dict, enum gf_task_types task_type)                  /* Check if status is NOT_STARTED, and continue early */                  memset (key, 0, 256);                  snprintf (key, 256, "status-%d", i); +                  ret = dict_get_int32 (dict, key, (int32_t *)&status_rcd);                  if (ret) { +                        gf_log ("cli", GF_LOG_TRACE, "count %d %d", count, i);                          gf_log ("cli", GF_LOG_TRACE, "failed to get status");                          goto out;                  } +                  if (GF_DEFRAG_STATUS_NOT_STARTED == status_rcd)                          continue; @@ -2245,6 +2252,7 @@ gf_cli_remove_brick_cbk (struct rpc_req *req, struct iovec *iov,          }          switch (cmd) { +        case GF_OP_CMD_DETACH_START:          case GF_OP_CMD_START:                  cmd_str = "start"; @@ -3913,30 +3921,7 @@ int32_t  gf_cli_detach_tier (call_frame_t *frame, xlator_t *this,                      void *data)  { -        gf_cli_req              req =  {{0,} }; -        int                     ret = 0; -        dict_t                  *dict = NULL; -        char                    *volname = NULL; - -        if (!frame || !this ||  !data) { -                ret = -1; -                goto out; -        } - -        dict = data; - -        ret = cli_to_glusterd (&req, frame, gf_cli_remove_brick_cbk, -                              (xdrproc_t) xdr_gf_cli_req, dict, -                               GLUSTER_CLI_DETACH_TIER, this, -                               cli_rpc_prog, NULL); - - -out: -        gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); - -        GF_FREE (req.dict.dict_val); - -        return ret; +        return gf_cli_remove_brick(frame, this, data);  } diff --git a/cli/src/cli.h b/cli/src/cli.h index 2648d25ee9c..c0750f2dd74 100644 --- a/cli/src/cli.h +++ b/cli/src/cli.h @@ -256,6 +256,10 @@ cli_cmd_volume_add_brick_parse (const char **words, int wordcount,                                  dict_t **options, int *type);  int32_t +cli_cmd_volume_detach_tier_parse (const char **words, int wordcount, +                                  dict_t **options); + +int32_t  cli_cmd_volume_remove_brick_parse (const char **words, int wordcount,                                     dict_t **options, int *question); diff --git a/rpc/xdr/src/cli1-xdr.x b/rpc/xdr/src/cli1-xdr.x index 72581b0c5d5..affbb3ab0d2 100644 --- a/rpc/xdr/src/cli1-xdr.x +++ b/rpc/xdr/src/cli1-xdr.x @@ -5,7 +5,9 @@          GF_DEFRAG_CMD_START_LAYOUT_FIX,          GF_DEFRAG_CMD_START_FORCE, /* used by remove-brick data migration */          GF_DEFRAG_CMD_START_TIER, -        GF_DEFRAG_CMD_STATUS_TIER +        GF_DEFRAG_CMD_STATUS_TIER, +        GF_DEFRAG_CMD_START_DETACH_TIER, +        GF_DEFRAG_CMD_STOP_DETACH_TIER  };   enum gf_defrag_status_t { @@ -57,7 +59,9 @@ enum gf_bitrot_type {          GF_OP_CMD_STOP,          GF_OP_CMD_STATUS,          GF_OP_CMD_COMMIT_FORCE, -        GF_OP_CMD_DETACH +        GF_OP_CMD_DETACH_START, +        GF_OP_CMD_DETACH_COMMIT, +        GF_OP_CMD_DETACH_COMMIT_FORCE  };  enum gf_quota_type { diff --git a/tests/basic/tier/tier.t b/tests/basic/tier/tier.t index d1e1041f87c..f1174e60fed 100755 --- a/tests/basic/tier/tier.t +++ b/tests/basic/tier/tier.t @@ -36,7 +36,7 @@ function file_on_fast_tier {  function confirm_tier_removed {      $CLI system getspec $V0 | grep $1 -    if [ $? == 0 ] ; then +    if [ $? == 0 ]; then          echo "1"      else          echo "0" @@ -52,6 +52,11 @@ function confirm_vol_stopped {      fi  } +LAST_BRICK=1 +CACHE_BRICK=2 +DEMOTE_TIMEOUT=12 +PROMOTE_TIMEOUT=5 +MIGRATION_TIMEOUT=10  cleanup @@ -108,21 +113,18 @@ sleep 5  EXPECT_WITHIN $PROMOTE_TIMEOUT "0" file_on_fast_tier d1/data2.txt  EXPECT_WITHIN $PROMOTE_TIMEOUT "0" file_on_fast_tier d1/data3.txt -# Test rebalance commands -TEST $CLI volume rebalance $V0 tier status -TEST $CLI volume rebalance $V0 stop -  # stop gluster, when it comes back info file should have tiered volume  killall glusterd  TEST glusterd -# TODO: Remove force. Gracefully migrate data off hot tier. -# Rebalance+promotion/demotion is under construction. +# Test rebalance commands +TEST $CLI volume rebalance $V0 tier status + +TEST $CLI volume detach-tier $V0 start -TEST $CLI volume detach-tier $V0 +TEST $CLI volume detach-tier $V0 commit -# temporarily comment out -#TEST ! [ -e $M0/d1/data.txt ] +EXPECT "0" file_on_slow_tier d1/data.txt  EXPECT "0" confirm_tier_removed ${V0}${CACHE_BRICK_FIRST} diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index e0b159ace32..307265fb56a 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -6277,6 +6277,8 @@ dht_notify (xlator_t *this, int event, void *data, ...)                                  goto unlock;                          if (cmd == GF_DEFRAG_CMD_STATUS)                                  gf_defrag_status_get (defrag, output); +                        else if (cmd == GF_DEFRAG_CMD_START_DETACH_TIER) +                                gf_defrag_start_detach_tier(defrag);                          else if (cmd == GF_DEFRAG_CMD_STOP)                                  gf_defrag_stop (defrag,                                                  GF_DEFRAG_STATUS_STOPPED, output); diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h index 3ca626feec8..43f7c0264f5 100644 --- a/xlators/cluster/dht/src/dht-common.h +++ b/xlators/cluster/dht/src/dht-common.h @@ -266,6 +266,9 @@ enum gf_defrag_type {          GF_DEFRAG_CMD_START_FORCE = 1 + 4,          GF_DEFRAG_CMD_START_TIER = 1 + 5,          GF_DEFRAG_CMD_STATUS_TIER = 1 + 6, +	GF_DEFRAG_CMD_START_DETACH_TIER = 1 + 7, +	GF_DEFRAG_CMD_STOP_DETACH_TIER = 1 + 8, +  };  typedef enum gf_defrag_type gf_defrag_type; @@ -838,6 +841,9 @@ int  gf_defrag_status_get (gf_defrag_info_t *defrag, dict_t *dict);  int +gf_defrag_start_detach_tier (gf_defrag_info_t *defrag); + +int  gf_defrag_stop (gf_defrag_info_t *defrag, gf_defrag_status_t status,                  dict_t *output); diff --git a/xlators/cluster/dht/src/dht-rebalance.c b/xlators/cluster/dht/src/dht-rebalance.c index 9f389c12213..98d9b58385d 100644 --- a/xlators/cluster/dht/src/dht-rebalance.c +++ b/xlators/cluster/dht/src/dht-rebalance.c @@ -1985,6 +1985,22 @@ gf_defrag_start_crawl (void *data)                          goto out;                  }                  methods->migration_other(this, defrag); +                if (defrag->cmd == GF_DEFRAG_CMD_START_DETACH_TIER) { +                        migrate_data = dict_new (); +                        if (!migrate_data) { +                                ret = -1; +                                goto out; +                        } +                        ret = dict_set_str (migrate_data, +                                            GF_XATTR_FILE_MIGRATE_KEY, +                                            "force"); +                        if (ret) +                                goto out; + +                        ret = gf_defrag_fix_layout (this, defrag, &loc, +                                                    fix_layout, +                                                    migrate_data); +                }          }          if ((defrag->defrag_status != GF_DEFRAG_STATUS_STOPPED) && @@ -2173,6 +2189,14 @@ out:  }  int +gf_defrag_start_detach_tier (gf_defrag_info_t *defrag) +{ +        defrag->cmd = GF_DEFRAG_CMD_START_DETACH_TIER; + +        return 0; +} + +int  gf_defrag_stop (gf_defrag_info_t *defrag, gf_defrag_status_t status,                  dict_t *output)  { diff --git a/xlators/cluster/dht/src/tier.c b/xlators/cluster/dht/src/tier.c index cf481c5e7f2..5c3c3aa5548 100644 --- a/xlators/cluster/dht/src/tier.c +++ b/xlators/cluster/dht/src/tier.c @@ -794,6 +794,15 @@ tier_start (xlator_t *this, gf_defrag_info_t *defrag)                          goto out;                  } +                if (defrag->cmd == GF_DEFRAG_CMD_START_DETACH_TIER) { +                        ret = 1; +                        gf_msg (this->name, GF_LOG_ERROR, 0, +                                DHT_MSG_LOG_TIER_ERROR, +                                "defrag->defrag_cmd == " +                                "GF_DEFRAG_CMD_START_DETACH_TIER"); +                        goto out; +                } +                  tick = (tick + 1) % TIMER_SECS;                  if ((next_demote != tick) && (next_promote != tick))                          continue; @@ -893,15 +902,19 @@ tier_migration_get_dst (xlator_t *this, dht_local_t *local)  {          dht_conf_t              *conf   = NULL;          int32_t                  ret = -1; +        gf_defrag_info_t        *defrag = NULL;          GF_VALIDATE_OR_GOTO("tier", this, out);          GF_VALIDATE_OR_GOTO(this->name, this->private, out);          conf = this->private; -        if (!conf) -                goto out; -        if (conf->subvolumes[0] == local->cached_subvol) +        defrag = conf->defrag; + +        if (defrag && defrag->cmd == GF_DEFRAG_CMD_START_DETACH_TIER) { +                local->rebalance.target_node = conf->subvolumes[0]; + +        } else if (conf->subvolumes[0] == local->cached_subvol)                  local->rebalance.target_node =                          conf->subvolumes[1];          else @@ -918,16 +931,25 @@ out:  xlator_t *  tier_search (xlator_t *this, dht_layout_t *layout, const char *name)  { -        xlator_t  *subvol = NULL; -        void      *value; -        int        search_first_subvol = 0; +        xlator_t                *subvol = NULL; +        void                    *value; +        int                      search_first_subvol = 0; +        dht_conf_t              *conf   = NULL; +        gf_defrag_info_t        *defrag = NULL;          GF_VALIDATE_OR_GOTO("tier", this, out);          GF_VALIDATE_OR_GOTO(this->name, layout, out);          GF_VALIDATE_OR_GOTO(this->name, name, out); +        GF_VALIDATE_OR_GOTO(this->name, this->private, out); + +        conf = this->private; + +        defrag = conf->defrag; +        if (defrag && defrag->cmd == GF_DEFRAG_CMD_START_DETACH_TIER) +                search_first_subvol = 1; -        if (!dict_get_ptr (this->options, "rule", &value) && -            !strcmp(layout->list[0].xlator->name, value)) { +        else if (!dict_get_ptr (this->options, "rule", &value) && +                 !strcmp(layout->list[0].xlator->name, value)) {                  search_first_subvol = 1;          } diff --git a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c index 165622f87ef..c69d2ada238 100644 --- a/xlators/mgmt/glusterd/src/glusterd-brick-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-brick-ops.c @@ -1604,6 +1604,7 @@ glusterd_op_stage_remove_brick (dict_t *dict, char **op_errstr)                  ret = 0;                  goto out; +        case GF_OP_CMD_DETACH_START:          case GF_OP_CMD_START:          {                  if ((volinfo->type == GF_CLUSTER_TYPE_REPLICATE) && @@ -1736,7 +1737,8 @@ glusterd_op_stage_remove_brick (dict_t *dict, char **op_errstr)                  break; -        case GF_OP_CMD_DETACH: +        case GF_OP_CMD_DETACH_COMMIT: +        case GF_OP_CMD_DETACH_COMMIT_FORCE:          case GF_OP_CMD_COMMIT_FORCE:                  break;          } @@ -1961,7 +1963,7 @@ glusterd_op_remove_brick (dict_t *dict, char **op_errstr)          xlator_t                *this          = NULL;          dict_t                  *bricks_dict   = NULL;          char                    *brick_tmpstr  = NULL; - +        int                      start_remove  = 0;          this = THIS;          GF_ASSERT (this); @@ -1985,10 +1987,15 @@ glusterd_op_remove_brick (dict_t *dict, char **op_errstr)          }          cmd = flag; +        if ((GF_OP_CMD_START == cmd) || +            (GF_OP_CMD_DETACH_START == cmd)) +                start_remove = 1; +          /* Set task-id, if available, in ctx dict for operations other than           * start           */ -        if (is_origin_glusterd (dict) && (cmd != GF_OP_CMD_START)) { + +        if (is_origin_glusterd (dict) && (!start_remove)) {                  if (!gf_uuid_is_null (volinfo->rebal.rebalance_id)) {                          ret = glusterd_copy_uuid_to_dict                                  (volinfo->rebal.rebalance_id, dict, @@ -2003,7 +2010,7 @@ glusterd_op_remove_brick (dict_t *dict, char **op_errstr)          /* Clear task-id, rebal.op and stored bricks on commmitting/stopping           * remove-brick */ -        if ((cmd != GF_OP_CMD_START) || (cmd != GF_OP_CMD_STATUS)) { +        if ((!start_remove) && (cmd != GF_OP_CMD_STATUS)) {                  gf_uuid_clear (volinfo->rebal.rebalance_id);                  volinfo->rebal.op = GD_OP_NONE;                  dict_unref (volinfo->rebal.dict); @@ -2047,6 +2054,7 @@ glusterd_op_remove_brick (dict_t *dict, char **op_errstr)                  goto out;          } +        case GF_OP_CMD_DETACH_START:          case GF_OP_CMD_START:                  /* Reset defrag status to 'NOT STARTED' whenever a                   * remove-brick/rebalance command is issued to remove @@ -2069,7 +2077,8 @@ glusterd_op_remove_brick (dict_t *dict, char **op_errstr)                  force = 1;                  break; -        case GF_OP_CMD_DETACH: +        case GF_OP_CMD_DETACH_COMMIT: +        case GF_OP_CMD_DETACH_COMMIT_FORCE:                  glusterd_op_perform_detach_tier (volinfo);                  /* fall through */ @@ -2105,7 +2114,7 @@ glusterd_op_remove_brick (dict_t *dict, char **op_errstr)           * remove-brick. Right now this is required for displaying the task           * parameters with task status in volume status.           */ -        if (GF_OP_CMD_START == cmd) { +        if (start_remove) {                  bricks_dict = dict_new ();                  if (!bricks_dict) {                          ret = -1; @@ -2118,6 +2127,10 @@ glusterd_op_remove_brick (dict_t *dict, char **op_errstr)                          goto out;                  }          } + +        if (volinfo->type == GF_CLUSTER_TYPE_TIER) +                count = glusterd_set_detach_bricks(dict, volinfo); +          while ( i <= count) {                  snprintf (key, 256, "brick%d", i);                  ret = dict_get_str (dict, key, &brick); @@ -2127,7 +2140,7 @@ glusterd_op_remove_brick (dict_t *dict, char **op_errstr)                          goto out;                  } -                if (GF_OP_CMD_START == cmd) { +                if (start_remove) {                          brick_tmpstr = gf_strdup (brick);                          if (!brick_tmpstr) {                                  ret = -1; @@ -2150,7 +2163,7 @@ glusterd_op_remove_brick (dict_t *dict, char **op_errstr)                          goto out;                  i++;          } -        if (GF_OP_CMD_START == cmd) +        if (start_remove)                  volinfo->rebal.dict = dict_ref (bricks_dict);          volinfo->subvol_count = (volinfo->brick_count / @@ -2170,7 +2183,8 @@ glusterd_op_remove_brick (dict_t *dict, char **op_errstr)                   * volumes undergoing a detach operation, they should not                   * be modified here.                   */ -                if ((replica_count == 1) && (cmd != GF_OP_CMD_DETACH)) { +                if ((replica_count == 1) && (cmd != GF_OP_CMD_DETACH_COMMIT) && +                    (cmd != GF_OP_CMD_DETACH_COMMIT_FORCE)) {                          if (volinfo->type == GF_CLUSTER_TYPE_REPLICATE) {                                  volinfo->type = GF_CLUSTER_TYPE_NONE;                                  /* backward compatibility */ @@ -2195,8 +2209,8 @@ glusterd_op_remove_brick (dict_t *dict, char **op_errstr)                  goto out;          } -        if (GF_OP_CMD_START == cmd && -                        volinfo->status == GLUSTERD_STATUS_STARTED) { +        if (start_remove && +            volinfo->status == GLUSTERD_STATUS_STARTED) {                  ret = glusterd_svcs_reconfigure (volinfo);                  if (ret) {                          gf_log (this->name, GF_LOG_WARNING, diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index 5bfdb0bb43e..c91fdbcea4f 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -77,6 +77,11 @@ static struct cds_list_head gd_op_sm_queue;  synclock_t gd_op_sm_lock;  glusterd_op_info_t    opinfo = {{0},}; +int +glusterd_bricks_select_rebalance_volume (dict_t *dict, char **op_errstr, +                                         struct cds_list_head *selected); + +  int32_t  glusterd_txn_opinfo_dict_init ()  { @@ -5161,10 +5166,10 @@ glusterd_bricks_select_remove_brick (dict_t *dict, char **op_errstr,          int32_t                                 i = 1;          char                                    key[256] = {0,};          glusterd_pending_node_t                 *pending_node = NULL; +        int32_t                                 command = 0;          int32_t                                 force = 0; -          ret = dict_get_str (dict, "volname", &volname);          if (ret) { @@ -5185,6 +5190,15 @@ glusterd_bricks_select_remove_brick (dict_t *dict, char **op_errstr,                  goto out;          } +        ret = dict_get_int32 (dict, "command", &command); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, "Unable to get command"); +                goto out; +        } + +        if (command == GF_OP_CMD_DETACH_START) +                return glusterd_bricks_select_rebalance_volume(dict, op_errstr, selected); +          ret = dict_get_int32 (dict, "force", &force);          if (ret) {                  gf_log (THIS->name, GF_LOG_INFO, "force flag is not set"); @@ -5863,7 +5877,7 @@ out:  } -static int +int  glusterd_bricks_select_rebalance_volume (dict_t *dict, char **op_errstr,                                           struct cds_list_head *selected)  { @@ -5900,7 +5914,7 @@ glusterd_bricks_select_rebalance_volume (dict_t *dict, char **op_errstr,          } else {                  pending_node->node = volinfo;                  pending_node->type = GD_NODE_REBALANCE; -                cds_list_add_tail (&pending_node->list, &opinfo.pending_bricks); +                cds_list_add_tail (&pending_node->list, selected);                  pending_node = NULL;          } diff --git a/xlators/mgmt/glusterd/src/glusterd-rebalance.c b/xlators/mgmt/glusterd/src/glusterd-rebalance.c index f5bb319cb7d..840438df29a 100644 --- a/xlators/mgmt/glusterd/src/glusterd-rebalance.c +++ b/xlators/mgmt/glusterd/src/glusterd-rebalance.c @@ -215,6 +215,10 @@ glusterd_handle_defrag_start (glusterd_volinfo_t *volinfo, char *op_errstr,          GF_ASSERT (volinfo);          GF_ASSERT (op_errstr); +        if ((cmd == GF_OP_CMD_DETACH_START) && +            (volinfo->rebal.defrag_status == GF_DEFRAG_STATUS_STARTED)) +                return 0; +          ret = glusterd_defrag_start_validate (volinfo, op_errstr, len, op);          if (ret)                  goto out; @@ -495,6 +499,7 @@ __glusterd_handle_defrag_volume (rpcsvc_request_t *req)          if ((cmd == GF_DEFRAG_CMD_STATUS) ||              (cmd == GF_DEFRAG_CMD_STATUS_TIER) || +            (cmd == GF_DEFRAG_CMD_STOP_DETACH_TIER) ||                (cmd == GF_DEFRAG_CMD_STOP)) {                  ret = glusterd_op_begin (req, GD_OP_DEFRAG_BRICK_VOLUME,                                           dict, msg, sizeof (msg)); @@ -844,6 +849,7 @@ glusterd_op_rebalance (dict_t *dict, char **op_errstr, dict_t *rsp_dict)                  ret = 0;                  break; +        case GF_DEFRAG_CMD_START_DETACH_TIER:          case GF_DEFRAG_CMD_STATUS:          case GF_DEFRAG_CMD_STATUS_TIER:                  break; diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c index 0e581b198a9..fdf3365056b 100644 --- a/xlators/mgmt/glusterd/src/glusterd-store.c +++ b/xlators/mgmt/glusterd/src/glusterd-store.c @@ -2795,10 +2795,10 @@ glusterd_store_update_volinfo (glusterd_volinfo_t *volinfo)                          volinfo->tier_info.cold_disperse_count = atoi (value);                  } else if (!strncmp (key, GLUSTERD_STORE_KEY_HOT_COUNT,                                       strlen (key))) { -                        volinfo->tier_info.cold_brick_count = atoi (value); +                        volinfo->tier_info.hot_brick_count = atoi (value);                  } else if (!strncmp (key, GLUSTERD_STORE_KEY_HOT_REPLICA_COUNT,                                       strlen (key))) { -                        volinfo->tier_info.cold_replica_count = atoi (value); +                        volinfo->tier_info.hot_replica_count = atoi (value);                  } else if (!strncmp (key, GLUSTERD_STORE_KEY_HOT_TYPE,                                       strlen (key))) {                          volinfo->tier_info.hot_type = atoi (value); @@ -2890,7 +2890,10 @@ glusterd_store_update_volinfo (glusterd_volinfo_t *volinfo)                          break;                          case GF_CLUSTER_TYPE_TIER: -                        break; +                                volinfo->tier_info.cold_dist_leaf_count = +                                        glusterd_calc_dist_leaf_count ( +                                                volinfo->tier_info.cold_replica_count, 1); +                                break;                          default:                                  GF_ASSERT (0); diff --git a/xlators/mgmt/glusterd/src/glusterd-syncop.c b/xlators/mgmt/glusterd/src/glusterd-syncop.c index c5066b015a3..663b0a73875 100644 --- a/xlators/mgmt/glusterd/src/glusterd-syncop.c +++ b/xlators/mgmt/glusterd/src/glusterd-syncop.c @@ -1542,6 +1542,7 @@ gd_brick_op_phase (glusterd_op_t op, dict_t *op_ctx, dict_t *req_dict,          rpc_clnt_t              *rpc = NULL;          dict_t                  *rsp_dict = NULL;          glusterd_conf_t         *conf = NULL; +        int32_t                 cmd = GF_OP_CMD_NONE;          this = THIS;          conf = this->private; @@ -1585,8 +1586,24 @@ gd_brick_op_phase (glusterd_op_t op, dict_t *op_ctx, dict_t *req_dict,                                  "due to rpc failure.");                          goto out;                  } + +                /* Redirect operation to be detach tier via rebalance flow. */ +                ret = dict_get_int32 (req_dict, "command", &cmd); +                if (!ret) { +                        if (cmd == GF_OP_CMD_DETACH_START) { +                                op = GD_OP_REBALANCE; +                                ret = dict_set_int32 (req_dict, "rebalance-command", +                                                      GF_DEFRAG_CMD_START_DETACH_TIER); +                                if (ret) +                                        goto out; +                        } +                }                  ret = gd_syncop_mgmt_brick_op (rpc, pending_node, op, req_dict,                                                 op_ctx, op_errstr); +                if (cmd == GF_OP_CMD_DETACH_START) { +                        op = GD_OP_REMOVE_BRICK; +                        dict_del (req_dict, "rebalance-command"); +                }                  if (ret)                          goto out; diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index afc3faaefb5..50c5c58bcfa 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -4535,6 +4535,12 @@ glusterd_restart_gsyncds (glusterd_conf_t *conf)          return ret;  } +int +glusterd_calc_dist_leaf_count (int rcount, int scount) +{ +        return (rcount ? rcount : 1) * (scount ? scount : 1); +} +  inline int  glusterd_get_dist_leaf_count (glusterd_volinfo_t *volinfo)  { @@ -4544,7 +4550,7 @@ glusterd_get_dist_leaf_count (glusterd_volinfo_t *volinfo)      if (volinfo->type == GF_CLUSTER_TYPE_DISPERSE)          return volinfo->disperse_count; -    return (rcount ? rcount : 1) * (scount ? scount : 1); +    return glusterd_calc_dist_leaf_count (rcount, scount);  }  int @@ -5258,6 +5264,10 @@ out:  int  glusterd_is_defrag_on (glusterd_volinfo_t *volinfo)  { +        /* Defrag is never enabled for tiered volumes. */ +        if (volinfo->type == GF_CLUSTER_TYPE_TIER) +                return 0; +          return (volinfo->rebal.defrag != NULL);  } diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h index d2dbddec3f1..59a07bacc1c 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.h +++ b/xlators/mgmt/glusterd/src/glusterd-utils.h @@ -378,6 +378,9 @@ glusterd_add_node_to_dict (char *server, dict_t *dict, int count,                             dict_t *vol_opts);  int +glusterd_calc_dist_leaf_count (int rcount, int scount); + +int  glusterd_get_dist_leaf_count (glusterd_volinfo_t *volinfo);  glusterd_brickinfo_t* diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c index ce63e4fc0a4..38c425e8440 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volgen.c +++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c @@ -3025,6 +3025,11 @@ volgen_graph_build_dht_cluster (volgen_graph_t *graph,          if (clusters < 0)                  goto out; +        if (volinfo->type == GF_CLUSTER_TYPE_TIER) { +                ret = 0; +                goto out; +        } +          dht = first_of (graph);          ret = _graph_get_decommissioned_children (dht, volinfo,                                                    &decommissioned_children); @@ -3271,6 +3276,7 @@ volume_volgen_graph_build_clusters_tier (volgen_graph_t *graph,          int                st_type = 0;          char               st_volname[GD_VOLUME_NAME_MAX];          int                dist_count = 0; +        char              *decommissioned_children = NULL;          st_brick_count     = volinfo->brick_count;          st_replica_count   = volinfo->replica_count; @@ -3338,6 +3344,17 @@ volume_volgen_graph_build_clusters_tier (volgen_graph_t *graph,          st_type = GF_CLUSTER_TYPE_TIER; +        ret = _graph_get_decommissioned_children (xl, volinfo, +                                                  &decommissioned_children); +        if (ret) +                goto out; +        if (decommissioned_children) { +                ret = xlator_set_option (xl, "decommissioned-bricks", +                                         decommissioned_children); +                if (ret) +                        goto out; +        } +   out:          volinfo->brick_count     = st_brick_count;          volinfo->replica_count   = st_replica_count;  | 
