From 493908c4b45c7b75e4a6b4aea3b5b63ea5c268d5 Mon Sep 17 00:00:00 2001 From: Lexi Winter Date: Tue, 9 Apr 2024 15:49:56 -0600 Subject: [PATCH] periodic/daily/801.trim-zfs: Add a daily zfs trim script As mentioned in zpoolprops(7), on some SSDs, it may not be desirable to use ZFS autotrim because a large number of trim requests can degrade disk performance; instead, the pool should be manually trimmed at regular intervals. Add a new daily periodic script for this purpose, 801.trim-zfs. If enabled (daily_trim_zfs_enable=YES; the default is NO), it will run a 'zpool trim' operation on all online pools, or on the pools listed in 'daily_trim_zfs_pools'. The trim is not started if the pool is degraded (which matches the behaviour of the existing 800.scrub-zfs script) or if a trim is already running on that pool. Having autotrim enabled does not inhibit the periodic trim; it's sometimes desirable to run periodic trims even with autotrim enabled, because autotrim can elide trims for very small regions. PR: 275965 MFC after: 1 week Reviewed by: imp Pull Request: https://github.com/freebsd/freebsd-src/pull/956 --- share/man/man5/periodic.conf.5 | 11 ++++- usr.sbin/periodic/etc/daily/801.trim-zfs | 59 ++++++++++++++++++++++++ usr.sbin/periodic/etc/daily/Makefile | 3 +- usr.sbin/periodic/periodic.conf | 5 ++ 4 files changed, 76 insertions(+), 2 deletions(-) create mode 100755 usr.sbin/periodic/etc/daily/801.trim-zfs diff --git a/share/man/man5/periodic.conf.5 b/share/man/man5/periodic.conf.5 index 29fff146c21..a2ed2b09d77 100644 --- a/share/man/man5/periodic.conf.5 +++ b/share/man/man5/periodic.conf.5 @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd December 31, 2023 +.Dd April 9, 2024 .Dt PERIODIC.CONF 5 .Os .Sh NAME @@ -634,6 +634,15 @@ The same as .Va daily_scrub_zfs_default_threshold but specific to the pool .Ao Ar poolname Ac Ns . +.It Va daily_trim_zfs_enable +.Pq Vt bool +Set to +.Dq Li YES +if you want to run a zfs trim daily. +.It Va daily_trim_zfs_pools +.Pq Vt str +A space separated list of names of zfs pools to trim. +If the list is empty or not set, all zfs pools are trimmed. .It Va daily_local .Pq Vt str Set to a list of extra scripts that should be run after all other diff --git a/usr.sbin/periodic/etc/daily/801.trim-zfs b/usr.sbin/periodic/etc/daily/801.trim-zfs new file mode 100755 index 00000000000..17d2ce217c1 --- /dev/null +++ b/usr.sbin/periodic/etc/daily/801.trim-zfs @@ -0,0 +1,59 @@ +#!/bin/sh +# +# + +# 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 + +case "$daily_trim_zfs_enable" in + [Yy][Ee][Ss]) + echo + echo 'Trimming of zfs pools:' + + if [ -z "${daily_trim_zfs_pools}" ]; then + daily_trim_zfs_pools="$(zpool list -H -o name)" + fi + + rc=0 + for pool in ${daily_trim_zfs_pools}; do + # sanity check + _status=$(zpool list -Hohealth "${pool}" 2> /dev/null) + if [ $? -ne 0 ]; then + rc=2 + echo " WARNING: pool '${pool}' specified in" + echo " '/etc/periodic.conf:daily_trim_zfs_pools'" + echo " does not exist" + continue + fi + case ${_status} in + FAULTED) + rc=3 + echo "Skipping faulted pool: ${pool}" + continue ;; + UNAVAIL) + rc=4 + echo "Skipping unavailable pool: ${pool}" + continue ;; + esac + + if ! zpool status "${pool}" | grep -q '(trimming)'; then + echo " starting trim of pool '${pool}'" + zpool trim ${daily_zfs_trim_flags} "${pool}" + else + echo " trim of pool '${pool}' already in progress, skipping" + fi + done + ;; + + *) + rc=0 + ;; +esac + +exit $rc diff --git a/usr.sbin/periodic/etc/daily/Makefile b/usr.sbin/periodic/etc/daily/Makefile index 4eabc0bb1d5..3bf4601f514 100644 --- a/usr.sbin/periodic/etc/daily/Makefile +++ b/usr.sbin/periodic/etc/daily/Makefile @@ -60,7 +60,8 @@ SENDMAILPACKAGE= sendmail .if ${MK_ZFS} != "no" CONFS+= 223.backup-zfs \ 404.status-zfs \ - 800.scrub-zfs + 800.scrub-zfs \ + 801.trim-zfs .endif .include diff --git a/usr.sbin/periodic/periodic.conf b/usr.sbin/periodic/periodic.conf index 5e3a7837c6b..608a199b3cc 100644 --- a/usr.sbin/periodic/periodic.conf +++ b/usr.sbin/periodic/periodic.conf @@ -179,6 +179,11 @@ daily_scrub_zfs_pools="" # empty string selects all pools daily_scrub_zfs_default_threshold="35" # days between scrubs #daily_scrub_zfs_${poolname}_threshold="35" # pool specific threshold +# 801.trim-zfs +daily_trim_zfs_enable="NO" +daily_trim_zfs_pools="" # empty string selects all pools +daily_trim_zfs_flags="" # zpool-trim(8) flags + # 999.local daily_local="/etc/daily.local" # Local scripts