Home | History | Annotate | Download | only in zoneadm
      1 #!/sbin/sh
      2 #
      3 # CDDL HEADER START
      4 #
      5 # The contents of this file are subject to the terms of the
      6 # Common Development and Distribution License (the "License").
      7 # You may not use this file except in compliance with the License.
      8 #
      9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10 # or http://www.opensolaris.org/os/licensing.
     11 # See the License for the specific language governing permissions
     12 # and limitations under the License.
     13 #
     14 # When distributing Covered Code, include this CDDL HEADER in each
     15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16 # If applicable, add the following below this CDDL HEADER, with the
     17 # fields enclosed by brackets "[]" replaced with your own identifying
     18 # information: Portions Copyright [yyyy] [name of copyright owner]
     19 #
     20 # CDDL HEADER END
     21 #
     22 #
     23 # Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     24 # Use is subject to license terms.
     25 
     26 . /lib/svc/share/smf_include.sh
     27 
     28 #
     29 # Return a list of running, non-global zones for which a shutdown via
     30 # "/sbin/init 0" may work (typically only Solaris zones.)
     31 #
     32 # At present, this means any running "lx" zones don't qualify.
     33 #
     34 shutdown_zones()
     35 {
     36 	zoneadm list -p | nawk -F: '{
     37 		if (($5 != "lx") && ($2 != "global")) {
     38 			print $2
     39 		}
     40 	}'
     41 }
     42 
     43 [ ! -x /usr/sbin/zoneadm ] && exit 0	# SUNWzoneu not installed
     44 
     45 if [ -z "$SMF_FMRI" ]; then
     46 	echo "this script can only be invoked by smf(5)"	
     47 	exit $SMF_EXIT_ERR_NOSMF
     48 fi
     49 
     50 # Make sure working directory is / to prevent unmounting problems.
     51 cd /
     52 PATH=/usr/sbin:/usr/bin; export PATH
     53 
     54 case "$1" in
     55 'start')
     56 	egrep -vs '^#|^global:' /etc/zones/index || exit 0  # no local zones
     57 
     58 	#
     59 	# Boot the installed zones for which the "autoboot" zone property is
     60 	# set and invoke the sysboot hook for all other installed zones.
     61 	#
     62 	ZONES=""
     63 	for zone in `zoneadm list -pi | nawk -F: '{
     64 			if ($3 == "installed") {
     65 				print $2
     66 			}
     67 		}'`; do
     68 		zonecfg -z $zone info autoboot | grep "true" >/dev/null 2>&1
     69 		if [ $? -eq 0 ]; then
     70 			[ -z "$ZONES" ] && echo "Booting zones:\c"
     71 			ZONES=yes
     72 			echo " $zone\c"
     73 			#
     74 			# zoneadmd puts itself into its own contract so
     75 			# this service will lose sight of it.  We don't
     76 			# support restart so it is OK for zoneadmd to
     77 			# to be in an orphaned contract.
     78 			#
     79 			zoneadm -z $zone boot &
     80 		else
     81 			zoneadm -z $zone sysboot &
     82 		fi
     83 	done
     84 
     85 	#
     86 	# Wait for all zoneadm processes to finish before allowing the
     87 	# start method to exit.
     88 	#
     89 	wait
     90 	[ -n "$ZONES" ] && echo .
     91 	;;
     92 
     93 'stop')
     94 	egrep -vs '^#|^global:' /etc/zones/index || exit 0  # no local zones
     95 	[ "`zoneadm list`" = "global" ] && exit 0   # no zones running
     96 
     97 	SVC_TIMEOUT=`svcprop -p stop/timeout_seconds $SMF_FMRI`
     98 
     99 	#
    100 	# First, try shutting down any running zones for which an "init 0" may
    101 	# work.
    102 	#
    103 	MAXSHUT=`expr 3 \* $SVC_TIMEOUT \/ 4` # 3/4 of time to zone shutdown
    104 	MAXHALT=`expr $SVC_TIMEOUT \/ 4`      # rest of time goes to halt
    105 
    106 	zonelist=`shutdown_zones`
    107 
    108 	if [ -n "$zonelist" ]; then
    109 		SHUTDOWN=0
    110 		echo "Shutting down running zones (for up to $MAXSHUT" \
    111 		    "seconds):\c"
    112 
    113 		for zone in $zonelist; do
    114 			echo " $zone\c"
    115 			zlogin -S $zone /sbin/init 0 < /dev/null >&0 2>&0 &
    116 			SHUTDOWN=1
    117 		done
    118 
    119 		[ $SHUTDOWN -eq 1 ] && echo "."
    120 
    121 		# Allow time for zones to shutdown cleanly
    122 
    123 		while [ $MAXSHUT -gt 0 -a "`shutdown_zones`" != "" ]; do
    124 			MAXSHUT=`expr $MAXSHUT - 1`
    125 			sleep 1	# wait a bit longer
    126 		done
    127 	fi
    128 
    129 	#
    130 	# Second, try halting any non-global zones still running
    131 	#
    132 	WAITPIDS=""
    133 	for zone in `zoneadm list`; do
    134 		if [ "$zone" != "global" ]; then
    135 			[ -z "$WAITPIDS" ] &&
    136 			    echo "Zones failed to shutdown; trying to halt " \
    137 			    "(for up to $MAXHALT seconds):\c"
    138 			echo " $zone\c"
    139 			zoneadm -z $zone halt &
    140 			WAITPIDS="$WAITPIDS $!"
    141 		fi
    142 	done
    143 	[ ! -z "$WAITPIDS" ] && echo .
    144 
    145 	# Wait for the 'zoneadm halt' commands to complete.  We will let this
    146 	# run forever, since the restart daemon will eventually kill us off
    147 	# anyway if the halts do not complete after a certain period of time.
    148 	wait $WAITPIDS
    149 
    150 	# If the halts complete but a zone is still not shutdown, it might
    151 	# be in a state like 'shutting_down' or 'down'.  So we give it some
    152 	# time to come all the way down.
    153 
    154 	while [ $MAXHALT -gt 0 -a "`zoneadm list`" != "global" ]; do
    155 		MAXHALT=`expr $MAXHALT - 1`
    156 		sleep 1	# wait a bit longer
    157 	done
    158 
    159 	# If there are any remaining file systems in zones, try to unmount them.
    160 	umountall -Z
    161 
    162 	#
    163 	# Report on zones which failed to shutdown.
    164 	#
    165 	for zone in `zoneadm list`; do
    166 		if [ "$zone" != "global" ]; then
    167 			echo "Zone '$zone' failed to halt."
    168 		fi
    169 	done
    170 	[ "`zoneadm list`" != "global" ] && exit 1   # zones still running
    171 	;;
    172 
    173 *)
    174 	echo "Usage: $0 { start | stop }"
    175 	exit 1
    176 	;;
    177 esac
    178 exit 0
    179