]> git.ipfire.org Git - thirdparty/dracut.git/blob - modules.d/99shutdown/shutdown.sh
d6a532b0c213c7957d223515a0fcf6328be7a403
[thirdparty/dracut.git] / modules.d / 99shutdown / shutdown.sh
1 #!/bin/sh
2 # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
3 # ex: ts=8 sw=4 sts=4 et filetype=sh
4 #
5 # Licensed under the GPLv2
6 #
7 # Copyright 2011, Red Hat, Inc.
8 # Harald Hoyer <harald@redhat.com>
9 ACTION="$1"
10
11 [ -w /dev/console ] && exec </dev/console >>/dev/console 2>>/dev/console
12
13 export TERM=linux
14 export PATH=/usr/sbin:/usr/bin:/sbin:/bin
15 . /lib/dracut-lib.sh
16
17 mkdir /oldsys
18 for i in sys proc run dev; do
19 mkdir /oldsys/$i
20 mount --move /oldroot/$i /oldsys/$i
21 done
22
23 # if "kexec" was installed after creating the initramfs, we try to copy it from the real root
24 # libz normally is pulled in via kmod/modprobe and udevadm
25 if [ "$ACTION" = "kexec" ] && ! command -v kexec >/dev/null 2>&1; then
26 for p in /usr/sbin /usr/bin /sbin /bin; do
27 cp -a /oldroot/${p}/kexec $p >/dev/null 2>&1 && break
28 done
29 hash kexec
30 fi
31
32 trap "emergency_shell --shutdown shutdown Signal caught!" 0
33 getarg 'rd.break=pre-shutdown' && emergency_shell --shutdown pre-shutdown "Break before pre-shutdown"
34
35 source_hook pre-shutdown
36
37 warn "Killing all remaining processes"
38
39 killall_proc_mountpoint /oldroot
40
41 umount_a() {
42 local _did_umount="n"
43 while read a mp a; do
44 if strstr "$mp" oldroot; then
45 if umount "$mp"; then
46 _did_umount="y"
47 warn "Unmounted $mp."
48 fi
49 fi
50 done </proc/mounts
51 losetup -D
52 [ "$_did_umount" = "y" ] && return 0
53 return 1
54 }
55
56 _cnt=0
57 while [ $_cnt -le 40 ]; do
58 umount_a 2>/dev/null || break
59 _cnt=$(($_cnt+1))
60 done
61
62 [ $_cnt -ge 40 ] && umount_a
63
64 if strstr "$(cat /proc/mounts)" "/oldroot"; then
65 warn "Cannot umount /oldroot"
66 for _pid in /proc/*; do
67 _pid=${_pid##/proc/}
68 case $_pid in
69 *[!0-9]*) continue;;
70 esac
71 [ -e /proc/$_pid/exe ] || continue
72 [ -e /proc/$_pid/root ] || continue
73 if strstr "$(ls -l /proc/$_pid /proc/$_pid/fd 2>/dev/null)" "oldroot"; then
74 warn "Blocking umount of /oldroot [$_pid] $(cat /proc/$_pid/cmdline)"
75 elif [ $_pid -ne $$ ]; then
76 warn "Still running [$_pid] $(cat /proc/$_pid/cmdline)"
77 fi
78 ls -l /proc/$_pid/fd 2>&1 | vwarn
79 done
80 fi
81
82 _check_shutdown() {
83 local __f
84 local __s=1
85 for __f in $hookdir/shutdown/*.sh; do
86 [ -e "$__f" ] || continue
87 ( . "$__f" $1 )
88 if [ $? -eq 0 ]; then
89 rm -f $__f
90 __s=0
91 fi
92 done
93 return $__s
94 }
95
96 while _check_shutdown; do
97 :
98 done
99 _check_shutdown final
100
101 getarg 'rd.break=shutdown' && emergency_shell --shutdown shutdown "Break before shutdown"
102
103 case "$ACTION" in
104 reboot|poweroff|halt)
105 $ACTION -f -d -n
106 warn "$ACTION failed!"
107 ;;
108 kexec)
109 kexec -e
110 warn "$ACTION failed!"
111 ;;
112 *)
113 warn "Shutdown called with argument '$ACTION'. Rebooting!"
114 reboot -f -d -n
115 ;;
116 esac
117
118 emergency_shell --shutdown shutdown