Imagine You're a Goofball: Dynamic Preventative ZFS Snapshots

On Hacker News, there is an article about how NILFS seems to "take" continuous snapshots. In addition to checkpoints, one can stop a NILFS filesystem from garbage collecting, roll back to a point in time, and recover a file that was once there. And, this seems great, if you can take the performance hit of a log-structured file system (which is substantial).

But perhaps like our mother's said "an ounce of prevention is worth a pound of cure"? Why not just take a snapshot before you do something silly? With httm, one can now take these sorts of no mental overhead, non-periodic dynamic snapshots, which can complement your current periodic snapshot scheme.

Let me reiterate -- one can and should be able to take a snapshot without needing to specify a dataset or snapshot name. Just feed httm a filename and httm will figure out the rest.

See, for example:

#!/bin/bash
function ounce_of_prevention {
    for a; do
        # is the argument a file?
        if [[ -f "$a" ]]; then
            local LIVE_FILE="$a"
        else
            continue
        fi

        # get last snap version of the live file?
        local LAST_SNAP="$(httm -l "$LIVE_FILE")"

        # check whether to take snap - do we have a snap of the live file already?
        # 1) if empty, live file does not have a snapshot, then take snap, or
        # 2) if live file is not the same as the last snap, then take snap
        if [[ -z "$LAST_SNAP" ]] || \
           [[ ! -z "$LAST_SNAP" && "$(stat -c %Y "$LIVE_FILE")" -ne "$(stat -c %Y "$LAST_SNAP")" ]]
        then
            # httm will dynamically determine the location of
            # the file's ZFS dataset and snapshot that mount
            sudo httm --snap "$LIVE_FILE" > /dev/null &
        fi
    done
}

ounce_of_prevention "$@"
# expressly used `nano` instead of `vim` or `emacs` to avoid a unholy war
/usr/bin/nano "$@"

First, we check whether we even need to take a snapshot:

  1. The 0th condition checks whether an argument is a file.
  2. The command httm -l $LIVE_FILE requests the last snapshot for the file, allowing you to test the 1st condition, which checks whether that file has a snapshot, and,
  3. The 2nd condition checks whether the live file is not the same as the last snapshot version.

Next, httm makes certain that it doesn't matter whether you are editing ~/.zshrc or /etc/samba/smb.conf. httm dynamically determines and snapshots the appropriate mount (before you modify/screw up the file!).

Now, one will have to also set up a bash alias (alias nano=nano-with-prevention), and a sudoers policy (kimono ALL=(ALL) NOPASSWD: /usr/bin/httm --snap), which allows these types of dynamic snapshots, but this pattern does seem to work pretty well.

Does anyone else have any other fancy dynamic snapshot tricks I could add to my arsenal?

The latest release of httm is 0.16.0.