ShaoLin Microsystems  
Leading Enterprise Linux Utility Computing
Corporate Products Services Support Partners
Downloads  Store  Contact Us   

3.5. HALT script

In order to umount Cogofs mounts properly, you may need to modify your system HALT script so that all the cogofs mount points will be unmounted in reverse order. The following is a sample HALT script ( ie. /etc/rc.d/init.d/halt ) based on RedHat 7.2 system, (Note: Modification in bolded text):

#!/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