Super-simple perl script for zfs snapshots

June 1, 2007

Here’s a simple script for creating daily zfs snapshots that get rotated every week (so you always have one for Mon, Tues, Wed, etc)


use warnings;
use strict;

my $zfsname = shift || die "Need a filesystem name\n";

my $day = `date`;

$day =~ s/(Sun|Mon|Tue|Wed|Thu|Fri|Sat)[\S\s]+/$1/gi;

my $snapname = "$zfsname\@$day";
my $exist = system("zfs list $snapname");

# if it already exists, delete it
if($exist == 0) {
print "Destroying previous weeks snapshot...";
system("zfs destroy $snapname");
print "done.\n";

print "Creating daily snapshot...";
system("zfs snapshot $snapname\n");
print "done.\n";

And here’s the crontab entry:
0 2 * * * /usr/sbin/ pool/zones/lava2019
(replace “pool/zones/lava2019″ with whichever zfs you want a snapshot of)

Easy as cake, you’ll always have a zfs snapshot called <zfsname>@Sun through <zfsname>@Sat to rollback to!

posted in geekery, perl, solaris, sun, zfs by Lee

5 Comments to "Super-simple perl script for zfs snapshots"

  1. Mark J Musante wrote:

    You could go one step further, and loop over the output of ‘zpool list -H -o name’, and do a ‘zfs snapshot -r’. That would do all your filesystems for you at once.

  2. thnetos wrote:

    That would make sense, but in this case I don’t actually want to make snapshots of every filesystem, just the ones I specified. Definitely would be easy to add though.

  3. Ralf Ramge wrote:

    Here’s a simple quick&dirty script I wrote some time ago. Its status is definitely super-alpha, I would never use it as a crontab entry on my own servers and neither should you :-) But I think it can be useful as a demonstration for your readers.

    I do *not* include an information of how to use it. The script is self-explanatory and someone who doesn’t understand it shouldn’t use it anyway, for his/her own sake ;-)


    #, (c) 2007

    DSTAMP=`date ‘+%y%m%d-%H%M%S’`
    BACKUPNAME=`echo $FILESYS | sed ‘s/\//_/g’`

    if [ ! -d $BACKUPDIR ]; then
    echo “Backup Directory doesn’t exist”
    exit 1


    # Check here if we have 7 backup files, create them if we don’t
    COUNT_FILES=`ls -1 $BACKUPNAME* | wc -l`
    if [ $COUNT_FILES -le 1 ]; then
    for COUNT in 1 2 3 4 5 6 7
    if [ ! -f $BACKUPNAME”-000000-00000″$COUNT”.zfs” ]; then
    touch $BACKUPNAME”-000000-00000″$COUNT”.zfs”
    sleep 1

    # Check here that we have less than 8 backup files
    COUNT_FILES=`ls -1 $BACKUPNAME* | wc -l`
    if [ $COUNT_FILES -gt 7 ]; then
    # echo “More than 7 backup files exist”
    # exit 1
    while [ $COUNT_FILES -gt 7 ]
    OLDEST_BACKUP_FILE=`ls -rt1 $BACKUPNAME* | head -1`


    # Find the oldest backup file to delete
    OLDEST_BACKUP_FILE=`ls -rt1 $BACKUPNAME* | head -1`

    # Create the snapshot
    zfs snapshot $SNAPSHOT

    # Create a filesystem image in the local backup directory

    # Check for $2 and, if exists, create a second copy on a remote host for tape archival
    if [ ! -z $2 ]; then
    `zfs send $SNAPSHOT | ssh root@$2 “cat >$BACKUPDIR/$BACKUPFILE”`

    # Check for $3 and, if exists, mirror the filesystem on the remote host
    if [ ! -z $3 ]; then
    `ssh root@$2 “zfs receive $3

  4. Ralf Ramge wrote:

    Damn, looks like the blog software can’t handle it. Please delete the entry and feel free to contact me, I’ll send you the script by e-mail for inclusion in your blog.

  5. fifthecho wrote:

    Nice script! Thanks! Saved me a having to hash this out myself.

Powered by Wordpress and MySQL. Theme by Shlomi Noach,