diff options
-rwxr-xr-x | samizdat-eject.sh | 87 |
1 files changed, 54 insertions, 33 deletions
diff --git a/samizdat-eject.sh b/samizdat-eject.sh index bfd8e1c..d95a49d 100755 --- a/samizdat-eject.sh +++ b/samizdat-eject.sh | |||
@@ -5,6 +5,48 @@ die() | |||
5 | exit 1 | 5 | exit 1 |
6 | } | 6 | } |
7 | 7 | ||
8 | btrfs_subdevices() | ||
9 | { | ||
10 | local mountpoint="$1" | ||
11 | btrfs filesystem show "$mountpoint" | sed -ne 's/^[ \t]*devid.* path //p' | ||
12 | } | ||
13 | |||
14 | btrfs_subdevice_count() | ||
15 | { | ||
16 | btrfs_subdevices "$1" | wc -l | ||
17 | } | ||
18 | |||
19 | remove() | ||
20 | { | ||
21 | for dev; do | ||
22 | (set -x; btrfs device remove "$dev" /) | ||
23 | dmsetup remove "$dev" 2>/dev/null | ||
24 | losetup -D | ||
25 | done | ||
26 | } | ||
27 | |||
28 | dm_name() | ||
29 | { | ||
30 | dmsetup info "$1" | sed -ne 's/^Name: *//p' | ||
31 | } | ||
32 | |||
33 | md_ready() | ||
34 | { | ||
35 | local mountpoint="$1" count dev | ||
36 | count=$(mdadm_subdevices /dev/md55|wc -l) | ||
37 | [ "$count" = 1 ] || return | ||
38 | dev=$(mdadm_subdevices /dev/md55) | ||
39 | [ "$(dm_name "$dev")" = samizdatiso ] | ||
40 | } | ||
41 | |||
42 | copy() | ||
43 | { | ||
44 | temp_target=$(mktemp --tmpdir=/outerfs) | ||
45 | mdadm_copy_eject_crypt /dev/md55 "$temp_target" | ||
46 | } | ||
47 | |||
48 | . mdadm-dup.sh || exit 1 | ||
49 | |||
8 | target=$1 | 50 | target=$1 |
9 | 51 | ||
10 | if [ ! "$target" ] && mountpoint -q /srv && [ ! -e /srv/samizdat.iso ]; then | 52 | if [ ! "$target" ] && mountpoint -q /srv && [ ! -e /srv/samizdat.iso ]; then |
@@ -14,20 +56,10 @@ fi | |||
14 | [ "$target" ] || die "Usage: $0 <target filename>" | 56 | [ "$target" ] || die "Usage: $0 <target filename>" |
15 | [ ! -e "$target" ] || die "Error: file exists: $target" | 57 | [ ! -e "$target" ] || die "Error: file exists: $target" |
16 | 58 | ||
17 | if mountpoint -q /outerfs; then | 59 | if ! mountpoint -q /outerfs; then |
18 | temp_target=$(mktemp --tmpdir=/outerfs) | ||
19 | else | ||
20 | die "Error: /outerfs is not a mountpoint. Please mount a safe filesystem to temporarily store the ISO on /outerfs" | 60 | die "Error: /outerfs is not a mountpoint. Please mount a safe filesystem to temporarily store the ISO on /outerfs" |
21 | fi | 61 | fi |
22 | 62 | ||
23 | . mdadm-dup.sh || exit 1 | ||
24 | |||
25 | btrfs_subdevices() | ||
26 | { | ||
27 | local mountpoint="$1" | ||
28 | btrfs filesystem show "$mountpoint" | sed -ne 's/^[ \t]*devid.* path //p' | ||
29 | } | ||
30 | |||
31 | devices=$(btrfs_subdevices /) || exit 1 | 63 | devices=$(btrfs_subdevices /) || exit 1 |
32 | 64 | ||
33 | set -- | 65 | set -- |
@@ -41,31 +73,20 @@ for dev in $devices; do | |||
41 | done | 73 | done |
42 | [ "$seen" ] || set -- # avoid messing up someone's btrfs! | 74 | [ "$seen" ] || set -- # avoid messing up someone's btrfs! |
43 | 75 | ||
44 | copy() | ||
45 | { | ||
46 | mdadm_copy_eject_crypt /dev/md55 "$temp_target" && | ||
47 | mdadm_copy_eject /dev/md55 "$target".part && | ||
48 | mv "$target".part "$target" | ||
49 | } | ||
50 | 76 | ||
51 | remove() | ||
52 | { | ||
53 | for dev; do | ||
54 | (set -x; btrfs device remove "$dev" /) | ||
55 | dmsetup remove "$dev" 2>/dev/null | ||
56 | losetup -D | ||
57 | done | ||
58 | } | ||
59 | 77 | ||
60 | # Doing the mdadm copy before removing the devices means our filesystem includes | ||
61 | # devices that are ultimately backed by files ON THE SAME FILESYSTEM. As such, it | ||
62 | # might conceivably put btrfs into a deadlock of some kind. | ||
63 | 78 | ||
64 | # If it turns out this doesn't work, the order can be reversed. This will | ||
65 | # perform the read IO twice, though, almost doubling the total installation | ||
66 | # time. | ||
67 | 79 | ||
68 | copy & remove "$@" | ||
69 | 80 | ||
70 | set -x | 81 | if ! md_ready; then |
82 | copy & | ||
83 | fi | ||
84 | |||
85 | remove "$@" | ||
86 | |||
71 | wait | 87 | wait |
88 | |||
89 | if [ "$(btrfs_subdevice_count /)" = 1 ] && md_ready; then | ||
90 | mdadm_copy_eject /dev/md55 "$target".part && | ||
91 | mv "$target".part "$target" | ||
92 | fi | ||