From f3bde4fa351e78e4c8e39db453afc99f596a0b8b Mon Sep 17 00:00:00 2001 From: michele Date: Wed, 19 Mar 2014 00:09:07 +0100 Subject: [PATCH] add tool to take bounded, tagged zfs snapshots --- zfssnap.sh | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100755 zfssnap.sh diff --git a/zfssnap.sh b/zfssnap.sh new file mode 100755 index 0000000..b9c2bf2 --- /dev/null +++ b/zfssnap.sh @@ -0,0 +1,83 @@ +#! /bin/sh + +tstamp=`date +%Y%m%d-%H%M%S` +label_pfx="zbk-" +usrlabel=$1 +maxnum=$2 +zpool="zroot" + +# names of the DATASETs to exclude (datasets, not mountpoints!) +excludes="/usr/ports /usr/src /backups" + +usage () { + echo Usage: + echo "zfssnap [label [maxnum]]" + echo "default label: 'default'" + echo "default maxnum: infinite" + echo "Takes a ZFS snapshot with given custom label." + echo "If maxnum specified, keeps the so-many newest snaps only." + echo + echo "Optional envvars:" + echo "EXCLUDES list of dataset paths to exclude from snaps. Overrides default." + echo "EXTRA_EXCLUDES list of dataset paths to exclude from snaps. Extends default." + echo "default excluded DATASET paths:" + echo $excludes +} + +# build list of dataset paths to exclude +if [ "x$EXCLUDES" != x ] +then + excludes=$EXCLUDES +elif [ "x$EXTRA_EXCLUDES" != x ] +then + excludes="$excludes $EXTRA_EXCLUDES" +fi + +# label +if [ "x$usrlabel" != "x" ] +then + if echo "$usrlabel" | grep -qiE '^([a-z0-9]{1,10})$' + then + label_pfx="$label_pfx$usrlabel" + else + echo "Invalid label '$usrlabel'! Quitting." + usage + exit 1 + fi +else + label_pfx="${label_pfx}default" +fi + +# maxnum +if [ "x$maxnum" != "x" ] +then + if ! echo "$maxnum" | grep -qE '^[0-9]+$' + then + echo "Invalid maxnum '$maxnum'! Terminating." + usage + exit 1 + fi +fi + + +# add timestamp to label +label="${label_pfx}-$tstamp" + +# take recursive snap +zfs snapshot -r $zpool@$label || exit $? +# exclude folders +for xm in $excludes +do + # let this fail, the ds might not exist + zfs destroy -r $zpool$xm@$label +done + +# prune dbs if requested +if [ "x$maxnum" != x ] +then + ls /.zfs/snapshot/ | sort -rt- -k 3,4 | awk -v maxnum=$maxnum -v matchlabel=$label_pfx 'BEGIN {x=0} $0 ~ "^"matchlabel { x++; if (x>maxnum) print}' | while read snapname + do + zfs destroy -r $zpool@$snapname || exit $? + done +fi +