Rev 207 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | 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## modified for LiveCD, Urs BeyerleNOLOCALE=1. /etc/init.d/functionsUMOUNT="umount"[ ! -w /etc ] && UMOUNT="umount -n"action() {echo -n "$1 "shiftif [ "$BOOTUP" = "color" ]; then"$@" && echo_success || echo_failureelse"$@"fiecho}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$'; then/sbin/cryptsetup remove "$dst"elsefnval=1fifidone < /etc/crypttabreturn $fnval}# 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 killaction $"Sending all processes the TERM signal..." /sbin/killall5 -15sleep 5action $"Sending all processes the KILL signal..." /sbin/killall5 -9# Write to wtmp file before unmounting /var/sbin/halt -w# Save mixer settings, here for lack of a better place.grep -q "\(alsa\)" /proc/devicesif [ $? = 0 -a -x /usr/sbin/alsactl ]; thenaction $"Saving mixer settings" alsactl 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# Sync the system clock.ARC=0SRM=0UTC=0if [ -f /etc/sysconfig/clock ]; then. /etc/sysconfig/clock# convert old style clock config to new valuesif [ "${CLOCKMODE}" = "GMT" ]; thenUTC=trueelif [ "${CLOCKMODE}" = "ARC" ]; thenARC=truefifiCLOCKDEF=""CLOCKFLAGS="$CLOCKFLAGS --systohc"case "$UTC" inyes|true)CLOCKFLAGS="$CLOCKFLAGS -u";CLOCKDEF="$CLOCKDEF (utc)";;;no|false)CLOCKFLAGS="$CLOCKFLAGS --localtime";CLOCKDEF="$CLOCKDEF (localtime)";;;esaccase "$ARC" inyes|true)CLOCKFLAGS="$CLOCKFLAGS -A";CLOCKDEF="$CLOCKDEF (arc)";;;esaccase "$SRM" inyes|true)CLOCKFLAGS="$CLOCKFLAGS -S";CLOCKDEF="$CLOCKDEF (srm)";;;esac# [ -x /sbin/hwclock ] && action $"Syncing hardware clock to system time" /sbin/hwclock $CLOCKFLAGS# 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): " \# -f#LANG=C __umount_loop '$2 ~ /^\/$|^\/proc|^\/dev/{next}# $3 == "tmpfs" || $3 == "proc" {print $2 ; next}# /(loopfs|autofs|nfs|cifs|smbfs|ncpfs|sysfs|^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 ] && \LANG=C action $"Stopping disk encryption: " 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)$/ && $1 !~ /^\/dev\/ram/ { print $2 }' \/proc/mounts | grep -v "/livecd/" | sort -r | \while read line; dofstab-decode $UMOUNT -f $linedoneif [ -x /sbin/halt.local ]; then/sbin/halt.localfi# Remount read only anything that's left mounted.# echo $"Remounting remaining filesystems readonly"mount | awk '{ print $3 }' | while read line; dofstab-decode mount -n -o ro,remount $linedone# 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."fiif [ "$command" = /sbin/halt -a -r /etc/ups/upsmon.conf -a -f /etc/killpower -a -f /etc/sysconfig/ups ] ; then. /etc/sysconfig/upsif [ "$SERVER" = "yes" -a "$MODEL" = "upsdrvctl" ] ; then/sbin/upsdrvctl shutdownelif [ "$SERVER" = "yes" -a "$MODEL" != "NONE" -a -n "$MODEL" -a -n "$DEVICE" ] ; then$MODEL $OPTIONS_HALT -k $DEVICEfifi# ------------------ LiveCD -------------------------# dir of mounted live system: /$MOUNTDIR/liveMOUNTDIR=livecd# source functions of liblinuxlive. /$MOUNTDIR/live/liblinuxlive# root on NFS?NFSROOT=$( cmdline_value nfsroot )# noeject set?NOEJECT=$( cmdline_parameter noeject )# eject CDROM# if CDROM is not on NFS and if noeject is not setif [ ! $NFSROOT ] && [ ! $NOEJECT ]; thenCDROM_DEV=$( grep /$MOUNTDIR/live/livecd /proc/mounts | awk '{print $1}' )echo -n "Ejecting CD-ROM $CDROM_DEV ... "eject $CDROM_DEV 2>/dev/null || ejectechofiif [ "${command##*/}" = "reboot" ]; thenecho "Rebooting."; sleep 1/livecd/live/bin/busybox reboot 2>/dev/nullrebootelseecho "Poweroff."; sleep 1/livecd/live/bin/busybox poweroff 2>/dev/nullpowerofffi# ------------------ LiveCD -------------------------# First, try kexec. If that fails, fall back to rebooting the old way.[ -n "$kexec_command" ] && $kexec_command -e -x >& /dev/nullHALTARGS="-d"[ -f /poweroff -o ! -f /halt ] && HALTARGS="$HALTARGS -p"exec $command $HALTARGS