ZFS: Automated Snapshots

2 minute read

Snapshots allow you to copy the state of your zpool at a given instance. This can be useful in many ways. For instance, if you delete a file that you still want and you have a snapshot of a time when you had the file you can go retrieve it. Snapshots are cheap to make, so one is encouraged to make them often. Before setting up automated snapshots I had only ever made two snapshots. You can view your snapshots with zfs list -t snapshot:

sudo zfs list -t snapshot
[sudo] password for koopman: 
NAME                          USED  AVAIL  REFER  MOUNTPOINT
lotus/koopman@fresh            84K      -   112K  -
lotus/koopman@home_restored  2.36G      -   138G  -

In this output fresh was made when I had just made the zpool and home_restored was made just after I had restored my home directory from backup to the zpool.

This is a great start, but we don’t want to just rely on making snapshots by hand. It would be more useful if we have some automated system for taking snapshots. Thankfully, such tools already exists. I am going to install zfs-auto-snapshot-git from the AUR, which is from the folks at zfsonlinux. Upon installation we will see the following output:

== Enable and start snapshot timers as needed:
== systemctl enable zfs-auto-snapshot-daily.timer
== available intervals: frequent, hourly, daily, weekly, monthly
== Recursively (-r) list available snapshots:
=> # zfs list -t snap -r pool/dataset
== You can set properties on pools/datasets to enable/disable
== specific snapshots (if unset, then it evaluates to "true"):
=> # zfs set com.sun:auto-snapshot=true pool/dataset
=> # zfs set com.sun:auto-snapshot:hourly=false pool/dataset

This automated system used to use cronjobs to run the included zfs-auto-snapshot script, but it looks like back in September 2014 the cronjobs were swapped out for systemd timers.

If you are unfamiliar with systemd timers (like I was when I came across this) they are simply timers which control a systemd service. You can view active timers with systemctl list-timers. You will notice that when we installed zfs-auto-snapshot-git a set of .service and .timer files were installed in /usr/lib/systemd/system:


Each .service and .timer pair is for a time interval for making snapshots. Let’s take a look at the hourly pair.


# See systemd.timers and systemd.time manpages for details
Description=ZFS hourly snapshot timer




Description=ZFS hourly snapshot service

ExecStart=/usr/bin/zfs-auto-snapshot --prefix=znap --quiet --syslog --label=hourly --keep=24 //

As you can see the files are fairly simple. Persistent=true in the .timer file will run the job if we happened to miss the last time it should have run, say if your computer was off or suspended, like an anacron job. The .service file just runs the the zfs-auto-snapshot script, labels it as hourly and keeps 24 snapshots. The // refers to all storage nodes.

To enable automated snapshots we will first have to set an auto-snapshot parameter as stated in the installation output:

zfs set com.sun:auto-snapshot=true pool/dataset

Then we just have to enable whatever timer(s) we want, this will enable an automated backup at that interval:

systemctl enable zfs-auto-snapshot-daily.timer

You can always manually run zfs-auto-snapshot which will produce a single backup. I have setup an hourly, daily, weekly and monthly auto-snapshot which has been running now for two months and everything seems to be going smoothly.

If you’d like to read more about snapshots I’d suggest checking out this page: https://pthree.org/2012/12/19/zfs-administration-part-xii-snapshots-and-clones/.