From 6ca8343202c20d00f6aae784867c1039b310e225 Mon Sep 17 00:00:00 2001 From: surtur Date: Mon, 3 May 2021 15:23:51 +0200 Subject: [PATCH] feat: add snapshot locking via chattr +i the snapshot might get deleted from underneath us so lock it by setting the immutable bit on the snapshot; note we don't need a recursive lock because the snapshot already is read-only, we just need to prevent it from getting pruned by 'btrfs subvolume delete' --- README.md | 5 +++-- btrfs-sync | 13 +++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b9d2579..44b0d82 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # btrfs-sync -> **Note**: This fork simply adds in-transfer `zstd` compression support +> **Note**: This fork simply adds in-transfer `zstd` compression support and snapshot locking capability (see [Features](#features)) Smart and easy sync of BTRFS snapshots, locally or through SSH. @@ -35,6 +35,7 @@ Delete subvolume (no-commit): '/media/USBdrive/home-snapshots/hourly_2018-03-08_ - Simple syntax - Optional progress indication (using `pv`) - Support for `zstd`, `xz` or `pbzip2` compression in order to save bandwidth. +- Snapshot locking via `chattr +i` while sync (`btrfs-send`) is in progress to prevent snapshot deletion, namely by `btrfs subvolume delete ...` invoked e.g as part of `btrfs-snp` - Retention policy - Automatic incremental synchronization - Cron friendly @@ -114,4 +115,4 @@ chmod +x /etc/cron.daily/btrfs-sync Original work by *nachoparker* of [ownyourbits.com](https://ownyourbits.com/2018/03/09/easy-sync-of-btrfs-snapshots-with-btrfs-sync/) -zstd compression support added by wanderer of [dotya.ml](https://git.dotya.ml/wanderer) +zstd compression support and snapshot locking capability added by wanderer of [dotya.ml](https://git.dotya.ml/wanderer) diff --git a/btrfs-sync b/btrfs-sync index 957f8c2..c837fd6 100755 --- a/btrfs-sync +++ b/btrfs-sync @@ -298,11 +298,24 @@ sync_snapshot() { echov "* Check destination" get_dst_snapshots "$DST" # sets DSTS DST_UUIDS for src in "${SRCS[@]}"; do + # the snapshot might get deleted from underneath us so lock it by setting + # the immutable bit on the snapshot; note we don't need a recursive lock + # because the snapshot already is read-only, we just need to prevent it from + # getting pruned by 'btrfs subvolume delete' + echov "* Locking '$src'" + chattr +i "$src" sync_snapshot "$src" && RET=0 || RET=1 + # unlock after we're done + echov "* Freeing lock on '$src'" + chattr -i "$src" for i in $(seq 1 2); do [[ "$RET" != "1" ]] && break echo "* Retrying '$src'..." + echov "* Locking '$src'" + chattr +i "$src" sync_snapshot "$src" && RET=0 || RET=1 + echov "* Freeing lock on '$src'" + chattr -i "$src" done [[ "$RET" == "1" ]] && { echo "Abort"; exit 1; } done