Periodic ZFS snapshots
As I continue exploring the nearly endless possibilities within ZFS, I figured it would be neat to have periodic snapshots of my mail files. The “Interweb” is filled with various shell scripts for this purpose, and I guess another one won’t make much difference.
#!/bin/sh
# Shell script for creating periodic ZFS snapshots.
# Copyright © 2012 Trond Endrestøl <Trond.Endrestol@ximalas.info>
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
# This script creates a monthly snapshot at midnight on the first day of every month.
# Should the snapshot exist, the old snapshot will be removed and recreated.
# Next, this script will create a daily snapshot at midnight,
# and hourly snapshots for the hours 01 to 23,
# and finally minutely snapshots for the minutes 01 to 59.
# Should the snapshot exist, the old snapshot will be removed and recreated.
# This script is supposed to be run by cron every minute.
# Example of invocation of this script from the system /etc/crontab:
# * * * * * root /path/to/create-periodic-zfs-snapshots.sh zpool/filesystem
# Example of invocation of this script from a user's crontab:
# * * * * * /path/to/create-periodic-zfs-snapshots.sh zpool/filesystem
# Tested on FreeBSD/amd64 9.0-STABLE.
# A suitable PATH is nice to have, though most of the commands are given using absolute file names.
PATH=/bin:/sbin:/usr/bin:/usr/sbin
export PATH
# Make sure we have been given one, and only one, file system on the command line.
if [ "${#}" -ne 1 ]; then
echo "Usage: ${0} zpool[/dataset]" >/dev/stderr;
exit 1;
fi
# Make sure the file system exist.
if ! /sbin/zfs list -H -t filesystem ${1} >/dev/null 2>/dev/null; then
echo "${0}: cannot find the file system ${1}" >/dev/stderr;
exit 1;
fi
# I prefer to use English names on months and weekdays.
export LANG=C
export LC_ALL=${LANG}
export LC_COLLATE=${LANG}
export LC_CTYPE=${LANG}
export LC_MESSAGES=${LANG}
export LC_MONETARY=${LANG}
export LC_NUMERIC=${LANG}
export LC_TIME=${LANG}
# Extract the necessary details on the present.
month=`/bin/date +%B | /usr/bin/tr "[:upper:]" "[:lower:]"`
weekday=`/bin/date +%A | /usr/bin/tr "[:upper:]" "[:lower:]"`
day=`/bin/date +%d`
hour=`/bin/date +%H`
minute=`/bin/date +%M`
# The monthly snapshot will ALWAYS be created when appropriate.
if [ ${day} -eq 1 -a ${hour} -eq 0 -a ${minute} -eq 0 ]; then
snapshot="${1}@${month}";
# Destroy the monthly snapshot, if it exist.
if /sbin/zfs list -H -t snapshot ${snapshot} >/dev/null 2>/dev/null; then
/sbin/zfs destroy ${snapshot};
zfs_destroy=${?};
if [ ${zfs_destroy} -ne 0 ]; then
exit ${zfs_destroy};
fi;
fi;
# Create the monthly snapshot.
/sbin/zfs snapshot ${snapshot};
zfs_snapshot=${?};
if [ ${zfs_snapshot} -ne 0 ]; then
exit ${zfs_snapshot};
fi;
fi
# Pick weekday, hour, or minute.
if [ ${hour} -eq 0 -a ${minute} -eq 0 ]; then
snapshot="${1}@${weekday}";
elif [ ${minute} -eq 0 ]; then
snapshot="${1}@hourly${hour}";
else
snapshot="${1}@minute${minute}";
fi
# Destroy the snapshot, if it exist.
if /sbin/zfs list -H -t snapshot ${snapshot} >/dev/null 2>/dev/null; then
/sbin/zfs destroy ${snapshot};
zfs_destroy=${?};
if [ ${zfs_destroy} -ne 0 ]; then
exit ${zfs_destroy};
fi;
fi
# Create the snapshot.
/sbin/zfs snapshot ${snapshot}
exit ${?}
# EOF of create-periodic-zfs-snapshots.sh.
Here’s how the snapshots will appear by the use of the command zfs list -t all:
NAME USED AVAIL REFER MOUNTPOINT enterprise_zroot/var/mail 1,91M 419G 184K /var/mail enterprise_zroot/var/mail@february 124K - 172K - enterprise_zroot/var/mail@march 0 - 176K - enterprise_zroot/var/mail@thursday 0 - 176K - enterprise_zroot/var/mail@friday 132K - 180K - enterprise_zroot/var/mail@saturday 124K - 172K - enterprise_zroot/var/mail@sunday 136K - 184K - enterprise_zroot/var/mail@monday 132K - 184K - enterprise_zroot/var/mail@tuesday 124K - 184K - enterprise_zroot/var/mail@hourly19 0 - 184K - enterprise_zroot/var/mail@hourly20 0 - 184K - enterprise_zroot/var/mail@hourly21 0 - 184K - enterprise_zroot/var/mail@hourly22 0 - 184K - enterprise_zroot/var/mail@hourly23 72K - 184K - enterprise_zroot/var/mail@wednesday 0 - 184K - enterprise_zroot/var/mail@hourly01 0 - 184K - enterprise_zroot/var/mail@hourly02 0 - 184K - enterprise_zroot/var/mail@hourly03 0 - 184K - enterprise_zroot/var/mail@hourly04 0 - 192K - enterprise_zroot/var/mail@hourly05 0 - 192K - enterprise_zroot/var/mail@hourly06 0 - 192K - enterprise_zroot/var/mail@hourly07 0 - 184K - enterprise_zroot/var/mail@hourly08 0 - 184K - enterprise_zroot/var/mail@hourly09 0 - 184K - enterprise_zroot/var/mail@hourly10 0 - 184K - enterprise_zroot/var/mail@hourly11 0 - 184K - enterprise_zroot/var/mail@hourly12 0 - 184K - enterprise_zroot/var/mail@hourly13 0 - 220K - enterprise_zroot/var/mail@hourly14 0 - 220K - enterprise_zroot/var/mail@hourly15 0 - 220K - enterprise_zroot/var/mail@hourly16 0 - 220K - enterprise_zroot/var/mail@hourly17 0 - 220K - enterprise_zroot/var/mail@minute44 0 - 184K - enterprise_zroot/var/mail@minute45 0 - 184K - enterprise_zroot/var/mail@minute46 0 - 184K - enterprise_zroot/var/mail@minute47 0 - 184K - enterprise_zroot/var/mail@minute48 0 - 184K - enterprise_zroot/var/mail@minute49 0 - 184K - enterprise_zroot/var/mail@minute50 0 - 184K - enterprise_zroot/var/mail@minute51 0 - 184K - enterprise_zroot/var/mail@minute52 0 - 184K - enterprise_zroot/var/mail@minute53 0 - 184K - enterprise_zroot/var/mail@minute54 0 - 184K - enterprise_zroot/var/mail@minute55 0 - 184K - enterprise_zroot/var/mail@minute56 0 - 184K - enterprise_zroot/var/mail@minute57 0 - 184K - enterprise_zroot/var/mail@minute58 0 - 184K - enterprise_zroot/var/mail@minute59 0 - 184K - enterprise_zroot/var/mail@hourly18 0 - 184K - enterprise_zroot/var/mail@minute01 0 - 184K - enterprise_zroot/var/mail@minute02 0 - 184K - enterprise_zroot/var/mail@minute03 0 - 184K - enterprise_zroot/var/mail@minute04 0 - 184K - enterprise_zroot/var/mail@minute05 0 - 184K - enterprise_zroot/var/mail@minute06 0 - 184K - enterprise_zroot/var/mail@minute07 0 - 184K - enterprise_zroot/var/mail@minute08 0 - 184K - enterprise_zroot/var/mail@minute09 0 - 184K - enterprise_zroot/var/mail@minute10 0 - 184K - enterprise_zroot/var/mail@minute11 0 - 184K - enterprise_zroot/var/mail@minute12 0 - 184K - enterprise_zroot/var/mail@minute13 0 - 184K - enterprise_zroot/var/mail@minute14 0 - 184K - enterprise_zroot/var/mail@minute15 0 - 184K - enterprise_zroot/var/mail@minute16 0 - 184K - enterprise_zroot/var/mail@minute17 0 - 184K - enterprise_zroot/var/mail@minute18 0 - 184K - enterprise_zroot/var/mail@minute19 0 - 184K - enterprise_zroot/var/mail@minute20 0 - 184K - enterprise_zroot/var/mail@minute21 0 - 184K - enterprise_zroot/var/mail@minute22 0 - 184K - enterprise_zroot/var/mail@minute23 0 - 184K - enterprise_zroot/var/mail@minute24 0 - 184K - enterprise_zroot/var/mail@minute25 0 - 184K - enterprise_zroot/var/mail@minute26 0 - 184K - enterprise_zroot/var/mail@minute27 0 - 184K - enterprise_zroot/var/mail@minute28 0 - 184K - enterprise_zroot/var/mail@minute29 0 - 184K - enterprise_zroot/var/mail@minute30 0 - 184K - enterprise_zroot/var/mail@minute31 0 - 184K - enterprise_zroot/var/mail@minute32 0 - 184K - enterprise_zroot/var/mail@minute33 0 - 184K - enterprise_zroot/var/mail@minute34 0 - 184K - enterprise_zroot/var/mail@minute35 0 - 184K - enterprise_zroot/var/mail@minute36 0 - 184K - enterprise_zroot/var/mail@minute37 0 - 184K - enterprise_zroot/var/mail@minute38 0 - 184K - enterprise_zroot/var/mail@minute39 0 - 184K - enterprise_zroot/var/mail@minute40 0 - 184K - enterprise_zroot/var/mail@minute41 0 - 184K - enterprise_zroot/var/mail@minute42 0 - 184K - enterprise_zroot/var/mail@minute43 0 - 184K -