Hi everyone, I’m back again with another perl script to hopefully be useful to a few of you.
Firstly, the script: http://lee.hinmanphoto.com/files/zdiff.txt (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: http://www.sun.com/bigadmin/scripts/submittedScripts/zdiff.txt
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
./zdiff.pl [-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:
./zdiff.pl -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
./zdiff.pl -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# ./zdiff.pl -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
17d16
< 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
13d12
< 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.

7 Comments
June 5, 2007 at 4:27 pm
Very cool. You should submit it to Sun’s bigadmin site (www.sun.com/bigadmin)
September 27, 2007 at 10:08 am
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…
Chris
September 27, 2007 at 1:22 pm
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!
July 1, 2008 at 9:29 am
Simply correct manual: replace zfs name to mount point name
February 2, 2009 at 4:08 am
If you change the following line:
my $fsname = “/” . $1;
to the following two lines:
my $fsname = `zfs get -H mountpoint $1 | awk ‘{print \$3}’`;
chomp($fsname);
then the script will get the correct mount point and use it.
You might also want to check that the snapdir is visible and error if not.
Thanks
Yonah
March 3, 2009 at 9:44 am
Yonah – it shouldn’t matter if snapdir is vissible or not – as long as file system is mounted you can go directly to snapdir directory even if it is hidden.
March 12, 2009 at 2:41 am
Another problem is with zfs that have a “legacy” mount point… I’ve not found an easy solution here