3 |
- |
1 |
#!/bin/bash
|
|
|
2 |
#
|
|
|
3 |
# halt This file is executed by init when it goes into runlevel
|
|
|
4 |
# 0 (halt) or runlevel 6 (reboot). It kills all processes,
|
|
|
5 |
# unmounts file systems and then either halts or reboots.
|
|
|
6 |
#
|
|
|
7 |
# Author: Miquel van Smoorenburg, <miquels@drinkel.nl.mugnet.org>
|
|
|
8 |
# Modified for RHS Linux by Damien Neil
|
|
|
9 |
#
|
|
|
10 |
|
|
|
11 |
NOLOCALE=1
|
|
|
12 |
. /etc/init.d/functions
|
|
|
13 |
|
|
|
14 |
UMOUNT="umount"
|
|
|
15 |
[ ! -w /etc ] && UMOUNT="umount -n"
|
|
|
16 |
|
|
|
17 |
halt_crypto() {
|
|
|
18 |
fnval=0
|
|
|
19 |
while read dst src key; do
|
|
|
20 |
[ -z "$dst" -o "${dst#\#}" != "$dst" ] && continue
|
|
|
21 |
if [ -b "/dev/mapper/$dst" ]; then
|
|
|
22 |
if /sbin/dmsetup info "$dst" | grep -q '^Open count: *0$'; then
|
|
|
23 |
action $"Stopping disk encryption for $dst" /sbin/cryptsetup remove "$dst"
|
|
|
24 |
else
|
|
|
25 |
fnval=1
|
|
|
26 |
fi
|
|
|
27 |
fi
|
|
|
28 |
done < /etc/crypttab
|
|
|
29 |
return $fnval
|
|
|
30 |
}
|
|
|
31 |
|
|
|
32 |
kill_all() {
|
|
|
33 |
local STRING rc
|
|
|
34 |
|
|
|
35 |
STRING=$1
|
|
|
36 |
echo -n "$STRING "
|
|
|
37 |
shift
|
|
|
38 |
/sbin/killall5 "$@"
|
|
|
39 |
rc=$?
|
|
|
40 |
# Retval: 0: success 1: error 2: no processes found to kill
|
|
|
41 |
if [ "$rc" == 1 ]; then
|
|
|
42 |
failure $"$STRING"
|
|
|
43 |
else
|
|
|
44 |
success $"$STRING"
|
|
|
45 |
fi
|
|
|
46 |
echo
|
|
|
47 |
return $rc
|
|
|
48 |
}
|
|
|
49 |
|
|
|
50 |
# See how we were called.
|
|
|
51 |
case "$0" in
|
|
|
52 |
*halt)
|
|
|
53 |
message=$"Halting system..."
|
|
|
54 |
command="/sbin/halt"
|
|
|
55 |
;;
|
|
|
56 |
*reboot)
|
|
|
57 |
message=$"Please stand by while rebooting the system..."
|
|
|
58 |
command="/sbin/reboot"
|
|
|
59 |
kexec_command="/sbin/kexec"
|
|
|
60 |
;;
|
|
|
61 |
*)
|
|
|
62 |
echo $"$0: call me as 'halt' or 'reboot' please!"
|
|
|
63 |
exit 1
|
|
|
64 |
;;
|
|
|
65 |
esac
|
|
|
66 |
case "$1" in
|
|
|
67 |
*start)
|
|
|
68 |
;;
|
|
|
69 |
*)
|
|
|
70 |
echo $"Usage: $0 {start}"
|
|
|
71 |
exit 1
|
|
|
72 |
;;
|
|
|
73 |
esac
|
|
|
74 |
|
|
|
75 |
# Kill all processes.
|
|
|
76 |
[ "${BASH+bash}" = bash ] && enable kill
|
|
|
77 |
|
|
|
78 |
# Find mdmon pid's and omit killing them
|
|
|
79 |
OMITARGS=
|
|
|
80 |
for i in /dev/md/*.pid; do
|
|
|
81 |
if [ ! -r "$i" ]; then
|
|
|
82 |
continue
|
|
|
83 |
fi
|
|
|
84 |
OMITARGS="$OMITARGS -o $(cat $i)"
|
|
|
85 |
done
|
|
|
86 |
|
|
|
87 |
kill_all $"Sending all processes the TERM signal..." -15 $OMITARGS
|
|
|
88 |
# No need to sleep and kill -9 if no processes to kill were found
|
|
|
89 |
if [ "$?" == 0 ]; then
|
|
|
90 |
sleep 2
|
|
|
91 |
kill_all $"Sending all processes the KILL signal..." -9 $OMITARGS
|
|
|
92 |
fi
|
|
|
93 |
|
|
|
94 |
# Write to wtmp file before unmounting /var
|
|
|
95 |
/sbin/halt -w
|
|
|
96 |
|
|
|
97 |
# Save mixer settings, here for lack of a better place.
|
|
|
98 |
if [ -s /etc/alsa/alsactl.conf -a -x /sbin/alsactl -a -w /etc/asound.state ]; then
|
|
|
99 |
action $"Saving mixer settings" /sbin/alsactl -E ALSA_CONFIG_PATH=/etc/alsa/alsactl.conf --ignore store
|
|
|
100 |
fi
|
|
|
101 |
|
|
|
102 |
# Save random seed
|
|
|
103 |
touch /var/lib/random-seed
|
|
|
104 |
chmod 600 /var/lib/random-seed
|
|
|
105 |
action $"Saving random seed: " dd if=/dev/urandom of=/var/lib/random-seed count=1 bs=512 2>/dev/null
|
|
|
106 |
|
|
|
107 |
[ -x /sbin/hwclock -a -e /dev/rtc ] && action $"Syncing hardware clock to system time" /sbin/hwclock --systohc
|
|
|
108 |
|
|
|
109 |
# Try to unmount tmpfs filesystems to avoid swapping them in. Ignore failures.
|
|
|
110 |
tmpfs=$(awk '$2 ~ /^\/($|proc|dev)/ { next; }
|
|
|
111 |
$3 == "tmpfs" { print $2; }' /proc/mounts | sort -r)
|
|
|
112 |
[ -n "$tmpfs" ] && fstab-decode $UMOUNT $tmpfs 2>/dev/null
|
|
|
113 |
|
|
|
114 |
# Turn off swap, then unmount file systems.
|
|
|
115 |
[ -f /proc/swaps ] && SWAPS=$(awk '! /^Filename/ { print $1 }' /proc/swaps)
|
|
|
116 |
if [ -n "$SWAPS" ]; then
|
|
|
117 |
action $"Turning off swap: " swapoff $SWAPS
|
|
|
118 |
for dst in $SWAPS; do
|
|
|
119 |
if [[ "$dst" == /dev/mapper* ]] \
|
|
|
120 |
&& [ "$(dmsetup status "$dst" | cut -d ' ' -f 3)" = crypt ]; then
|
|
|
121 |
backdev=$(/sbin/cryptsetup status "$dst" \
|
|
|
122 |
| awk '$1 == "device:" { print $2 }')
|
|
|
123 |
/sbin/cryptsetup remove "$dst"
|
|
|
124 |
fi
|
|
|
125 |
done
|
|
|
126 |
fi
|
|
|
127 |
|
|
|
128 |
[ -x /sbin/quotaoff ] && action $"Turning off quotas: " /sbin/quotaoff -aug
|
|
|
129 |
|
|
|
130 |
# Unmount file systems, killing processes if we have to.
|
|
|
131 |
# Unmount loopback stuff first
|
|
|
132 |
__umount_loopback_loop
|
|
|
133 |
|
|
|
134 |
# Unmount RPC pipe file systems
|
|
|
135 |
__umount_loop '$3 ~ /^rpc_pipefs$/ || $3 ~ /^rpc_svc_gss_pipefs$/ {print $2}' \
|
|
|
136 |
/proc/mounts \
|
|
|
137 |
$"Unmounting pipe file systems: " \
|
|
|
138 |
$"Unmounting pipe file systems (retry): " \
|
|
|
139 |
-f
|
|
|
140 |
|
|
|
141 |
LANG=C __umount_loop '$2 ~ /^\/$|^\/proc|^\/dev/{next}
|
|
|
142 |
$3 == "tmpfs" || $3 == "proc" {print $2 ; next}
|
|
|
143 |
$3 ~ /(loopfs|autofs|nfs|cifs|smbfs|ncpfs|sysfs)/ {next}
|
|
|
144 |
/(^none|^\/dev\/ram|^\/dev\/root$)/ {next}
|
|
|
145 |
{print $2}' /proc/mounts \
|
|
|
146 |
$"Unmounting file systems: " \
|
|
|
147 |
$"Unmounting file systems (retry): " \
|
|
|
148 |
-f
|
|
|
149 |
|
|
|
150 |
[ -f /proc/bus/usb/devices ] && $UMOUNT /proc/bus/usb
|
|
|
151 |
|
|
|
152 |
[ -f /etc/crypttab ] && halt_crypto
|
|
|
153 |
|
|
|
154 |
# remove the crash indicator flag
|
|
|
155 |
rm -f /.autofsck
|
|
|
156 |
|
|
|
157 |
# Try all file systems other than root, essential filesystems and RAM disks,
|
|
|
158 |
# one last time.
|
|
|
159 |
awk '$2 !~ /\/(|dev|proc|selinux|sys)$/ && $1 !~ /^\/dev\/ram/ { print $2 }' \
|
|
|
160 |
/proc/mounts | sort -r | \
|
|
|
161 |
while read line; do
|
|
|
162 |
fstab-decode $UMOUNT -f $line
|
|
|
163 |
done
|
|
|
164 |
|
|
|
165 |
HALTARGS="-d"
|
|
|
166 |
[ "$INIT_HALT" != "HALT" ] && HALTARGS="$HALTARGS -p"
|
|
|
167 |
|
|
|
168 |
if [ -x /sbin/halt.local ]; then
|
|
|
169 |
/sbin/halt.local "$message" "$command" "$HALTARGS" "$kexec_command"
|
|
|
170 |
fi
|
|
|
171 |
|
|
|
172 |
# Tell init to re-exec itself.
|
|
|
173 |
kill -TERM 1
|
54 |
- |
174 |
# And give init some time to do that (#1259873)
|
|
|
175 |
sleep 1
|
3 |
- |
176 |
|
|
|
177 |
# Remount read only anything that's left mounted.
|
|
|
178 |
# echo $"Remounting remaining filesystems readonly"
|
|
|
179 |
mount | awk '{ print $1,$3 }' | while read dev dir; do
|
|
|
180 |
fstab-decode mount -n -o ro,remount $dev $dir
|
|
|
181 |
done
|
|
|
182 |
|
|
|
183 |
# If we left mdmon's running wait for the raidsets to become clean
|
|
|
184 |
if [ -n "$OMITARGS" ]; then
|
|
|
185 |
sync
|
|
|
186 |
HALTARGS="$HALTARGS -n"
|
|
|
187 |
mdadm --wait-clean --scan
|
|
|
188 |
fi
|
|
|
189 |
|
|
|
190 |
# Now halt or reboot.
|
|
|
191 |
echo $"$message"
|
|
|
192 |
if [ -f /fastboot ]; then
|
|
|
193 |
echo $"On the next boot fsck will be skipped."
|
|
|
194 |
elif [ -f /forcefsck ]; then
|
|
|
195 |
echo $"On the next boot fsck will be forced."
|
|
|
196 |
fi
|
|
|
197 |
|
|
|
198 |
# Shutdown UPS drivers
|
|
|
199 |
if [ "$command" = /sbin/halt -a -f /etc/sysconfig/ups ]; then
|
|
|
200 |
. /etc/sysconfig/ups
|
|
|
201 |
if [ -z $POWERDOWNFLAG ]; then
|
|
|
202 |
POWERDOWNFLAG=/etc/killpower
|
|
|
203 |
fi
|
|
|
204 |
if [ "$SERVER" = "yes" -a -f $POWERDOWNFLAG ]; then
|
|
|
205 |
/sbin/upsdrvctl shutdown
|
33 |
- |
206 |
sleep 120
|
|
|
207 |
/sbin/reboot --force
|
3 |
- |
208 |
fi
|
|
|
209 |
fi
|
|
|
210 |
|
|
|
211 |
# Turn off UPS in powerfail situation
|
|
|
212 |
if [ -x /etc/apcupsd/apccontrol -a -f /etc/apcupsd/powerfail ]; then
|
|
|
213 |
/etc/apcupsd/apccontrol killpower
|
|
|
214 |
fi
|
|
|
215 |
|
|
|
216 |
# First, try kexec. If that fails, fall back to rebooting the old way.
|
|
|
217 |
[ -n "$kexec_command" ] && $kexec_command -e -x >& /dev/null
|
|
|
218 |
|
|
|
219 |
|
|
|
220 |
exec $command $HALTARGS
|