bin/121366: [zfs] [patch] Automatic disk scrubbing from
periodic(8)
Giorgos Keramidas
keramida at freebsd.org
Tue May 19 03:30:04 UTC 2009
The following reply was made to PR bin/121366; it has been noted by GNATS.
From: Giorgos Keramidas <keramida at freebsd.org>
To: bug-followup at 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 at 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
%%%
More information about the freebsd-fs
mailing list