diff options
Diffstat (limited to 'xlators')
| -rw-r--r-- | xlators/cluster/dht/src/dht-common.h | 28 | ||||
| -rw-r--r-- | xlators/cluster/dht/src/dht-rebalance.c | 243 | 
2 files changed, 247 insertions, 24 deletions
diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h index 53d1489e41b..edfb80566c0 100644 --- a/xlators/cluster/dht/src/dht-common.h +++ b/xlators/cluster/dht/src/dht-common.h @@ -26,15 +26,16 @@  #ifndef _DHT_H  #define _DHT_H -#define GF_XATTR_FIX_LAYOUT_KEY     "distribute.fix.layout" -#define GF_XATTR_FILE_MIGRATE_KEY   "trusted.distribute.migrate-data" -#define GF_DHT_LOOKUP_UNHASHED_ON   1 -#define GF_DHT_LOOKUP_UNHASHED_AUTO 2 -#define DHT_PATHINFO_HEADER         "DISTRIBUTE:" -#define DHT_FILE_MIGRATE_DOMAIN     "dht.file.migrate" -#define DHT_LAYOUT_HEAL_DOMAIN      "dht.layout.heal" -#define DHT_LAYOUT_HASH_INVALID     1 -#define TIERING_MIGRATION_KEY       "tiering.migration" +#define GF_XATTR_FIX_LAYOUT_KEY         "distribute.fix.layout" +#define GF_XATTR_TIER_LAYOUT_FIXED_KEY  "trusted.tier.fix.layout.complete" +#define GF_XATTR_FILE_MIGRATE_KEY       "trusted.distribute.migrate-data" +#define GF_DHT_LOOKUP_UNHASHED_ON       1 +#define GF_DHT_LOOKUP_UNHASHED_AUTO     2 +#define DHT_PATHINFO_HEADER             "DISTRIBUTE:" +#define DHT_FILE_MIGRATE_DOMAIN         "dht.file.migrate" +#define DHT_LAYOUT_HEAL_DOMAIN          "dht.layout.heal" +#define TIERING_MIGRATION_KEY           "tiering.migration" +#define DHT_LAYOUT_HASH_INVALID         1  #define DHT_DIR_STAT_BLOCKS          8  #define DHT_DIR_STAT_SIZE            4096 @@ -354,6 +355,13 @@ typedef enum tier_pause_state_ {          TIER_PAUSED  } tier_pause_state_t; +/* This Structure is only used in tiering fixlayout */ +typedef struct gf_tier_fix_layout_arg { +        xlator_t                *this; +        dict_t                  *fix_layout; +        pthread_t               thread_id; +} gf_tier_fix_layout_arg_t; +  typedef struct gf_tier_conf {          int                          is_tier;          int                          watermark_hi; @@ -375,6 +383,8 @@ typedef struct gf_tier_conf {          pthread_mutex_t              pause_mutex;          int                          promote_in_progress;          int                          demote_in_progress; +        /* This Structure is only used in tiering fixlayout */ +        gf_tier_fix_layout_arg_t     tier_fix_layout_arg;  } gf_tier_conf_t;  struct gf_defrag_info_ { diff --git a/xlators/cluster/dht/src/dht-rebalance.c b/xlators/cluster/dht/src/dht-rebalance.c index e28bb76be66..c0041db9436 100644 --- a/xlators/cluster/dht/src/dht-rebalance.c +++ b/xlators/cluster/dht/src/dht-rebalance.c @@ -3058,6 +3058,189 @@ out:  } + + +/****************************************************************************** + *                      Tier background Fix layout functions + ******************************************************************************/ +/* This is the background tier fixlayout thread */ +void * +gf_tier_do_fix_layout (void *args) +{ +        gf_tier_fix_layout_arg_t *tier_fix_layout_arg   =  args; +        int                 ret                         = -1; +        xlator_t            *this                       = NULL; +        dht_conf_t          *conf                       = NULL; +        gf_defrag_info_t    *defrag                     = NULL; +        dict_t              *dict                       = NULL; +        loc_t               loc                         = {0,}; +        struct iatt         iatt                        = {0,}; +        struct iatt         parent                      = {0,}; + +        GF_VALIDATE_OR_GOTO ("tier", tier_fix_layout_arg, out); +        GF_VALIDATE_OR_GOTO ("tier", tier_fix_layout_arg->this, out); +        this = tier_fix_layout_arg->this; + +        conf = this->private; +        GF_VALIDATE_OR_GOTO (this->name, conf, out); + +        defrag = conf->defrag; +        GF_VALIDATE_OR_GOTO (this->name, defrag, out); +        GF_VALIDATE_OR_GOTO (this->name, defrag->root_inode, out); + +        GF_VALIDATE_OR_GOTO (this->name, tier_fix_layout_arg->fix_layout, out); + + +        /* Get Root loc_t */ +        dht_build_root_loc (defrag->root_inode, &loc); +        ret = syncop_lookup (this, &loc, &iatt, &parent, NULL, NULL); +        if (ret) { +                gf_msg (this->name, GF_LOG_ERROR, 0, +                        DHT_MSG_REBALANCE_START_FAILED, +                        "Lookup on root failed."); +                ret = -1; +                goto out; +        } + + +        /* Start the crawl */ +        gf_msg (this->name, GF_LOG_INFO, 0, +                        DHT_MSG_LOG_TIER_STATUS, "Tiering Fixlayout started"); + +        ret = gf_defrag_fix_layout (this, defrag, &loc, +                                    tier_fix_layout_arg->fix_layout, NULL); +        if (ret && ret != 2) { +                gf_msg (this->name, GF_LOG_ERROR, 0, DHT_MSG_REBALANCE_FAILED, +                        "Tiering fixlayout failed."); +                ret = -1; +                goto out; +        } + +        if (ret != 2 && gf_defrag_settle_hash +                        (this, defrag, &loc, +                                tier_fix_layout_arg->fix_layout) != 0) { +                defrag->total_failures++; +                ret = -1; +                goto out; +        } + +        dict = dict_new (); +        if (!dict) { +                ret = -1; +                goto out; +        } + +        ret = dict_set_str (dict, GF_XATTR_TIER_LAYOUT_FIXED_KEY, "yes"); +        if (ret) { +                gf_msg (this->name, GF_LOG_ERROR, 0, +                        DHT_MSG_REBALANCE_FAILED, +                        "Failed to set dictionary value: key = %s", +                        GF_XATTR_TIER_LAYOUT_FIXED_KEY); +                ret = -1; +                goto out; +        } + +        /* Marking the completion of tiering fix layout via a xattr on root */ +        ret = syncop_setxattr (this, &loc, dict, 0, NULL, NULL); +        if (ret) { +                gf_log (this->name, GF_LOG_ERROR, "Failed to set tiering fix " +                        "layout completed xattr on %s", loc.path); +                ret = -1; +                goto out; +        } + +        ret = 0; +out: +        if (ret) +                defrag->total_failures++; + +        if (dict) +                dict_unref (dict); + +        return NULL; +} + +int +gf_tier_start_fix_layout (xlator_t *this, +                         loc_t *loc, +                         gf_defrag_info_t *defrag, +                         dict_t *fix_layout) +{ +        int ret                                       = -1; +        dict_t  *tier_dict                            = NULL; +        gf_tier_fix_layout_arg_t *tier_fix_layout_arg = NULL; + +        tier_dict = dict_new (); +        if (!tier_dict) { +                gf_log ("tier", GF_LOG_ERROR, "Tier fix layout failed :" +                        "Creation of tier_dict failed"); +                ret = -1; +                goto out; +        } + +        /* Check if layout is fixed already */ +        ret = syncop_getxattr (this, loc, &tier_dict, +                                GF_XATTR_TIER_LAYOUT_FIXED_KEY, +                                NULL, NULL); +        if (ret != 0) { + +                tier_fix_layout_arg = &defrag->tier_conf.tier_fix_layout_arg; + +                /*Fill crawl arguments */ +                tier_fix_layout_arg->this = this; +                tier_fix_layout_arg->fix_layout = fix_layout; + +                /* Spawn the fix layout thread so that its done in the +                 * background */ +                ret = pthread_create (&tier_fix_layout_arg->thread_id, NULL, +                                gf_tier_do_fix_layout, tier_fix_layout_arg); +                if (ret) { +                        gf_log ("tier", GF_LOG_ERROR, "Thread creation failed. " +                                "Background fix layout for tiering will not " +                                "work."); +                        defrag->total_failures++; +                        goto out; +                } +        } +        ret = 0; +out: +        if (tier_dict) +                dict_unref (tier_dict); + +        return ret; +} + +int +gf_tier_clear_fix_layout (xlator_t *this, loc_t *loc, gf_defrag_info_t *defrag) +{ +        int ret = -1; + +        ret = syncop_removexattr (this, loc, GF_XATTR_TIER_LAYOUT_FIXED_KEY, +                                  NULL, NULL); +        if (ret) { +                gf_log (this->name, GF_LOG_WARNING, +                        "Failed removing tier fix layout " +                        "xattr from %s", loc->path); +                defrag->total_failures++; +                ret = -1; +                goto out; +        } +        ret = 0; +out: +        return ret; +} + +void +gf_tier_wait_fix_lookup (gf_defrag_info_t *defrag) { +        if (defrag->tier_conf.tier_fix_layout_arg.thread_id) { +                pthread_join (defrag->tier_conf.tier_fix_layout_arg.thread_id, +                        NULL); +        } +} +/******************Tier background Fix layout functions END********************/ + + +  int  gf_defrag_start_crawl (void *data)  { @@ -3247,23 +3430,16 @@ gf_defrag_start_crawl (void *data)                  }          } -        ret = gf_defrag_fix_layout (this, defrag, &loc, fix_layout, -                                    migrate_data); -        if (ret) { -                defrag->total_failures++; -                ret = -1; -                goto out; -        } - -        if (gf_defrag_settle_hash (this, defrag, &loc, fix_layout) != 0) { -                defrag->total_failures++; -                ret = -1; -                goto out; -        } -          if (defrag->cmd == GF_DEFRAG_CMD_START_TIER) { +                /* Fix layout for attach tier */ +                ret = gf_tier_start_fix_layout (this, &loc, defrag, fix_layout); +                if (ret) { +                        goto out; +                } +                  methods = &(conf->methods); +                /* Calling tier_start of tier.c */                  methods->migration_other(this, defrag);                  if (defrag->cmd == GF_DEFRAG_CMD_START_DETACH_TIER) { @@ -3274,9 +3450,35 @@ gf_defrag_start_crawl (void *data)                                  goto out;                  } +        } else { +                ret = gf_defrag_fix_layout (this, defrag, &loc, fix_layout, +                                    migrate_data); +                if (ret && ret != 2) { +                        defrag->total_failures++; +                        ret = -1; +                        goto out; +                } + +                if (ret != 2 && gf_defrag_settle_hash +                        (this, defrag, &loc, fix_layout) != 0) { +                        defrag->total_failures++; +                        ret = -1; +                        goto out; +                } + +                if (defrag->cmd == GF_DEFRAG_CMD_START_DETACH_TIER) { +                        /* If its was a detach remove the tier fix-layout +                         * xattr on root */ +                         ret = gf_tier_clear_fix_layout (this, &loc, defrag); +                         if (ret) { +                                goto out; +                         } +                }          } +          gf_log ("DHT", GF_LOG_INFO, "crawling file-system completed");  out: +          /* We are here means crawling the entire file system is done             or something failed. Set defrag->crawl_done flag to intimate             the migrator threads to exhaust the defrag->queue and terminate*/ @@ -3301,6 +3503,13 @@ out:                  pthread_join (tid[i], NULL);          } +        if (defrag->cmd == GF_DEFRAG_CMD_START_TIER) { +                /* Wait for the tier fixlayout to +                 * complete if its was started.*/ +                 gf_tier_wait_fix_lookup (defrag); +        } + +          if (defrag->queue) {                  gf_dirent_free (defrag->queue[0].df_entry);                  INIT_LIST_HEAD (&(defrag->queue[0].list)); @@ -3329,7 +3538,11 @@ out:          conf->defrag = NULL;          if (dict) -                dict_unref(dict); +                dict_unref (dict); + +        if (migrate_data) +                dict_unref (migrate_data); +  exit:          return ret;  }  | 
