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