#!/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.
#
# Author: Miquel van Smoorenburg, <miquels@drinkel.nl.mugnet.org>
# Modified for RHS Linux by Damien Neil
#
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 '$2 ~ /^\/$|^\/proc|^\/dev/{next}
$3 == "tmpfs" || $3 == "proc" {print $2 ; next}
/(^#|loopfs|autofs|devfs|^none|^\/dev\/root)/ {next}
{print $2}' /proc/mounts
}
# See how we were called.
case "$0" in
*halt)
message=`gprintf "Halting system..."`
command="/sbin/halt"
;;
*reboot)
message=`gprintf "Please stand by while rebooting the system..."`
command="/sbin/reboot"
;;
*)
gprintf "%s: call me as 'halt' or 'reboot' please!\n" $0
exit 1
;;
esac
case "$1" in
*start)
;;
*)
gprintf "Usage: %s\n" "$(basename $0) {start}"
exit 1
;;
esac
# Recreate the /initrd if needed
if [ ! -d /initrd ]; then
runcmd "Creating initrd directory" mkdir /initrd
fi
if [ -d /initrd -a ! -f /initrd/README.WARNING ]; then
cat > /initrd/README.WARNING <<EOF
(mkinitrd) Don't remove this directory, it's needed at boot time,
in the initrd, to perform the pivot_root.
EOF
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
/sbin/halt -w
# 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/quotaoff ] && runcmd "Turning off quotas: " /sbin/quotaoff -aug
# first remove entry /initrd/loopfs as it can't be unmounted
mtab=$(fgrep -v "/initrd/loopfs[^/]" /etc/mtab)
(IFS= ; echo $mtab > /etc/mtab)
# Unmount file systems, killing processes if we have to.
# Unmount loopback stuff first
remaining=`awk '!/^#/ && $1 ~ /^\/dev\/loop/ && $2 != "/" {print $2}' /proc/mounts`
devremaining=`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 $devremaining ; do
losetup $dev > /dev/null 2>&1 && \
runcmd "Detaching loopback device %s: " $dev losetup -d $dev
done
remaining=`awk '!/^#/ && $1 ~ /^\/dev\/loop/ && $2 != "/" {print $2}' /proc/mounts`
devremaining=`awk '!/^#/ && $1 ~ /^\/dev\/loop/ && $2 != "/" {print $1}' /proc/mounts`
[ -z "$remaining" ] && break
/sbin/fuser -k -m $sig $remaining >/dev/null
sleep 5
retry=$(($retry -1))
sig=-9
done
}
sig=
retry=3
remaining=`halt_get_remaining | sort -r`
while [ -n "$remaining" -a "$retry" -gt 0 ]
do
if [ "$retry" -lt 3 ]; then
LC_ALL=C runcmd "Unmounting file systems (retry): " umount -f $remaining
else
LC_ALL=C runcmd "Unmounting file systems: " umount -f $remaining
fi
sleep 2
remaining=`halt_get_remaining | sort -r`
[ -z "$remaining" ] && break
/sbin/fuser -k -m $sig $remaining >/dev/null
sleep 5
retry=$(($retry-1))
sig=-9
done
if [ -f /etc/lvm/lvm.conf -a -x /sbin/lvm2 ]; then
if grep -q -s 'device-mapper' /proc/devices; then
_vgchange_cmd="/sbin/lvm2 vgchange -a n"
fi
fi
if [ -z "${_vgscan_cmd}" -a -f /etc/lvmtab -a -e /proc/lvm ] ; then
if [ -x /sbin/lvm1-vgchange ]; then
_vgchange_cmd="/sbin/lvm1-vgchange -a n"
elif [ -x /sbin/vgchange ]; then
_vgchange_cmd="/sbin/vgchange -a n"
fi
fi
if [ -n "${_vgchange_cmd}" ]; then
runcmd "Shutting down LVM:" ${_vgchange_cmd}
fi
[ -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 -t nodevfs,noproc
# Remount read only anything that's left mounted.
#gprintf "Remounting remaining filesystems (if any) readonly\n"
mount | awk '/( \/ |^\/dev\/root)/ { print $3 }' | while read line; do
mount -n -o ro,remount $line
done
runcmd "Unmounting proc file system: " umount /proc
# See if this is a powerfail situation.
if [ -f /etc/apcupsd/powerfail ]; then
gprintf "APCUPSD will now power off the UPS!\n"
echo
/etc/apcupsd/apccontrol killpower
echo
gprintf "Please ensure that the UPS has powered off before rebooting\n"
gprintf "Otherwise, the UPS may cut the power during the reboot!!!\n"
echo
sleep 120
exit 1
fi
# for NUT
if [ -f /etc/init.d/upsd ]; then
/etc/init.d/upsd powerdown
[ $? == 3 ] && exit 1
fi
# Now halt or reboot.
echo "$message"
if [ -f /fastboot ]; then
gprintf "On the next boot fsck will be skipped.\n"
elif [ -f /forcefsck ]; then
gprintf "On the next boot fsck will be forced.\n"
fi
if [ -x /sbin/halt.local ]; then
/sbin/halt.local
fi
HALTARGS="-i -d -p -h"
mount -n -t proc proc /proc
exec $command $HALTARGS