#!/bin/bash set -e -o pipefail btrfs_subvolume_list_args=('-o' "$@") list_mounted_btrfs_devices() { mount -t btrfs | while read do printf '%s\n' "${REPLY%% *}" done | sort -u } list_all_subvolumes() { for dev in $(list_mounted_btrfs_devices) do [ -b "$dev" ] || return d=btrfs/pid-$$/$(systemd-escape "$dev") ( cd /run mkdir -p "$d" || exit trap 'umount "$d"; rmdir -p "$d" 2>/dev/null' EXIT root= ( set -x mountpoint -q "$d" || mount -o ro,subvol=/ "$dev" "$d" || return btrfs subvolume list "$@" "$d" ) | extract_subvolume_path "/run/$d" || return ) done } extract_subvolume_path() { while read do path=${REPLY#* path } [ "$path" != "$REPLY" ] path=${path#/} tryroot=$1/$path [ -d "$tryroot" ] || exit while ! [ "$root" ] do if [ / -ef "$tryroot" ] then root=${tryroot#$1/} break elif [ ! "$tryroot" -o "$tryroot" = / ] then break else tryroot=${tryroot%/*} fi done if [ "$root" ] then case "$path" in "$root" | "$root"/*) path=$root/.${path#$root} ;; esac fi printf '%s//%s\n' "${1##*/}" "$path" done } datetime_glob_a=.snapshot~[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9],[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9]:[0-9][0-9] datetime_glob_b=*_mirror.[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]_[0-9][0-9]:[0-9][0-9]:[0-9][0-9],[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9]:[0-9][0-9] squash_snapshots() { while read line do if [[ $line == */$datetime_glob_a ]] || [[ $line == $datetime_glob_b ]] then echo "${line%.*}.*" else echo "$line" fi done | sort -u } #SQUASH_SNAPSHOTS=y if [ "$SQUASH_SNAPSHOTS" ] then list_all_subvolumes "${btrfs_subvolume_list_args[@]}" | sort -u | squash_snapshots else list_all_subvolumes "${btrfs_subvolume_list_args[@]}" | sort -u fi