summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/ec
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/cluster/ec')
-rw-r--r--xlators/cluster/ec/src/ec-heal.c14
-rw-r--r--xlators/cluster/ec/src/ec.c50
-rw-r--r--xlators/cluster/ec/src/ec.h2
3 files changed, 55 insertions, 11 deletions
diff --git a/xlators/cluster/ec/src/ec-heal.c b/xlators/cluster/ec/src/ec-heal.c
index 31685356db0..6ee1f9ee832 100644
--- a/xlators/cluster/ec/src/ec-heal.c
+++ b/xlators/cluster/ec/src/ec-heal.c
@@ -26,9 +26,6 @@
#include "syncop-utils.h"
#include "cluster-syncop.h"
-#define EC_MAX_BACKGROUND_HEALS 8
-#define EC_MAX_HEAL_WAITERS 128
-
#define alloca0(size) ({void *__ptr; __ptr = alloca(size); memset(__ptr, 0, size); __ptr; })
#define EC_COUNT(array, max) ({int __i; int __res = 0; for (__i = 0; __i < max; __i++) if (array[__i]) __res++; __res; })
#define EC_INTERSECT(dst, src1, src2, max) ({int __i; for (__i = 0; __i < max; __i++) dst[__i] = src1[__i] && src2[__i]; })
@@ -2329,10 +2326,9 @@ __ec_dequeue_heals (ec_t *ec)
if (list_empty (&ec->heal_waiting))
goto none;
- if (ec->healers == EC_MAX_BACKGROUND_HEALS)
+ if ((ec->background_heals > 0) && (ec->healers >= ec->background_heals))
goto none;
- GF_ASSERT (ec->healers < EC_MAX_BACKGROUND_HEALS);
fop = list_entry(ec->heal_waiting.next, ec_fop_data_t, healer);
ec->heal_waiters--;
list_del_init(&fop->healer);
@@ -2400,12 +2396,14 @@ ec_heal_throttle (xlator_t *this, ec_fop_data_t *fop)
LOCK (&ec->lock);
{
- if (ec->heal_waiters >= EC_MAX_HEAL_WAITERS) {
- can_heal = _gf_false;
- } else {
+ if ((ec->background_heals > 0) &&
+ (ec->heal_wait_qlen + ec->background_heals) >
+ (ec->heal_waiters + ec->healers)) {
list_add_tail(&fop->healer, &ec->heal_waiting);
ec->heal_waiters++;
fop = __ec_dequeue_heals (ec);
+ } else {
+ can_heal = _gf_false;
}
}
UNLOCK (&ec->lock);
diff --git a/xlators/cluster/ec/src/ec.c b/xlators/cluster/ec/src/ec.c
index dd51630ea79..e28f402e6fe 100644
--- a/xlators/cluster/ec/src/ec.c
+++ b/xlators/cluster/ec/src/ec.c
@@ -219,15 +219,35 @@ int32_t mem_acct_init(xlator_t * this)
return 0;
}
+void
+ec_configure_background_heal_opts (ec_t *ec, int background_heals,
+ int heal_wait_qlen)
+{
+ if (background_heals == 0) {
+ ec->heal_wait_qlen = 0;
+ } else {
+ ec->heal_wait_qlen = heal_wait_qlen;
+ }
+ ec->background_heals = background_heals;
+}
+
int32_t
reconfigure (xlator_t *this, dict_t *options)
{
- ec_t *ec = this->private;
+ ec_t *ec = this->private;
+ uint32_t heal_wait_qlen = 0;
+ uint32_t background_heals = 0;
- GF_OPTION_RECONF ("self-heal-daemon", ec->shd.enabled, options, bool, failed);
+ GF_OPTION_RECONF ("self-heal-daemon", ec->shd.enabled, options, bool,
+ failed);
GF_OPTION_RECONF ("iam-self-heal-daemon", ec->shd.iamshd, options,
bool, failed);
-
+ GF_OPTION_RECONF ("background-heals", background_heals, options,
+ uint32, failed);
+ GF_OPTION_RECONF ("heal-wait-qlength", heal_wait_qlen, options,
+ uint32, failed);
+ ec_configure_background_heal_opts (ec, background_heals,
+ heal_wait_qlen);
return 0;
failed:
return -1;
@@ -577,6 +597,10 @@ init (xlator_t *this)
ec_method_initialize();
GF_OPTION_INIT ("self-heal-daemon", ec->shd.enabled, bool, failed);
GF_OPTION_INIT ("iam-self-heal-daemon", ec->shd.iamshd, bool, failed);
+ GF_OPTION_INIT ("background-heals", ec->background_heals, uint32, failed);
+ GF_OPTION_INIT ("heal-wait-qlength", ec->heal_wait_qlen, uint32, failed);
+ ec_configure_background_heal_opts (ec, ec->background_heals,
+ ec->heal_wait_qlen);
if (ec->shd.iamshd)
ec_selfheal_daemon_init (this);
@@ -1188,6 +1212,10 @@ int32_t ec_dump_private(xlator_t *this)
gf_proc_dump_write("childs_up", "%u", ec->xl_up_count);
gf_proc_dump_write("childs_up_mask", "%s",
ec_bin(tmp, sizeof(tmp), ec->xl_up, ec->nodes));
+ gf_proc_dump_write("background-heals", "%d", ec->background_heals);
+ gf_proc_dump_write("heal-wait-qlength", "%d", ec->heal_wait_qlen);
+ gf_proc_dump_write("healers", "%d", ec->healers);
+ gf_proc_dump_write("heal-waiters", "%d", ec->heal_waiters);
return 0;
}
@@ -1271,5 +1299,21 @@ struct volume_options options[] =
"translator is running as part of self-heal-daemon "
"or not."
},
+ { .key = {"background-heals"},
+ .type = GF_OPTION_TYPE_INT,
+ .min = 0,/*Disabling background heals*/
+ .max = 256,
+ .default_value = "8",
+ .description = "This option can be used to control number of parallel"
+ " heals",
+ },
+ { .key = {"heal-wait-qlength"},
+ .type = GF_OPTION_TYPE_INT,
+ .min = 0,
+ .max = 65536, /*Around 100MB as of now with sizeof(ec_fop_data_t) at 1800*/
+ .default_value = "128",
+ .description = "This option can be used to control number of heals"
+ " that can wait",
+ },
{ }
};
diff --git a/xlators/cluster/ec/src/ec.h b/xlators/cluster/ec/src/ec.h
index 7f140204ece..f335fd52afc 100644
--- a/xlators/cluster/ec/src/ec.h
+++ b/xlators/cluster/ec/src/ec.h
@@ -47,6 +47,8 @@ struct _ec
gf_lock_t lock;
gf_timer_t * timer;
gf_boolean_t shutdown;
+ uint32_t background_heals;
+ uint32_t heal_wait_qlen;
struct list_head pending_fops;
struct list_head heal_waiting;
struct list_head healing;