#!/bin/sh set -eu list_subvolumes() { btrfs subvolume list --sort=path "$1" | awk '{print $9}' | uniq } cleanup() { for volume in $(list_subvolumes "$source/.snapshot") do if [ -d "$source/.snapshot/$volume" ] then btrfs subvolume delete "$source/.snapshot/$volume" fi done btrfs subvolume delete "$source/.snapshot" sync --file-system "$source" } if [ "$#" -ne 2 ] then echo "Usage: $0 source destination" >&2 exit 1 fi source="$1" destination="$2" # Before the first snapshot is made. subvolumes="$(list_subvolumes "$source")" trap 'cleanup' INT QUIT EXIT TERM # It would be better to take all snapshots atomically, but that's not possible. btrfs subvolume snapshot "$source" "$source/.snapshot" for volume in $subvolumes do rm --dir "$source/.snapshot/$volume" btrfs subvolume snapshot "$source/$volume" "$source/.snapshot/$volume" done sync --file-system "$source" rsync --archive \ --delete \ "$source/.snapshot/" \ "$destination"