Collection of scripts used for data backup and snapshots, i.e. for btrfs and lizardfs.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

132 lines
4.0 KiB

7 years ago
#!/bin/bash -e
BTRFS_VOLUMES=${BTRFS_VOLUMES:-$(awk '!/^#/ && $3=="btrfs" {print $2}' /etc/fstab | tr '\n' ' ' | sed 's, $,,')}
TMP_MNT=${TMP_MNT:-/var/tmp/btrfs-backup}
vols=()
del=
dryrun=0
periodity=${0%/*}
periodity=${periodity##*/}
if [[ $periodity =~ ^cron\... ]]; then
periodity=${periodity#cron}
else
periodity=
fi
case "$periodity" in
(.hourly) del=25;;
(.daily) del=8;;
(.weekly) del=5;;
(.monthly);;
esac
7 years ago
while test $# -gt 0; do
case "$1" in
(-h|--help) cat <<EOF
$0 [OPTIONS]
OPTIONS
-h, --help show this help
-n, --dry-run execute dry run, do not backup, just show commands
-p, --path <path> add a path that contains a btrfs (sub-) volume
(defaults to: ${BTRFS_VOLUMES})
-m, --mnt <path> temporary mount point (default: ${TMP_MNT})
not yet implemented:
-d, --del <number> delete oldes snapshots beginning at <numbers>-th
7 years ago
ENVIRONMENT
BTRFS_VOLUMES specify all volume pathes (instead of -p)
TMP_MNT temporary mount point (instead of -m)
DESCRIPTION
Creates a snapshot for all btrfs volumes specified. Snapshot is named
from the subvol name or if there is no subvol, from the path by
appending -snapshot-YYYY-MM-DD-HH-mm.
To create regular snapshots on a daily base, just run:
sudo cp btrfs-snapshots.sh /etc/cron.daily/btrfs-snapshots
If btrfs-snapshots is run from a cron.daily, cron.hourly,
cron. monthly or cron.weekly directory, the periodity is automatically
appended to the snapshot name, and the expiry is set meaningfull:
- hourly → keep only 24 hours, --del 25
- daily → keep only 7 days, --del 8
- weekly → keep only 4 weeks, --del 5
- monthly → old snapshots are not deleted
7 years ago
EOF
exit;;
(-n|--dry-run) dryrun=1;;
(-p|--path) shift; vols+=( "$1" );;
(-m|--mnt) shift; TMP_MNT="$1";;
(-d|--del) shift; del="$1";;
(*) echo "ERROR: unknown option $1, try $0 --help" 1>&2
exit 1;;
esac
if test $# -lt 1; then
echo "ERROR: missing argument, try $0 --help" 1>&2
exit 1
fi
shift
done
if test -n "${vols[*]}"; then
BTRFS_VOLUMES="${vols[*]}"
fi
7 years ago
test -d "${TMP_MNT}" || mkdir -p "${TMP_MNT}"
for fs in ${BTRFS_VOLUMES}; do
device=$(mount | awk '$3=="'$fs'" && $5=="btrfs" {print $1}')
subvol=$(mount | awk '$3=="'$fs'" && $5=="btrfs" {split(substr($6, 2, length($6)-2), res, ","); for (r in res) {if (res[r]~/^subvol=/) {sub(/^subvol=/,"" , res[r]); print res[r]}}}')
if test -n "$subvol"; then
if test "$subvol" = "/@"; then
name=${subvol}
else
name=${subvol}-
fi
7 years ago
else
if test "$fs" = "/"; then
name="/"
7 years ago
else
name=${fs#/}
name=${name%/}
name=/${name//\//-}-
7 years ago
fi
fi
date="-$(date +%Y-%m-%d-%H-%M)"
target="${name}snapshot${periodity}"
if test -n "$device"; then
if mount | grep -q " on $TMP_MNT type "; then
sudo umount "$TMP_MNT"
fi
sudo mount "$device" "$TMP_MNT"
if test $dryrun -eq 1; then
echo -e "→ \e[1mbackup ${subvol:+subvol $subvol of }$fs on $device\e[0m"
echo " " mount "$device" "$TMP_MNT"
echo " " btrfs subvolume snapshot "${TMP_MNT}${subvol}" "${TMP_MNT}${target}${date}"
if test -n "$del"; then
for f in $(ls -1 "${TMP_MNT}${target}"-* | tail -n +"$del"); do
echo " " btrfs subvolume delete "$f"
done
fi
echo " " umount "$TMP_MNT"
else
sudo btrfs subvolume snapshot "${TMP_MNT}${subvol}" "${TMP_MNT}${target}${date}"
#if test -n "$del"; then
# for f in $(ls -1 "${TMP_MNT}${target}"-* | tail -n +"$del"); do
# sudo btrfs subvolume delete "$f"
# done
#fi
7 years ago
fi
sudo umount "$TMP_MNT"
else
echo "ERROR: no device found for $fs" 1>&2
exit 2
7 years ago
fi
done