bin/121366: [zfs] [patch] Automatic disk scrubbing from periodic(8)
Stefan Moeding
sm at kill-9.net
Tue Mar 4 20:10:02 UTC 2008
>Number: 121366
>Category: bin
>Synopsis: [zfs] [patch] Automatic disk scrubbing from periodic(8)
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Tue Mar 04 20:10:01 UTC 2008
>Closed-Date:
>Last-Modified:
>Originator: Stefan Moeding
>Release: FreeBSD 7.0-STABLE i386
>Organization:
>Environment:
System: FreeBSD elan.setuid.de 7.0-STABLE FreeBSD 7.0-STABLE #23: Sat Mar 1 14:17:18 CET 2008 root at elan.setuid.de:/usr/obj/usr/src/sys/ELAN i386
>Description:
The ZFS Best Practices Guide recommends disk scrubbing on a regular
basis. The attached file fits into the periodic(8) framework to start
a weekly scrub. It will look at all pools and choose one of them on a
round-robin basis depending on the date of the last scrub/resilver
unless there is already a scrub or resilver running.
The script should probably be installed to run at the end the weekly
schedule to avoid I/O contention from scrubbing and other weekly scripts.
The new periodic(8) switch 'weekly_zfs_scrubbing_enable' is introduced.
One drawback: ZFS seems to forget the time of a scrub/resilver when
shutting down. On machines with regular reboots and multiple pools
the script will probably pick the same pool every time.
>How-To-Repeat:
>Fix:
#!/bin/sh
#
# $FreeBSD$
#
# 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() {
# Echo lines with timestamp (0=never, -1=running)
# of last scrub/resilver and pool name to stdout.
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")
echo $date $pool
;;
scrub:\ scrub\ in\ progress*|scrub:\ resilver\ in\ progress*)
# Scrub or resilver is running
echo -1 $pool
;;
scrub:\ none\ requested)
# Pool has never been scrubed or resilvered
echo 0 $pool
;;
esac
done
done
}
case "$weekly_zfs_scrubbing_enable" in
[Yy][Ee][Ss])
line=$(scrubdate | sort -n | head -1)
if [ -n "$line" ]; then
date=$(echo $line | cut -d" " -f1)
pool=$(echo $line | cut -d" " -f2)
echo ""
case "$date" in
-1)
echo "Scrub or resilver is running for pool $pool:"
/sbin/zpool status $pool
rc=1
;;
*)
echo "Starting scrub for pool $pool:"
/sbin/zpool scrub $pool
rc=$?
;;
esac
else
echo '$weekly_zfs_scrubbing_enable is set' \
'but no zfs pools have been created'
rc=2
fi;;
*) rc=0;;
esac
exit $rc
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list