From 9dcb6e07cf432a047654a3f04a23a438fe969bfb Mon Sep 17 00:00:00 2001 From: Venky Shankar Date: Mon, 4 May 2015 11:58:23 +0530 Subject: features/bitrot: Scrubber pause/resume With logical scan/scrub split, pausing filesystem scrubber is an override to the thread throttling mechanism, which effectively throttles "down" number of scrubber threads to zero. This causes scanner to wait until threads are spawned again (when resumed) thereby continuing where it left off (since the file tree walk stack is effectively preserved when the main scanner thread is waiting for scrubbers to consume scanned entries). The only catch is when scrubber daemon restarts: file tree walk stack is lost and scrubbing initiates from root. This is probably OK for now (can be changed later to persist parent directory information before entering pause state). Change-Id: I5109a749b7fccd0f5367765078f46e6522dd32a1 BUG: 1208131 Signed-off-by: Venky Shankar Reviewed-on: http://review.gluster.org/10521 Reviewed-by: Vijay Bellur Tested-by: Vijay Bellur --- xlators/features/bit-rot/src/bitd/bit-rot-scrub.c | 65 +++++++++++++++++++---- xlators/features/bit-rot/src/bitd/bit-rot.c | 1 + xlators/features/bit-rot/src/bitd/bit-rot.h | 1 + 3 files changed, 58 insertions(+), 9 deletions(-) (limited to 'xlators/features/bit-rot') diff --git a/xlators/features/bit-rot/src/bitd/bit-rot-scrub.c b/xlators/features/bit-rot/src/bitd/bit-rot-scrub.c index 8a80052f250..e96d82d6282 100644 --- a/xlators/features/bit-rot/src/bitd/bit-rot-scrub.c +++ b/xlators/features/bit-rot/src/bitd/bit-rot-scrub.c @@ -555,6 +555,7 @@ br_scrubber_calc_scale (xlator_t *this, switch (throttle) { case BR_SCRUB_THROTTLE_VOID: + case BR_SCRUB_THROTTLE_STALLED: scale = 0; break; case BR_SCRUB_THROTTLE_LAZY: @@ -839,10 +840,28 @@ br_scrubber_configure (xlator_t *this, br_private_t *priv, return ret; } +static inline int32_t +br_scrubber_fetch_option (xlator_t *this, + char *opt, dict_t *options, char **value) +{ + if (options) + GF_OPTION_RECONF (opt, *value, options, str, error_return); + else + GF_OPTION_INIT (opt, *value, str, error_return); + + return 0; + + error_return: + return -1; +} + +/* internal "throttle" override */ +#define BR_SCRUB_STALLED "STALLED" + /* TODO: token buket spec */ static int32_t -br_scrubber_handle_throttle (xlator_t *this, - br_private_t *priv, dict_t *options) +br_scrubber_handle_throttle (xlator_t *this, br_private_t *priv, + dict_t *options, gf_boolean_t scrubstall) { int32_t ret = 0; char *tmp = NULL; @@ -851,11 +870,12 @@ br_scrubber_handle_throttle (xlator_t *this, fsscrub = &priv->fsscrub; - if (options) - GF_OPTION_RECONF ("scrub-throttle", - tmp, options, str, error_return); - else - GF_OPTION_INIT ("scrub-throttle", tmp, str, error_return); + ret = br_scrubber_fetch_option (this, "scrub-throttle", options, &tmp); + if (ret) + goto error_return; + + if (scrubstall) + tmp = BR_SCRUB_STALLED; if (strcasecmp (tmp, "lazy") == 0) nthrottle = BR_SCRUB_THROTTLE_LAZY; @@ -863,6 +883,8 @@ br_scrubber_handle_throttle (xlator_t *this, nthrottle = BR_SCRUB_THROTTLE_NORMAL; else if (strcasecmp (tmp, "aggressive") == 0) nthrottle = BR_SCRUB_THROTTLE_AGGRESSIVE; + else if (strcasecmp (tmp, BR_SCRUB_STALLED) == 0) + nthrottle = BR_SCRUB_THROTTLE_STALLED; else goto error_return; @@ -878,13 +900,38 @@ br_scrubber_handle_throttle (xlator_t *this, return -1; } -/* TODO: pause/resume, frequency */ +static int32_t +br_scrubber_handle_stall (xlator_t *this, br_private_t *priv, + dict_t *options, gf_boolean_t *scrubstall) +{ + int32_t ret = 0; + char *tmp = NULL; + + ret = br_scrubber_fetch_option (this, "scrub-state", options, &tmp); + if (ret) + goto error_return; + + if (strcasecmp (tmp, "pause") == 0) /* anything else is active */ + *scrubstall = _gf_true; + + return 0; + + error_return: + return -1; +} + +/* TODO: frequency */ int32_t br_scrubber_handle_options (xlator_t *this, br_private_t *priv, dict_t *options) { int32_t ret = 0; + gf_boolean_t scrubstall = _gf_false; /* not as dangerous as it sounds */ + + ret = br_scrubber_handle_stall (this, priv, options, &scrubstall); + if (ret) + goto error_return; - ret = br_scrubber_handle_throttle (this, priv, options); + ret = br_scrubber_handle_throttle (this, priv, options, scrubstall); if (ret) goto error_return; diff --git a/xlators/features/bit-rot/src/bitd/bit-rot.c b/xlators/features/bit-rot/src/bitd/bit-rot.c index eea81aec53a..5638b0f348b 100644 --- a/xlators/features/bit-rot/src/bitd/bit-rot.c +++ b/xlators/features/bit-rot/src/bitd/bit-rot.c @@ -1626,6 +1626,7 @@ struct volume_options options[] = { }, { .key = {"scrub-state"}, .type = GF_OPTION_TYPE_STR, + .default_value = "active", .description = "Pause/Resume scrub. Upon resume, scrubber " "continues from where it left off.", }, diff --git a/xlators/features/bit-rot/src/bitd/bit-rot.h b/xlators/features/bit-rot/src/bitd/bit-rot.h index 6f21a6985ba..66515e3213c 100644 --- a/xlators/features/bit-rot/src/bitd/bit-rot.h +++ b/xlators/features/bit-rot/src/bitd/bit-rot.h @@ -43,6 +43,7 @@ typedef enum scrub_throttle { BR_SCRUB_THROTTLE_LAZY = 0, BR_SCRUB_THROTTLE_NORMAL = 1, BR_SCRUB_THROTTLE_AGGRESSIVE = 2, + BR_SCRUB_THROTTLE_STALLED = 3, } scrub_throttle_t; #define signature_size(hl) (sizeof (br_isignature_t) + hl + 1) -- cgit