#!/bin/bash die() { printf 'Error: %s\n' "$*"; exit 1; } if [ $UID != 0 ] then exec sudo -- "$0" "$@" || die 'You are not root.' fi help() { printf '%s\n' "Usage: $0 [-h|--help] [--] " } unset force delete verbose while [ $# -gt 0 ] do case "$1" in -h|--help) help; exit;; --force) force=y ;; --delete-after) delete=y ;; -v) verbose=y ;; --) shift; break ;; -*) die unknown option ;; *) break; esac shift done [ $# = 1 ] || die 'You must specify a target directory to create.' target=$1 root=$target/root mkdir "$target" || die 'creating target directory' btrfs subvolume snapshot / "$root" verbosely() { ( if [ "$verbose" ] then set -x fi "$@" ) } bind_it() { verbosely mount --bind "$mountpoint" "$root"/"$mountpoint" } copy_mountpoint() { [ "$1" -a "$2" ] || return [ -d "$2" ] && return [ -d "${2%/*}" ] || copy_mountpoint "${1%/*}" "${2%/*}" mkdir -p "$2" chown --reference "$1" "$2" chmod --reference "$1" "$2" } mounts=$(tempfile) cat /proc/mounts > "$mounts" while read mountdev mountpoint fstype fsoptions _ do case "$mountpoint" in /sys |/proc |/dev |/usr | /usr/local) bind_it; continue ;; /sys/*|/proc/*|/dev/* ) continue ;; esac case "$PWD" in "$mountpoint"/*) bind_it; continue ;; esac case "$fstype" in tmpfs) case "$mountpoint" in /run/*) copy_mountpoint "$mountpoint" "$root"/"$mountpoint" ;; esac mount "$mountdev" -t "$fstype" -o "$fsoptions" "$root"/"$mountpoint" ;; esac done < "$mounts" tac "$mounts" | while read mountdev mountpoint fstype fsoptions _ do case "$mountpoint" in "$root"/*) verbosely umount -l "$mountpoint";; esac done chroot "$root" /bin/bash confirm() { cat < " line case "$line" in [yY]) "$@"; return ;; esac } if [ "$delete" -a "$force" ] then btrfs subvolume delete "$target"/root rmdir "$target" elif [ "$delete" ] then confirm btrfs subvolume delete "$target"/root rmdir "$target" fi