comparison etc/periodic/daily/750.local-trim-zfs @ 356:2ba1072103f1

Implement a new periodic script (daily) to control the automatic TRIM of SSD that contain ZFS pools/datasets
author Franz Glasner <fzglas.hg@dom66.de>
date Thu, 08 Dec 2022 09:55:12 +0100
parents f1c8fc3af3e1
children 84d2735fe7f6
comparison
equal deleted inserted replaced
355:f1c8fc3af3e1 356:2ba1072103f1
1 #!/bin/sh 1 #!/bin/sh
2 # 2 #
3 # $FreeBSD$ 3 # # @(#)@@PKGORIGIN@@ $HGid$
4 #
5 # Heavily inspired (aka "copied") from /etc/periodic/daily/800.scrub-zfs
4 # 6 #
5 7
6 # If there is a global system configuration file, suck it in. 8 # If there is a global system configuration file, suck it in.
7 # 9 #
8 10
13 then 15 then
14 . /etc/defaults/periodic.conf 16 . /etc/defaults/periodic.conf
15 source_periodic_confs 17 source_periodic_confs
16 fi 18 fi
17 19
18 : ${daily_scrub_zfs_default_threshold=35} 20 : ${daily_local_trim_zfs_enable:=NO}
21 : ${daily_local_trim_zfs_pools=}
22 : ${daliy_local_trim_zfs_default_threshold=35}
23 # \${daily_local_trim_zfs_$(echo "${pool}"|tr ".:-" "_")_threshold}
19 24
20 case "$daily_scrub_zfs_enable" in 25 case "$daily_local_trim_zfs_enable" in
21 [Yy][Ee][Ss]) 26 [Yy][Ee][Ss])
22 echo 27 echo
23 echo 'Scrubbing of zfs pools:' 28 echo 'TRIM of zfs pools:'
24 29
25 if [ -z "${daily_scrub_zfs_pools}" ]; then 30 if [ -z "${daily_local_trim_zfs_pools}" ]; then
26 daily_scrub_zfs_pools="$(zpool list -H -o name)" 31 daily_local_trim_zfs_pools="$(zpool list -H -o name)"
27 fi 32 fi
28 33
29 rc=0 34 rc=0
30 for pool in ${daily_scrub_zfs_pools}; do 35 for pool in ${daily_local_trim_zfs_pools}; do
31 # sanity check 36 # sanity check
32 _status=$(zpool list "${pool}" 2> /dev/null) 37 _status=$(zpool list "${pool}" 2> /dev/null)
33 if [ $? -ne 0 ]; then 38 if [ $? -ne 0 ]; then
34 rc=2 39 rc=2
35 echo " WARNING: pool '${pool}' specified in" 40 echo " WARNING: pool '${pool}' specified in"
36 echo " '/etc/periodic.conf:daily_scrub_zfs_pools'" 41 echo " '/etc/periodic.conf:daily_local_trim_zfs_pools'"
37 echo " does not exist" 42 echo " does not exist"
38 continue 43 continue
39 fi 44 fi
40 _status=${_status##*$newline} 45 _status=${_status##*$newline}
41 case ${_status} in 46 case ${_status} in
47 rc=4 52 rc=4
48 echo "Skipping unavailable pool: ${pool}" 53 echo "Skipping unavailable pool: ${pool}"
49 continue ;; 54 continue ;;
50 esac 55 esac
51 56
52 # determine how many days shall be between scrubs 57 # determine how many days shall be between trums
53 eval _pool_threshold=\${daily_scrub_zfs_$(echo "${pool}"|tr ".:-" "_")_threshold} 58 eval _pool_threshold=\${daily_local_trim_zfs_$(echo "${pool}"|tr ".:-" "_")_threshold}
54 if [ -z "${_pool_threshold}" ];then 59 if [ -z "${_pool_threshold}" ]; then
55 _pool_threshold=${daily_scrub_zfs_default_threshold} 60 _pool_threshold=${daliy_local_trim_zfs_default_threshold}
56 fi 61 fi
57 62
58 _last_scrub=$(zpool history ${pool} | \ 63 _last_local_trim=$(zpool history ${pool} | \
59 egrep "^[0-9\.\:\-]{19} zpool scrub ${pool}\$" | tail -1 |\ 64 egrep "^[0-9\.\:\-]{19} zpool trim( -w)? ${pool}\$" | tail -1 |\
60 cut -d ' ' -f 1) 65 cut -d ' ' -f 1)
61 if [ -z "${_last_scrub}" ]; then 66 if [ -z "${_last_local_trim}" ]; then
62 # creation time of the pool if no scrub was done 67 # creation time of the pool if no trim was done
63 _last_scrub=$(zpool history ${pool} | \ 68 _last_local_trim=$(zpool history ${pool} | \
64 sed -ne '2s/ .*$//p') 69 sed -ne '2s/ .*$//p')
65 fi 70 fi
66 if [ -z "${_last_scrub}" ]; then 71 if [ -z "${_last_local_trim}" ]; then
67 echo " skipping scrubbing of pool '${pool}':" 72 echo " skipping TRIM of pool '${pool}':"
68 echo " can't get last scrubbing date" 73 echo " can't get last TRIM date"
69 continue 74 continue
70 fi 75 fi
71 76
72 # Now minus last scrub (both in seconds) converted to days. 77 # Now minus last trim (both in seconds) converted to days.
73 _scrub_diff=$(expr -e \( $(date +%s) - \ 78 _local_trim_diff=$(expr -e \( $(date +%s) - \
74 $(date -j -v -70M -f %F.%T ${_last_scrub} +%s) \) / 60 / 60 / 24) 79 $(date -j -v -70M -f %F.%T ${_last_local_trim} +%s) \) / 60 / 60 / 24)
75 if [ ${_scrub_diff} -lt ${_pool_threshold} ]; then 80 if [ ${_local_trim_diff} -lt ${_pool_threshold} ]; then
76 echo " skipping scrubbing of pool '${pool}':" 81 echo " skipping TRIM of pool '${pool}':"
77 echo " last scrubbing is ${_scrub_diff} days ago, threshold is set to ${_pool_threshold} days" 82 echo " last TRIM is ${_local_trim_diff} days ago, threshold is set to ${_pool_threshold} days"
78 continue 83 continue
79 fi 84 fi
80 85
86 # Check general pool status (as in scrub-zfs)
81 _status="$(zpool status ${pool} | grep scan:)" 87 _status="$(zpool status ${pool} | grep scan:)"
82 case "${_status}" in 88 case "${_status}" in
83 *"scrub in progress"*) 89 *"scrub in progress"*)
84 echo " scrubbing of pool '${pool}' already in progress, skipping:" 90 echo " scrubbing of pool '${pool}' in progress, skipping:"
91 continue
85 ;; 92 ;;
86 *"resilver in progress"*) 93 *"resilver in progress"*)
87 echo " resilvering of pool '${pool}' is in progress, skipping:" 94 echo " resilvering of pool '${pool}' is in progress, skipping:"
88 ;; 95 continue
89 *"none requested"*)
90 echo " starting first scrub (since reboot) of pool '${pool}':"
91 zpool scrub ${pool}
92 [ $rc -eq 0 ] && rc=1
93 ;; 96 ;;
94 *) 97 *)
95 echo " starting scrub of pool '${pool}':" 98 # VOID
96 zpool scrub ${pool} 99 ;;
100 esac
101
102 # Check whether a trim is already running
103 _status="$(zpool status ${pool} | fgrep trimming)"
104 case "${_status}" in
105 *\(trimming\)*)
106 echo " TRIM of pool '${pool}' already in progress, skipping:"
107 ;;
108 *)
109 echo " starting TRIM of pool '${pool}':"
110 zpool trim -w ${pool}
97 [ $rc -eq 0 ] && rc=1 111 [ $rc -eq 0 ] && rc=1
98 ;; 112 ;;
99 esac 113 esac
100
101 echo " consult 'zpool status ${pool}' for the result"
102 done 114 done
103 ;; 115 ;;
104 116
105 *) 117 *)
106 rc=0 118 rc=0