1
0
Files
zfssnap/zfssnap.sh
2014-03-20 13:03:21 +01:00

91 lines
2.1 KiB
Bash
Executable File

#! /bin/sh
# change this to the name of your ZFS pool.
zpool="zroot"
# names of the DATASETs to exclude (datasets, not mountpoints!)
# can override this list at runtime with EXCLUDES envvar.
# can extend this list at runtime with EXTRA_EXCLUDES envvar.
excludes="/usr/ports /usr/src /backups"
# You do not want to edit anything below here
tstamp=`date +%Y%m%d-%H%M%S`
label_pfx="zbk-"
usrlabel=$1
maxnum=$2
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