#!/sbin/sh

################################################################################
#
# 	Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
# 	Use is subject to license terms.
#	Copyright 1992-95 AT&T Global Information Solutions
#
# ident	"@(#)lu_init_d.sh	5.22	09/01/06 SMI"
#
# USAGE:        /usr/lib/lu/lu_init_d ( start | stop )
#
# This script is called at system startup and shutdown - it is intended to be called
# from the appropriate scripts installed in the appropriate /etc/*.d directories and
# called only during system startup and shutdown. Typically, "/etc/init.d/lu" will
# contain the "master" init script that has links to it placed in /etc/rc*.d/{S,K}*lu
# as appropriate. As the system is brought up or shut down, that /etc/init.d/lu script
# will be called, which in turn will call this script with a single command line argument
# of either "start" (on system startup) or "stop" (on system shutdown).
#
# If no BEs are defined, this script will exit and not perform any operations.
# If one or more BEs are defined, this script will perform the following functions:
#
# On startup:
# 1. Determine name of the current boot environment.
# 2. Determine which BE was active before the last reboot.
# 3. update the /etc/lu/sync.log file to reflect which BE was booted (only if LU_DEBUG set).
# 4. If a switch of BEs was done (current BE is not prior BE), then:
# 4a. Execute any "S*" scripts in /etc/lu/rc.d
# 4b. run "lusync" on the last BE - this causes files listed in "LU_SYNC_FILES" to be
#	copied from the prior BE to this BE, synchronizing critical system files.
# 5. Update name of active BE to the current boot environment.
#
# On shutdown:
# 1. Determine name of the current boot environment.
# 2. Determine which BE will be booted up next.
# 3. If a switch of BEs is about to be done (current BE is not next BE), then:
# 3a. Mount the next boot environment to be booted.
# 3b. Determine if new boot environment needs to be synchronized.
# 3c. Umount the next boot environment.
# 3d. If (3b) is true, execute any "K*" scripts in /etc/lu/rc.d
# 4. if luactivate created a "delayed update" script on the current boot
#	environment, run it now.
#
# Notes for synchronization operation carried out for non-global zones:
# 1. lusync script is called for every global and non-global zones as well
# 2. Everytime it is necessary to carry out synchronization operation within 
#    non-global zone, this zone is put in "mounted" state, then appropriate
#    operation is conducted and zone is "unmounted"
# 3. It is possible to "mount" non-global zone only when it was in "installed"
#    state before. This is assured by following mechanism:
#    Non-global zones are started by means of svc:/system/zones:default
#    service (if the zone has autoboot flag set). This service is dependent
#    on milestone we are booting in. The start method of this milestone executes
#    old legacy scripts, so lu_init_d is invoked before svc:/system/zones:default
#    service is put in "online" state. This asures that if we are dealing with
#    non-global zones, they are not in "running" state.
# 4. The similar process is carried out during shutting down.
# 5. We remap zone paths on BE start-up and shut-down.  The goal is to make
#    sure that the running BE never has LU-modified zone paths (which would
#    confuse the user) and that the non-running BEs always have LU-modified
#    zone paths.
################################################################################

LU_PROG_FULL_PATH="$0"
LU_PROG_NAME="`basename ${LU_PROG_FULL_PATH}`"; export LU_PROG_NAME
LOG="/etc/lu/lustartup.log"
LU_LOG_FILES_LIST="${LOG}"
MAX_LOG_SIZE="2000"
BE_CONFIG_FILE="/etc/lu/jumpstart-profile-options.xml"

################################################################################
# Name:		run_sync_at_start
# Description:	Check to see if any synchronization issues will occur when the
#		BE is synchronized.
# Local Prefix:	csi_
# Arguments:	$1 = current BE name.
#		$2 = previous BE name.
# Example:      check_sync_issues mntpt
# Returns:	<none>
################################################################################

run_sync_at_start()
{
	CURR_BE=$1
	LAST_BE=$2

	# Mount the slices of ABE.
	LASTBE_ID=`$LUETCBIN/ludo get_be_id $LAST_BE`
	LASTBE_MNTPT=`LU_OUTPUT_FORMAT=text $LUBIN/lumount -Zi \
	    /etc/lu/ICF.$LASTBE_ID`

	if [ "$?" -ne '0' ] ; then
		return;
	fi

	$LUETCBIN/lu_init_sync_start / $LAST_BE \
	    $LASTBE_MNTPT $CURR_BE global >> $LU_SYNC_LOG_FILE 2>&1

	# umount the BE.
	$LUBIN/luumount -f -i /etc/lu/ICF.$LASTBE_ID

	#
	# synchronization process in non-global zones
	# is carried out in following steps:
	# [1] mount all non-global zones
	# [2] mount old BE
	# [3] run lu_init_sync_start() in zones
	# [4] unmount old BE
	# [5] unount all non-global zones
	#

	# [1] mount all non-global zones

	# This should be done only if the current
	# BE has zones installed.

	lulib_zone_check /
	has_ngz=$?
	if [ $has_ngz -eq 1 ]; then
		for zone in `all_nonglobal_zones`
		do
			zoneadm -z $zone mount
		done

		# [2] mount old BE
		LASTBE_MNTPT=`LU_OUTPUT_FORMAT=text $LUBIN/lumount $LAST_BE`

		# [3] run lu_init_sync_start() in zones which conducts appropriate
		#     synchronization steps
		for zone in `all_nonglobal_zones`
		do
			zlogin -S $zone "/etc/lib/lu/lu_init_sync_start /a $LAST_BE \
		        $LASTBE_MNTPT $CURR_BE $zone >> /a/$LU_SYNC_LOG_FILE 2>&1"
		done

		# [4] unmount old BE
		$LUBIN/luumount $LAST_BE

		# [5] unount all non-global zones
		for zone in `all_nonglobal_zones`
		do
			zoneadm -z $zone unmount
		done
	fi
}

run_sync_at_stop()
{
	NEXTBEMNTPT=$1

	$LUETCBIN/lu_init_sync_stop / $NEXTBEMNTPT

	SAVEIFS="$IFS"
	lulib_list_zones -i |
	while IFS=: read zoneid zonename state zonepath uuid extra; do
		IFS="$SAVEIFS"

		if [ "$zonename" = global ]; then
			continue
		fi

		# Check if the CURR_BE and NEXT_BE have same zones by searching
		# on zone name and UUID.  If they do, log into the scratch zone
		# mounted within NEXT_BE.
		if azname=`zoneadm -R $NEXTBEMNTPT -z $zonename -u $uuid list`
		then
			# Enter the scratch zone and run the sync process.
			zlogin -S -R $NEXTBEMNTPT $azname \
			    "$LUETCBIN/lu_init_sync_stop /b /a \
			    >> /a/$LU_SYNC_LOG_FILE 2>&1"
		fi
	done
}

#
# lu_start: process live upgrade "system startup" condition
#
lu_start()
{
	# See if we need to sync up files from previous BE and then 
	# execute the Live Upgrade "rc exec" startup scripts.
	if [ -s "$LU_LUTAB_FILE" ] ; then
		lu_zone_update
		lu_start_sync
	else
		lu_start_create
	fi
}

# lu_zone_update: handle zone path renames.
#
# If SYNCKEY is set to a different name, then the user did luactivate
# to get here.  If it's not, then he may have switched without doing
# luactivate.  Look at the zone configuration to find out.
#
# Either way, scan the old environment for non-global zones, and make
# sure the paths are renamed out of the way.  Then scan our new
# environment for non-global zones, and rename them back to their
# natural state.
lu_zone_update()
{
	CURR_BE="`lulib_lucurr`"
	if [ $? -ne 0 -o -z "$CURR_BE" ]; then
		return 0
	fi
	if [ -s "$SYNCKEY" ]; then
		LAST_BE=`cat "$SYNCKEY"`
		$LUPRINTF +X -1S ${LU_SYSLOG_FACILITY}.$LU_SYSLOG_PRIORITY \
		    "`gettext 'last activated environment: <%s>.'`" "$LAST_BE"
	else
		LAST_BE="$CURR_BE"
	fi

	if [ "$LAST_BE" = "$CURR_BE" ]; then
		# If no change, then we're done.
		if [ ! -s /etc/zones/lu_suffix ]; then
			return 0
		fi
		# Otherwise, try to find out what the previous running BE
		# was.  If we can't, that's not a problem; it simply means
		# that no renames are needed on the previous BE because it
		# didn't have zones configured.
		lutmp=/tmp/lutmp.$$
		rm -rf $lutmp
		mkdir $lutmp
		LAST_ID=`SAVEIFS="$IFS"
			while IFS=: read beid betag bedev junk; do
			IFS="$SAVEIFS"
			if [ "$betag" = / ]; then
				prev_mnt=\`lulib_mount_pathname $bedev $lutmp\`
				if [ -d $lutmp/etc/zones -a \
				    ! -s $lutmp/etc/zones/lu_suffix ]; then
					echo "$beid"
					lulib_unmount_pathname $lutmp
					if [ -n "$prev_mnt" ]; then
						/sbin/zfs set mountpoint="$prev_mnt" "$bedev"
					fi
					break
				fi
				lulib_unmount_pathname $lutmp 2>/dev/null
				if [ -n "$prev_mnt" ]; then
					/sbin/zfs set mountpoint="$prev_mnt" "$bedev"
				fi
			fi
		done < $LU_LUTAB_FILE`
		LAST_BE=`awk -F: "/^$LAST_ID:/ "'{ print $2; exit }' < \
		    $LU_LUTAB_FILE`
		if [ -z "$LAST_ID" -o -z "$LAST_BE" ]; then
			$LUPRINTF +X -1S \
			    ${LU_SYSLOG_FACILITY}.$LU_SYSLOG_PRIORITY \
			    "`gettext 'no previous BE with zones found'`"
			LAST_BE="$CURR_BE"
		else
			$LUPRINTF +X -1S \
			    ${LU_SYSLOG_FACILITY}.$LU_SYSLOG_PRIORITY \
			    "`gettext 'found previous BE <%s>'`" "$LAST_BE"
		fi
	fi

	if [ "$LAST_BE" != "$CURR_BE" ]; then
		# Check that previous BE.  If it hasn't had its zones
		# renamed, then try to rename them now.  Note that
		# this can fail if the user switches from a
		# zones-using to a non-zones-aware BE through means
		# other than luactivate.  There's little we can do
		# about it.
		LU_ALT="`lumount -Zn $LAST_BE`"
		if [ ! -f "$LU_ALT/etc/zones/lu_suffix" ]; then
			lulib_zone_check "$LU_ALT" "return 0"
			has_ngz=$?
			if [ $has_ngz -eq 1 ]; then
				$LUPRINTF +X -1S \
				    ${LU_SYSLOG_FACILITY}.$LU_SYSLOG_PRIORITY \
		"`gettext 'setting zone paths on previous BE <%s> at <%s>.'`" \
				    "$LAST_BE" "$LU_ALT"
				lulib_change_zone_paths "$LU_ALT" "$LAST_BE"
			fi
		fi
		luumount "$LAST_BE"
	fi

	# Now look at our own BE.  If our zones were renamed, then switch them
	# back.
	lulib_zone_check / "return 0"
	has_ngz=$?
	if [ $has_ngz -eq 1 ]; then
		$LUPRINTF +X -1S ${LU_SYSLOG_FACILITY}.$LU_SYSLOG_PRIORITY \
		    "`gettext 'clearing zone paths on new BE'`"
		lulib_change_zone_paths / ""
	fi
}

#
# lu_start_sync: process live upgrade system startup sync operation
#
lu_start_sync()
{
	CURR_BE="`lulib_lucurr`"
	if [ "$?" -eq "0" -a -n "${CURR_BE}" -a -f "${SYNCKEY}" -a -s "${SYNCKEY}" ] ; then
		LAST_BE="`cat ${SYNCKEY}`"
		if [ -n "${LU_DEBUG}" -a "${LU_DEBUG}" -gt "0" ]; then
			echo "LAST_BE=${LAST_BE}" >> ${LU_SYNC_LOG_FILE}
			echo "CURR_BE=${CURR_BE}" >> ${LU_SYNC_LOG_FILE}
		fi
		# SYNCKEY/LAST_BE is only different from CURR_BE
		# on the first boot to a newly created BE or
		# to a BE that was activated with the sync option.
		# Subsequent boots to this or the previous BE
		# will not trigger an lusync. Also, /etc/lu/rc.d
		# scripts are only executed in this sync mode.
		if [ "${LAST_BE}" != "${CURR_BE}" ] ; then
			# Indicate to console log and system logs that activation is about to happen.
			${LUPRINTF} +X -1S ${LU_SYSLOG_FACILITY}.${LU_SYSLOG_PRIORITY} \
"`gettext 'Live Upgrade: Synchronizing new boot environment.'`"

			# Assure that /tmp exists
			if [ ! -d "/tmp" ] ; then
				/bin/mkdir -m 1777 /tmp
			else
				/bin/chmod 1777 /tmp
			fi
			/bin/chown root:sys /tmp

			# Execute any ABE startup scripts
			for f in /etc/lu/rc.d/S* ; do
				if [ -s "${f}" ] ; then
					case ${f} in
						*.sh) # source it
							. ${f}
							;;
						*) # sub shell
							/sbin/sh ${f} start
							;;
					esac
				fi
			done

			# Report on any synchronization conflicts.
			run_sync_at_start "${CURR_BE}" "${LAST_BE}" >> ${LU_SYNC_LOG_FILE} 2>&1

			#Touch LU_DB_SYNC_LOCAL file
			[ -f "${LU_DB_SYNC_LOCAL}" ] && /bin/touch "${LU_DB_SYNC_LOCAL}" > /dev/null 2>&1

			${LUPRINTF} +X -1S ${LU_SYSLOG_FACILITY}.${LU_SYSLOG_PRIORITY} \
			"`gettext 'Live Upgrade: Creating synchronization snapshot of current boot environment.'`"

			#Create an initial "initial" snapshot of newly activated BE
			$LUETCBIN/lusync -u -d $LU_DB_SYNC_LOCAL -m / -t initial -s $LU_SYNCLIST

			#Copy the temporary sync file to the local database of the current BE.
			/bin/cp  $LU_DB_SYNC_LOCAL $LU_DB_LOCAL

			#Remove the temporary sync file from the current BE.
			/bin/rm -f  $LU_DB_SYNC_LOCAL

			#
			# Create an "initial" snapshot in zones
			# of newly activated BE. This should be 
			# done only when the newly activate BE has
			# zones installed.
			# 
			lulib_zone_check /
			has_ngz=$?
			if [ $has_ngz -eq 1 ]; then
				for zone in `all_nonglobal_zones`
				do
					zoneadm -z $zone mount

					zlogin -S $zone "$LUETCBIN/lusync -u -d /a/$LU_DB_LOCAL \
				        -m /a -t initial -s /a/$LU_SYNCLIST >> /a/$LU_SYNC_LOG_FILE 2>&1"

					zoneadm -z $zone unmount
				done
			fi

			LASTBE_ID=`$LUETCBIN/ludo get_be_id $LAST_BE`
			LASTBE_MNTPT=`LU_OUTPUT_FORMAT=text $LUBIN/lumount -i /etc/lu/ICF.$LASTBE_ID`

			[ -f $LASTBE_MNTPT/$LU_DB_SYNC_LOCAL ] && /bin/touch $LASTBE_MNTPT/$LU_DB_SYNC_LOCAL > /dev/null 2>&1

			#Clear out any first time boot database information from the last BE.
			$LUETCBIN/lusync -i -d $LASTBE_MNTPT/$LU_DB_LOCAL >> $LU_SYNC_LOG_FILE 2>&1

			$LUPRINTF +X -1S $LU_SYSLOG_FACILITY.$LU_SYSLOG_PRIORITY \
			    "`gettext 'Live Upgrade: Creating synchronization snapshot of previously active boot environment.'`"

			#Create an initial "initial" snapshot of the last BE
			$LUETCBIN/lusync -u -d $LASTBE_MNTPT/$LU_DB_SYNC_LOCAL -m / -t initial -s $LASTBE_MNTPT/$LU_SYNCLIST

			#Copy the temporary sync file to the local database of the last BE.
			/bin/cp  $LASTBE_MNTPT/$LU_DB_SYNC_LOCAL $LASTBE_MNTPT/$LU_DB_LOCAL

			#Remove the temporary sync file of the last BE.
			/bin/rm -f  $LASTBE_MNTPT/$LU_DB_SYNC_LOCAL

			#
			# Create an "initial" snapshot in zones
			# of the last BE. This should be done
			# only when the last BE has zones installed.
			#
			lulib_zone_check "$LASTBE_MNTPT"
			has_ngz=$?
			if [ $has_ngz -eq 1 ]; then
				for zone in `all_nonglobal_zones $LASTBE_MNTPT`
				do
					# Clear out any first time boot database information from the last BE.
					zlogin -S -R $LASTBE_MNTPT $zone "$LUETCBIN/lusync -i \
			                -d /a/$LU_DB_LOCAL >> /a/$LU_SYNC_LOG_FILE 2>&1"

					# Create an "initial" snapshot of the last BE
					zlogin -S -R $LASTBE_MNTPT $zone "$LUETCBIN/lusync -u \
				        -d /a/$LU_DB_LOCAL -m /a -t initial -s /a/$LU_SYNCLIST \
				        >> /a/$LU_SYNC_LOG_FILE 2>&1"
				done
			fi

			#Unmount the last BE.
			$LUBIN/luumount -f -i /etc/lu/ICF.$LASTBE_ID

			# Indicate to console and system logs that activation is completed.
			${LUPRINTF} +X -1S ${LU_SYSLOG_FACILITY}.${LU_SYSLOG_PRIORITY} \
			    "`gettext 'Live Upgrade: Previous boot environment was <%s>.'`" "${LAST_BE}"
			${LUPRINTF} +X -1S ${LU_SYSLOG_FACILITY}.${LU_SYSLOG_PRIORITY} \
			    "`gettext 'Live Upgrade: Current boot environment is now <%s>.'`" "${CURR_BE}"
		fi
	fi

	# SYNCKEY is needed only to drive sync process when the abe
	# is booted for the first time. Once that is done, SYNCKEY
	# need to be removed. During subsequent reboots, sync could
	# be kicked off only by providing '-s' option to luactivate(1M).
	/bin/rm -f $SYNCKEY

	# There is no "next active BE".
	/bin/rm -f ${NEXT_ACTIVE}

	# Synchronize the current BE's root slice entries in case they have 
	# changed since the last boot. This handles the case where the current
	# root slice has been newly mirrored or encapsulated.
	${LUETCBIN}/lusync -b "${CURR_BE}" >> ${LU_SYNC_LOG_FILE} 2>&1

	# Return success
	return 0
}

#
# lu_start_create: process live upgrade system startup BE create operation
# This handles Jumpstart profile creation of LU BEs.
#
lu_start_create()
{
	# return success if boot environment config file does not exist
	[ -n "${BE_CONFIG_FILE}" -a -f "${BE_CONFIG_FILE}" ] || return 0 

	# remove BE config file and return success if file exists but is empty
	if [ ! -s "${BE_CONFIG_FILE}" ] ; then
		/bin/rm -f "${BE_CONFIG_FILE}"
		return 0
	fi

	# configure current boot environment if it is not already configured
	if [ ! -s "${LU_LUTAB_FILE}" ] ; then
		${LUPRINTF} +X -a "${LOG}" "`gettext 'Initializing Live Upgrade <%s>.'`" \
"`/bin/date`"
		ERRMSG="`${LUBIN}/lucreate -i 2>&1`"
		if [ "$?" -eq "0" ] ; then
			CURR_BE="`lulib_lucurr`"
			${LUPRINTF} +X -1S ${LU_SYSLOG_FACILITY}.${LU_SYSLOG_PRIORITY} \
"`gettext 'Live Upgrade: primary boot environment configured as <%s>.\n'`" "${CURR_BE}"
		else
			echo "${ERRMSG}" | while read line ; do
				${LUPRINTF} +X -W1S ${LU_SYSLOG_FACILITY}.${LU_SYSLOG_PRIORITY} \
"`gettext 'Live Upgrade: %s'`" "${line}"
			done
			${LUPRINTF} +X -W1S ${LU_SYSLOG_FACILITY}.${LU_SYSLOG_PRIORITY} \
"`gettext 'Live Upgrade: unable to configure primary boot environment.\n'`"
		fi
	fi

	# BE config file exists - process file
	${LUPRINTF} +X -a "${LOG}" "`gettext 'Processing boot environment requests <%s>.'`" \
"`/bin/date`"
	${LUETCBIN}/ludo process_be_config_file ${BE_CONFIG_FILE}
	rc="$?"
	/bin/rm -f "${BE_CONFIG_FILE}"
	return ${rc}
}

#
# lu_stop: process live upgrade "system shutdown" condition
#
lu_stop()
{
	# Execute luactivate's delayupdate processing, if any.
	# Actually the term 'delayupdate' is a misnomer; 'delay_till_shutdown'
	# is a better descriptor.
	[ -f "${LU_LUTAB_FILE}" -a -s "${LU_LUTAB_FILE}" ] || return 1

	CURR_BE="`lulib_lucurr`"
	if [ "$?" -eq "0" -a -n "${CURR_BE}" -a -f "${NEXT_ACTIVE}" -a -s "${NEXT_ACTIVE}" ] ; then
		NEXT_BE="`cat ${NEXT_ACTIVE}`"
		if [ "${NEXT_BE}" != "${CURR_BE}" ] ; then
			# Indicate to console log and system logs that deactivation is about to happen.
			${LUPRINTF} +X -1S ${LU_SYSLOG_FACILITY}.${LU_SYSLOG_PRIORITY} \
"`gettext 'Live Upgrade: Deactivating current boot environment <%s>.'`" "${CURR_BE}"

			# Force the next be to be unmounted just in case the user
			# had the BE mounted before the init/shutdown command.
			${LUBIN}/luumount -f "${NEXT_BE}" 2>/dev/null 1>&2

			# A BE change is in order. The lu/rc.d
			# scripts should only be run in this case
			# if this target BE is new or was activated
			# with the sync option.
			NEXTBE_ID=`${LUETCBIN}/ludo get_be_id "$NEXT_BE"`
			NEXTBEMNTPT=`LU_OUTPUT_FORMAT=text ${LUBIN}/lumount -Zi /etc/lu/ICF.${NEXTBE_ID}`
			rc="$?"

			# If the next BE was successfully mounted, check to see
			# if the sync key on the BE indicates the next BE - if 
			# so this means the current BE has been activated and
			# synchronization cannot be done.
			if [ "${rc}" -eq '0' ] ; then
				/bin/cat ${NEXTBEMNTPT}/${SYNCKEY} 2>/dev/null | \
/bin/awk '{print $1}' | grep -w "$NEXT_BE" >/dev/null
				[ "$?" -eq '0' ] && rc=1
			fi

			# If synchronization can be done, and the first time boot
			# information is in the local database on the next BE, then
			# cause the synchronization information in the database to
			# be updated with the current information at the time the
			# current BE was shut down.
			if [ "${rc}" -eq '0' -a -s "${NEXTBEMNTPT}/${LU_DB_LOCAL}" ] ; then
				run_sync_at_stop "${NEXTBEMNTPT}"

				# Current be's database file need to be
				# re-initialized after updating the local
				# database on the next be.
				$LUETCBIN/lusync -i -d "$LU_DB_LOCAL"
			fi

			# Unmount the next BE.
			${LUBIN}/luumount -f -i /etc/lu/ICF.${NEXTBE_ID}

			# If synchronization is possible, execute synchronization
			# shutdown scripts on the current BE.
			if [ "$rc" -eq '0' ] ; then
				# Sync option active..Execute startup scripts
				${LUPRINTF} +X -1S ${LU_SYSLOG_FACILITY}.${LU_SYSLOG_PRIORITY} \
"`gettext 'Live Upgrade: Executing Stop procedures for boot environment <%s>.'`" "${CURR_BE}" 

				for f in /etc/lu/rc.d/K* ; do
					if [ -s ${f} ]; then
						case ${f} in
							*.sh) # source it
								. ${f}
								;;
							*) # sub shell
								/sbin/sh ${f} stop
								;;
						esac
					fi
				done
			fi

			# Rename our zones out of the way for the next
			# BE.  We do this on shutdown as well as
			# start-up so that we can handle switching
			# from a zones-using to a non-zones-aware BE,
			# and so that we can catch switches that don't
			# involve luactivate and normal system
			# shutdown. This should be done only when the 
			# the current BE has zones installed. 

			lulib_zone_check /
			has_ngz=$?
			if [ $has_ngz -eq 1 ]; then
				lulib_change_zone_paths / "$CURR_BE"
			fi
			
			# Indicate to console and system logs that activation is completed.
			${LUPRINTF} +X -1S ${LU_SYSLOG_FACILITY}.${LU_SYSLOG_PRIORITY} \
"`gettext 'Live Upgrade: Current boot environment is <%s>.'`" "${CURR_BE}"
			${LUPRINTF} +X -1S ${LU_SYSLOG_FACILITY}.${LU_SYSLOG_PRIORITY} \
"`gettext 'Live Upgrade: New boot environment will be <%s>.'`" "${NEXT_BE}"
		fi
	fi
	
	# If luactivate has left behind an activation script
	# then now is the time to run it - right before system
	# shutdown.
	
	DELAY_UPD_DIR="/etc/lu/DelayUpdate"
	DELAY_UPD_SCRIPT="${DELAY_UPD_DIR}/activate.sh"
	DELAY_UPD_SCRIPT_EXEC="${DELAY_UPD_DIR}/exec_activate.sh"
	if [ -f "${DELAY_UPD_SCRIPT_EXEC}" -a -s "${DELAY_UPD_SCRIPT_EXEC}" -a -x "${DELAY_UPD_SCRIPT_EXEC}" ] ; then
		${DELAY_UPD_SCRIPT_EXEC}
		/bin/rm -f "${DELAY_UPD_SCRIPT_EXEC}" "${DELAY_UPD_SCRIPT}" 2> /dev/null 1>&2
	fi

	# Synchronize the current BE's root slice entries in case they have 
	# changed since the system was booted. This handles the case where 
	# the current root slice has been newly mirrored or encapsulated.
	# Note: look for the root slice in the 'vfstab' file (-S vfstab)
	# because on shutdown the root slice may have been changed in the
	# vfstab file due to the root being mirrored or encapsulated.
	${LUETCBIN}/lusync -b "${CURR_BE}" -S 'vfstab' >> ${LU_SYNC_LOG_FILE} 2>&1

	# Return success
	return "0"
}

#
# check_log_size: do not allow any of the log files grow beyond a certain size
#
check_log_size()
{
	for ilog in ${LU_LOG_FILES_LIST} ; do
		blocks="`/bin/du -s ${ilog} 2>${LOG} | /bin/cut -f1 2>>${LOG}`"
		if [ -n "${blocks}" -a "${blocks}" -gt "${MAX_LOG_SIZE}" ]; then
			if [ -n "${LU_DEBUG}" -a "${LU_DEBUG}" -gt "0" ]; then
				echo "${LU_PROG_NAME}: ""`gettext 'Information: Live Upgrade clearing log file: '`" "${ilog}"
			fi
			>$ilog
		fi
	done
}

################################################################################
# main
################################################################################

# Setting this environment variable causes live upgrade to not alter
# any scheduling priorities

_LU__SCHEDULING_PRIORITY_SET_="yes"; export _LU__SCHEDULING_PRIORITY_SET_

# Dot the defaults file.

if [ ! -s /etc/default/lu ] ; then
	echo "${LU_PROG_NAME}: ""`gettext 'ERROR: Live Upgrade product is not \
installed properly (/etc/default/lu not found).'`"
	exit 1
fi
. /etc/default/lu

# Default global variables we expect to be set from /etc/default/lu.

LUBIN=${LUBIN:=/usr/lib/lu}

# Dot the Live Upgrade library functions.

if [ ! -s $LUBIN/lulib ] ; then
	echo "${LU_PROG_NAME}: ""`gettext 'ERROR: Live Upgrade product is not \
installed properly (${LUBIN}/lulib not found).'`"
	exit 1
fi

. $LUBIN/lulib

# Don't allow the ${LOG} to get too big.
check_log_size

# Direct processing according to mode

case $1 in
stop)
	[ ! -s "${LU_LUTAB_FILE}" ] && exit 0
	lu_stop
	;;
start)
	lu_start
	;;
*)
	echo "${LU_PROG_NAME}: ""`gettext 'ERROR: Live Upgrade given \
unknown or unspecified direction: '`""$1"
	exit 1
esac
