summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/dht/src/dht-rebalance.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/cluster/dht/src/dht-rebalance.c')
-rw-r--r--xlators/cluster/dht/src/dht-rebalance.c243
1 files changed, 228 insertions, 15 deletions
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;
}