xref: /onnv-gate/usr/src/cmd/initpkg/shutdown.sh (revision 8944:e4ff744ddfe1)
10Sstevel@tonic-gate#!/sbin/sh
20Sstevel@tonic-gate#
30Sstevel@tonic-gate# CDDL HEADER START
40Sstevel@tonic-gate#
50Sstevel@tonic-gate# The contents of this file are subject to the terms of the
6*8944Sdp@eng.sun.com# Common Development and Distribution License (the "License").
7*8944Sdp@eng.sun.com# You may not use this file except in compliance with the License.
80Sstevel@tonic-gate#
90Sstevel@tonic-gate# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate# or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate# See the License for the specific language governing permissions
120Sstevel@tonic-gate# and limitations under the License.
130Sstevel@tonic-gate#
140Sstevel@tonic-gate# When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate# If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate# fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate# information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate#
200Sstevel@tonic-gate# CDDL HEADER END
210Sstevel@tonic-gate#
22*8944Sdp@eng.sun.com#	Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate#	Use is subject to license terms.
240Sstevel@tonic-gate#
250Sstevel@tonic-gate#	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T
260Sstevel@tonic-gate#	  All Rights Reserved
270Sstevel@tonic-gate
280Sstevel@tonic-gate
290Sstevel@tonic-gate
300Sstevel@tonic-gate#	Sequence performed to change the init state of a machine.  Only allows
310Sstevel@tonic-gate#	transitions to states 0,1,5,6,s,S (i.e.: down or administrative states).
320Sstevel@tonic-gate
330Sstevel@tonic-gate#	This procedure checks to see if you are permitted and allows an
340Sstevel@tonic-gate#	interactive shutdown.  The actual change of state, killing of
350Sstevel@tonic-gate#	processes and such are performed by the new init state, say 0,
360Sstevel@tonic-gate#	and its /sbin/rc0.
370Sstevel@tonic-gate
380Sstevel@tonic-gateusage() {
390Sstevel@tonic-gate	echo "Usage: $0 [ -y ] [ -g<grace> ] [ -i<initstate> ] [ message ]"
400Sstevel@tonic-gate	exit 1
410Sstevel@tonic-gate}
420Sstevel@tonic-gate
430Sstevel@tonic-gatenotify() {
440Sstevel@tonic-gate	/usr/sbin/wall -a <<-!
450Sstevel@tonic-gate	$*
460Sstevel@tonic-gate	!
470Sstevel@tonic-gate	if [ -x /usr/sbin/showmount -a -x /usr/sbin/rwall ]
480Sstevel@tonic-gate	then
490Sstevel@tonic-gate		remotes=`/usr/sbin/showmount`
500Sstevel@tonic-gate		if [ "X${remotes}" != "X" ]
510Sstevel@tonic-gate		then
520Sstevel@tonic-gate			/usr/sbin/rwall -q ${remotes} <<-!
530Sstevel@tonic-gate			$*
540Sstevel@tonic-gate			!
550Sstevel@tonic-gate		fi
560Sstevel@tonic-gate	fi
570Sstevel@tonic-gate}
580Sstevel@tonic-gate
590Sstevel@tonic-gatenologin=/etc/nologin
600Sstevel@tonic-gate
610Sstevel@tonic-gate# Set the PATH so that to guarentee behavior of shell built in commands
620Sstevel@tonic-gate# (such as echo).
630Sstevel@tonic-gate
640Sstevel@tonic-gatePATH=/usr/sbin:/usr/bin:/sbin
650Sstevel@tonic-gate
660Sstevel@tonic-gate# Initial sanity checks:
670Sstevel@tonic-gate#	Make sure /usr is mounted
680Sstevel@tonic-gate#	Check the user id (only root can run shutdown)
690Sstevel@tonic-gate
700Sstevel@tonic-gateif [ ! -d /usr/bin ]
710Sstevel@tonic-gatethen
720Sstevel@tonic-gate	echo "$0:  /usr is not mounted.  Mount /usr or use init to shutdown."
730Sstevel@tonic-gate	exit 1
740Sstevel@tonic-gatefi
750Sstevel@tonic-gate
760Sstevel@tonic-gateif [ -x /usr/bin/id ]
770Sstevel@tonic-gatethen
780Sstevel@tonic-gate	eval `/usr/bin/id  |  /usr/bin/sed 's/[^a-z0-9=].*//'`
790Sstevel@tonic-gate	if [ "${uid:=0}" -ne 0 ]
800Sstevel@tonic-gate	then
810Sstevel@tonic-gate	        echo "$0:  Only root can run $0"
820Sstevel@tonic-gate		exit 2
830Sstevel@tonic-gate	fi
840Sstevel@tonic-gateelse
850Sstevel@tonic-gate	echo "$0:  can't check user id."
860Sstevel@tonic-gate	exit 2
870Sstevel@tonic-gatefi
880Sstevel@tonic-gate
890Sstevel@tonic-gate# Get options (defaults immediately below):
900Sstevel@tonic-gate
910Sstevel@tonic-gategrace=60
920Sstevel@tonic-gateaskconfirmation=yes
930Sstevel@tonic-gateinitstate=s
940Sstevel@tonic-gate
950Sstevel@tonic-gatewhile getopts g:i:y? c
960Sstevel@tonic-gatedo
970Sstevel@tonic-gate	case $c in
980Sstevel@tonic-gate	g)
990Sstevel@tonic-gate		case $OPTARG in
1000Sstevel@tonic-gate		*[!0-9]* )
1010Sstevel@tonic-gate			echo "$0: -g requires a numeric option"
1020Sstevel@tonic-gate			usage
1030Sstevel@tonic-gate			;;
1040Sstevel@tonic-gate		[0-9]* )
1050Sstevel@tonic-gate			grace=$OPTARG
1060Sstevel@tonic-gate			;;
1070Sstevel@tonic-gate		esac
1080Sstevel@tonic-gate		;;
1090Sstevel@tonic-gate	i)
1100Sstevel@tonic-gate		case $OPTARG in
1110Sstevel@tonic-gate		[Ss0156])
1120Sstevel@tonic-gate			initstate=$OPTARG
1130Sstevel@tonic-gate			;;
1140Sstevel@tonic-gate		[234abcqQ])
1150Sstevel@tonic-gate			echo "$0: Initstate $OPTARG is not for system shutdown"
1160Sstevel@tonic-gate			exit 1
1170Sstevel@tonic-gate			;;
1180Sstevel@tonic-gate		*)
1190Sstevel@tonic-gate			echo "$0: $OPTARG is not a valid initstate"
1200Sstevel@tonic-gate			usage
1210Sstevel@tonic-gate			;;
1220Sstevel@tonic-gate		esac
1230Sstevel@tonic-gate		;;
1240Sstevel@tonic-gate	y)
1250Sstevel@tonic-gate		askconfirmation=
1260Sstevel@tonic-gate		;;
1270Sstevel@tonic-gate	\?)	usage
1280Sstevel@tonic-gate		;;
1290Sstevel@tonic-gate	esac
1300Sstevel@tonic-gatedone
1310Sstevel@tonic-gateshift `expr $OPTIND - 1`
1320Sstevel@tonic-gate
1330Sstevel@tonic-gateecho '\nShutdown started.    \c'
1340Sstevel@tonic-gate/usr/bin/date
1350Sstevel@tonic-gateecho
1360Sstevel@tonic-gate
1370Sstevel@tonic-gateNODENAME=`uname -n`
1380Sstevel@tonic-gate
1390Sstevel@tonic-gatecd /
1400Sstevel@tonic-gate
1410Sstevel@tonic-gatetrap "rm $nologin >/dev/null 2>&1 ;exit 1"  1 2 15
1420Sstevel@tonic-gate
1430Sstevel@tonic-gate# If other users are on the system (and any grace period is given), warn them.
1440Sstevel@tonic-gate
1450Sstevel@tonic-gatefor i in 7200 3600 1800 1200 600 300 120 60 30 10; do
1460Sstevel@tonic-gate	if [ ${grace} -gt $i ]
1470Sstevel@tonic-gate	then
1480Sstevel@tonic-gate		hours=`/usr/bin/expr ${grace} / 3600`
1490Sstevel@tonic-gate		minutes=`/usr/bin/expr ${grace} % 3600 / 60`
1500Sstevel@tonic-gate		seconds=`/usr/bin/expr ${grace} % 60`
1510Sstevel@tonic-gate		time=""
1520Sstevel@tonic-gate		if [ ${hours} -gt 1 ]
1530Sstevel@tonic-gate		then
1540Sstevel@tonic-gate			time="${hours} hours "
1550Sstevel@tonic-gate		elif [ ${hours} -eq 1 ]
1560Sstevel@tonic-gate		then
1570Sstevel@tonic-gate			time="1 hour "
1580Sstevel@tonic-gate		fi
1590Sstevel@tonic-gate		if [ ${minutes} -gt 1 ]
1600Sstevel@tonic-gate		then
1610Sstevel@tonic-gate			time="${time}${minutes} minutes "
1620Sstevel@tonic-gate		elif [ ${minutes} -eq 1 ]
1630Sstevel@tonic-gate		then
1640Sstevel@tonic-gate			time="${time}1 minute "
1650Sstevel@tonic-gate		fi
1660Sstevel@tonic-gate		if [ ${hours} -eq 0 -a ${seconds} -gt 0 ]
1670Sstevel@tonic-gate		then
1680Sstevel@tonic-gate			if [ ${seconds} -eq 1 ]
1690Sstevel@tonic-gate			then
1700Sstevel@tonic-gate				time="${time}${seconds} second"
1710Sstevel@tonic-gate			else
1720Sstevel@tonic-gate				time="${time}${seconds} seconds"
1730Sstevel@tonic-gate			fi
1740Sstevel@tonic-gate		fi
1750Sstevel@tonic-gate
1760Sstevel@tonic-gate		(notify \
1770Sstevel@tonic-gate"The system ${NODENAME} will be shut down in ${time}
1780Sstevel@tonic-gate$*") &
1790Sstevel@tonic-gate
1800Sstevel@tonic-gatepid1=$!
1810Sstevel@tonic-gate
1820Sstevel@tonic-gate		rm $nologin >/dev/null 2>&1
1830Sstevel@tonic-gate		cat > $nologin <<-!
1840Sstevel@tonic-gate
1850Sstevel@tonic-gate			NO LOGINS: System going down in ${time}
1860Sstevel@tonic-gate			$*
1870Sstevel@tonic-gate
1880Sstevel@tonic-gate		!
1890Sstevel@tonic-gate
1900Sstevel@tonic-gate		/usr/bin/sleep `/usr/bin/expr ${grace} - $i`
1910Sstevel@tonic-gate		grace=$i
1920Sstevel@tonic-gate	fi
1930Sstevel@tonic-gatedone
1940Sstevel@tonic-gate
1950Sstevel@tonic-gate# Confirm that we really want to shutdown.
1960Sstevel@tonic-gate
1970Sstevel@tonic-gateif [ ${askconfirmation} ]
1980Sstevel@tonic-gatethen
1990Sstevel@tonic-gate	echo "Do you want to continue? (y or n):   \c"
2000Sstevel@tonic-gate	read b
2010Sstevel@tonic-gate	if [ "$b" != "y" ]
2020Sstevel@tonic-gate	then
2030Sstevel@tonic-gate		notify "False Alarm:  The system ${NODENAME} will not be brought down."
2040Sstevel@tonic-gate		echo 'Shutdown aborted.'
2050Sstevel@tonic-gate		rm $nologin >/dev/null 2>&1
2060Sstevel@tonic-gate		exit 1
2070Sstevel@tonic-gate	fi
2080Sstevel@tonic-gatefi
2090Sstevel@tonic-gate
2100Sstevel@tonic-gate# Final shutdown message, and sleep away the final 10 seconds (or less).
2110Sstevel@tonic-gate
2120Sstevel@tonic-gate(notify \
2130Sstevel@tonic-gate"THE SYSTEM ${NODENAME} IS BEING SHUT DOWN NOW ! ! !
2140Sstevel@tonic-gateLog off now or risk your files being damaged
2150Sstevel@tonic-gate$*") &
2160Sstevel@tonic-gate
2170Sstevel@tonic-gatepid2=$!
2180Sstevel@tonic-gate
2190Sstevel@tonic-gateif [ ${grace} -gt 0 ]
2200Sstevel@tonic-gatethen
2210Sstevel@tonic-gate	/usr/bin/sleep ${grace}
2220Sstevel@tonic-gatefi
2230Sstevel@tonic-gate
2240Sstevel@tonic-gate# Go to the requested initstate.
2250Sstevel@tonic-gate
2260Sstevel@tonic-gate
2270Sstevel@tonic-gateecho "Changing to init state $initstate - please wait"
2280Sstevel@tonic-gate
2290Sstevel@tonic-gateif [ "$pid1" ] || [ "$pid2" ]
2300Sstevel@tonic-gatethen
2310Sstevel@tonic-gate	/usr/bin/kill $pid1 $pid2 > /dev/null 2>&1
2320Sstevel@tonic-gatefi
2330Sstevel@tonic-gate
2340Sstevel@tonic-gate/sbin/init ${initstate}
235