2024-12-08 16:49:16 +00:00
|
|
|
#!/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"
|
2024-12-11 10:55:41 +00:00
|
|
|
ln -sv "../$TS_PARENT" "$DEST/$TS_CURRENT/$PARENTNAME"
|
2024-12-08 16:49:16 +00:00
|
|
|
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
|