I recently moved my OPNSense from a Dell R220 to a GoWin R86S which reminded me that I really should get a scheduled ZFS scrub going until the developers include something natively. After trying a few different methods I settled on this method to perform a scrub on a monthly basis.
First step is to create the task. SSH to the server and cd to
/usr/local/opnsense/service/conf/actions.d
and create a new file called actions_zfs.conf with the following content:
[scrub_zroot]
command:/sbin/zpool scrub zroot
parameters:
type:script
description:ZFS Scrub zroot Pool
message:Performing a ZFS scrub of the zroot Pool
[trim_zroot]
command:/sbin/zpool trim zroot
parameters:
type:script
description:ZFS trim zroot Pool
message:Performing a ZFS trim of the zroot Pool
After saving the file you will need to restart a service so it picks up the new configuration file by running
service configd restart
Head over to the OPNSense web GUI and navigate to SYSTEM: SETTINGS: CRON and select the plus sign to add a cron task and fill out as you see fit. In my example below I am choosing 02:00 AM on the first of the month to run it. For the Command just type 'zfs' and you can select the scrub command we just created. Finally, give it a description and click Save.
After selecting save, be sure to select Apply on the Cron page and you're done.If you are using SSD storage that supports Trim (most do), you can create another cron entry to run that task. Performing weekly is good for this IMO since it's not a file server such as TrueNAS. With that said, a better option would be to just enable autotrim for the zroot pool and it will perform trim on blocks when it is convenient. Simply SSH to the OPNSense system and run:
zpool set autotrim=on zroot
Note that trim has a cost depending if it is an automatic or a manual process. More detail at the man page:
When set to on space which has been recently freed, and is no longer allocated by the pool, will be periodically trimmed ... Automatic TRIM does not immediately reclaim blocks after a free. Instead, it will optimistically delay allowing smaller ranges to be aggregated in to a few larger ones. These can then be issued more efficiently to the storage.
As a bonus you can follow this OPNSense forum post to setup a Monit task so you get alerted when important things happen to the ZFS pool such as it getting full or mirrored drive dies, etc.
Update
Per the 23.1 release notes, there are now two built-in tasks to perform these ZFs functions built in. They are very similar to the ones I created above.
If you use this howto and then upgrade you will need to delete the two tasks and recreate using the included ones as they used the same actions_zfs.conf file. Be sure to put zroot in the Parameters field or whatever your pool is called if you did not use the default of zroot.