--- libglusterfs/src/xlator.c | 84 +++++++++++++++++++++++++++++++ libglusterfs/src/xlator.h | 1 + xlators/cluster/dht/src/dht-common.h | 3 +- xlators/cluster/dht/src/dht-diskusage.c | 52 ++++++++++++++------ xlators/cluster/dht/src/dht.c | 39 ++++++++++---- xlators/cluster/dht/src/nufa.c | 34 +++++++++--- 6 files changed, 176 insertions(+), 37 deletions(-) diff --git a/libglusterfs/src/xlator.c b/libglusterfs/src/xlator.c index c20499d..cdbbacd 100644 --- a/libglusterfs/src/xlator.c +++ b/libglusterfs/src/xlator.c @@ -431,6 +431,90 @@ _volume_option_value_validate (xlator_t *xl, ret = 0; } break; + case GF_OPTION_TYPE_PERCENTORSIZET: + { + uint32_t percent = 0; + uint64_t input_size = 0; + + /* Check if the value is valid percentage */ + if (gf_string2percent (pair->value->data, + &percent) == 0) { + if (percent > 100) { + gf_log (xl->name, GF_LOG_DEBUG, + "value given was greater than 100, " + "assuming this is actually a size"); + if (gf_string2bytesize (pair->value->data, + &input_size) == 0) { + /* Check the range */ + if ((opt->min == 0) && (opt->max == 0)) { + gf_log (xl->name, GF_LOG_DEBUG, + "no range check required for " + "'option %s %s'", + pair->key, pair->value->data); + // It is a size + ret = 0; + goto out; + } + if ((input_size < opt->min) || + (input_size > opt->max)) { + gf_log (xl->name, GF_LOG_ERROR, + "'%"PRId64"' in 'option %s %s' is " + "out of range [%"PRId64" - %"PRId64"]", + input_size, pair->key, + pair->value->data, + opt->min, opt->max); + } + // It is a size + ret = 0; + goto out; + } else { + // It's not a percent or size + gf_log (xl->name, GF_LOG_ERROR, + "invalid number format \"%s\" " + "in \"option %s\"", + pair->value->data, pair->key); + } + + } + // It is a percent + ret = 0; + goto out; + } else { + if (gf_string2bytesize (pair->value->data, + &input_size) == 0) { + /* Check the range */ + if ((opt->min == 0) && (opt->max == 0)) { + gf_log (xl->name, GF_LOG_DEBUG, + "no range check required for " + "'option %s %s'", + pair->key, pair->value->data); + // It is a size + ret = 0; + goto out; + } + if ((input_size < opt->min) || + (input_size > opt->max)) { + gf_log (xl->name, GF_LOG_ERROR, + "'%"PRId64"' in 'option %s %s' is " + "out of range [%"PRId64" - %"PRId64"]", + input_size, pair->key, + pair->value->data, + opt->min, opt->max); + } + } else { + // It's not a percent or size + gf_log (xl->name, GF_LOG_ERROR, + "invalid number format \"%s\" " + "in \"option %s\"", + pair->value->data, pair->key); + } + //It is a size + ret = 0; + goto out; + } + + } + break; case GF_OPTION_TYPE_TIME: { uint32_t input_time = 0; diff --git a/libglusterfs/src/xlator.h b/libglusterfs/src/xlator.h index 2bacc04..c232264 100644 --- a/libglusterfs/src/xlator.h +++ b/libglusterfs/src/xlator.h @@ -808,6 +808,7 @@ typedef enum { GF_OPTION_TYPE_INT, GF_OPTION_TYPE_SIZET, GF_OPTION_TYPE_PERCENT, + GF_OPTION_TYPE_PERCENTORSIZET, GF_OPTION_TYPE_BOOL, GF_OPTION_TYPE_XLATOR, GF_OPTION_TYPE_PATH, diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h index 63a8bb2..1c2b6f4 100644 --- a/xlators/cluster/dht/src/dht-common.h +++ b/xlators/cluster/dht/src/dht-common.h @@ -117,7 +117,8 @@ struct dht_conf { gf_boolean_t search_unhashed; int gen; dht_du_t *du_stats; - uint32_t min_free_disk; + uint64_t min_free_disk; + char disk_unit; int32_t refresh_interval; gf_boolean_t unhashed_sticky_bit; struct timeval last_stat_fetch; diff --git a/xlators/cluster/dht/src/dht-diskusage.c b/xlators/cluster/dht/src/dht-diskusage.c index 561e5d5..4d9e771 100644 --- a/xlators/cluster/dht/src/dht-diskusage.c +++ b/xlators/cluster/dht/src/dht-diskusage.c @@ -43,6 +43,7 @@ dht_du_info_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int this_call_cnt = 0; int i = 0; double percent = 0; + uint64_t bytes = 0; local = frame->local; conf = this->private; @@ -51,14 +52,25 @@ dht_du_info_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (op_ret == -1) goto out; - if (statvfs && statvfs->f_blocks) + if (statvfs && statvfs->f_blocks) { percent = (statvfs->f_bfree * 100) / statvfs->f_blocks; + bytes = (statvfs->f_bfree * statvfs->f_bsize); + } LOCK (&conf->subvolume_lock); { - for (i = 0; i < conf->subvolume_cnt; i++) - if (prev->this == conf->subvolumes[i]) - conf->du_stats[i].avail_percent = percent; + for (i = 0; i < conf->subvolume_cnt; i++){ + if (prev->this == conf->subvolumes[i]){ + conf->du_stats[i].avail_percent = percent; + conf->du_stats[i].avail_space = bytes; + gf_log (this->name, GF_LOG_DEBUG, + "avail_percent on %d is: %f, " + "and avail_space on %d is: %llu", + i, conf->du_stats[i].avail_percent, + i, conf->du_stats[i].avail_space); + } + } + } UNLOCK (&conf->subvolume_lock); @@ -171,19 +183,28 @@ dht_is_subvol_filled (xlator_t *this, xlator_t *subvol) { int i = 0; int subvol_filled = 0; - dht_conf_t *conf = NULL; + dht_conf_t *conf = NULL; conf = this->private; - /* Check for values above 90% free disk */ + /* Check for values above specified percent or free disk */ LOCK (&conf->subvolume_lock); { for (i = 0; i < conf->subvolume_cnt; i++) { - if ((subvol == conf->subvolumes[i]) && - (conf->du_stats[i].avail_percent < - conf->min_free_disk)) { - subvol_filled = 1; - break; + if (subvol == conf->subvolumes[i]) { + if (conf->disk_unit == 'p') { + if (conf->du_stats[i].avail_percent < + conf->min_free_disk) { + subvol_filled = 1; + break; + } + } else { + if (conf->du_stats[i].avail_space < + conf->min_free_disk) { + subvol_filled = 1; + break; + } + } } } } @@ -191,10 +212,10 @@ dht_is_subvol_filled (xlator_t *this, xlator_t *subvol) if (subvol_filled) { if (!(conf->du_stats[i].log++ % GF_UNIVERSAL_ANSWER)) { - gf_log (this->name, GF_LOG_CRITICAL, + gf_log (this->name, GF_LOG_WARNING, "disk space on subvolume '%s' is getting " - "full (%.2f %%), consider adding more nodes", - subvol->name, + "full (%.2f %%), consider adding more nodes", + subvol->name, (100 - conf->du_stats[i].avail_percent)); } } @@ -202,11 +223,12 @@ dht_is_subvol_filled (xlator_t *this, xlator_t *subvol) return subvol_filled; } + xlator_t * dht_free_disk_available_subvol (xlator_t *this, xlator_t *subvol) { int i = 0; - double max_avail = 0; + uint64_t max_avail = 0; xlator_t *avail_subvol = NULL; dht_conf_t *conf = NULL; diff --git a/xlators/cluster/dht/src/dht.c b/xlators/cluster/dht/src/dht.c index 21f468b..4ff9d29 100644 --- a/xlators/cluster/dht/src/dht.c +++ b/xlators/cluster/dht/src/dht.c @@ -81,9 +81,10 @@ int init (xlator_t *this) { dht_conf_t *conf = NULL; - char *lookup_unhashed_str = NULL; + char *temp_str = NULL; int ret = -1; int i = 0; + uint32_t temp_free_disk = 0; if (!this->children) { gf_log (this->name, GF_LOG_CRITICAL, @@ -106,26 +107,40 @@ init (xlator_t *this) conf->search_unhashed = 0; if (dict_get_str (this->options, "lookup-unhashed", - &lookup_unhashed_str) == 0) { - gf_string2boolean (lookup_unhashed_str, + &temp_str) == 0) { + gf_string2boolean (temp_str, &conf->search_unhashed); } conf->unhashed_sticky_bit = 0; if (dict_get_str (this->options, "unhashed-sticky-bit", - &lookup_unhashed_str) == 0) { - gf_string2boolean (lookup_unhashed_str, + &temp_str) == 0) { + gf_string2boolean (temp_str, &conf->unhashed_sticky_bit); } conf->min_free_disk = 10; - - if (dict_get_str (this->options, "min-free-disk", - &lookup_unhashed_str) == 0) { - gf_string2percent (lookup_unhashed_str, - &conf->min_free_disk); - } + conf->disk_unit = 'p'; + + if (dict_get_str (this->options, "min-free-disk", + &temp_str) == 0) { + if (gf_string2percent (temp_str, + &temp_free_disk) == 0) { + if (temp_free_disk > 100) { + gf_string2bytesize (temp_str, + &conf->min_free_disk); + conf->disk_unit = 'b'; + } else { + conf->min_free_disk = (uint64_t)temp_free_disk; + conf->disk_unit = 'p'; + } + } else { + gf_string2bytesize (temp_str, + &conf->min_free_disk); + conf->disk_unit = 'b'; + } + } ret = dht_init_subvolumes (this, conf); @@ -246,7 +261,7 @@ struct volume_options options[] = { .type = GF_OPTION_TYPE_BOOL }, { .key = {"min-free-disk"}, - .type = GF_OPTION_TYPE_PERCENT + .type = GF_OPTION_TYPE_PERCENTORSIZET }, { .key = {NULL} }, }; diff --git a/xlators/cluster/dht/src/nufa.c b/xlators/cluster/dht/src/nufa.c index a61daf8..64b9309 100644 --- a/xlators/cluster/dht/src/nufa.c +++ b/xlators/cluster/dht/src/nufa.c @@ -527,10 +527,11 @@ init (xlator_t *this) xlator_list_t *trav = NULL; data_t *data = NULL; char *local_volname = NULL; - char *lookup_unhashed_str = NULL; + char *temp_str = NULL; int ret = -1; int i = 0; char my_hostname[256]; + uint32_t temp_free_disk = 0; if (!this->children) { gf_log (this->name, GF_LOG_CRITICAL, @@ -553,8 +554,8 @@ init (xlator_t *this) conf->search_unhashed = 0; if (dict_get_str (this->options, "lookup-unhashed", - &lookup_unhashed_str) == 0) { - gf_string2boolean (lookup_unhashed_str, + &temp_str) == 0) { + gf_string2boolean (temp_str, &conf->search_unhashed); } @@ -607,11 +608,26 @@ init (xlator_t *this) conf->local_volume = trav->xlator; conf->min_free_disk = 10; - - data = dict_get (this->options, "min-free-disk"); - if (data) { - gf_string2percent (data->data, &conf->min_free_disk); - } + conf->disk_unit = 'p'; + + if (dict_get_str (this->options, "min-free-disk", + &temp_str) == 0) { + if (gf_string2percent (temp_str, + &temp_free_disk) == 0) { + if (temp_free_disk > 100) { + gf_string2bytesize (temp_str, + &conf->min_free_disk); + conf->disk_unit = 'b'; + } else { + conf->min_free_disk = (uint64_t)temp_free_disk; + conf->disk_unit = 'p'; + } + } else { + gf_string2bytesize (temp_str, + &conf->min_free_disk); + conf->disk_unit = 'b'; + } + } conf->du_stats = CALLOC (conf->subvolume_cnt, sizeof (dht_du_t)); if (!conf->du_stats) { @@ -720,7 +736,7 @@ struct volume_options options[] = { .type = GF_OPTION_TYPE_BOOL }, { .key = {"min-free-disk"}, - .type = GF_OPTION_TYPE_PERCENT + .type = GF_OPTION_TYPE_PERCENTORSIZET }, { .key = {NULL} }, }; -- 1.6.0.6