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.c204
1 files changed, 180 insertions, 24 deletions
diff --git a/xlators/cluster/dht/src/dht-rebalance.c b/xlators/cluster/dht/src/dht-rebalance.c
index 09bfac2dd1f..5653116a814 100644
--- a/xlators/cluster/dht/src/dht-rebalance.c
+++ b/xlators/cluster/dht/src/dht-rebalance.c
@@ -48,6 +48,7 @@
} \
uint64_t g_totalfiles = 0;
+uint64_t g_totalsize = 0;
void
@@ -2586,6 +2587,7 @@ gf_defrag_migrate_single_file (void *opaque)
LOCK (&defrag->lock);
{
defrag->skipped += 1;
+ defrag->size_processed += iatt.ia_size;
}
UNLOCK (&defrag->lock);
} else if (fop_errno == ENOTSUP) {
@@ -2594,6 +2596,7 @@ gf_defrag_migrate_single_file (void *opaque)
LOCK (&defrag->lock);
{
defrag->skipped += 1;
+ defrag->size_processed += iatt.ia_size;
}
UNLOCK (&defrag->lock);
} else if (fop_errno != EEXIST) {
@@ -2604,6 +2607,7 @@ gf_defrag_migrate_single_file (void *opaque)
LOCK (&defrag->lock);
{
defrag->total_failures += 1;
+ defrag->size_processed += iatt.ia_size;
}
UNLOCK (&defrag->lock);
@@ -2627,6 +2631,7 @@ gf_defrag_migrate_single_file (void *opaque)
{
defrag->total_files += 1;
defrag->total_data += iatt.ia_size;
+ defrag->size_processed += iatt.ia_size;
}
UNLOCK (&defrag->lock);
@@ -2896,8 +2901,11 @@ gf_defrag_get_entry (xlator_t *this, int i, struct dht_container **container,
!strcmp (df_entry->d_name, ".."))
continue;
- if (IA_ISDIR (df_entry->d_stat.ia_type))
+
+ if (IA_ISDIR (df_entry->d_stat.ia_type)) {
+ defrag->size_processed += df_entry->d_stat.ia_size;
continue;
+ }
defrag->num_files_lookedup++;
@@ -2905,6 +2913,7 @@ gf_defrag_get_entry (xlator_t *this, int i, struct dht_container **container,
(gf_defrag_pattern_match (defrag, df_entry->d_name,
df_entry->d_stat.ia_size)
== _gf_false)) {
+ defrag->size_processed += df_entry->d_stat.ia_size;
continue;
}
@@ -3975,10 +3984,25 @@ gf_tier_wait_fix_lookup (gf_defrag_info_t *defrag) {
/******************Tier background Fix layout functions END********************/
+uint64_t
+gf_defrag_subvol_file_size (xlator_t *this, loc_t *root_loc)
+{
+ int ret = -1;
+ struct statvfs buf = {0,};
+ if (!this)
+ return 0;
+ ret = syncop_statfs (this, root_loc, &buf, NULL, NULL);
+ if (ret) {
+ /* Aargh! */
+ return 0;
+ }
+ return ((buf.f_blocks - buf.f_bfree) * buf.f_frsize);
+}
-uint64_t gf_defrag_subvol_file_cnt (xlator_t *this, loc_t *root_loc)
+uint64_t
+gf_defrag_subvol_file_cnt (xlator_t *this, loc_t *root_loc)
{
int ret = -1;
struct statvfs buf = {0,};
@@ -3996,6 +4020,35 @@ uint64_t gf_defrag_subvol_file_cnt (xlator_t *this, loc_t *root_loc)
uint64_t
+gf_defrag_total_file_size (xlator_t *this, loc_t *root_loc)
+{
+ dht_conf_t *conf = NULL;
+ int i = 0;
+ uint64_t size_files = 0;
+ uint64_t total_size = 0;
+
+ conf = this->private;
+ if (!conf) {
+ return 0;
+ }
+
+ for (i = 0 ; i < conf->local_subvols_cnt; i++) {
+ size_files = gf_defrag_subvol_file_size (conf->local_subvols[i],
+ root_loc);
+ total_size += size_files;
+ gf_msg (this->name, GF_LOG_INFO, 0, 0, "local subvol: %s,"
+ "cnt = %"PRIu64, conf->local_subvols[i]->name,
+ size_files);
+ }
+
+ gf_msg (this->name, GF_LOG_INFO, 0, 0,
+ "Total size files = %"PRIu64, total_size);
+
+ return total_size;
+}
+
+
+uint64_t
gf_defrag_total_file_cnt (xlator_t *this, loc_t *root_loc)
{
dht_conf_t *conf = NULL;
@@ -4080,8 +4133,12 @@ out:
static void*
dht_file_counter_thread (void *args)
{
- gf_defrag_info_t *defrag = NULL;
- loc_t root_loc = {0,};
+ gf_defrag_info_t *defrag = NULL;
+ loc_t root_loc = {0,};
+ struct timespec time_to_wait = {0,};
+ struct timeval now = {0,};
+ uint64_t tmp_size = 0;
+
if (!args)
return NULL;
@@ -4091,18 +4148,38 @@ dht_file_counter_thread (void *args)
while (defrag->defrag_status == GF_DEFRAG_STATUS_STARTED) {
- sleep (FILE_CNT_INTERVAL);
- g_totalfiles = gf_defrag_total_file_cnt (defrag->this,
+ gettimeofday (&now, NULL);
+ time_to_wait.tv_sec = now.tv_sec + 600;
+ time_to_wait.tv_nsec = 0;
+
+
+ pthread_mutex_lock (&defrag->fc_mutex);
+ pthread_cond_timedwait (&defrag->fc_wakeup_cond,
+ &defrag->fc_mutex,
+ &time_to_wait);
+
+ pthread_mutex_unlock (&defrag->fc_mutex);
+
+
+ if (defrag->defrag_status != GF_DEFRAG_STATUS_STARTED)
+ break;
+
+ tmp_size = gf_defrag_total_file_size (defrag->this,
&root_loc);
- if (!g_totalfiles) {
+ gf_log ("dht", GF_LOG_INFO,
+ "tmp data size =%"PRIu64,
+ tmp_size);
+
+ if (!tmp_size) {
gf_msg ("dht", GF_LOG_ERROR, 0, 0, "Failed to get "
- "the total number of files. Unable to estimate "
+ "the total data size. Unable to estimate "
"time to complete rebalance.");
} else {
+ g_totalsize = tmp_size;
gf_msg_debug ("dht", 0,
- "total number of files =%"PRIu64,
- g_totalfiles);
+ "total data size =%"PRIu64,
+ g_totalsize);
}
}
@@ -4136,7 +4213,9 @@ gf_defrag_start_crawl (void *data)
gf_boolean_t is_tier_detach = _gf_false;
call_frame_t *statfs_frame = NULL;
xlator_t *old_THIS = NULL;
- int j = 0;
+ int j = 0;
+ gf_boolean_t fc_thread_started = _gf_false;
+
this = data;
if (!this)
@@ -4281,6 +4360,13 @@ gf_defrag_start_crawl (void *data)
}
}
+ g_totalsize = gf_defrag_total_file_size (this, &loc);
+ if (!g_totalsize) {
+ gf_msg (this->name, GF_LOG_ERROR, 0, 0, "Failed to get "
+ "the total data size. Unable to estimate "
+ "time to complete rebalance.");
+ }
+
g_totalfiles = gf_defrag_total_file_cnt (this, &loc);
if (!g_totalfiles) {
gf_msg (this->name, GF_LOG_ERROR, 0, 0, "Failed to get "
@@ -4288,16 +4374,19 @@ gf_defrag_start_crawl (void *data)
"time to complete rebalance.");
}
- ret = gf_thread_create_detached (&filecnt_thread,
- &dht_file_counter_thread,
- (void *)defrag);
+ ret = pthread_create (&filecnt_thread, NULL,
+ &dht_file_counter_thread,
+ (void *)defrag);
if (ret) {
gf_msg (this->name, GF_LOG_ERROR, ret, 0, "Failed to "
"create the file counter thread ");
ret = 0;
+ } else {
+ fc_thread_started = _gf_true;
}
+
/* Initialize global entry queue */
defrag->queue = GF_CALLOC (1, sizeof (struct dht_container),
gf_dht_mt_container_t);
@@ -4416,8 +4505,6 @@ out:
pthread_join (tid[i], NULL);
}
-
-
GF_FREE (tid);
if (defrag->cmd == GF_DEFRAG_CMD_START_TIER) {
@@ -4443,6 +4530,16 @@ out:
defrag->defrag_status = GF_DEFRAG_STATUS_COMPLETE;
}
+ if (fc_thread_started) {
+ pthread_mutex_lock (&defrag->fc_mutex);
+ {
+ pthread_cond_broadcast (&defrag->fc_wakeup_cond);
+ }
+ pthread_mutex_unlock (&defrag->fc_mutex);
+
+ pthread_join (filecnt_thread, NULL);
+ }
+
dht_send_rebalance_event (this, defrag->cmd, defrag->defrag_status);
LOCK (&defrag->lock);
@@ -4532,6 +4629,52 @@ out:
uint64_t
+gf_defrag_get_estimates_based_on_size (dht_conf_t *conf)
+{
+ gf_defrag_info_t *defrag = NULL;
+ double rate_processed = 0;
+ uint64_t total_processed = 0;
+ uint64_t tmp_count = 0;
+ uint64_t time_to_complete = 0;
+ struct timeval now = {0,};
+ double elapsed = 0;
+
+ defrag = conf->defrag;
+
+ if (!g_totalsize)
+ goto out;
+
+ gettimeofday (&now, NULL);
+ elapsed = now.tv_sec - defrag->start_time.tv_sec;
+
+ total_processed = defrag->size_processed;
+
+ /* rate at which files processed */
+ rate_processed = (total_processed)/elapsed;
+
+ tmp_count = g_totalsize;
+
+ if (rate_processed) {
+ time_to_complete = (tmp_count)/rate_processed;
+
+ } else {
+
+ gf_msg (THIS->name, GF_LOG_ERROR, 0, 0,
+ "Unable to calculate estimated time for rebalance");
+ }
+
+ gf_log (THIS->name, GF_LOG_INFO,
+ "TIME: (size) total_processed=%"PRIu64" tmp_cnt = %"PRIu64","
+ "rate_processed=%f, elapsed = %f", total_processed, tmp_count,
+ rate_processed, elapsed);
+
+out:
+ return time_to_complete;
+}
+
+
+
+uint64_t
gf_defrag_get_estimates (dht_conf_t *conf)
{
gf_defrag_info_t *defrag = NULL;
@@ -4542,17 +4685,17 @@ gf_defrag_get_estimates (dht_conf_t *conf)
uint64_t total_processed = 0;
uint64_t tmp_count = 0;
uint64_t time_to_complete = 0;
- struct timeval end = {0,};
+ struct timeval now = {0,};
double elapsed = 0;
defrag = conf->defrag;
if (!g_totalfiles)
- return 0;
+ goto out;
- gettimeofday (&end, NULL);
- elapsed = end.tv_sec - defrag->start_time.tv_sec;
+ gettimeofday (&now, NULL);
+ elapsed = now.tv_sec - defrag->start_time.tv_sec;
/* I tried locking before accessing num_files_lookedup and
* num_dirs_processed but the status function
@@ -4599,7 +4742,7 @@ gf_defrag_get_estimates (dht_conf_t *conf)
}
gf_log (THIS->name, GF_LOG_INFO,
- "TIME: total_processed=%"PRIu64" tmp_cnt = %"PRIu64","
+ "TIME: (count) total_processed=%"PRIu64" tmp_cnt = %"PRIu64","
"rate_lookedup=%f", total_processed, tmp_count,
rate_lookedup);
@@ -4646,19 +4789,32 @@ gf_defrag_status_get (dht_conf_t *conf, dict_t *dict)
elapsed = end.tv_sec - defrag->start_time.tv_sec;
+ /* The rebalance is still in progress */
+
if ((defrag->cmd != GF_DEFRAG_CMD_START_TIER)
- && (defrag->defrag_status == GF_DEFRAG_STATUS_STARTED)) {
+ && (defrag->defrag_status == GF_DEFRAG_STATUS_STARTED)) {
+/*
time_to_complete = gf_defrag_get_estimates (conf);
if (time_to_complete && (time_to_complete > elapsed))
time_left = time_to_complete - elapsed;
gf_log (THIS->name, GF_LOG_INFO,
- "TIME: Estimated total time to complete = %"PRIu64
- " seconds, seconds left = %"PRIu64"",
+ "TIME: Estimated total time to complete based on"
+ " count = %"PRIu64 " seconds, seconds left = %"PRIu64"",
time_to_complete, time_left);
+*/
+ time_to_complete = gf_defrag_get_estimates_based_on_size (conf);
+
+ if (time_to_complete && (time_to_complete > elapsed))
+ time_left = time_to_complete - elapsed;
+
+ gf_log (THIS->name, GF_LOG_INFO,
+ "TIME: Estimated total time to complete (size)= %"PRIu64
+ " seconds, seconds left = %"PRIu64"",
+ time_to_complete, time_left);
}
if (!dict)