summaryrefslogtreecommitdiff
path: root/src/initrd/umountall.sh
diff options
context:
space:
mode:
Diffstat (limited to 'src/initrd/umountall.sh')
-rwxr-xr-xsrc/initrd/umountall.sh126
1 files changed, 126 insertions, 0 deletions
diff --git a/src/initrd/umountall.sh b/src/initrd/umountall.sh
new file mode 100755
index 0000000..bf89838
--- /dev/null
+++ b/src/initrd/umountall.sh
@@ -0,0 +1,126 @@
1#!/bin/sh
2OPEN_SHELL_BEFORE_SHUTDOWN=
3
4movemount() {
5 if mountpoint -q "$1"; then
6 umount /root/"$1"
7 else
8 mkdir -p "$1"
9 mount --move /root/"$1" "$1"
10 fi
11}
12
13retry_n_delay() {
14 local n="$1" delay="$2"
15 shift 2
16 while [ "$n" -gt 0 ]; do "$@" && break; sleep $delay; n=$((n-1)); done
17}
18
19umount_all_novirtual()
20{
21 # EQUIVALENT: umount -a -t norootfs,nosysfs,noproc,notmpfs,nodevpts,nodevtmpfs
22 # busyboxy umount does not support -t, therefore:
23 tac /proc/mounts | {
24 errors=0
25 while read dev mp type opts _; do
26 case $type in
27 rootfs|sysfs|proc|tmpfs|devpts|devtmpfs) ;;
28 *) umount "$mp" || errors=$((errors+1)) ;;
29 esac
30 done
31 return $errors
32 }
33}
34
35losetup_delete_all()
36{
37 local f dev
38 for f in /sys/dev/block/7:*/loop; do
39 dev=${f#/sys/dev/block/7:}
40 dev=/dev/loop${dev%%/*}
41 losetup -d $dev
42 done
43}
44
45mdadm_stop_all()
46{
47 for md in /dev/md* /dev/md/*; do
48 test -b "$md" && mdadm --stop "$md"
49 done
50}
51
52lvm_deactivate() { lvm lvchange -v -an samizdat 11>&-; }
53
54killemdead() {
55 force= pids="$(pidof "$@")"
56 while [ "$pids" ]; do
57 kill $force $pids
58 living=
59 for p in $pids; do
60 if [ -e /proc/$p ]; then
61 living=1
62 break
63 fi
64 done
65 [ ! "$living" ] && break
66 force=-9
67 done
68}
69
70specials= movemounts= umounts=
71while read dev mp type opts _; do # N.B. order is reversed in variables
72case $mp in
73 /root/dev|/root/proc)
74 specials="$mp $specials" ;;
75 /root/sys|/root/cdrom|/root/mnt/*|/root/gpg|/root/overlay|/root/xino|/root/squashes/*)
76 movemounts="$mp $movemounts" ;;
77 /root/*)
78 umounts="$mp $umounts" ;;
79esac
80done < /proc/mounts
81
82# Unmount mounts under /root that we didn't put there
83while true; do
84 error=0; success=0
85 for m in $umounts; do
86 if umount $m; then
87 success=$((success+1))
88 else
89 error=$((error+1))
90 fi
91 done
92 [ $error = 0 ] && break
93 [ $success = 0 ] && break
94done
95
96# Move back mounts that we moved
97for m in $movemounts; do
98 movemount "${m#/root}" # TODO: error handling
99done
100
101killemdead gpg-agent samizdat-pinentry
102
103umount /root/dev
104umount /root/proc
105ln -sf /proc/mounts /etc/mtab
106
107umount_all_novirtual
108mdadm_stop_all
109losetup_delete_all
110lvm_deactivate
111cryptsetup remove samizdatcrypt
112losetup_delete_all
113umount_all_novirtual
114
115if [ "$OPEN_SHELL_BEFORE_SHUTDOWN" ]; then
116 read cmd < /halt
117 echo
118 echo "Remove cdrom and press ctrl-d to run '$cmd'."
119 /bin/sh -i
120fi
121
122read cmd < /halt && $cmd
123sleep 1
124
125echo "Error! Starting emergency shell with pid 1."
126exec /bin/sh -i