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)

#!/usr/bin/perl

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/zsnap.pl 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 ;-)


    #!/bin/bash

    # backup_zfssnap.sh, (c) 2007 ralf.ramge@webde.de

    BACKUPDIR=”/export/backup/snapshots”
    DSTAMP=`date ‘+%y%m%d-%H%M%S’`
    FILESYS=$1
    DEST=$2
    REPLICA=$3
    BACKUPNAME=`echo $FILESYS | sed ‘s/\//_/g’`
    BACKUPFILE=$BACKUPNAME”-“$DSTAMP”.zfs”
    SNAPSHOT=$FILESYS”@backup-“$DSTAMP

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

    cd $BACKUPDIR

    # 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
    do
    if [ ! -f $BACKUPNAME”-000000-00000″$COUNT”.zfs” ]; then
    touch $BACKUPNAME”-000000-00000″$COUNT”.zfs”
    sleep 1
    fi
    done
    fi

    # 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 ]
    do
    OLDEST_BACKUP_FILE=`ls -rt1 $BACKUPNAME* | head -1`
    rm $OLDEST_BACKUP_FILE
    let COUNT_FILES=COUNT_FILES-1
    done

    fi

    # 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
    zfs send $SNAPSHOT > $BACKUPDIR”/”$BACKUPFILE

    # 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”`
    fi

    # 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, openark.org