Not-as-simple perl script for ZFS snapshot auditing

June 5, 2007

Hi everyone, I’m back again with another perl script to hopefully be useful to a few of you.

Firstly, the script: (formatting long scripts in wordpress’ crazy editor is a very long and arduous process, thus I’m just linking to the script in this case, if anyone knows of a better place to stick it let me know). chmod +x it and away you go!

Edit: Sun was nice enough to host the file for me, here’s a link to their version in case the other one goes down:

In a nutshell, here’s what it does:

  • Allows you to diff a file inside a ZFS snapshot with the current file in the filesystem and (optionally) print out the line differences
  • Recursively diff an entire snapshot using md5 sums and (optionally) printing out the line differences
  • Display the md5 sums for each file in a ZFS snapshot and filesystem (this can get old to look at very quickly)

Basically, that doesn’t mean a whole lot, here’s the output from the -h option:

ZFS Snapshot diff
./ [-dhirv] <zfs shapshot name> [filename]

-d Display the lines that are different (diff output)
-h Display this usage
-i Ignore files that don't exist in the snapshot (only necessary for recursing)
-r Recursively diff every file in the snapshot (filename not required)
-v Verbose mode

[filename] is the filename RELATIVE to the ZFS snapshot root. For example, if
I had a filesystem snapshot called pool/data/zone@initial. The filename '/etc/passwd'
would refer to the filename /pool/data/zone/etc/passwd in the filesystem and filename
/pool/data/zone/.zfs/snapshot/initial/etc/passwd in the snapshot.

A couple of examples:
./ -v -r -i pool/zones/lava2019@Fri
Checks the current pool/zones/lava2019 filesystem against the snapshot
returning the md5sum difference of any files (ignore files that don't
exist in the snapshot). With verbose mode

./ -d pool/zones/lava2019@Mon /root/etc/passwd
Check the md5sum for /pool/zones/lava2019/root/etc/passwd and compare
it to /pool/zones/lava2019/.zfs/snapshot/Mon/root/etc/passwd. Display
the lines that are different also.

Here’s what the output is going to look like:

-bash-3.00# ./ -d -v -r -i pool/zones/lava2019@Fri
Recursive diff on pool/zones/lava2019@Fri
Filesystem: /pool/zones/lava2019, Snapshot: Fri
Comparing: /pool/zones/lava2019/
to: /pool/zones/lava2019/.zfs/snapshot/Fri/
** /pool/zones/lava2019/root/etc/shadow is different
** MD5(/pool/zones/lava2019/root/etc/shadow)= 04fa68e7f9dbc0afbf8950bbb84650a6
** MD5(/pool/zones/lava2019/.zfs/snapshot/Fri/root/etc/shadow)= 4fc845ff7729e804806d8129852fa494
< tom:*LK*:::::::
** /pool/zones/lava2019/root/etc/dfs/dfstab is different
** MD5(/pool/zones/lava2019/root/etc/dfs/dfstab)= 8426d34aa7aae5a512a0c576ca2977b7
** MD5(/pool/zones/lava2019/.zfs/snapshot/Fri/root/etc/dfs/dfstab)= c3803f151cb3018f77f42226f699ee1b
< share -F nfs -o rw -d "Data" /data

etc, etc, etc.

I am planning on using it so I can audit certain files on different zones (like /etc/passwd) against an initial ZFS snapshot to see what’s changed. Nice little way to keep track of stuff. Email me with any bugs. Matthew dot hinman at gmail dot com.

posted in geekery, perl, security, software, solaris, sun, work, zfs by Lee

5 Comments to "Not-as-simple perl script for ZFS snapshot auditing"

  1. Mark J Musante wrote:

    Very cool. You should submit it to Sun’s bigadmin site (

  2. Chris wrote:

    great script, but it does not work quite well for me…
    # zfs list
    mypool/d 270G 3.69G 145G /d/d2
    mypool/d@2006_10_month 3.72G – 123G –
    I have mountpint as /d/d2, your script is looking for /mypool/d, so if I create symbolic link /mypool/d pointing to /d/d2 then it works.

    anyway great tool…


  3. Lee Hinman wrote:

    Chris: Thanks for pointing that out, I wasn’t considering that the mountpoint of the FS can be different than the name, I’ll have to work on an update, thanks!

  4. Dude-man wrote:

    Will its a very old post/script… but looks usefull still

    Somewhere in the code

    zfs get mountpoint -o value $datasetName -H

    Would substitue the right mount point… don’t know where yet

  5. Dude-man wrote:

    Heres a bash script which I think does something simular but uses zfs diff to find files that differ… just a hack

    pass snapshot name as first argument


    snapshot=$(echo $datasetANDsnapshot | cut -d’@’ -f 2)
    datasetName=$(echo $datasetANDsnapshot | cut -d’@’ -f 1)

    echo “Looking for differences for ” $datasetName”@”$snapshot

    for f in $(zfs diff $datasetANDsnapshot | grep “^M” | awk ‘{print $2;}’)
    echo “+++++++++++++++++++”
    echo “File modified from ”
    diff $(zfs get mountpoint -o value $datasetName -H)”.zfs/snapshot/$snapshot$f” $f

Powered by Wordpress and MySQL. Theme by Shlomi Noach,