blob: 1ab42440ddb6ae92bfce3caa2b923e5d01698ae7 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
#!/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] [--] <target directory>"
}
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 <<EOF
The following command will execute:
$*
The data will be permanently lost.
EOF
read -p "Continue? [y/N]> " 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
|