blob: ce7de236aa1c3b80a0adfad363f03f6f35427001 (
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
|
#!/usr/bin/ash
# teardown a single device by node name
# $1: device node name, e.g. md0, dm-2
stop_device() {
local devtype= devname=
# the device must still be active
[ -e "/sys/class/block/$1" ] || return 1
# this can sometimes fail on stopped md devices, when the
# sysfs node doesn't go away as quickly as i'd like it to.
devtype=$(lsblk -drno TYPE "/dev/$1" 2>/dev/null) || return 1
case $devtype in
crypt)
read devname <"$1/dm/name"
cryptsetup remove "$devname"
;;
dm)
read devname <"$1/dm/name"
dmsetup remove "$devname"
;;
lvm)
# disassemble the parent VG
read devname <"$1/dm/name"
lvm lvdisplay -c "/dev/mapper/$devname" | {
IFS=: read _ vgname _
lvm vgchange -an "$vgname"
}
;;
raid*)
mdadm --stop "/dev/$1"
;;
dmraid)
read devname <"$1/dm/name"
dmraid -an "$devname"
;;
# silently ignore unstacked devices
esac
}
# recursively disassemble a device chain
# $1: device node name, e.g. md0, dm-2
disassemble() {
local holder=
for holder in "$1"/holders/*; do
if [ ! -e "$holder" ]; then
# end of the chain, recurse back up
stop_device "$1"
return
fi
disassemble "${holder##*/}"
stop_device "$1"
done
}
printf '%s\n' 'Detaching loop devices.'
for loop in loop*/loop; do
[ -e "$loop" ] && losetup -d "${loop%/loop}"
done
printf '%s\n' "Unmounting all devices."
# unmount everything in /oldroot
findmnt -Rruno TARGET /oldroot | awk '
BEGIN { i = 0 }
{
i++
mounts[i] = $0
}
END {
for (j = i; j > 0; j--) {
print mounts[j]
}
}
' | while read -r mount; do
umount "$mount"
done
printf '%s\n' "Disassembling stacked devices."
# chdir, so that we can avoid a lot of path chopping
cd /sys/class/block
# iterate over devices with holders
for part in */holders/*; do
[ -e "$part" ] && disassemble "${part%%/*}"
done
case $1 in
poweroff|shutdown|halt)
"$1" -f
;;
*)
type kexec >/dev/null && kexec -e
reboot -f
;;
esac
# vim: ft=sh ts=4 sw=4
|