Rev 3 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
#!/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/functionsUMOUNT="umount"[ ! -w /etc ] && UMOUNT="umount -n"halt_crypto() {fnval=0while read dst src key; do[ -z "$dst" -o "${dst#\#}" != "$dst" ] && continueif [ -b "/dev/mapper/$dst" ]; thenif /sbin/dmsetup info "$dst" | grep -q '^Open count: *0$'; thenaction $"Stopping disk encryption for $dst" /sbin/cryptsetup remove "$dst"elsefnval=1fifidone < /etc/crypttabreturn $fnval}kill_all() {local STRING rcSTRING=$1echo -n "$STRING "shift/sbin/killall5 "$@"rc=$?# Retval: 0: success 1: error 2: no processes found to killif [ "$rc" == 1 ]; thenfailure $"$STRING"elsesuccess $"$STRING"fiechoreturn $rc}# See how we were called.case "$0" in*halt)message=$"Halting system..."command="/sbin/halt";;*reboot)message=$"Please stand by while rebooting the system..."command="/sbin/reboot"kexec_command="/sbin/kexec";;*)echo $"$0: call me as 'halt' or 'reboot' please!"exit 1;;esaccase "$1" in*start);;*)echo $"Usage: $0 {start}"exit 1;;esac# Kill all processes.[ "${BASH+bash}" = bash ] && enable kill# Find mdmon pid's and omit killing themOMITARGS=for i in /dev/md/*.pid; doif [ ! -r "$i" ]; thencontinuefiOMITARGS="$OMITARGS -o $(cat $i)"donekill_all $"Sending all processes the TERM signal..." -15 $OMITARGS# No need to sleep and kill -9 if no processes to kill were foundif [ "$?" == 0 ]; thensleep 2kill_all $"Sending all processes the KILL signal..." -9 $OMITARGSfi# Write to wtmp file before unmounting /var/sbin/halt -w# Save mixer settings, here for lack of a better place.if [ -s /etc/alsa/alsactl.conf -a -x /sbin/alsactl -a -w /etc/asound.state ]; thenaction $"Saving mixer settings" /sbin/alsactl -E ALSA_CONFIG_PATH=/etc/alsa/alsactl.conf --ignore storefi# Save random seedtouch /var/lib/random-seedchmod 600 /var/lib/random-seedaction $"Saving random seed: " dd if=/dev/urandom of=/var/lib/random-seed count=1 bs=512 2>/dev/null[ -x /sbin/hwclock -a -e /dev/rtc ] && action $"Syncing hardware clock to system time" /sbin/hwclock --systohc# Try to unmount tmpfs filesystems to avoid swapping them in. Ignore failures.tmpfs=$(awk '$2 ~ /^\/($|proc|dev)/ { next; }$3 == "tmpfs" { print $2; }' /proc/mounts | sort -r)[ -n "$tmpfs" ] && fstab-decode $UMOUNT $tmpfs 2>/dev/null# Turn off swap, then unmount file systems.[ -f /proc/swaps ] && SWAPS=$(awk '! /^Filename/ { print $1 }' /proc/swaps)if [ -n "$SWAPS" ]; thenaction $"Turning off swap: " swapoff $SWAPSfor dst in $SWAPS; doif [[ "$dst" == /dev/mapper* ]] \&& [ "$(dmsetup status "$dst" | cut -d ' ' -f 3)" = crypt ]; thenbackdev=$(/sbin/cryptsetup status "$dst" \| awk '$1 == "device:" { print $2 }')/sbin/cryptsetup remove "$dst"fidonefi[ -x /sbin/quotaoff ] && action $"Turning off quotas: " /sbin/quotaoff -aug# Unmount file systems, killing processes if we have to.# Unmount loopback stuff first__umount_loopback_loop# Unmount RPC pipe file systems__umount_loop '$3 ~ /^rpc_pipefs$/ || $3 ~ /^rpc_svc_gss_pipefs$/ {print $2}' \/proc/mounts \$"Unmounting pipe file systems: " \$"Unmounting pipe file systems (retry): " \-fLANG=C __umount_loop '$2 ~ /^\/$|^\/proc|^\/dev/{next}$3 == "tmpfs" || $3 == "proc" {print $2 ; next}$3 ~ /(loopfs|autofs|nfs|cifs|smbfs|ncpfs|sysfs)/ {next}/(^none|^\/dev\/ram|^\/dev\/root$)/ {next}{print $2}' /proc/mounts \$"Unmounting file systems: " \$"Unmounting file systems (retry): " \-f[ -f /proc/bus/usb/devices ] && $UMOUNT /proc/bus/usb[ -f /etc/crypttab ] && halt_crypto# remove the crash indicator flagrm -f /.autofsck# Try all file systems other than root, essential filesystems and RAM disks,# one last time.awk '$2 !~ /\/(|dev|proc|selinux|sys)$/ && $1 !~ /^\/dev\/ram/ { print $2 }' \/proc/mounts | sort -r | \while read line; dofstab-decode $UMOUNT -f $linedoneHALTARGS="-d"[ "$INIT_HALT" != "HALT" ] && HALTARGS="$HALTARGS -p"if [ -x /sbin/halt.local ]; then/sbin/halt.local "$message" "$command" "$HALTARGS" "$kexec_command"fi# Tell init to re-exec itself.kill -TERM 1# Remount read only anything that's left mounted.# echo $"Remounting remaining filesystems readonly"mount | awk '{ print $1,$3 }' | while read dev dir; dofstab-decode mount -n -o ro,remount $dev $dirdone# If we left mdmon's running wait for the raidsets to become cleanif [ -n "$OMITARGS" ]; thensyncHALTARGS="$HALTARGS -n"mdadm --wait-clean --scanfi# Now halt or reboot.echo $"$message"if [ -f /fastboot ]; thenecho $"On the next boot fsck will be skipped."elif [ -f /forcefsck ]; thenecho $"On the next boot fsck will be forced."fi# Shutdown UPS driversif [ "$command" = /sbin/halt -a -f /etc/sysconfig/ups ]; then. /etc/sysconfig/upsif [ -z $POWERDOWNFLAG ]; thenPOWERDOWNFLAG=/etc/killpowerfiif [ "$SERVER" = "yes" -a -f $POWERDOWNFLAG ]; then/sbin/upsdrvctl shutdownsleep 120/sbin/reboot --forcefifi# Turn off UPS in powerfail situationif [ -x /etc/apcupsd/apccontrol -a -f /etc/apcupsd/powerfail ]; then/etc/apcupsd/apccontrol killpowerfi# First, try kexec. If that fails, fall back to rebooting the old way.[ -n "$kexec_command" ] && $kexec_command -e -x >& /dev/nullexec $command $HALTARGS