Implemented zpool scrub pause/resume

Currently, there is no way to pause a scrub. Pausing may
be useful when the pool is busy with other I/O to preserve
bandwidth.

This patch adds the ability to pause and resume scrubbing.
This is achieved by maintaining a persistent on-disk scrub state.
While the state is 'paused' we do not scrub any more blocks.
We do however perform regular scan housekeeping such as
freeing async destroyed and deadlist blocks while paused.

Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: Thomas Caputi <tcaputi@datto.com>
Reviewed-by: Serapheim Dimitropoulos <serapheimd@gmail.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Alek Pinchuk <apinchuk@datto.com>
Closes #6167
This commit is contained in:
Alek P
2017-07-06 22:16:13 -07:00
committed by Brian Behlendorf
parent 94b25662c5
commit 0ea05c64f8
17 changed files with 364 additions and 126 deletions
+26 -15
View File
@@ -1999,54 +1999,65 @@ function check_vdev_state # pool disk state{online,offline,unavail}
#
# Return 0 is contain, 1 otherwise
#
function check_pool_status # pool token keyword
function check_pool_status # pool token keyword <verbose>
{
typeset pool=$1
typeset token=$2
typeset keyword=$3
typeset verbose=${4:-false}
zpool status -v "$pool" 2>/dev/null | nawk -v token="$token:" '
($1==token) {print $0}' \
| grep -i "$keyword" > /dev/null 2>&1
scan=$(zpool status -v "$pool" 2>/dev/null | nawk -v token="$token:" '
($1==token) {print $0}')
if [[ $verbose == true ]]; then
log_note $scan
fi
echo $scan | grep -i "$keyword" > /dev/null 2>&1
return $?
}
#
# These 5 following functions are instance of check_pool_status()
# These 6 following functions are instance of check_pool_status()
# is_pool_resilvering - to check if the pool is resilver in progress
# is_pool_resilvered - to check if the pool is resilver completed
# is_pool_scrubbing - to check if the pool is scrub in progress
# is_pool_scrubbed - to check if the pool is scrub completed
# is_pool_scrub_stopped - to check if the pool is scrub stopped
# is_pool_scrub_paused - to check if the pool has scrub paused
#
function is_pool_resilvering #pool
function is_pool_resilvering #pool <verbose>
{
check_pool_status "$1" "scan" "resilver in progress since "
check_pool_status "$1" "scan" "resilver in progress since " $2
return $?
}
function is_pool_resilvered #pool
function is_pool_resilvered #pool <verbose>
{
check_pool_status "$1" "scan" "resilvered "
check_pool_status "$1" "scan" "resilvered " $2
return $?
}
function is_pool_scrubbing #pool
function is_pool_scrubbing #pool <verbose>
{
check_pool_status "$1" "scan" "scrub in progress since "
check_pool_status "$1" "scan" "scrub in progress since " $2
return $?
}
function is_pool_scrubbed #pool
function is_pool_scrubbed #pool <verbose>
{
check_pool_status "$1" "scan" "scrub repaired"
check_pool_status "$1" "scan" "scrub repaired" $2
return $?
}
function is_pool_scrub_stopped #pool
function is_pool_scrub_stopped #pool <verbose>
{
check_pool_status "$1" "scan" "scrub canceled"
check_pool_status "$1" "scan" "scrub canceled" $2
return $?
}
function is_pool_scrub_paused #pool <verbose>
{
check_pool_status "$1" "scan" "scrub paused since " $2
return $?
}