blob: bf898384af0de2936e98a3861334ec0ac690a64c (
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
121
122
123
124
125
126
|
#!/bin/sh
OPEN_SHELL_BEFORE_SHUTDOWN=
movemount() {
if mountpoint -q "$1"; then
umount /root/"$1"
else
mkdir -p "$1"
mount --move /root/"$1" "$1"
fi
}
retry_n_delay() {
local n="$1" delay="$2"
shift 2
while [ "$n" -gt 0 ]; do "$@" && break; sleep $delay; n=$((n-1)); done
}
umount_all_novirtual()
{
# EQUIVALENT: umount -a -t norootfs,nosysfs,noproc,notmpfs,nodevpts,nodevtmpfs
# busyboxy umount does not support -t, therefore:
tac /proc/mounts | {
errors=0
while read dev mp type opts _; do
case $type in
rootfs|sysfs|proc|tmpfs|devpts|devtmpfs) ;;
*) umount "$mp" || errors=$((errors+1)) ;;
esac
done
return $errors
}
}
losetup_delete_all()
{
local f dev
for f in /sys/dev/block/7:*/loop; do
dev=${f#/sys/dev/block/7:}
dev=/dev/loop${dev%%/*}
losetup -d $dev
done
}
mdadm_stop_all()
{
for md in /dev/md* /dev/md/*; do
test -b "$md" && mdadm --stop "$md"
done
}
lvm_deactivate() { lvm lvchange -v -an samizdat 11>&-; }
killemdead() {
force= pids="$(pidof "$@")"
while [ "$pids" ]; do
kill $force $pids
living=
for p in $pids; do
if [ -e /proc/$p ]; then
living=1
break
fi
done
[ ! "$living" ] && break
force=-9
done
}
specials= movemounts= umounts=
while read dev mp type opts _; do # N.B. order is reversed in variables
case $mp in
/root/dev|/root/proc)
specials="$mp $specials" ;;
/root/sys|/root/cdrom|/root/mnt/*|/root/gpg|/root/overlay|/root/xino|/root/squashes/*)
movemounts="$mp $movemounts" ;;
/root/*)
umounts="$mp $umounts" ;;
esac
done < /proc/mounts
# Unmount mounts under /root that we didn't put there
while true; do
error=0; success=0
for m in $umounts; do
if umount $m; then
success=$((success+1))
else
error=$((error+1))
fi
done
[ $error = 0 ] && break
[ $success = 0 ] && break
done
# Move back mounts that we moved
for m in $movemounts; do
movemount "${m#/root}" # TODO: error handling
done
killemdead gpg-agent samizdat-pinentry
umount /root/dev
umount /root/proc
ln -sf /proc/mounts /etc/mtab
umount_all_novirtual
mdadm_stop_all
losetup_delete_all
lvm_deactivate
cryptsetup remove samizdatcrypt
losetup_delete_all
umount_all_novirtual
if [ "$OPEN_SHELL_BEFORE_SHUTDOWN" ]; then
read cmd < /halt
echo
echo "Remove cdrom and press ctrl-d to run '$cmd'."
/bin/sh -i
fi
read cmd < /halt && $cmd
sleep 1
echo "Error! Starting emergency shell with pid 1."
exec /bin/sh -i
|