#! /bin/sh
# Copyright (c) 1996-2008 SuSE Linux Products GmbH, Nuernberg, Germany.
# All rights reserved.
#
# Author: Florian La Roche, 1996
#	  Werner Fink <werner@suse.de>, 1996-2008
#
# Please send feedback to http://www.suse.de/feedback
#
# /etc/init.d/halt (and symlinked to reboot)
#

. /etc/rc.status
. /etc/sysconfig/boot
. /etc/sysconfig/shutdown

test -s /etc/sysconfig/bootsplash && . /etc/sysconfig/bootsplash
test -e /proc/splash || SPLASH="no"
test -x /sbin/splash || SPLASH="no"

#
# Avoid being interrupted by child or keyboard
#
trap "echo" SIGINT SIGSEGV SIGQUIT SIGTERM
set +e

case "${0##*/}" in
    *halt)
	message="The system will be halted immediately."
	arch=$(/bin/uname -m)
	command="halt"
	mddev=""
	opts=""
	#
	# Sysvinit's shutdown is knowning about the option -P and -H to set
	# the environment variable INIT_HALT within init for the runlevel 0.
	# If this variable is not set we use the system default.
	#
	if test -z "$INIT_HALT" ; then
	    case "$HALT" in
	    [Pp]*) INIT_HALT=POWEROFF ;;
	    [Hh]*) INIT_HALT=HALT     ;;
	    *)
		INIT_HALT=POWEROFF
		#
		# Check this if valid for AMD/Intel based systems
		#
		case "$arch" in
		i?86|x86_64)
		    if test -e /proc/apm -o -e /proc/acpi -o -e /proc/sys/acpi ; then
			INIT_HALT=POWEROFF
		    else
		    	INIT_HALT=HALT
			case "$(rc_cmdline apm)" in
			apm=smp-power-off|apm=power-off) INIT_HALT=POWEROFF ;;
			esac
		    fi
		    ;;
		esac
		;;
	    esac
	fi
	#
	# The manual page of shutdown utilizes POWEROFF whereas in
	# the code the word POWERDOWN shows up for the option -P.
	#
	case "$INIT_HALT" in
	POWEROFF|POWERDOWN)
	    opts="${opts:+$opts }-p" ;;
	esac
	#
	# Sometimes wake-on-lan isn't wanted, if so stop network
	#
	if test "$HALT_NETWORK" = "yes" ; then
	    opts="${opts:+$opts }-i"
	fi
	#
	# Sometimes it is wanted to stop also the disks
	#
	if test "$HALT_DISKS" = "yes" ; then
	    opts="${opts:+$opts }-h"
	fi
	;;
    *reboot)
	message="Please stand by while rebooting the system..."
	command="reboot"
	mddev=""
	opts=""
	if test "$HALT_NETWORK" = "yes" ; then
	    opts="${opts:+$opts }-i"
	fi
	;;
    *)
	echo "$0: call me as \"halt\" or \"reboot\" please!"
	exit 1
	;;
esac

#
# first do local stuff
#
rc_reset
if test -e /etc/init.d/halt.local ; then
    echo Running /etc/init.d/halt.local
    /bin/sh /etc/init.d/halt.local
    rc_status -v1 -r
fi

# write to wtmp file before unmounting /var
$command -w 

# set a flag that we had success upto this point
test -w / && > /success

# give processes in front a chance to quit
vhangup ${REDIRECT} /dev/tty1 /dev/tty2 /dev/tty3 /dev/tty4 /dev/tty5 /dev/tty6 /dev/ttyS0 /dev/ttyS1

test -s /etc/init.d/.depend.halt  || RUN_PARALLEL="no"
type -p startpar &> /dev/null     || RUN_PARALLEL="no"
startpar -v      &> /dev/null     || RUN_PARALLEL="no"

if test "$COLD_BOOT" != "yes" ; then
    #
    # set back system boot configuration
    #
    if test "$RUN_PARALLEL" = "yes" ; then

	startopt="-p4 -t 30 -T 3"
	eval $(startpar $startopt -M halt)
	unset failed_service skipped_service

    elif test -d /etc/init.d/boot.d/ ; then
	#
	# call modules in boot.d via K* symlinks
	#
	for link in /etc/init.d/boot.d/K[0-9][0-9]*; do
	    test -x $link || continue
	    $link stop
	done
	unset link
    fi
fi

# check out if a software raid is active
if test -e /proc/mdstat -a -x /sbin/mdadm ; then
    while read line ; do
	case "$line" in
	md*:*active*) mddev=--scan; break ;;
	esac
    done < /proc/mdstat
    unset line
    if test -n "$mddev" -a -e /etc/mdadm.conf ; then
	mddev=""
	while read type dev rest; do
	    case "$dev" in
	    /dev/md*) mddev="${mddev:+$mddev }$dev" ;;
	    esac
	done < /etc/mdadm.conf
	unset type dev rest
    fi
fi

# kill splash animation
test "$SPLASH" = yes && /sbin/splash -q

echo "Sending all processes the TERM signal..."
killall5 -15
echo -e "$rc_done_up"

# wait between last SIGTERM and the next SIGKILL
rc_wait /sbin/blogd /sbin/splash

echo "Sending all processes the KILL signal..."
killall5 -9
echo -e "$rc_done_up"

if test -n "$REDIRECT" && /sbin/checkproc /sbin/blogd ; then
    # redirect our famous last messages to default console
    exec 0<> $REDIRECT 1>&0 2>&0
fi

# on umsdos fs this would lead to an error message, so direct errors to
# /dev/null
mount -no remount,ro / 2> /dev/null
sync

# wait for md arrays to become clean
if test -x /sbin/mdadm; then
    /sbin/mdadm --wait-clean --scan
fi
# stop any inactive software raid
if test -n "$mddev" ; then
    /sbin/mdadm --quiet --stop $mddev
    # redirect shell errors to /dev/null
    exec 3>&2 2>/dev/null
    # cause the md arrays to be marked clean immediately
    for proc in /proc/[0-9]* ; do
	test ! -e $proc/exe || continue
	read -t 1 tag name rest < $proc/status || continue
	case "$name" in
	md*_raid*) killproc -n -SIGKILL "$name" ;;
	esac
    done
    unset tag name rest
    # get shell errors back
    exec 2>&3-
fi

# show "the system is down" message
test "$SPLASH" = yes && /sbin/splash -q -p 65535 -t "isdown"

# we do not really unmount /proc any more since halt(8) might need it
#umount -anvt proc

# Make reboot noise and wait a few seconds to give harddisks the chance
# to really flush their buffers before power goes down.
if test -n "$REDIRECT" ; then
    case "$HALT_SOUND" in
    "yes"|"quint")
	echo -en "\033[10;393]\a\033[10;262]"
	;;
    "octave")
	for tone in 524 491 440 393 349 328 295 262; do
	    echo -en "\033[10;${tone}]\a"
	    usleep 125000
	done
	echo -en "\033[10;262]"
	;;
    "no")
	;;
    *)
    	echo -en "\033[10;440]\a"
	usleep 250000
	;;
    esac
else
    test "$HALT_SOUND" = "no" || echo -en "\a"
fi
echo $message
test "$HALT_SOUND" = "no" || echo -en "\a"

test -n "$HALT_POWERDOWN_INSERT" && $HALT_POWERDOWN_INSERT

# Set system console back to intial value
test -n "$REDIRECT" -a -n "$CONSOLE" && setconsole $REDIRECT < $CONSOLE

# Test if we should boot into the new kernel
if test "$command" = "reboot" -a -x /sbin/kexec -a -f /sys/kernel/kexec_loaded ; then
    read -t 2 loaded < /sys/kernel/kexec_loaded
    if test "$loaded" = "1" ; then
	echo -n "Loaded kernel image found, executing ... "
	/sbin/kexec --exec
	echo "${warn}failed, doing normal reboot${norm}"
    fi
fi

# Now talk to kernel
exec $command -d -f -n $opts
