summaryrefslogtreecommitdiff
path: root/src/initrd/samizdat-eject.sh
blob: a950ec5c936f23ea5482f24510bc2d4a78b0c260 (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
#!/bin/sh
die()
{
    printf '%s\n' "$*" >&2
    exit 1
}

btrfs_subdevices()
{
    local mountpoint="$1"
    btrfs filesystem show "$mountpoint" | sed -ne 's/^[ \t]*devid.* path //p'
}

btrfs_subdevice_count()
{
    btrfs_subdevices "$1" | wc -l
}

remove()
{
    for dev; do
        (set -x; btrfs device remove "$dev" /)
        dmsetup remove "$dev" 2>/dev/null
        losetup -D
    done
}

dm_name()
{
    dmsetup info "$1" | sed -ne 's/^Name: *//p'
}

md_ready()
{
    local mountpoint="$1" count dev
    count=$(mdadm_subdevices /dev/md55|wc -l)
    [ "$count" = 1 ] || return
    dev=$(mdadm_subdevices /dev/md55)
    [ "$(dm_name "$dev")" = samizdatiso ]
}

copy()
{
    temp_target=$(mktemp --tmpdir=/outerfs)
    mdadm_copy_eject_crypt /dev/md55 "$temp_target"
}

. mdadm-dup.sh || exit 1

target=$1

if [ ! "$target" ] && mountpoint -q /srv && [ ! -e /srv/samizdat.iso ]; then
    target=/srv/samizdat.iso
fi

[ "$target" ] || die "Usage: $0 <target filename>"
[ ! -e "$target" ] || die "Error: file exists: $target"

if ! mountpoint -q /outerfs; then
    die "Error: /outerfs is not a mountpoint.  Please mount a safe filesystem to temporarily store the ISO on /outerfs"
fi

devices=$(btrfs_subdevices /) || exit 1

set --
seen=
for dev in $devices; do
    [ -b "$dev" ] || exit 1
    case "$dev" in
        /dev/mapper/loop*) set -- "$@" "$dev" ;;
        /dev/mapper/samizdatcrypt) seen=y ;;
    esac
done
[ "$seen" ] || set -- # avoid messing up someone's btrfs!






if ! md_ready; then
    copy &
fi

remove "$@"

echo 'Waiting while boot medium is freed...' >&2
wait

notified=
while true; do
    if [ "$(btrfs_subdevice_count /)" = 1 ] && md_ready; then
        if [ -z "$notified" ]; then
            echo 'Boot medium is free.  It may be ejected now.' >&2
            notified=y
        fi
        mdadm_copy_eject /dev/md55 "$target".part &&
            mv "$target".part "$target"
        exit
    fi
    sleep 5
done