reorg and new lizardfs-snapshots.sh
This commit is contained in:
20
btrfs/README.md
Normal file
20
btrfs/README.md
Normal file
@@ -0,0 +1,20 @@
|
||||
Use BTRFS Snapshots For Backups
|
||||
===============================
|
||||
|
||||
btrfs-snapshots.sh
|
||||
------------------
|
||||
|
||||
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.
|
||||
|
||||
Try: `btrfs-snapshots.sh --help`
|
172
btrfs/btrfs-snapshots.sh
Executable file
172
btrfs/btrfs-snapshots.sh
Executable file
@@ -0,0 +1,172 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
# defaults
|
||||
HOURLY_DEL=25
|
||||
HOURLY_FAST=1
|
||||
DAILY_DEL=8
|
||||
DAILY_FAST=0
|
||||
WEEKLY_DEL=5
|
||||
WEEKLY_FAST=1
|
||||
MONTHLY_DEL=
|
||||
MONTHLY_FAST=1
|
||||
FAST=0
|
||||
REBALANCE=0
|
||||
BTRFS_VOLUMES=${BTRFS_VOLUMES:-$(awk '!/^#/ && $3=="btrfs" {print $2}' /etc/fstab | tr '\n' ' ' | sed 's, $,,')}
|
||||
TMP_MNT=${TMP_MNT:-/var/tmp/btrfs-backup}
|
||||
|
||||
# overwrite defaults in configs
|
||||
if test -e /etc/btrfs-snapshots.conf; then
|
||||
. /etc/btrfs-snapshots.conf
|
||||
fi
|
||||
if test -e ~/.btrfs-snapshots; then
|
||||
. ~/.btrfs-snapshots
|
||||
fi
|
||||
|
||||
# evaluate commandline
|
||||
vols=()
|
||||
del=${DEL}
|
||||
dryrun=0
|
||||
fast=${FAST}
|
||||
rebalance=${REBALANCE}
|
||||
periodity=${0%/*}
|
||||
periodity=${periodity##*/}
|
||||
if [[ $periodity =~ ^cron\... ]]; then
|
||||
periodity=${periodity#cron}
|
||||
else
|
||||
periodity=
|
||||
fi
|
||||
|
||||
case "$periodity" in
|
||||
(.hourly) del=${HOURLY_DEL}; fast=${HOURLY_FAST};;
|
||||
(.daily) del=${DAILY_DEL}; fast=${DAILY_FAST};;
|
||||
(.weekly) del=${WEEKLY_DEL}; fast=${WEEKLY_FAST};;
|
||||
(.monthly) del=${MONTHLY_DEL}; fast=${MONTHLY_FAST};;
|
||||
esac
|
||||
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
|
||||
-f, --fast fast run, do not optimize btrfs (otherwise done daily)
|
||||
-r, --rebalance enable rebalancing (always disabled in fast mode)
|
||||
-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
|
||||
|
||||
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
|
||||
|
||||
EOF
|
||||
exit;;
|
||||
(-n|--dry-run) dryrun=1;;
|
||||
(-f|--fast) fast=1;;
|
||||
(-r|--rebalance) rebalance=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
|
||||
|
||||
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
|
||||
else
|
||||
if test "$fs" = "/"; then
|
||||
name="/"
|
||||
else
|
||||
name=${fs#/}
|
||||
name=${name%/}
|
||||
name=/${name//\//-}-
|
||||
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 -d1 "${TMP_MNT}${target}"-* | sort -r | tail -n +"$del"); do
|
||||
echo " " btrfs subvolume delete "$f"
|
||||
done
|
||||
fi
|
||||
echo " " umount "$TMP_MNT"
|
||||
if test $fast -eq 0; then
|
||||
echo " " btrfs filesystem defragment ${fs}
|
||||
if test $rebalance -eq 1; then
|
||||
echo " " btrfs balance start ${fs}
|
||||
fi
|
||||
fi
|
||||
else
|
||||
sudo btrfs subvolume snapshot "${TMP_MNT}${subvol}" "${TMP_MNT}${target}${date}"
|
||||
if test -n "$del"; then
|
||||
for f in $(ls -d1 "${TMP_MNT}${target}"-* | sort -r | tail -n +"$del"); do
|
||||
sudo btrfs subvolume delete "$f"
|
||||
done
|
||||
fi
|
||||
fi
|
||||
sudo umount "$TMP_MNT"
|
||||
if test $fast -eq 0; then
|
||||
echo "Defragment subvolume: '${fs}'"
|
||||
sudo btrfs filesystem defragment "${fs}"
|
||||
if test $rebalance -eq 1; then
|
||||
echo "Rebalance subvolume: '${fs}'"
|
||||
sudo btrfs balance start "${fs}"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "ERROR: no device found for $fs" 1>&2
|
||||
exit 2
|
||||
fi
|
||||
done
|
Reference in New Issue
Block a user