This script will start a scrub on each ZFS pool (one at a time) and will send an e-mail or display the result when everyting is completed. I wrote this script to launch each scrub one after the other and a summary by e-mail that can tell me how much time it took to each ZFS scrub.
Put this script on your FreeNAS box using the File Manager or directly at the shell by copy-pasting it. I put it in “/mnt/usb-data/bin/scrub.sh”.
To make it run automatically, go into System –> Advanced –> Cron and add it as Monthly cron job.
NOTE: Don’t forget to change the e-mail addresses in the script!
FROM=from@devnull.com TO=to@devnull.com
Here’s the script:
#!/bin/bash
#VERSION: 0.2
#AUTHOR: gimpe
#EMAIL: gimpe [at] hype-o-thetic.com
#WEBSITE: http://hype-o-thetic.com
#DESCRIPTION: Created on FreeNAS 0.7RC1 (Sardaukar)
# This script will start a scrub on each ZFS pool (one at a time) and
# will send an e-mail or display the result when everyting is completed.
#CHANGELOG
# 0.2: 2009-08-27 Code clean up
# 0.1: 2009-08-25 Make it work
#SOURCES:
# http://aspiringsysadmin.com/blog/2007/06/07/scrub-your-zfs-file-systems-regularly/
# http://www.sun.com/bigadmin/scripts/sunScripts/zfs_completion.bash.txt
# http://www.packetwatch.net/documents/guides/2009073001.php
# e-mail variables
FROM=from@devnull.com
TO=to@devnull.com
SUBJECT="$0 results"
BODY=""
# arguments
VERBOSE=0
SENDEMAIL=1
args=("$@")
for arg in $args; do
case $arg in
"-v" | "--verbose")
VERBOSE=1
;;
"-n" | "--noemail")
SENDEMAIL=0
;;
"-a" | "--author")
echo "by gimpe at hype-o-thetic.com"
exit
;;
"-h" | "--help" | *)
echo "
usage: $0 [-v --verbose|-n --noemail]
-v --verbose output display
-n --noemail don't send an e-mail with result
-a --author display author info (by gimpe at hype-o-thetic.com)
-h --help display this help
"
exit
;;
esac
done
# work variables
ERROR=0
SEP=" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "
RUNNING=1
# commands & configuration
ZPOOL=/sbin/zpool
PRINTF=/usr/bin/printf
MSMTP=/usr/local/bin/msmtp
MSMTPCONF=/var/etc/msmtp.conf
# print a message
function _log {
DATE="`date +"%Y-%m-%d %H:%M:%S"`"
# add message to e-mail body
BODY="${BODY}$DATE: $1\n"
# output to console if verbose mode
if [ $VERBOSE = 1 ]; then
echo "$DATE: $1"
fi
}
# find all pools
pools=$($ZPOOL list -H -o name)
# for each pool
for pool in $pools; do
# start scrub for $pool
_log "starting scrub on $pool"
zpool scrub $pool
RUNNING=1
# wait until scrub for $pool has finished running
while [ $RUNNING = 1 ]; do
# still running?
if $ZPOOL status -v $pool | grep -q "scrub in progress"; then
sleep 60
# not running
else
# finished with this pool, exit
_log "scrub ended on $pool"
_log "`$ZPOOL status -v $pool`"
_log "$SEP"
RUNNING=0
# check for errors
if ! $ZPOOL status -v $pool | grep -q "No known data errors"; then
_log "data errors detected on $pool"
ERROR=1
fi
fi
done
done
# change e-mail subject if there was error
if [ $ERROR = 1 ]; then
SUBJECT="${SUBJECT}: ERROR(S) DETECTED"
fi
# send e-mail
if [ $SENDEMAIL = 1 ]; then
$PRINTF "From:$FROM\nTo:$TO\nSubject:$SUBJECT\n\n$BODY" | $MSMTP --file=$MSMTPCONF -t
fi
Here’s what the e-mail content looks like:
2009-09-01 02:00:01: starting scrub on backup
2009-09-01 02:35:19: scrub ended on backup
2009-09-01 02:35:19: pool: backup
state: ONLINE
scrub: scrub completed with 0 errors on Tue Sep 1 02:34:50 2009
config:
NAME STATE READ WRITE CKSUM
backup ONLINE 0 0 0
mirror ONLINE 0 0 0
ad8 ONLINE 0 0 0
ad10 ONLINE 0 0 0
errors: No known data errors
2009-09-01 02:35:19: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2009-09-01 02:35:19: starting scrub on data
2009-09-01 02:41:24: scrub ended on data
2009-09-01 02:41:24: pool: data
state: ONLINE
scrub: scrub completed with 0 errors on Tue Sep 1 02:40:50 2009
config:
NAME STATE READ WRITE CKSUM
data ONLINE 0 0 0
ad6 ONLINE 0 0 0
errors: No known data errors
2009-09-01 02:41:24: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2009-09-01 02:41:24: starting scrub on media
2009-09-01 05:41:58: scrub ended on media
2009-09-01 05:41:58: pool: media
state: ONLINE
scrub: scrub completed with 0 errors on Tue Sep 1 05:41:00 2009
config:
NAME STATE READ WRITE CKSUM
media ONLINE 0 0 0
ad14 ONLINE 0 0 0
errors: No known data errors
2009-09-01 05:41:58: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please, leave me a comment if you use it to let me know what you think!


[...] You can find the script here: FreeNAS Bash script to start a ZFS scrub on each pool (scrub.sh) – hype-o-thetic?com [...]
[...] hype-o-thetic?com : FreeNAS Bash playscript to move a ZFS vegetation on … [...]
Many thanks for this script. I’ve written a blogpost about scrubbing and take snapshots and I’ve added a link to your website…
See here -> http://harryd71.blogspot.com/2009/10/freenas-07-zfs-snapshots-and-scrubbing.html
[...] hype-o-thetic?com : FreeNAS Bash script to start a ZFS scrub …pools=$($ZPOOL list -H -o name) # for each pool. for pool in $pools; do # start scrub for … zpool [...]