#!/bin/bash
#
# halt This file is executed by init when it goes into runlevel
# 0 (halt) or runlevel 6 (reboot). It kills all processes,
# unmounts file systems and then either halts or reboots.
#
#
# Set the path.
PATH=/sbin:/bin:/usr/bin:/usr/sbin
export NOLOCALE=1
. /etc/init.d/functions
runcmd() {
echo -n $"$1 "
shift
if [ "$BOOTUP" = "color" ]; then
$* && echo_success || echo_failure
else
$*
fi
echo
}
halt_get_remaining() {
awk '!/(^#|proc|loopfs|autofs|^none|^/dev/root| / )/ {print $2}' /proc/mounts
awk '{ if ($3 ~ /^proc$/ && $2 !~ /^/proc/) print $2; }' /proc/mounts
}
# See how we were called.
case "$0" in
*halt)
message=$"Halting system..."
command="halt"
;;
*reboot)
message=$"Please stand by while rebooting the system..."
command="reboot"
;;
*)
echo $"$0: call me as 'rc.halt' or 'rc.reboot' please!"
exit 1
;;
esac
if [ -n "$1" ]; then
case "$1" in
*start)
;;
*)
echo $"Usage: (halt|reboot) {start}"
exit 1
;;
esac
fi
# Kill all processes.
[ "${BASH+bash}" = bash ] && enable kill
runcmd $"Sending all processes the TERM signal..." /sbin/killall5 -15
sleep 5
runcmd $"Sending all processes the KILL signal..." /sbin/killall5 -9
# Write to wtmp file before unmounting /var
halt -w
# Save mixer settings, here for lack of a better place.
grep -q "(sparcaudio|sound)" /proc/devices
if [ $? = 0 -a -x /bin/aumix-minimal ]; then
runcmd $"Saving mixer settings" /bin/aumix-minimal -f /etc/.aumixrc -S
fi
# Sync the system clock.
ARC=0
SRM=0
UTC=0
if [ -f /etc/sysconfig/clock ]; then
. /etc/sysconfig/clock
# convert old style clock config to new values
if [ "${CLOCKMODE}" = "GMT" ]; then
UTC=true
elif [ "${CLOCKMODE}" = "ARC" ]; then
ARC=true
fi
fi
CLOCKDEF=""
CLOCKFLAGS="$CLOCKFLAGS --systohc"
case "$UTC" in
yes|true)
CLOCKFLAGS="$CLOCKFLAGS -u";
CLOCKDEF="$CLOCKDEF (utc)";
;;
no|false)
CLOCKFLAGS="$CLOCKFLAGS --localtime";
CLOCKDEF="$CLOCKDEF (localtime)";
;;
esac
case "$ARC" in
yes|true)
CLOCKFLAGS="$CLOCKFLAGS -A";
CLOCKDEF="$CLOCKDEF (arc)";
;;
esac
case "$SRM" in
yes|true)
CLOCKFLAGS="$CLOCKFLAGS -S";
CLOCKDEF="$CLOCKDEF (srm)";
;;
esac
runcmd $"Syncing hardware clock to system time" /sbin/hwclock $CLOCKFLAGS
# Turn off swap, then unmount file systems.
SWAPS=`awk '! /^Filename/ { print $1 }' /proc/swaps`
[ -n "$SWAPS" ] && runcmd $"Turning off swap: " swapoff $SWAPS
[ -x /sbin/accton ] && runcmd $"Turning off accounting: " /sbin/accton
[ -x /sbin/quotaoff ] && runcmd $"Turning off quotas: " /sbin/quotaoff -aug
# Unmount file systems, killing processes if we have to.
# Unmount loopback stuff first
remaining=`awk '!/^#/ && $1 ~ /^/dev/loop/ && $2 != "/" {print $1}' /proc/mounts`
[ -n "$remaining" ] && {
sig=
retry=3
while [ -n "$remaining" -a "$retry" -gt 0 ]
do
if [ "$retry" -lt 3 ]; then
runcmd $"Unmounting loopback filesystems (retry):" umount $remaining
else
runcmd $"Unmounting loopback filesystems: " umount $remaining
fi
for dev in $remaining ; do
losetup $dev > /dev/null 2>&1 && runcmd $"Detaching loopback device $dev: " losetup -d $device
done
remaining=`awk '!/^#/ && $1 ~ /^/dev/loop/ && $2 != "/" {print $2}' /proc/mounts`
[ -z "$remaining" ] && break
/sbin/fuser -k -m $sig $remaining >/dev/null
sleep 5
retry=$(($retry -1))
sig=-9
done
}
#
# everytime, we got the last entry from the remaining list,
# do an umount, then reread the remaining list to get the last
# entry again. If the last entry is indeed the same as the previous
# run, it means that the last mount can't be unmounted, in this
# case, we try to unmount the previous one. Repeat the whole procedure
# until we have nothing to unmount, or we reach the begining of the list
#
retry=3
sig=
# retry for 3 times
while [ "$retry" -gt 0 ]; do
lasttry=
while [ /bin/true ]; do
remaining=`halt_get_remaining`
# if nothing remaings in the mount table, break the loop
if [ -z "$remaining" ]; then
break
fi
lastmnt=""
# get the last entry from the mount tab
for mnt in $remaining; do
if [ -n "$lasttry" -a "$lasttry" = "$mnt" ]; then
lastmnt=$lastmnt
break
fi
lastmnt=$mnt
done
lasttry=$lastmnt
if [ "$retry" -lt 3 ]; then
echo "Unmounting (retry): $lasttry"
LANG=C runcmd $"Unmounting file systems (retry): " umount -f $lasttry
else
echo "Unmounting: $lasttry"
LANG=C runcmd $"Unmounting file systems: " umount -f $lasttry
fi
for m in $remaining; do
first=$m
break
done
# if we reach the first entry in the list, break the loop
if [ "$lasttry" = "$first" ]; then
break
fi
sleep 2
done
retry=$(($retry-1))
sig=-9
if [ -z "`halt_get_remaining`" ]; then
break
fi
done
[ -f /proc/bus/usb/devices ] && umount /proc/bus/usb
# remove the crash indicator flag
rm -f /.autofsck
# Try them all, one last time.
umount -a -f
# Remount read only anything that's left mounted.
#echo $"Remounting remaining filesystems (if any) readonly"
mount | awk '/( / |^/dev/root)/ { print $3 }' | while read line; do
mount -n -o ro,remount $line
done
# Now halt or reboot.
echo $"$message"
if [ -f /fastboot ]; then
echo $"On the next boot fsck will be skipped."
elif [ -f /forcefsck ]; then
echo $"On the next boot fsck will be forced."
fi
HALTARGS="-i -d"
if [ -f /poweroff -o ! -f /halt ]; then
HALTARGS="$HALTARGS -p"
fi
if [ "$command" = halt ] ; then
if [ -r /etc/ups/upsmon.conf -a -f /etc/killpower -a -f /etc/sysconfig/ups ] ; then
. /etc/sysconfig/ups
[ "$SERVER" = "yes" -a "$MODEL" != "NONE" -a -n "$MODEL" -a -n "$DEVICE" ] && $MODEL -k $DEVICE
fi
fi
eval $command $HALTARGS
|