From 1075351f0289a7a9774e8fb221a082aaeaf848f3 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 Change-Id: I9b60f2ce24ca3787423a45ec7d502f89215fe45f Signed-off-by: Venky Shankar BUG: 1220041 Reviewed-on: http://review.gluster.org/10721 Tested-by: Gluster Build System Reviewed-by: Gaurav Kumar Garg --- 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