1#!/bin/sh 2# 3# $FreeBSD$ 4# 5 6# If there is a global system configuration file, suck it in. 7# 8 9newline=" 10" # A single newline 11 12if [ -r /etc/defaults/periodic.conf ] 13then 14 . /etc/defaults/periodic.conf 15 source_periodic_confs 16fi 17 18: ${daily_scrub_zfs_default_threshold=35} 19 20case "$daily_scrub_zfs_enable" in 21 [Yy][Ee][Ss]) 22 echo 23 echo 'Scrubbing of zfs pools:' 24 25 if [ -z "${daily_scrub_zfs_pools}" ]; then 26 daily_scrub_zfs_pools="$(zpool list -H -o name)" 27 fi 28 29 rc=0 30 for pool in ${daily_scrub_zfs_pools}; do 31 # sanity check 32 _status=$(zpool list "${pool}" 2> /dev/null) 33 if [ $? -ne 0 ]; then 34 rc=2 35 echo " WARNING: pool '${pool}' specified in" 36 echo " '/etc/periodic.conf:daily_scrub_zfs_pools'" 37 echo " does not exist" 38 continue 39 fi 40 _status=${_status##*$newline} 41 case ${_status} in 42 *FAULTED*) 43 rc=3 44 echo "Skipping faulted pool: ${pool}" 45 continue ;; 46 *UNAVAIL*) 47 rc=4 48 echo "Skipping unavailable pool: ${pool}" 49 continue ;; 50 esac 51 52 # determine how many days shall be between scrubs 53 eval _pool_threshold=\${daily_scrub_zfs_$(echo "${pool}"|tr ".:-" "_")_threshold} 54 if [ -z "${_pool_threshold}" ];then 55 _pool_threshold=${daily_scrub_zfs_default_threshold} 56 fi 57 58 _last_scrub=$(zpool history ${pool} | \ 59 egrep "^[0-9\.\:\-]{19} zpool scrub ${pool}\$" | tail -1 |\ 60 cut -d ' ' -f 1) 61 if [ -z "${_last_scrub}" ]; then 62 # creation time of the pool if no scrub was done 63 _last_scrub=$(zpool history ${pool} | \ 64 sed -ne '2s/ .*$//p') 65 fi 66 if [ -z "${_last_scrub}" ]; then 67 echo " skipping scrubbing of pool '${pool}':" 68 echo " can't get last scrubbing date" 69 continue 70 fi 71 72 # Now minus last scrub (both in seconds) converted to days. 73 _scrub_diff=$(expr -e \( $(date +%s) - \ 74 $(date -j -v -70M -f %F.%T ${_last_scrub} +%s) \) / 60 / 60 / 24) 75 if [ ${_scrub_diff} -lt ${_pool_threshold} ]; then 76 echo " skipping scrubbing of pool '${pool}':" 77 echo " last scrubbing is ${_scrub_diff} days ago, threshold is set to ${_pool_threshold} days" 78 continue 79 fi 80 81 _status="$(zpool status ${pool} | grep scan:)" 82 case "${_status}" in 83 *"scrub in progress"*) 84 echo " scrubbing of pool '${pool}' already in progress, skipping:" 85 ;; 86 *"resilver in progress"*) 87 echo " resilvering of pool '${pool}' is in progress, skipping:" 88 ;; 89 *"none requested"*) 90 echo " starting first scrub (since reboot) of pool '${pool}':" 91 zpool scrub ${pool} 92 [ $rc -eq 0 ] && rc=1 93 ;; 94 *) 95 echo " starting scrub of pool '${pool}':" 96 zpool scrub ${pool} 97 [ $rc -eq 0 ] && rc=1 98 ;; 99 esac 100 101 echo " consult 'zpool status ${pool}' for the result" 102 done 103 ;; 104 105 *) 106 rc=0 107 ;; 108esac 109 110exit $rc 111