blob: 1f9ab0e030d6f96ccf8c02573ce00c980dca71fb [file] [log] [blame]
#!/bin/bash
#
# btrfs-snap - make periodic snapshots of btrfs filesystem
#
# Copyright (C) 2010 Birger Monsen birger@birger.sh
#
# This program is distributed under the GNU General Public License
# http://www.gnu.org/licenses/gpl.txt
#
LOG_FACILITY=local0
VERSION="1.0"
prog=${0##*/}
USAGE="Usage: ${prog} -h for usage help
${prog} -V for version
${prog} <mountpoint> <prefix> <count>"
SYNOPSIS="${prog} <mountpoint> <prefix> <count>
<mountpoint> is the mountpoint of the btrfs file system to make a
snapshot of
<prefix> is the prefix to be used in the name of the snapshot.
E.g. hourly, daily, weekly...
<count> The number of snapshots with the given prefix to keep.
btrfs-snap / hourly 24
would make a snapshot in /.snapshot called hourly_<date>_<time>
where <date> is on the form YYYY-MM-DD and <time> is on the form
HH:MM:SS. This format makes shure snapshot names sort correctly in
cronological order even when sorted alphabetically. The 24 newest
snapshots matching the prefix are kept around. The rest are deleted.
Snapshots are always created in a directory called .snapshot at the
top level of the given mount point.
Example usage for a system with 2 btrfs file systems mounted as
/ and /home (remember to make these scripts executable):
/etc/cron.hourly/btrfs-snap
#!/bin/bash
${0} / hourly 24
${0} /home hourly 24
/etc/cron.daily/btrfs-snap
#!/bin/bash
${0} / daily 7
${0} /home daily 7
/etc/cron.weekly/btrfs-snap
#!/bin/bash
${0} /home weekly 4
Remember that at the moment snapshots cannot be made read-only, but you
should not modify the snapshots created by this script, as they will
get deleted without any notice. To restore a file, just copy it back from
a snapshot to the main branch."
while getopts "hV" arg; do
case "${arg}" in
h )
echo "$SYNOPSIS"
exit 0
;;
V )
echo "${prog} Version ${VERSION}"
exit 0
;;
* )
echo "$USAGE"
exit 1
;;
esac
done
if [ $# -ne 3 ] ; then
echo "$USAGE"
exit 1
fi
if [ -f /etc/sysconfig/btrfs-snap ] ; then
. /etc/sysconfig/btrfs-snap
fi
mp=$1
pf=$2
cnt=$(( $3+1 ))
mount -t btrfs | cut -d " " -f 3 | grep "^${mp}$" > /dev/null
if [ $? -ne 0 ] ; then
echo "Error: ${mp} is not a btrfs mountpoint"
exit 1
fi
if [ ! -d "${mp}/.snapshot" ]; then
logger -p ${LOG_FACILITY}.info -t ${prog} "Creating ${mp}/.snapshot"
mkdir "${mp}/.snapshot"
fi
dt=`date +'%Y-%m-%d_%H:%M:%S'`
out=`/sbin/btrfs subvol snapshot ${mp} ${mp}/.snapshot/${pf}_${dt} 2>&1`
if [ $? -eq 0 ] ; then
logger -p ${LOG_FACILITY}.info -t ${prog} "${out}"
else
logger -p ${LOG_FACILITY}.err -t ${prog} "${out}"
fi
ls -dr ${mp}/.snapshot/${pf}_* | tail -n +${cnt} | while read snap ; do
out=`/sbin/btrfs subvolume delete ${snap} 2>&1`
if [ $? -eq 0 ] ; then
logger -p ${LOG_FACILITY}.info -t ${prog} "${out}"
else
logger -p ${LOG_FACILITY}.err -t ${prog} "${out}"
fi
done