Backup-Scripts/btrfs/subvolume-delta-file

71 lines
1.6 KiB
Bash
Executable File

#!/bin/sh
#
# BTRFS delta snapshots with incomplete send handling
# CC0 ~caskd
: ${SRC:?'Source not defined'}
: ${SNAPDIR:?'Snapdir not defined'}
: ${DEST:?'Destination not defined'}
CDATE="$(date '+%s')"
SNAPSRC="$SRC"
SNAPPATH="$SNAPSRC/$SNAPDIR"
PREV="$SNAPPATH/prev"
CUR="$SNAPPATH/cur"
TMP="$SNAPPATH/tmp"
SNAPDEST="$SNAPPATH/$CDATE"
PARENTNAME="parent"
DESTNAME="data"
msg() {
echo "$1" >&2
}
compress() {
zstd -T0 -z -9
}
delta() {
local TS_PARENT="$(basename "$(realpath "$CUR")")"
local TS_CURRENT="$(basename "$(realpath "$TMP")")"
[ -d "$(realpath "$CUR")" ] || return 1
[ -e "$DEST/$TS_PARENT/$DATA" ] || return
msg "Attempting to send delta"
mkdir -vp "$DEST/$TS_CURRENT"
ln -sv "../$TS_PARENT" "$DEST/$TS_CURRENT/$PARENTNAME"
btrfs -v send --compressed-data -p "$CUR" "$TMP" | compress > "$DEST/$TS_CURRENT/$DESTNAME.tmp"
mv -v "$DEST/$TS_CURRENT/$DESTNAME.tmp" "$DEST/$TS_CURRENT/$DESTNAME"
}
full() {
local TS_CURRENT="$(basename "$(realpath "$TMP")")"
msg "Attempting to send full"
mkdir -vp "$DEST/$TS_CURRENT"
btrfs -v send --compressed-data "$TMP" | compress > "$DEST/$TS_CURRENT/$DESTNAME.tmp"
mv -v "$DEST/$TS_CURRENT/$DESTNAME.tmp" "$DEST/$TS_CURRENT/$DESTNAME"
}
symdel() {
if [ -L "$1" ]; then
btrfs subvolume delete "$1" >&2 || true
rm -v "$1" >&2
fi
}
mkdir -vp "$SNAPPATH" >&2
symdel "$TMP"
symdel "$PREV"
ln -sv "$CDATE" "$TMP" >&2
btrfs subvolume snapshot -r "$SNAPSRC" "$SNAPDEST" >&2
delta || full || return 1
# Mark snapshot transmission as complete
[ -L "$CUR" ] && \
mv -v "$CUR" "$PREV" >&2
mv -v "$TMP" "$CUR" >&2