Date: Tue, 19 May 2009 03:30:03 GMT From: Giorgos Keramidas <keramida@freebsd.org> To: freebsd-fs@FreeBSD.org Subject: Re: bin/121366: [zfs] [patch] Automatic disk scrubbing from periodic(8) Message-ID: <200905190330.n4J3U3V6017615@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR bin/121366; it has been noted by GNATS. From: Giorgos Keramidas <keramida@freebsd.org> To: bug-followup@freebsd.org Cc: Subject: Re: bin/121366: [zfs] [patch] Automatic disk scrubbing from periodic(8) Date: Tue, 19 May 2009 06:29:07 +0300 On Mon, 18 May 2009 02:57:00 GMT, linimon@FreeBSD.org wrote: > Synopsis: [zfs] [patch] Automatic disk scrubbing from periodic(8) > > Responsible-Changed-From-To: freebsd-bugs->freebsd-fs > Responsible-Changed-By: linimon > Responsible-Changed-When: Mon May 18 02:56:46 UTC 2009 > Responsible-Changed-Why: > Over to maintainer(s). > > http://www.freebsd.org/cgi/query-pr.cgi?pr=121366 A variation of the same idea that should auto-kick scrubbing if the 'age' of the last scrub exceeds a configurable threshold would be nice too. The _untested_ patch below is a start at implementing that: http://people.freebsd.org/~keramida/diff/zfs-scrub.periodic.diff I'll give this a few test runs and if it looks useful resubmit with the matching manpage updates too. %%% diff -r cc894c49974d etc/defaults/periodic.conf --- a/etc/defaults/periodic.conf Mon May 18 10:31:18 2009 +0300 +++ b/etc/defaults/periodic.conf Tue May 19 06:27:09 2009 +0300 @@ -226,6 +226,11 @@ pkg_version=pkg_version # Use this program pkg_version_index=/usr/ports/INDEX-8 # Use this index file +# 500.zfs-scrub +weekly_status_zfs_scrub_enable="NO" # Scrub zfs pools +weekly_status_zfs_scrub_auto="NO" # Auto-scrub old pools +weekly_status_zfs_scrub_max_age="1728000" # Scrub age in seconds + # 999.local weekly_local="/etc/weekly.local" # Local scripts diff -r cc894c49974d etc/periodic/weekly/500.zfs-scrub --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/etc/periodic/weekly/500.zfs-scrub Tue May 19 06:27:09 2009 +0300 @@ -0,0 +1,131 @@ +#!/bin/sh +# +# $FreeBSD$ +# +# Report the last time a zfs pool was scrubbed and if auto-scrubbing is +# enabled, kick off a 'zfs scrub' run for pools that were checked too +# far in the past. +# + +# If there is a global system configuration file, suck it in. +if [ -r /etc/defaults/periodic.conf ] +then + . /etc/defaults/periodic.conf + source_periodic_confs +fi + +# scrubdate +# Find the time since the Epoch of the last pool scrub for all +# active zfs pools (0=never, -1=running now). +scrubdate() +{ + for pool in $(/sbin/zpool list -H -o name) ; do + /sbin/zpool status "${pool}" | + while read line ; do + case "${line}" in + scrub:\ scrub\ completed*|scrub:\ resilver\ completed*) + # Extract date from zpool output and convert to epoch. + date=$(echo $line | sed 's/^scrub: .* on //') + date=$(date -jn -f '%+' "$date" '+%s') + ;; + + scrub:\ scrub\ in\ progress*|scrub:\ resilver\ in\ progress*) + # Scrub or resilver is running now. + date='-1' + ;; + + scrub:\ none\ requested) + # Pool has never been scrubed or resilvered. + date='0' + ;; + esac + echo "${date} ${pool}" + done + done +} + +# scrubpool POOL TIME +# Kick off a scrub of zfs pool `POOL' if the `TIME' of its last +# scrub is too old and auto-scrubbing is enabled. +scrubpool() +{ + local _pool="$1" + local _time="$2" + + case "${weekly_status_zfs_scrub_auto}" in + [Yy][Ee][Ss]) + case "${weekly_status_zfs_scrub_max_age}" in + [0-9]*) + ;; + *) + echo '$weekly_status_zfs_scrub_max_age is not set' \ + 'properly - see periodic.conf(5)' + ;; + esac + now=$(date '+%s') + age=$(( "${now}" - "${_time}" )) + if [ -z "${age}" ]; then + echo "Cannot find scrub age for pool ${_pool} -" \ + "forcing a scrub run" + zfs scrub "${_pool}" + return $? + fi + if [ "${age}" -gt "${weekly_status_zfs_scrub_max_age}" ]; then + echo "Last scrub for pool ${_pool} was ${age} seconds ago." + echo "Starting automatic scrub run." + zfs scrub "${_pool}" + return $? + fi + ;; + + [Nn][Oo]) + return 0 + ;; + + *) + echo '$weekly_zfs_scrub_auto is not set properly - ' \ + 'see periodic.conf(5)' + return 1 + ;; + esac +} + +rc=0 +case "$weekly_zfs_scrub_enable" in + [Yy][Ee][Ss]) + havepools=1 + scrubdate | sort -n | \ + while read date pool ; do + havepools=1 + echo "" + case ${date} in + -1) + echo "Scrub or resilver is running for pool $pool:" + /sbin/zpool status ${pool} + status=$? + [ ${status} -ne 0 ] && rc=${status} + ;; + + 0) + scrubpool ${pool} ${time} + status=$? + [ ${status} -ne 0 ] && rc=${status} + ;; + esac + done + if [ ${havepools} -eq 0 ]; then + echo '$weekly_zfs_scrub_enable is set' \ + 'but no zfs pools have been created' + rc=2 + fi + ;; + + [Nn][Oo]) + ;; + + *) + echo '$weekly_zfs_scrub_enable is not set properly - ' \ + 'see periodic.conf(5)' + ;; +esac +exit $rc %%%
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905190330.n4J3U3V6017615>
