/ FreeNAS

FreeNAS How to Wipe a Dataset Routinely Using ZFS Snapshots & Cron

I have a dataset which is on an SSD zpool and utilized primarily for fast inter-system copies, like for copying installation files from my PC to the wife's PC and vice versa.

This dataset is known as "scratch" and it works great, however I needed a reliable way to clean the dataset at an interval. I initially thought about writing a bash script to just run rm -rf /mnt/zpool02/scratch/* but that won't clean up dot files like .DS_Store and such. There are workarounds to this like enabling globbing, or deleting the wole dataset, but they're all more messy than I prefer.

Enter ZFS snapshots. One of the many things ZFS excels at is the ability to take snapshots of an entire pool, dataset, or series of datasets. These snapshots are essentially delta's of the dataset and ZFS allows you to rollback to those snapshots very easily. I won't go into the specifics of ZFS snapshots but if you want to read more about them, I've always found the oracle ZFS docs to be excellent. You can read more about zfs snapshots here.

Table of Contents

Create ZFS scratch dataset

In the FreeNAS GUI, under Storage create a new dataset under the zpool that you like.

create-zfs-dataset
save-zfs-dataset

Create ZFS snapshot on the empty scratch dataset

Next create a snapshot on that empty dataset and call it "empty"

create-zfs-dataset-snapshot
save-zfs-dataset-snapshot

Validate ZFS snapshot exists in the GUI

Validate that the ZFS snapshot was actually created by going to Storage > Snapshots and make sure the snapshot "empty" is showing up for your zpool.

Mine looks like this:
snap-visible-in-gui

Setup a cron task to rollback the dataset to that snapshot

Finally, on the left hand side of the FreeNAS GUI click System > Cron jobs > Add Cron job. The command we will be using is zfs rollback <zpool_name>/<dataset_name>@<snapshot_name>. You can read the full oracle documentation for zfs rollback here. The cron task I am using will run every day at midnight, and it look like this:

User: root
Command: zfs rollback zpool02/scratch@empty
Short Description: rollback zpool02/scratch daily
Minute: Each Selected Minute -> 00
Hour: Each Selected Hour -> 00

and click save.

The cron task screen should look similar to this:
new-cron-task

Conclusion

This has worked great for me so far and is a MUCH cleaner solution for wiping a dataset on a routine basis.