#!/sbin/sh

################################################################################
# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#	Copyright 1992-95 AT&T Global Information Solutions
#
#pragma ident	"@(#)luactivate.sh	5.46	05/10/28 SMI"
#
# luactivate is used to activate an alternative boot environment; that is, prepares the system
# to boot from another boot environment the next time the system is brought down gracefully.
#
# USAGE: luactivate [-l error_log] [-o outfile] [-s] [ [-n] BE-name ]
#
# -l - if specified error messages are logged to this file.
#	-> This overrides the LU_ERROR_LOG_FILE setting read from /etc/default/lu.
# -o - if specified entire session is logged to thie file.
#	-> This overrides the LU_SESSION_LOG_FILE setting read from /etc/default/lu.
# -s - if specified, force a sync on the newly activated be.
# -n n - name of the boot environment to activate.
#
# UNDOCUMENTED PRIVATE USAGE BY LUUPD_BOOT:
#	luactivate -u -n "be-name"
#
# Cause a newly created BE to have its vtoc and bootstrap information updated in real time.
#
# The VTOC is updated to change the partition identification flag of the root slice of the 
# BE to be activated to "V_ROOT", and to change any existing partition marked as the root
# slice to "V_UNASSIGNED".
#
# The bootstrap is updated to be compatible with the version of the OS on the BE to be activated.
#
# OUTPUT  :  For no arguments, the name of BE that will be active on next
#            reboot will be printed.
# DEV     :  Satish
#
# NOTES:
# If the -u option is specified, the behavior of luactivate is modified as follows:
# 
# 1. No check is done to prevent operation if a COPYLOCK is present (a BE is busy).
# 2. No delayed update scripts are created; the following actions are performed in real time:
# 2a. the vtoc on the target BE boot disk is updated using fmthard.
# 2b. the OS bootstrap on the target BE boot disk is updated using installboot.
# 3. No check is done to see if the current PBE is being activated.
# 4. The fallback information is not updated.
# 5. The system boot device parameters are not updated.
# 6. No activate/fallback information is output.
#
# Note: performance testing has proven that "/sbin/sh" provides the best performance over
# /bin/sh and /bin/ksh.
#
################################################################################

## set -xv

LU_PROG_FULL_PATH="$0"
LU_PROG_NAME="`basename ${LU_PROG_FULL_PATH}`"; export LU_PROG_NAME

TMPFILE=/tmp/.luactivate.$$
TMP_RESULT_FILE="/tmp/.luactivate.results.tmp.$$"

PFINSTALL_UPGRADE_FAILED_PKGADDS='/var/sadm/system/data/upgrade_failed_pkgadds'
PFINSTALL_PACKAGES_TO_BE_ADDED='/var/sadm/system/data/packages_to_be_added'

DELAY_UPD_DIR=/etc/lu/DelayUpdate
#
# If changing the name of the DELAY_UPD_SCRIPT
# then change bootadm in ON to also use
# the new filename.
#
DELAY_UPD_SCRIPT=$DELAY_UPD_DIR/activate.sh
DELAY_UPD_SCRIPT_EXEC=$DELAY_UPD_DIR/exec_activate.sh

GRUB_INSTALL=sbin/installgrub
CREATE_RAMDISK='boot/solaris/bin/create_ramdisk'
MBR="mbrfile"
PBE_BOOT_MENU_FILE="menu.pbe"
BOOT_RAW_SLICE=""
BOOT_LOGICAL_SLICE=""
BOOT_LOGICAL_FSTYP=""
BOOT_SLICE_IS_PART=""

################################################################################
# Name:		usage
# Description:	output command line usage information; then call exit to terminate execution.
# Local Prefix:	<none>
# Arguments:	$1 = exit code for script ("" defaults to "1").
# Example:	usage 1
# Returns:	<none> 
################################################################################

usage()
{
  ${LUPRINTF} -p2 "`gettext 'USAGE: %s [ -X ] [ -l error_log ] [ -o outfile ] \
[ -s ] [ [ -n ] BE_name ]'`" "${LU_PROG_NAME}"
  ${LUPRINTF} -Ip2 "`gettext 'Any BE_name should be enclosed in single quotes.'`"
  if [ -z "$1" ] ; then
    exit 1
  fi
  exit "$1"
}

################################################################################
# Name:		check_sync_issues
# Description:	Check to see if any synchronization issues will occur when the
#		BE is synchronized on reboot.
# Local Prefix:	csi_
# Arguments:	$1 = mount point for BE to check.
# Example:      check_sync_issues mntpt
# Returns:	<none>
################################################################################

check_sync_issues() 
{
	csi_mntPt="$1"
	csi_tmp_sync_file="${csi_mntPt}/tmp/.luactivate.sync.$$"


	#If SYNCLIST file is different in Source BE and Target BE, the following
        #code takes the diff of the two files and appends those entries to the
        #new BE that are present in the current BE but not in the BE that is to
        #be activated.

        /bin/diff -w -b  "${LU_SYNCLIST}" "${csi_mntPt}${LU_SYNCLIST}"|/bin/egrep -e "^<"| \
           while read line; do
             xt=`/bin/echo "$line"|/bin/sed -e 's/^<\([^< ]*[\t ]*\)\([^ \t]*\)/\1\2/g'`
             [ -n "$xt" ] && /bin/echo "$xt" >> "${csi_tmp_sync_file}"
           done

        if [ -s "${csi_tmp_sync_file}" ]; then
          /bin/cat "${csi_tmp_sync_file}" >> "${csi_mntPt}${LU_SYNCLIST}"
        fi

	/bin/grep '^<beSyncList type="initial" ' ${csi_mntPt}/${LU_DB_LOCAL} \
2>/dev/null 1>&2
	[ "$?" -ne '0' ] && return

	# Compute source and target synchronization file values.
	${LUETCBIN}/lusync -u -d "${csi_mntPt}/${LU_DB_LOCAL}" -m '/' -t 'source' \
-s "${csi_mntPt}${LU_SYNCLIST}"
	${LUETCBIN}/lusync -u -d "${csi_mntPt}/${LU_DB_LOCAL}" -m "${csi_mntPt}/" \
-t 'target' -s "${csi_mntPt}${LU_SYNCLIST}"

	# Check to see if any 'sourcetarget' synchronization files are 
	# in conflict.
	ERRMSG="`${LUETCBIN}/lusync -R sourcetarget -d \"${csi_mntPt}/${LU_DB_LOCAL}\"`"
	[ -z "${ERRMSG}" ] && return

	# A file has changed on the source and on the target - warn user.
	${LUPRINTF} -fWelp2 "`gettext 'The following files have changed on \
both the current boot environment <%s> and the boot environment to be activated \
<%s>:'`" "${CURR_BE}" "${BE_NAME}"
	echo "${ERRMSG}" | while read line ; do
		${LUPRINTF} -elp2 '   %s' "${line}"
	done

	${LUPRINTF} -fIelp2 "`gettext 'The files listed above are in \
conflict between the current boot environment <%s> and the boot environment \
to be activated <%s>. These files will not be automatically synchronized \
from the current boot environment <%s> when boot environment <%s> is \
activated.'`" "${CURR_BE}" "${BE_NAME}" "${CURR_BE}" "${BE_NAME}"

	#Remove the temp file
        /bin/rm -f "${csi_tmp_sync_file}"

}

################################################################################
# Name:		check_os_on_be
# Description:	Check to see if the OS on a boot environment is bootable.
# Local Prefix:	cob_
# Arguments:	$1 = mount point for BE to check.
# Example:      check_os_on_be mntpt
# Returns:	0 = successful (BE can be booted).
#		1 = failure (BE cannot be booted).
################################################################################

check_os_on_be() {
	cob_mntPt="$1"
	cob_returnCode=0

	# Check to see if any packages failed to be added during an upgrade - 
	# this is a warning situation only because a normal upgrade will allow
	# the system to boot with failed packages.
	if [ -f "${cob_mntPt}${PFINSTALL_UPGRADE_FAILED_PKGADDS}" ] ; then
		${LUPRINTF} -Welp2 "`gettext '<%d> packages failed to install \
properly on boot environment <%s>.'`" \
"`/bin/cat ${cob_mntPt}${PFINSTALL_UPGRADE_FAILED_PKGADDS} | /bin/wc -l`" "${BE_NAME}"
		${LUPRINTF} -fIlp1 "`gettext '<%s> on boot environment <%s> \
contains a list of packages that failed to upgrade or install properly. \
Review the file before you reboot the system to determine if any \
additional system maintenance is required.'`" \
"${PFINSTALL_UPGRADE_FAILED_PKGADDS}" "${BE_NAME}"
	fi

	# Check to see if any packages need to be added as a result of a partial
	# upgrade - this is an error condition as the boot environment has an
	# incomplete or failed upgrade.
	if [ -f "${cob_mntPt}${PFINSTALL_PACKAGES_TO_BE_ADDED}" ] ; then
		${LUPRINTF} -Eelp2 "`gettext '<%d> required packages are not \
installed on boot environment <%s>.'`" \
"`/bin/grep -c '^PKG=' ${cob_mntPt}${PFINSTALL_PACKAGES_TO_BE_ADDED}`" "${BE_NAME}"
		${LUPRINTF} -fIlp1 "`gettext '<%s> on boot environment <%s> \
contains a list of required packages that are not installed. The boot \
environment is missing required packages. This might be the result of \
an upgrade operation that failed or that is incomplete. If the boot \
environment was upgraded using a multiple media distribution, for example \
the Solaris CD media, you must continue the upgrade process until it is \
fully completed. Failure to complete the upgrade process with all media of \
the software distribution makes the boot environment unstable.'`" \
"${PFINSTALL_PACKAGES_TO_BE_ADDED}" "${BE_NAME}"
		cob_returnCode=1
	fi

	return "${cob_returnCode}"
}

################################################################################
# Name:		create_delayupdate_script
# Description:	Create the delayed update processing script run by delayed update exec script.
# Local Prefix:	
# Arguments:	$1 = entire command line to luactivate (placed in delayed update script as comment).
#		<none>
# Example:      create_delayupdate_script
# Returns:	0 = successful.
#		1 = failure.
################################################################################

create_delayupdate_script()
{
  dus_commandLineText="$1"

  ${LUPRINTF} -lp2D - "`gettext 'Creating delayed update script <%s>.'`" "${DELAY_UPD_SCRIPT}"

  /bin/rm -f $DELAY_UPD_DIR/boot.* 2>/dev/null
  /bin/rm -f $DELAY_UPD_DIR/vtoc.* 2>/dev/null
  /bin/rm -f $DELAY_UPD_DIR/${MBR} 2>/dev/null
  /bin/rm -f $DELAY_UPD_DIR/${BOOT_MENU_FILE} 2>/dev/null
  /bin/rm -f "${DELAY_UPD_SCRIPT}"
  ERRMSG="`${LUPRINTF} -c \"${DELAY_UPD_SCRIPT}\" 2>&1`"
  if [ $? -ne 0 ] ; then
    [ -n "${ERRMSG}" ] && ${LUPRINTF} -elp2 '%s' "${ERRMSG}"
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to create shutdown script <%s>.'`" "${DELAY_UPD_SCRIPT}"
    return 1
  fi

  # Output the preamble to the delayed update script.
  # Setup LU_PROG_NAME and LUPRINTF.

	/bin/cat <<-EOF >> ${DELAY_UPD_SCRIPT}
		#
		# File: ${DELAY_UPD_SCRIPT}
		# Command: ${dus_commandLineText}
		# OS: `uname -a`
		# Date: `/bin/date`
		# Who: `/bin/who -m`
		# Run-Level: `/bin/who -r`
		#
		# Setup Environment.
		#
		LU_PROG_NAME=\${LU_PROG_NAME:=/etc/init.d/lu}
		if [ -x /etc/lib/lu/luprintf ] ; then
		    LUPRINTF=/etc/lib/lu/luprintf
		else
		    LUPRINTF=\${LUPRINTF:=echo}
		fi
	EOF

  chmod 755 $DELAY_UPD_SCRIPT
  return 0
}

################################################################################
# Name:		create_delayupdate_exec_script
# Description:	Create the delayed update execute processing script run by the /etc/init.d/{K,S}#lu scripts
#		on system shutdown.
# Local Prefix:	dup_
# Arguments:	$1 = activated boot environment name (e.g. "be1").
#		$2 = entire command line to luactivate (placed in delayed update script as comment).
# Example:      create_delayupdate_exec_script "be1" "luactivate be1"
# Returns:	0 = successful.
#		1 = failure.
################################################################################

create_delayupdate_exec_script()
{
  dup_beName="$1"
  dup_commandLineText="$2"

  ${LUPRINTF} -lp2D - "`gettext 'Creating delayed update exec script <%s>.'`" "${DELAY_UPD_SCRIPT_EXEC}"

  /bin/rm -f "${DELAY_UPD_SCRIPT_EXEC}"

  ERRMSG="`${LUPRINTF} -c \"${DELAY_UPD_SCRIPT_EXEC}\" 2>&1`"
  if [ $? -ne 0 ] ; then
    [ -n "${ERRMSG}" ] && ${LUPRINTF} -elp2 '%s' "${ERRMSG}"
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to create shutdown execute script <%s>.'`" "${DELAY_UPD_SCRIPT_EXEC}"
    return 1
  fi

  # Output the entire delayed update exec script.
  # 1. Setup LU_PROG_NAME and LUPRINTF.
  # 2. Locate and run the delayed activation script.
  # 3. Output success/fail results.
  # 4. Remove any delayed update files so the procedure is not run on the next reboot again.

	/bin/cat <<-EOF >> ${DELAY_UPD_SCRIPT_EXEC}
		#
		# File: ${DELAY_UPD_SCRIPT_EXEC}
		# Command: "${dup_commandLineText}"
		# OS: `uname -a`
		# Date: `/bin/date`
		# Who: `/bin/who -m`
		# Run-Level: `/bin/who -r`
		#
		# Setup Environment.
		#
		LU_PROG_NAME=\${LU_PROG_NAME:=/etc/init.d/lu}
		if [ -f ${LUBIN}/lulib ] ; then
		    . ${LUBIN}/lulib
		fi
		if [ -x /etc/lib/lu/luprintf ] ; then
		    LUPRINTF="/etc/lib/lu/luprintf"
		else
		    LUPRINTF="echo"
		fi
		#
		# Run activation script and report results.
		#
		if [ -x "${DELAY_UPD_SCRIPT}" ] ; then
		    \${LUPRINTF} +X -fl1 "`gettext 'Live Upgrade: Activating boot environment <%s>.'`" '${dup_beName}'
		    ${DELAY_UPD_SCRIPT}
		    ret="\$?"
		else
		    \${LUPRINTF} +X -fEel1 "`gettext 'Live Upgrade: Unable to locate script <%s> to activate boot environment <%s>.'`" '${DELAY_UPD_SCRIPT}' '${dup_beName}'
		    ret="1"
		fi
		if [ "\$ret" -eq "0" ] ; then
		    \${LUPRINTF} +X -fl1 "`gettext 'Live Upgrade: Activation of boot environment <%s> completed.'`" '${dup_beName}'
		else
		    \${LUPRINTF} +X -fEel1 "`gettext 'Live Upgrade: Activation of boot environment <%s> FAILED.'`" '${dup_beName}'
		fi
		#
		# Remove temporary files and activation script and then exit.
		#
		/bin/rm -f /etc/lu/DelayUpdate/boot.*
		/bin/rm -f /etc/lu/DelayUpdate/vtoc.*
		/bin/rm -f /etc/lu/DelayUpdate/${MBR}
		/bin/rm -f /etc/lu/DelayUpdate/${BOOT_MENU_FILE}
		#
		# For the restore GRUB feature of Live Upgrade to work
		# correctly, it is important that the DELAY_UPD_SCRIPT
		# is deleted after it runs.
		# 
		/bin/rm -f ${DELAY_UPD_SCRIPT}
	EOF

  ret="$?"
  chmod 755 $DELAY_UPD_SCRIPT_EXEC
  if [ "${LU_SYSTEM_ARCH}" = "sparc" ] ; then
    /bin/cp -p /usr/platform/${LU_HARDWARE_IMPLEMENTATION}/lib/fs/ufs/bootblk ${DELAY_UPD_DIR}/bootblk
    ret="$?"
  elif [ "${LU_SYSTEM_ARCH}" = "i386" -o "${LU_SYSTEM_ARCH}" = "ppc" ] ; then
    if [ "$PBE_boot_method" = GRUB ]; then
       /bin/cp -p /${GRUB_INSTALL} ${DELAY_UPD_DIR}/installgrub
       /bin/cp -p /${GRUB_DIR}/stage1 ${DELAY_UPD_DIR}/stage1
       /bin/cp -p /${GRUB_DIR}/stage2 ${DELAY_UPD_DIR}/stage2
    else
       /bin/cp -p /usr/sbin/installboot ${DELAY_UPD_DIR}/installboot
       /bin/cp -p /usr/platform/${LU_HARDWARE_IMPLEMENTATION}/lib/fs/ufs/pboot ${DELAY_UPD_DIR}/pboot
       ret="$?"
       if [ "${ret}" -eq "0" ] ; then
          /bin/cp -p /usr/platform/${LU_HARDWARE_IMPLEMENTATION}/lib/fs/ufs/bootblk ${DELAY_UPD_DIR}/bootblk
          ret="$?${ret}"
       fi
    fi
  fi
  return "${ret}"
}

################################################################################
# Name:		get_curr_bename
# Description:	Determine the current BE name given a BE mount point.
# Local Prefix:	gcb_
# Arguments:	$1 = BE mount point.
# Example:      get_curr_bename ""  <or>  get_curr_bename "/.alt.12321/"
# Returns:	Name of current BE from BE at given mount point.
#		0 - success.
#		1 - fail.
################################################################################

get_curr_bename()
{
  gcb_beMntpt="$1"
  gcb_beName="`${LUBIN}/lucurr -m \"${gcb_beMntpt}\"`"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine root slice for the boot environment mounted at <%s>.'`" "${gcb_beMntpt}"
    return 1
  fi
  ${LUPRINTF} -lp2D - "`gettext 'Current BE name from BE at mounted at <%s> is <%s>.'`" "${gcb_beMntpt}" "${gcb_beName}"

  echo "${gcb_beName}"
  return 0
}

################################################################################
# Name:		chk_mount
# Description:	verify that the ABE's root partition is not currently mounted,
#		and that it can be mounted. 
# Local Prefix:	ckm_
# Arguments:	$1 = the BE root device.
#		$2 = the BE root device file type.
#		$3 = the BE name.
# Return codes:
#    0 - ABE root slice is not mounted and is mountable
#    1 - ABE root slice is already mounted
#    2 - ABE root slice is not mountable
#    3 - ABE root slice was mounted but is now not unmountable 
################################################################################

chk_mount()
{
  # set -x
  ckm_device=$1
  ckm_fstype=$2
  ckm_beName="$3"
  ckm_mntpt="/tmp/.alt.luactivate.$$"
  
  /usr/sbin/mount | /bin/nawk -v dev=$ckm_device '{if ($3 == dev) {printf("%s\n", $1);exit 1;}}'
  if [ $? = 1 ] ; then
    ## The ABE root slice is already mounted - this is an error
    ${LUPRINTF} -Eelp2 "`gettext 'The target boot environment <%s> root device <%s> is already mounted.'`" "${ckm_beName}" "${ckm_device}"
    return 1
  fi
  
  ## the ABE root slice is NOT mounted - attempt to mount to verify it is correct
  if [ ! -d $ckm_mntpt ] ; then
    /bin/mkdir -p $ckm_mntpt
  fi
  
  /usr/sbin/mount -F$ckm_fstype $ckm_device $ckm_mntpt 2>$TMPFILE
  if [ $? != 0 ] ; then
    /bin/cat $TMPFILE
    /bin/rm -f $TMPFILE
    /bin/rmdir $ckm_mntpt
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to mount target boot environment <%s> root device <%s> to mount point <%s>.'`" "${ckm_beName}" "${ckm_device}" "${ckm_mntpt}"
    return 2
  fi

  # sync data to storage medium before unmounting
  /bin/sync

  # force log to be flushed before unmounting
  if [ -x "/usr/sbin/lockfs" ] ; then
	  /usr/sbin/lockfs -f "${ckm_mntpt}" 1>/dev/null 2>&1
  fi

  # Unmount the temporary mount point
  /usr/sbin/umount $ckm_device 2>$TMPFILE
  ret=$?
  if [ $ret -ne 0 ] ; then
    /usr/sbin/umount -f $ckm_device 2>>$TMPFILE
    ret=$?
  fi

  if [ $ret -eq 0 ] ; then
    /bin/rmdir $ckm_mntpt
  else
    /bin/cat $TMPFILE
    /bin/rm -f $TMPFILE
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to unmount target boot environment <%s> root device <%s> mount point <%s>.'`" "${ckm_beName}" "${ckm_device}" "${ckm_mntpt}"
    return 3
  fi
  /bin/rm -f $TMPFILE

  return 0
}

################################################################################
# Name:		fdisk130
# Description:	Examine the boot/root of every BE in /etc/lutab
#		if it is 0xbf partition id, change it to 0x82
# Local Prefix: fpa_
# Arguments:	$1 = device name
# Returns:	0 = successful.
#		1 = no fdisk partition table
#
# NOTE:		S9 (and before) will not recognize the new fdisk partition id
#		Therefore if luactivate is run on a system with a new
#		partitionid then switch to the old partition id
################################################################################
fdisk130()
{
  sbt_oosFlag="$1"
  #
  # This only applies to x86-32 and x86-64
  [ `uname -m` != 'i86pc' ] && return 0

  cat /etc/lutab \
  | grep '^[0-9].*[12]$' \
  | sed \
      -e 's/[^:]*:[^:]*://' \
      -e 's/:.*//' \
      -e 's/[sp][0-9][0-9]*/p0/' \
      -e 's/\/dsk\//\/rdsk\//' \
  | sort -u \
  | while read fpa_dvn
  do
    #
    # A really messed up MBR will produce a warning and pause for input
    # so if any message occurs, dont change anything
    echo "n" | fdisk -W - $fpa_dvn 2>&1 | grep '^[A-Za-z]' > /dev/null && continue

    #
    # Get block address of Solaris2 partition
    rsect=`fdisk -W - $fpa_dvn \
    | grep '^  191 ' \
    | awk '{print $9}'`

    #
    # Skip if Solaris2 partition doesnt exist
    [ "$rsect" -lt 1 ] && continue

    if [ -z "${sbt_oosFlag}" ] ; then
    echo "
      #
      #change Solaris2 to Solaris
      /sbin/fdisk -W - $fpa_dvn \\
      | /bin/grep '^ *[0-9]' \\
      | /bin/sed 's/^ *191 /  130 /' \\
      > /tmp/.fdisk.\$\$

      #
      # update partition id
      /sbin/fdisk -F /tmp/.fdisk.\$\$ $fpa_dvn

      /bin/rm -f /tmp/.fdisk.\$\$
      " >> ${DELAY_UPD_SCRIPT}
    else
       #change Solaris2 to Solaris
       /sbin/fdisk -W - $fpa_dvn \
       | /bin/grep '^ *[0-9]' \
       | /bin/sed 's/^ *191 /  130 /' \
       > /tmp/.fdisk.$$
       /sbin/fdisk -F /tmp/.fdisk.$$ $fpa_dvn
       /bin/rm -f /tmp/.fdisk.$$
    fi
  done

  return 0
}


 ################################################################################
 # Name:         fb_restore_boot_partition
 # Description:  Restore the boot partition for the fallback BE
 # Special:      Called during OOS and so may not call into lulib.
 #               Also, LUPRINTF may be set to "echo"
 # Local Prefix: rbp_
 # Arguments:    $1 = mount point of fallback BE
 #               $2 = Name of fallback BE
 # Returns:      0 = successful.
 #               1 = failure.
 ################################################################################
 fb_restore_boot_partition()
 {
    rbp_mntpt="$1"
    rbp_beName="$2"
    rbp_temp="/tmp/.luactivate.rbp.$$"

    # See set_boot() for why we do this.
    if [ "${PBE_boot_method}" != DCA ]; then
       ${LUPRINTF} "`gettext 'ERROR: fallback boot environment <%s> is not a DCA boot environment.'`" "${rbp_beName}"
       return 1
    fi

    rbp_boot="`/bin/grep -s -v '^#' ${rbp_mntpt}/etc/vfstab | /bin/grep \"[     ]/boot[         ]*pcfs[         ]\"`"
    if [ "$?" -ne 0 ]; then
      ${LUPRINTF} "`gettext 'Fallback boot environment <%s> doesn't use a boot partition.'`" "${rbp_beName}"
      return 0
    else
      rbp_boot="`echo $rbp_boot | /bin/awk '{print $1}' | /bin/sed -e 's:p0\:boot::g'`"
    fi
    diskid="`/bin/basename $rbp_boot`"

    # Get fdisk table after deleting all blank lines and comments
      /usr/sbin/fdisk -W - /dev/rdsk/${diskid}p0 | /bin/grep -v '^*' | /bin/grep -v '^$' > ${rbp_temp}

      num=1
      while read id act bhead bcyl ehead ecyl rsect numsect
      do
       # Ignore entry if not X86 /boot partition
       #ID '190' is the X86BOOT partition (see man fdisk(1M))

      if [ $id -ne "190" ] ; then
            num=`/bin/expr $num + 1`
            continue
      fi

     #
     # Found X86 boot partition - restore current boot partition (if one exists for PBE)
     # It is safe to do this without worrying about GRUB menu, since we are falling back from
     # a failed activation and the last active GRUB menu has been saved in the file
     # .dd_x86_boot_copy.
     #

     bootpart_id="/dev/rdsk/${diskid}p${num}"
    /sbin/umount /dev/dsk/${diskid}p0:boot > /dev/null 2>&1         # May not be mounted. so ignore errors
    ${LUPRINTF} "`gettext 'Restoring boot partition for boot environment <%s>.'`" "${rbp_beName}"
    /bin/dd if="${rbp_mntpt}/etc/lu/.dd_x86_boot_copy" of="${bootpart_id}"
    if [ "$?" -ne 0 ]; then
       ${LUPRINTF} "`gettext 'ERROR: Restore of boot partition failed.'`"
      return 1
    fi
    break;
    done < ${rbp_temp}

   return 0

}

 ################################################################################
 # Name:         fb_restore_bootpath
 # Description:  Restore the boot path for the fallback BE
 # Special:      Called during OOS and so may not call into lulib.
 #               Also, LUPRINTF may be set to "echo"
 # Local Prefix: rbt_
 # Arguments:    $1 = mount point of fallback BE
 #               $2 = Name of fallback BE
 # Returns:      0 = successful.
 #               1 = failure.
 ################################################################################
 fb_restore_bootpath()
 {
     rbt_mntpt="$1"
     rbt_beName="$2"
     rbt_temp="/tmp/.luactivate.rbt.$$"

     # See set_boot() for why we do this.
    if [ "${PBE_boot_method}" != DCA ]; then
       ${LUPRINTF} "`gettext 'ERROR: fallback boot environment <%s> is not a DCA boot environment.'`" "${rbt_beName}"
       return 1
    fi
    ${LUPRINTF} "`gettext 'Updating bootpath for fallback boot environment <%s>.'`" "${rbt_beName}"

    rbt_bpath_log=`${rbt_mntpt}/etc/lib/lu/ludo get_boot_device_from_be_name ${rbt_beName}`
    if [ "$?" -ne 0 -o -z "${rbt_bpath_log}" ]; then
         ${LUPRINTF} "`gettext 'ERROR: Cannot find bootpath for fallback boot environment <%s>.'`" "${rbt_beName}"
         return 1
    fi
    rbt_bpath_phys=`/bin/ls -l "$rbt_bpath_log" | /bin/sed 's:.*/devices/:/:g'`
    if [ "$?" -ne 0 -o -z "${rbt_bpath_phys}" ]; then
      ${LUPRINTF} "`gettext 'ERROR: Cannot determine bootpath for fallback boot environment <%s>.'`" "${rbt_beName}"
       return 1
    fi

    /bin/egrep -v '^setprop bootpath ' "${rbt_mntpt}"/boot/solaris/bootenv.rc > "$rbt_temp"
    echo "setprop bootpath ${rbt_bpath_phys}" >> "$rbt_temp"

    /bin/cp "${rbt_temp}" "${rbt_mntpt}"/boot/solaris/bootenv.rc
    /bin/rm -f "${rbt_temp}" > /dev/null 2>&1

    return 0
 }

 ################################################################################
 # Name:         fb_update_victim_BEs
 # Description:  Set fallback BE bootpath on DCA victim BEs. For a definition
 #               of a victim BE see set_boot()
 # Special:      Called during OOS and so may not call into lulib.
 #               Also, LUPRINTF may be set to "echo"
 #               Also, assumes that fallback BE has its bootpath set correctly
 # Local Prefix: uvb_
 # Arguments:    $1 = mount point of fallback BE
 #               $2 = Name of fallback BE
 # Returns:      0 = successful.
 #               1 = failure.
 ################################################################################

fb_update_victim_BEs()
 {
    uvb_mntpt="$1"
    uvb_beName="$2"
    uvb_temp="/tmp/.luactivate.uvb.$$"

    # See set_boot() for why we do this.
    if [ "${PBE_boot_method}" != DCA ]; then
      ${LUPRINTF} "`gettext 'ERROR: fallback boot environment <%s> is not a DCA boot environment.'`" "${rbt_beName}"
      return 1
    fi
    if [ ! -f "${uvb_mntpt}"/etc/lutab -o ! -s "${uvb_mntpt}"/etc/lutab ]; then
       ${LUPRINTF} "`gettext 'ERROR: Cannot find lutab in fallback boot environment <%s>.'`" "${uvb_beName}"
       return 1
    fi
   # First get the list of all BE IDs
    uvb_ids=`/bin/egrep -v "^#" "${uvb_mntpt}"/etc/lutab | nawk -F: '{print $1}' | sort -u -n`
    if [ -z "$uvb_ids" ]; then
       ${LUPRINTF} "`gettext 'ERROR: Cannot determine boot environment IDs.'`"
       return 1
    fi
    uvb_names=`for i in $uvb_ids; do "${uvb_mntpt}"/etc/lib/lu/ludo get_be_name "$i"; done`
    if [ -z "$uvb_names" ]; then
       ${LUPRINTF} "`gettext 'ERROR: Cannot determine boot environment names.'`"
       return 1
    fi

    uvb_currbeName=`/etc/lib/lu/ludo get_be_name_from_mntpt /`

    for i in $uvb_names
     do
      # Fallback BE bootpath should have been set correctly before this
      # function is called.
      if [ "$i" = "${uvb_beName}" ]; then
           continue
      fi
      uvb_status=`"${uvb_mntpt}"/etc/lib/lu/ludo get_be_status_from_be_name "$i"`
      if [ "$uvb_status" != C ]; then
           continue
      fi

      # Mount the BE. Cannot use lumount directly as it is in /usr

      if [ "$i" != "${uvb_currbeName}" ]; then
         uvb_temp_mntpt=`"${uvb_mntpt}"/etc/lib/lu/ludo lumount "$i"`
         if [ "$?" -ne 0 ]; then
           ${LUPRINTF} "`gettext 'ERROR: Cannot mount boot environment <%s>.'`" "$i"
           continue
         fi
      else
         #we do not mount current BE since its already mounted
         uvb_temp_mntpt="/"
      fi

      # Skip if GRUB BE - only DCA BEs can be victim BEs
     if [ "$i" != "${uvb_currbeName}" ]; then
        if [ -f "${uvb_temp_mntpt}"/platform/i86pc/multiboot ]; then
          #This is not the current BE, but not a DCA either
          #DO an unmount and continue
          "${uvb_mntpt}"/etc/lib/lu/ludo luumount "$i"
           continue
        fi
      else
      if [ -f "${uvb_temp_mntpt}"/platform/i86pc/multiboot ]; then
        #This is the case of the current BE which is a non DCA BE
        #we do not unmount current BE
        #so , continue
            continue
      fi
     fi

    #
    # The following assumes that bootpath setting for fallback BE is
    # correctly set
    #
    /bin/egrep -v '^setprop bootpath ' "${uvb_temp_mntpt}"/boot/solaris/bootenv.rc > "$uvb_temp"
    /bin/egrep '^setprop bootpath ' "${uvb_mntpt}"/boot/solaris/bootenv.rc >> "$uvb_temp"
    /bin/cp "$uvb_temp" "${uvb_temp_mntpt}"/boot/solaris/bootenv.rc
    /bin/rm -f "${uvb_temp}" > /dev/null 2>&1

    if [ "$i" != "${sbt_currbeName" ]; then
       "${uvb_mntpt}"/etc/lib/lu/ludo luumount "$i"
    fi
  done

  return 0
}



################################################################################
# Name:		set_boot
# Description:	Change the boot device for a newly activated BE
# Local Prefix:	sbt_
# Arguments:	$1 = the BE root device to boot the system from.
#		$2 = the BE root device mount point (where the $1 slice is currently mounted; "" = /).
#		$3 = the BE name of the newly activated BE.
#		$4 = do not delay flag ("" = delay until shutdown, otherwise do immediately).
#		$5 = doing oos servicing ("" = not doing OOS servicing)
# Returns:	0 = successful.
#		1 = failure.
################################################################################

set_boot()
{
  sbt_bootDisk="$1"
  sbt_beMntpt="$2"
  sbt_beName="$3"
  sbt_doNotDelay="$4"
  sbt_oosFlag="$5"

  # If in single user mode then there is no "current boot environment" as
  # the system may be booted from an install image and be in the
  # mini-root. In this case:
  # - assume the current BE name is "single-user-mode"
  # - if there is a /etc/lu/.BE_CONFIG then set the current BE name from there

  if [ -n "${sbt_oosFlag}" ] ; then
    sbt_currBeName="single-user-mode"
    if [ -f "${sbt_beMntpt}/etc/lu/.BE_CONFIG" ] ; then
      . ${sbt_beMntpt}/etc/lu/.BE_CONFIG
      if [ -n "${LUBECF_BE_NAME}" ] ; then
        sbt_currBeName="${LUBECF_BE_NAME}"
      fi
    fi
  else
    sbt_currBeName="`get_curr_bename ${sbt_beMntpt}`"
    if [ "$?" -ne "0" -o -z "${sbt_currBeName}" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine name of the target boot environment mounted at <%s>.'`" "${sbt_beMntpt}"
      exit 2
    fi
  fi
 
  #
  # For the "delayed" and "non-delayed" cases, we have already
  # called get_pbe_config(). We call get_pbe_config() here only
  # for the OOS case. luprintf may not be available and we may
  # have to fallback to echo. 
  #
  if [ -n "${sbt_oosFlag}" ]; then
     get_pbe_config "${sbt_currBeName}" "${sbt_beMntpt}" "${sbt_oosFlag}"
     if [ $? != 0 ] ; then
        ${LUPRINTF} "`gettext 'ERROR: Unable to determine the configuration of the target boot environment mounted at <%s>.'`" "${sbt_beMntpt}"
        exit 2
     fi
  fi

  if [ -z "${sbt_doNotDelay}" ] ; then
    # Delay: add proper boot environment changes to delayed update script.
    if [ "${LU_SYSTEM_ARCH}" = "sparc" ] ; then
        #
        # This is a SPARC architecture system with an Open Boot EEPROM interface.
        #
	sbt_bbootDisk="`echo ${sbt_bootDisk} |sed 's:/rdsk/:/dsk/:g'`"
	sbt_bootDev="`/bin/ls -l ${sbt_bbootDisk} |/bin/sed 's:.*/devices/:/:g'`"

	if [ "$LU_KEEP_ALTERNATIVE_BOOT" = "YES" -o "$LU_KEEP_ALTERNATIVE_BOOT" = "yes" ] ; then
	  sbt_lubootdevsetting="/etc/lib/lu/lubootdev '${sbt_bootDev}'"
	else
	  sbt_lubootdevsetting="/etc/lib/lu/lubootdev '${sbt_bootDev}' '$PBE_root_bdev'"
	fi

	${LUPRINTF} -lp2D - "`gettext 'Adding sparc boot device update from BE <%s> device <%s> to BE <%s> device <%s>.'`" "${sbt_currBeName}" "${PBE_root_bdev}" "${sbt_beName}" "${sbt_bootDev}"

	/bin/cat <<-EOF >> ${DELAY_UPD_SCRIPT}
		#
		# Change sparc boot device to boot environment "${sbt_beName}" device "${sbt_bootDev}"
		#
		\${LUPRINTF} +X -flS ${LU_SYSLOG_FACILITY}.${LU_SYSLOG_PRIORITY} "`gettext 'Live Upgrade: Changing primary boot device to boot environment <%s>.'`" "${sbt_beName}"
		currBootDevice="\`eeprom boot-device | cut -d= -f2\`"
		\${LUPRINTF} +X -flS ${LU_SYSLOG_FACILITY}.${LU_SYSLOG_PRIORITY} "`gettext 'Live Upgrade: The current boot environment <%s> boots from device <%s>.'`" "${sbt_currBeName}" "\${currBootDevice}"

		${sbt_lubootdevsetting}

		if [ "\$?" != "0" ] ; then
		    \${LUPRINTF} +X -fEel2S ${LU_SYSLOG_FACILITY}.${LU_SYSLOG_PRIORITY} "`gettext 'Live Upgrade: Unable to change primary boot device to boot environment <%s>.'`" "${sbt_beName}"
		    \${LUPRINTF} +X -fEel2S ${LU_SYSLOG_FACILITY}.${LU_SYSLOG_PRIORITY} "`gettext 'You must manually change the system boot prom to boot the system from device <%s>.'`" "${sbt_bootDev}"
		else
		    newBootDevice="\`eeprom boot-device | cut -d= -f2\`"
		    \${LUPRINTF} +X -flS ${LU_SYSLOG_FACILITY}.${LU_SYSLOG_PRIORITY} "`gettext 'Live Upgrade: The new boot environment <%s> boots from device <%s>.'`" "${sbt_beName}" "\${newBootDevice}"
		fi
		exit 0
	EOF

	${LUPRINTF} -lp2D - "`gettext 'Configured init.d scripts to change primary boot device to BE <%s> device <%s>.'`" "${sbt_beName}" "${sbt_bootDev}"
    elif [ "${LU_SYSTEM_ARCH}" = "i386" ] ; then
        #
        # This is an INTEL architecture system with potentially an X86 Boot Partition.
        #
	${LUPRINTF} -lp2D - "`gettext 'Adding i386 boot partition check from BE <%s> device <%s> to BE <%s> device <%s>.'`" "${sbt_currBeName}" "${PBE_root_bdev}" "${sbt_beName}" "${sbt_bootDev}"


	if [ -f ${LUBIN}/lux86devpathcare -a -x ${LUBIN}/lux86devpathcare ]
	then
		/bin/cat <<-EOF >> ${DELAY_UPD_SCRIPT}
			#
			# Update i386 boot device paths for boot environment "${sbt_beName}"
			#
			arc=`/bin/uname -r`

			if [ "\$arc" = "5.7" ] ; then
			    \${LUPRINTF} +X -fl1S ${LU_SYSLOG_FACILITY}.${LU_SYSLOG_PRIORITY} "`gettext 'Live Upgrade: Updating device paths for <%s>.'`" "${sbt_beName}"
			    \${LUBIN}/lux86devpathcare "${sbt_beName}"
			fi
		EOF
	fi


	#
        # The following code switches boot partitions via
	# lux86bootdevicecare (if applicable). It also allows
	# strapping DCA BEs by setting bootpath (necessary if
	# the DCA BE is on a disk which is not the boot disk.)
	# If there is a boot partition it is assumed that it
	# is on the boot disk.
	# 
	# The following matrix indicates how the boot partitions
	# are switched:
	# 
	# Transition		Boot partition change
	# -------------------------------------------
	# DCA  -> DCA		switch boot part
	# DCA  -> GRUB		save boot part 
	# GRUB -> DCA		restore boot part
	# GRUB -> GRUB		nop
	#
	# Note: It is not possible to strap via bootpath
	# from a GRUB BE to a DCA/GRUB BE. Doing so
	# will result in a kernel that is from GRUB BE,
	# but a root file system that is from the other BE.
	# Also GRUB BEs don't need strapping via
	# bootpath (we strap via menu.lst).
	# 
	# The following matrix indicates how each case
	# is handled. In the following, target BE is the BE
	# we are switching to. Victim BE is an inactive BE
	# whose bootpath may potentially be changed to
	# boot the target BE.
	#	
	# Victim-BE	Target-BE 	strap via bootpath ?
	# ---------------------------------------------------
	# DCA  		 DCA			YES
	# DCA   	 GRUB			NO
	# GRUB  	 DCA			NO
	# GRUB           GRUB			NO
	#
	# Note: bootpath has different semantics with GRUB boot.
	# It is actually the root filesystem mounted during boot.
	#
       
	if [ -f ${LUBIN}/lux86bootdevicecare -a -x ${LUBIN}/lux86bootdevicecare ]
	then
		/bin/cat <<-EOF >> ${DELAY_UPD_SCRIPT}

		#
		# Change boot partition information and boot device.
		#
		sbt_abe_mntpt=\`\${LUBIN}/lumount "$sbt_beName"\`
		if [ "\$?" -ne 0 -o -z "\$sbt_abe_mntpt" ]; then
			\${LUPRINTF} +X -fEel2 "`gettext 'Live Upgrade: Unable to mount boot environment <%s>: the activation is aborted.'`" "$sbt_beName"
			exit 2
		fi

		/bin/grep -s -v '^#' \${sbt_abe_mntpt}/etc/vfstab | /bin/grep "[ 	]/boot[ 	]*pcfs[ 	]" >/dev/null
		sbt_res1="\$?"
		\${LUBIN}/luumount "$sbt_beName"
		/bin/grep -s -v '^#' /etc/vfstab | /bin/grep "[ 	]/boot[ 	]*pcfs[ 	]" >/dev/null
		sbt_res2="\$?"

                #
		# Newboot BEs will *not* have a boot partition
	        # For legacy boot BEs - it is all or none.
                #
		if [ "\$sbt_res1" -eq 0 -o "\$sbt_res2" -eq 0 ] ; then
			\${LUPRINTF} +X -fl1S ${LU_SYSLOG_FACILITY}.${LU_SYSLOG_PRIORITY} "`gettext 'Live Upgrade: Updating boot partition for boot environment <%s>.'`" "${sbt_beName}"
			\${LUBIN}/lux86bootdevicecare "${sbt_beName}"

                elif [ "$ABE_boot_method" = DCA ]; then
		    #
		    # We have two goals in the following code: 
		    #
		    # 1) set bootpath for ABE(if DCA)
		    #    GRUB BEs already have their bootpath set
		    #    in create_script()
		    # 2) set DCA target bootpath in victim DCA BEs
		    #	 see comment above on victim and target BEs
		    #
		    
		    TMP_BOOTENV_RC=/tmp/.delayupdate.\$\$

		    # determine the active BE of the system.
		    curr_be=`lulib_lucurr`

                    #
		    # Determine the bootpath of the boot environment to be activated
                    # For legacy (DCA), the bootpath must be physical (not SVM path)
                    #
		    ABE_SLICE=`/etc/lib/lu/ludo get_boot_device_from_be_name ${sbt_beName}`
		    ABE_BOOT_DEV=\`/bin/ls -l \${ABE_SLICE} | /bin/sed 's:.*/devices/:/:g'\`

		    # Change bootpath's value in eeprom (i.e. PBE victim) only if DCA
		    if [ "$PBE_boot_method" = DCA ]; then 
		       /usr/sbin/eeprom bootpath=\${ABE_BOOT_DEV}
		    fi

		    # modify ABE_BOOT_DEV variable such that it can be used in sed command
		    # ABE_BOOT_DEV has format /pci@0,0/pci8086,341a@7,1/sd@0,0:a
		    # it should be changed to \/pci@0,0\/pci8086,341a@7,1\/sd@0,0:a
		    ABE_BOOT_DEV=\`/bin/echo \${ABE_BOOT_DEV} | /bin/sed "s/\\\\//\\\\\\\\\\\\\\\\\\\\//g"\`

		    # for each valid and complete BE, change the BE's bootpath value in eeprom
		    \$LUBIN/lunames_get |
		    while read be_name
		    do
		        # if the BE is active, then no need of modifying.
		        [ "\$be_name" = "\$curr_be" ] && continue

		        # determine the status of the target BE.
		        status="\`\${LUETCBIN}/ludo get_be_status_from_be_name \"\$be_name\"\`"
		        # if the status of this BE is not 'C' then we should not modify.
		        [ "\$status" != 'C' ] && continue

		        # Mount the BE
		        BE_MPT=\`\${LUBIN}/lumount "\${be_name}"\`
			if [ "\$?" -ne 0 -o -z "\${BE_MPT}" ]; then
			    \${LUPRINTF} +X -fEel2 "`gettext 'Live Upgrade: Unable to mount boot environment <%s>: cannot update bootpath value in <%s>.'`" "${be_name}" "/boot/solaris/bootenv.rc"
			    continue
			fi

 
			#
		        # Modify the boot/solaris/bootenv.rc file if it is a DCA BE
		        # The format of this file is:
		        # setprop variable_name 'value'
			#
			if [ -f "\${BE_MPT}/$MULTI_BOOT" ]; then
			   # A GRUB BE, so skip.
		           \${LUBIN}/luumount -f "\${BE_MPT}" 2>/dev/null
			   continue
			fi
		        /bin/cat \${BE_MPT}/boot/solaris/bootenv.rc | /bin/sed "s/\(.*\)bootpath.*$/\1bootpath '\${ABE_BOOT_DEV}'/g" > \${TMP_BOOTENV_RC}
		        /bin/cp \${TMP_BOOTENV_RC} \${BE_MPT}/boot/solaris/bootenv.rc
		        /bin/rm -f \${TMP_BOOTENV_RC} 2>/dev/null

		        # Unmount the BE
		        \${LUBIN}/luumount -f "\${BE_MPT}" 2>/dev/null
		    done
		fi
		EOF
	fi
	#
	# change the fdisk partition id of any device in /etc/lutab to 130
	fdisk130 ""
    fi
 elif [ -n "${sbt_oosFlag}" ] ; then
    # Doing oos servicing - bare minimum to fallback to previous boot environment.
    if [ -d /mnt/usr/lib/lu ] ; then
        LUBIN='/mnt/usr/lib/lu'
        LUETCBIN='/mnt/etc/lib/lu'
        LUPRINTF='/mnt/etc/lib/lu/luprintf'
    else
        LUBIN='/usr/lib/lu'
        LUETCBIN='/etc/lib/lu'
        LUPRINTF='/etc/lib/lu/luprintf'
    fi

    if [ -x $sbt_beMntpt/etc/lib/lu/lubootdev ] ; then
      sbt_bbootDisk=`echo ${sbt_bootDisk} | sed  "s/\/rdsk\//\/dsk\//g"`
      sbt_bootDev="`/bin/ls -l ${sbt_bbootDisk} | /bin/sed 's/.*\/devices\//\//g'`"

      if [ "${LU_SYSTEM_ARCH}" = "sparc" ] ; then
        ${LUPRINTF} -1 "`gettext 'Changing primary boot device to boot environment <%s>.'`" "${sbt_beName}"
        ${LUPRINTF} -1 "`gettext 'The current boot environment <%s> boots from device <%s>.'`" "${sbt_currBeName}" "`/usr/sbin/eeprom boot-device |cut -d= -f2`"

        if [ "$LU_KEEP_ALTERNATIVE_BOOT" = "YES" -o "$LU_KEEP_ALTERNATIVE_BOOT" = "yes" ] ; then
          $sbt_beMntpt/etc/lib/lu/lubootdev ${sbt_bootDev} $PBE_root_bdev
        else
          $sbt_beMntpt/etc/lib/lu/lubootdev ${sbt_bootDev}
        fi
        if [ "$?" -eq "0" ] ; then
          ${LUPRINTF} -1 "`gettext 'The new boot environment <%s> boots from device <%s>.'`" "${sbt_beName}" "`/usr/sbin/eeprom boot-device |cut -d= -f2`"
        else
          ${LUPRINTF} -1 "`gettext 'Unable to change primary boot device to boot environment <%s>.'`" "${sbt_bootDev}"
	 ${LUPRINTF} -1 "`gettext 'You must manually change the system boot prom to boot the system from device <%s>.'`" "${sbt_bootDev}"
        fi
        elif [ "${LU_SYSTEM_ARCH}" = "i386" ] ; then
             #
             # This is an INTEL architecture system with potentially an X86 Boot Partition.
             #

             # We have three goals here
             # 1. switching boot partition
             # 2. Setting bootpath for PBE
             # 3. setting bootpath for "victim" DCA BEs (see comments above)

             #
             # 1. Switch boot partition
             # During fallback the situation is much simpler than the "forward activation" case
             # We assume that the ABE is messed up (which is why are doing a fallback).
             # So we only need to restore the PBE i.e. the fallback BE's boot partition
             #
             # Here is the matrix explaining this situation
             #
             # ABE     Fallback-BE          Boot partition change
             # ---------------------------------------
             # DCA ->  DCA      restore boot partition
             # DCA ->  GRUB     nop
             # GRUB->  DCA      restore boot partition
             # GRUB -> GRUB     nop
             #

             #
             # We did a get_pbe_config() above and so we know
             # what type of boot the fallback BE uses
             #
             ${LUPRINTF} "`gettext 'Checking for a boot partition on fallback boot environment <%s>.'`" "${sbt_currBeName}"
             if [ "${PBE_boot_method}" = DCA ]; then
                fb_restore_boot_partition "${sbt_beMntpt}" "${sbt_currBeName}"
             fi

             # 2. Update bootpath. Only a DCA BE requires the update, since we never change bootpaths
             #    on GRUB BE to strap another BE
             if [ "${PBE_boot_method}" = DCA ]; then
                fb_restore_bootpath "${sbt_beMntpt}" "${sbt_currBeName}"
             fi

             #
             # 3. Update victim BEs (if applicable)
             # Here is a matrix explaining the changes
             #
             # Victim-BE                fallback-BE      strap via bootpath ?
             # ------------------------------------------------------------
             # DCA                      DCA             yes
             # DCA                      GRUB            no
             # GRUB                     DCA             no
             # GRUB                     GRUB            no
             #
             # So only DCA BEs will be victim BEs and that too only if
             # the fallback BE is a DCA BE
             #
             if [ "${PBE_boot_method}" = DCA ]; then
                fb_update_victim_BEs "${sbt_beMntpt}" "${sbt_currBeName}"
             fi

            # This is OOS. Since we already changed all fdisk IDs to 130 while going
            # in the forward direction, there is no need to set that again here.
        fi
       fi
else
    # Neither delayed update nor oos servicing - apply boot environment changes now.
    sbt_bbootDisk=`echo ${sbt_bootDisk} | sed  "s/\/rdsk\//\/dsk\//g"`
    sbt_bootDev="`/bin/ls -l ${sbt_bbootDisk} | /bin/sed 's/.*\/devices\//\//g'`"
    if [ "${LU_SYSTEM_ARCH}" = "sparc" ] ; then
      ${LUPRINTF} -lp1S ${LU_SYSLOG_FACILITY}.${LU_SYSLOG_PRIORITY} "`gettext 'Changing primary boot device to boot environment <%s>.'`" "${sbt_beName}"
      ${LUPRINTF} -lp1SD - ${LU_SYSLOG_FACILITY}.${LU_SYSLOG_PRIORITY} "`gettext 'The current boot environment <%s> boots from device <%s>.'`" "${sbt_currBeName}" "`eeprom boot-device |cut -d= -f2`"
      ${LUPRINTF} -lp2SD - ${LU_SYSLOG_FACILITY}.debug -D - "`gettext 'Changing boot environment from BE <%s> device <%s> to BE <%s> device <%s>.'`" "${sbt_currBeName}" "${PBE_root_bdev}" "${sbt_beName}" "${sbt_bootDev}"

	if [ "$LU_KEEP_ALTERNATIVE_BOOT" != "YES" ] ; then
	  /etc/lib/lu/lubootdev ${sbt_bootDev} $PBE_root_bdev
	else
	  /etc/lib/lu/lubootdev ${sbt_bootDev}
	fi

	if [ "$?" -eq "0" ] ; then
	  ${LUPRINTF} -lp1S ${LU_SYSLOG_FACILITY}.${LU_SYSLOG_PRIORITY} "`gettext 'The new boot environment <%s> boots from device <%s>.'`" "${sbt_beName}" "`eeprom boot-device |cut -d= -f2`"
	  ${LUPRINTF} -lp2D - "`gettext 'Changed primary boot device to BE <%s> device <%s>.'`" "${sbt_beName}" "${sbt_bootDev}"
	else
	  ${LUPRINTF} -Eelp2S ${LU_SYSLOG_FACILITY}.${LU_SYSLOG_PRIORITY} "`gettext 'Unable to change primary boot device to boot environment <%s>.'`" "${sbt_bootDev}"
	  ${LUPRINTF} -Eelp2 "`gettext 'You must manually change the system boot prom to boot the system from device <%s>.'`" "${sbt_bootDev}"
	fi
    fi
  fi
}

#
# This routine only accepts a char device
#
# Given a name in the c-t-d-p0:boot format, it converts it into
# c-t-d-p<n> where <n> is the real fdisk partition. <n> is number
# between 1 and 4.
# 
# It may be called during OOS
#
get_real_boot_partition()
{
   gbp_p0Boot="$1"

   gbp_tmp1="/tmp/.luact.gbp.1.$$"
   gbp_tmp2="/tmp/.luact.gbp.2.$$"

   /bin/rm -f "$gbp_tmp1" "$gbp_tmp2"

   if [ "$#" -ne 1 -o -z "$1" ]; then
	${LUPRINTF} "`gettext 'ERROR: Usage: get_real_boot_partition <boot-partition-p0>'`"
	return 1
   fi

   /bin/echo "$gbp_p0Boot" | /bin/egrep "p0:boot$" > /dev/null 2>&1
   if [ "$?" -ne 0 ]; then
	${LUPRINTF} "`gettext 'ERROR: Not a boot partition name: <%s>'`" "${gbp_p0Boot}"
	return 1
   fi

   #
   # Translate /dev/rdsk/c-t-d-p0:boot to p0
   #
   gbp_p0=`/bin/echo "$gbp_p0Boot" | /bin/sed 's/p0:boot$/p0/g'`
   if [ -z "$gbp_p0" -o ! -c "$gbp_p0" ]; then
	${LUPRINTF} "`gettext 'ERROR: No such partition or not a char device: <%s>'`" "${gbp_p0}"
	return 1
   fi

   /usr/sbin/fdisk -W "$gbp_tmp1" "$gbp_p0" > /dev/null 2>&1
   /usr/bin/grep -v \* "$gbp_tmp1" | /usr/bin/grep -v '^[ 	]*$' > "$gbp_tmp2"
   #
   # Note: while executed in a subshell
   #
   /bin/rm -f "$gbp_tmp1"
   num=1
   while read id act bhead bcycl ehead ecycl rsect numsect
   do
	if [ -z "$id" ]; then
	   continue
	fi

        if [ "$id" -eq 190 ]; then
	   /bin/echo "$num" > "$gbp_tmp1" 
	   break;
	fi
	num=`/bin/expr "$num" + 1`

   done < "$gbp_tmp2"

   if [ -f "$gbp_tmp1" -a -s "$gbp_tmp1" ]; then
      part=`/usr/bin/cat "$gbp_tmp1"`
      if [ "$part" -lt 1 -o "$part" -gt 4 ]; then
         ${LUPRINTF} "`gettext 'ERROR: partition number derived is invalid: <%s>'`" "${part}"
         /bin/echo ""
         retval=1
      else
         disk=`/bin/echo "$gbp_p0" | /bin/sed 's/p0$//g'`
         echo "${disk}p${part}"
         retval=0
      fi
     
   else
      ${LUPRINTF} "`gettext 'ERROR: No Solaris boot partition on device: <%s>'`" "${gbp_p0}"
      /bin/echo ""
      retval=1
   fi

   /bin/rm -f "$gbp_tmp1"
   /bin/rm -f "$gbp_tmp2"

   return "$retval"
}

#
# Given a s2 slice in Solaris, converts it into the GRUB fdisk
# partition number (which begins with 0)
# 
# Argument:
#	$1  A s2 Solaris slice
# Returns
#	GRUB partition number on standard output
#
grub_part()
{
  if [ "$#" -ne 1 -o -z "$1" ]; then
     ${LUPRINTF} -Eelp2 "`gettext 'grub_part(): invalid arguments.'`"
     echo ""
     return
  fi

  grp_disk=$1 

  grp_tmp1="/tmp/.luactivate.grp.1.$$"
  grp_tmp2="/tmp/.luactivate.grp.2.$$"


  grp_p0=`echo "$grp_disk" | /usr/bin/sed 's/s2$/p0/g'`

  /usr/sbin/fdisk -W "$grp_tmp1" "$grp_p0" > /dev/null 2>&1
  /usr/bin/grep -v \* "$grp_tmp1" | /usr/bin/grep -v '^[ 	]*$' > "$grp_tmp2"

  #
  # Note: while loop is executed in a subshell
  #
  /bin/rm -f "$grp_tmp1"
  num=1
  while read id act bhead bcycl ehead ecycl rsect numsect
  do
	if [ -z "$id" ]; then
          continue
        fi

	#
	# Handle both Solaris and Solaris2 IDs
	#
        if [ "$id" -eq 130 -o "$id" -eq 191 ]; then 
           # GRUB uses partition numbering from 0, so adjust
           num=`expr "$num" - 1`
           echo "$num" > "$grp_tmp1"
	   break
        fi
	num=`expr "$num" + 1`

  done < "$grp_tmp2"

  if [ -f "$grp_tmp1" -a -s "$grp_tmp1" ]; then
     /usr/bin/cat "$grp_tmp1"
  else
     ${LUPRINTF} -Eelp2 "`gettext ' No Solaris partition on device <%s>.'`" "${grp_p0}"
     echo ""
  fi

  /bin/rm -f "$grp_tmp1"
  /bin/rm -f "$grp_tmp2"
}

#
# Given a Solaris block slice (/dev/dsk/cNtNdNsN), find
# the corresponding GRUB slice designator (starting from 'a')
#
# Argument: 
#	$1 - A Solaris block slice
# Returns:
#	Slice on standard input
#
grub_slice()
{
  if [ "$#" -ne 1 -o -z "$1" ]; then
     ${LUPRINTF} -Eelp2 "`gettext 'grub_slice(): invalid arguments.'`"
     echo ""
     return
  fi

  grs_bdev="$1"

  grs_slice=`/bin/ls -l "$grs_bdev" | sed 's/.*\(.\)$/\1/g'`

  echo "$grs_slice"
}


get_pbe_config()
{
  gpc_beName="$1"
  gpc_mntpt=""
  if [ -n "$2" ] ; then
    gpc_mntpt="$2"
  fi
  gpc_oosFlag="$3"

  # If in single user mode then there is no "current boot environment"
  # so set the PBE BE ID to "0"
  if [ -n "${gpc_oosFlag}" ] ; then
    PBE_id=0
  else
    # Get the BE ID for the PBE.
    PBE_id="`${LUETCBIN}/ludo get_be_id \"${gpc_beName}\" \"${gpc_mntpt}${LU_LUTAB_FILE}\" 2>&1`"
    if [ "$?" -ne "0" -o -z "${PBE_id}" ] ; then
      [ -n "${PBE_id}" ] && ${LUPRINTF} -elp2 '%s' "${PBE_id}"
      return 1
    fi
  fi
  ${LUPRINTF} -lp2D - "`gettext 'PBE <%s> BE ID is <%s>.'`" "${gpc_beName}" "${PBE_id}"

  # Get the BE block boot device for the PBE.
  PBE_root_bdev="`${LUETCBIN}/lurootdev -m \"${gpc_mntpt}\"`"
  if [ "$?" -ne "0" -o -z "${PBE_root_bdev}" ] ; then
    return 1
  fi
  ${LUPRINTF} -lp2D - "`gettext 'PBE <%s> BE physical boot block device is <%s>.'`" "${gpc_beName}" "${PBE_root_bdev}"

  # Get the logical BE block boot device for the PBE (that is, it may contain a meta device name).
  PBE_root_logical_bdev="`${LUETCBIN}/lurootdev -a -m \"${gpc_mntpt}\"`"
  if [ "$?" -ne "0" -o -z "${PBE_root_logical_bdev}" ] ; then
    return 1
  fi
  ${LUPRINTF} -lp2D - "`gettext 'PBE <%s> BE logical boot block device is <%s>.'`" "${gpc_beName}" "${PBE_root_logical_bdev}"

  # Get the BE character boot device for the PBE.
  PBE_root_cdev=`echo $PBE_root_bdev | sed  "s/\/dsk\//\/rdsk\//g"`
  if [ "$?" -ne "0" -o -z "${PBE_root_cdev}" ] ; then
    return 1
  fi
  ${LUPRINTF} -lp2D - "`gettext 'PBE <%s> BE boot character device is <%s>.'`" "${gpc_beName}" "${PBE_root_cdev}"

  # Get the BE character boot device file system type for the PBE.
  # If in out of service (single user) mode, may not call lulib functions.
  if [ -z "${gpc_oosFlag}" ] ; then
    PBE_root_fstyp="`lulib_fstyp $PBE_root_cdev 2>/dev/null`"
    if [ "$?" -ne "0" -o -z "${PBE_root_fstyp}" ] ; then
      return 1
    fi
  else
    PBE_root_fstyp="`/usr/sbin/fstyp $PBE_root_cdev 2>/dev/null`"
    if [ "$?" -ne "0" -o -z "${PBE_root_fstyp}" ] ; then
      PBE_root_fstyp="ufs"
    fi
  fi
  ${LUPRINTF} -lp2D - "`gettext 'PBE <%s> BE boot character device fstype is <%s>.'`" "${gpc_beName}" "${PBE_root_fstyp}"

  # Get the BE boot character device entire disk access slice for the PBE.
  PBE_boot_disk="`echo $PBE_root_cdev| sed 's/.$/2/g'`"
  if [ "$?" -ne "0" -o -z "${PBE_boot_disk}" ] ; then
    return 1
  fi
  ${LUPRINTF} -lp2D - "`gettext 'PBE <%s> BE boot character device entire disk access slice is <%s>.'`" "${gpc_beName}" "${PBE_boot_disk}"
  
  PBE_root_slice="`echo $PBE_root_cdev| sed 's/.*\(.\)/\1/g'`"
  if [ $? != 0 ] ; then
    return 1
  fi
  case $PBE_root_slice in
    a)	PBE_root_slice=10;;
    b)	PBE_root_slice=11;;
    c)	PBE_root_slice=12;;
    d)	PBE_root_slice=13;;
    e)	PBE_root_slice=14;;
    f)	PBE_root_slice=15;;
  esac

  ${LUPRINTF} -lp2D - "`gettext 'PBE <%s> BE root slice is <%s>.'`" "${gpc_beName}" "${PBE_root_slice}"

  #
  # The rest only applies to x86
  #
  if [ "$LU_SYSTEM_ARCH" != "i386" ]; then
     PBE_boot_method=""
     return 0
  fi

  #
  # Checking if grub boot or DCA boot
  #
  PBE_boot_method=""
  if [ -f "${gpc_mntpt}/$MULTI_BOOT" -a -s "${gpc_mntpt}/$MULTI_BOOT" ]; then
          PBE_boot_method=GRUB
  else
          PBE_boot_method=DCA
  fi 


  ${LUPRINTF} -lp2D - "`gettext 'PBE <%s> boot method is <%s>.'`" "${gpc_beName}" "${PBE_boot_method}"

  if [ "$PBE_boot_method" = "GRUB" ]; then
      ${LUPRINTF} -lp2D - "`gettext 'Checking for GRUB binaries on PBE <%s>'`" "$gpc_beName"
      if [ ! -x "${gpc_mntpt}/${CREATE_RAMDISK}" -o ! -x "${gpc_mntpt}/${GRUB_INSTALL}" ]; then
          ${LUPRINTF} -Eelp2 "`gettext 'Missing GRUB binaries on PBE <%s>'`" "$gpc_beName"
          return 1
      fi
      ${LUPRINTF} -lp2D - "`gettext 'All GRUB binaries present on PBE <%s>'`" "$gpc_beName"
  fi

  #
  # There is no need to determine GRUB root entry if in OOS.
  # We rely on a saved menu.lst to do fallback.
  # Also note that we cannot determine the GRUB disk during
  # OOS since lulib functions are not available
  #
  if [ -n "$gpc_oosFlag" ]; then
     return 0
  fi

  #
  # Get GRUB partition and slice
  #
  PBE_hd=""
  if [ "$PBE_boot_method" = GRUB ]; then
     ${LUPRINTF} -lp2D - "`gettext 'Generating disk, partition and slice information for PBE <%s>'`" "$gpc_beName"
     LU_BOOT_HD=""
     lulib_get_bios_disk "${PBE_root_bdev}"
     if [ -z "$LU_BOOT_HD" ]; then
       	${LUPRINTF} -Eelp2 "`gettext 'Cannot determine GRUB id for PBE disk <%s>'`" "${PBE_root_bdev}"
	return 1
     fi
     PBE_hd="$LU_BOOT_HD"
     PBE_part=`grub_part $PBE_boot_disk`
     PBE_slice=`grub_slice $PBE_root_bdev`
     ${LUPRINTF} -lp2D 5 "`gettext 'PBE GRUB partition=<%s> and slice=<%s>'`" "$PBE_part" "$PBE_slice"

     #
     # Now save the GRUB root value in PBE/etc/lu/GRUB_root file.
     # This file is used to add transient reboot arg entries to
     # menu.lst
     #
    /bin/echo "(${PBE_hd},${PBE_part},${PBE_slice})" > "${gpc_mntpt}/${GRUB_root}"
  fi


  return 0
}

get_abe_config()
{
  gac_beName="$1"
  gac_tmpMnt="/tmp/.luactivate.gac.1.$$"
  gac_tmpFile="/tmp/.luactivate.gac.2.$$"

  # Get the BE ID for the ABE.
  ABE_id=`${LUETCBIN}/ludo get_be_id "${gac_beName}" 2>&1`
  if [ "$?" -ne "0" -o -z "${ABE_id}" ] ; then
    [ -n "${ABE_id}" ] && ${LUPRINTF} -Eelp2 '%s' "${ABE_id}"
    return 1
  fi
  ${LUPRINTF} -lp2D - "`gettext 'ABE <%s> BE ID is <%s>.'`" "${gac_beName}" "${ABE_id}"

  # The BE must not currently be mounted.
  lulib_verify_be_unmounted "${gac_beName}"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to activate boot environment <%s>.'`" "${gac_beName}"
    return 1
  fi

  # Get the BE block boot device for the ABE.
  forceFlag=""
  [ -n "${flag_u}" ] && forceFlag="-f"
  gac_beMntpt="`LU_OUTPUT_FORMAT=text ${LUBIN}/lumount ${forceFlag} \"${gac_beName}\" 2>${TMP_RESULT_FILE}`"
  if [ "$?" -ne "0" -o -z "${gac_beMntpt}" ] ; then
    [ -s "${TMP_RESULT_FILE}" ] && ${LUPRINTF} -elp2 '%R' < "${TMP_RESULT_FILE}"
    /bin/rm -f "${TMP_RESULT_FILE}"
    return 1
  fi
  /bin/rm -f "${TMP_RESULT_FILE}"

  ${LUPRINTF} -lp2D - "`gettext 'Mounted ABE <%s> at <%s>.'`" "${gac_beName}" "${gac_beMntpt}"

  #
  # Checking if grub boot or DCA boot
  #
  ABE_boot_method=""
  if [ "$LU_SYSTEM_ARCH" = "i386" ]; then
      if [ -f "${gac_beMntpt}/$MULTI_BOOT" -a -s "${gac_beMntpt}/$MULTI_BOOT" ]; then
          ABE_boot_method=GRUB
      else
          ABE_boot_method=DCA
      fi
  fi 


  ${LUPRINTF} -lp2D - "`gettext 'ABE <%s> boot method is <%s>.'`" "${gac_beName}" "${ABE_boot_method}"

  #
  # If ABE_boot_method value is GRUB, implies an x86 system
  #
  if [ "$ABE_boot_method" = "GRUB" ]; then
      ${LUPRINTF} -lp2D - "`gettext 'Checking for GRUB binaries on ABE <%s>'`" "$gac_beName"
      if [ ! -x "${gac_beMntpt}/${CREATE_RAMDISK}" -o ! -x "${gac_beMntpt}/${GRUB_INSTALL}" ]; then
          ${LUPRINTF} -Eelp2 "`gettext 'Missing GRUB binaries on ABE <%s>'`" "$gac_beName"
          ${LUBIN}/luumount -f $gac_beName 2>/dev/null
          return 1
      fi
      ${LUPRINTF} -lp2D - "`gettext 'All GRUB binaries found on ABE.'`"
  fi

  # Get the BE physical block boot device for the ABE, and get the
  # logical BE block boot device for the ABE (that is, it may contain a
  # meta device name).

  ABE_root_bdev="`${LUETCBIN}/lurootdev -m \"${gac_beMntpt}\"`"
  ret="$?"
  if [ "${ret}" -eq "0" ] ; then
    ABE_root_logical_bdev="`${LUETCBIN}/lurootdev -a -m \"${gac_beMntpt}\"`"
    ret="$?"
  fi
  ${LUBIN}/luumount -f $gac_beName 2>/dev/null
  if [ "${ret}" -ne "0" -o -z "${ABE_root_bdev}" -o -z "${ABE_root_logical_bdev}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Cannot determine root device for ABE <%s>'`" "${gac_beName}"
    return 1
  fi

  ${LUPRINTF} -lp2D - "`gettext 'ABE <%s> root block device is <%s>.'`" "${gac_beName}" "${ABE_root_bdev}"

  ${LUPRINTF} -lp2D - "`gettext 'ABE <%s> logical root block device is <%s>.'`" "${gac_beName}" "${ABE_root_logical_bdev}"

  ABE_hd=""
  if [ "$ABE_boot_method" = "GRUB" ]; then
     LU_BOOT_HD=""
     lulib_get_bios_disk "${ABE_root_bdev}"
     #
     # NOTE: We need an error message here, because lulib_get_bios_disk()
     # can fail for reasons other biosdev. If the root cause is biosdev
     # lulib_get_bios_disk() will also emit a message.
     #
     if [ -z "$LU_BOOT_HD" ]; then
       	${LUPRINTF} -Eelp2 "`gettext 'Cannot determine GRUB id for ABE disk <%s>'`" "${ABE_root_bdev}"
	return 1
     fi
     ABE_hd="$LU_BOOT_HD"
  fi

  # Get the BE character boot device for the ABE.
  ABE_root_cdev="`lulib_get_cdevice $ABE_root_bdev`"
  if [ "$?" -ne "0" -o -z "${ABE_root_cdev}" ] ; then
    return 1
  fi
  ${LUPRINTF} -lp2D - "`gettext 'ABE <%s> BE root character device is <%s>.'`" "${gac_beName}" "${ABE_root_cdev}"

  # Get the BE character boot device file system type for the ABE.
  ABE_root_fstyp="`lulib_fstyp $ABE_root_cdev 2>/dev/null`"
  if [ "$?" -ne "0" -o -z "${ABE_root_fstyp}" ] ; then
    return 1
  fi
  ${LUPRINTF} -lp2D - "`gettext 'ABE <%s> BE root character device fstype is <%s>.'`" "${gac_beName}" "${ABE_root_fstyp}"

  # Get the BE boot character device entire disk access slice for the ABE.  
  ABE_boot_disk="`echo $ABE_root_cdev| sed 's/s[^s]*$/s2/g'`"
  if [ "$?" -ne "0" -o -z "${ABE_boot_disk}" ] ; then
    return 1
  fi
  ${LUPRINTF} -lp2D - "`gettext 'ABE <%s> BE root character device entire disk access slice is <%s>.'`" "${gac_beName}" "${ABE_boot_disk}"

  ABE_root_slice="`echo $ABE_root_cdev| sed 's/.*s\([^s]*\)/\1/g'`"
  if [ $? != 0 ] ; then
    return 1
  fi
  
  case $ABE_root_slice in
    a)	ABE_root_slice=10;;
    b)	ABE_root_slice=11;;
    c)	ABE_root_slice=12;;
    d)	ABE_root_slice=13;;
    e)	ABE_root_slice=14;;
    f)	ABE_root_slice=15;;
  esac

  ${LUPRINTF} -lp2D - "`gettext 'ABE <%s> root slice is <%s>.'`" "${gac_beName}" "${ABE_root_slice}"

  # Now check if the ABE-Root slice is not mounted and is mountable.
  
  chk_mount $ABE_root_logical_bdev $ABE_root_fstyp "${gac_beName}"
  if [ $? -ne 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'ABE <%s> root slice <%s> is not available.'`" "${gac_beName}" "${ABE_root_logical_bdev}"
    return 1
  fi

  ${LUPRINTF} -lp2D - "`gettext 'ABE: not mounted and mountable.'`"

  if [ "$LU_SYSTEM_ARCH" = "i386" -a "$ABE_boot_method" = GRUB ]; then

     #
     # Get GRUB partition and slice
     #
     ${LUPRINTF} -lp1 "`gettext 'Generating partition and slice information for ABE <%s>'`" "$gac_beName"
     ABE_part=`grub_part $ABE_boot_disk`
     ABE_slice=`grub_slice $ABE_root_bdev`
     ${LUPRINTF} -lp2D - "`gettext 'ABE GRUB partition=<%s> and slice=<%s>.'`" "${ABE_part}" "${ABE_slice}"

     #
     # Now save the GRUB root value in ABE/etc/lu/GRUB_root file.
     # This file is used to add transient reboot arg entries to
     # menu.lst. We checked above that ABE root slice is mountable
     # and is not mounted - so it is safe to mount it now.
     #
     if [ ! -d "$gac_tmpMnt" ]; then
        /bin/mkdir -p "$gac_tmpMnt"
     fi
     /sbin/mount -F "$ABE_root_fstyp" "$ABE_root_logical_bdev" "$gac_tmpMnt" > /dev/null 2>"$gac_tmpFile"
     if [ "$?" -ne 0 ]; then
        /bin/cat "$gac_tmpFile"
        /bin/rm -f "$gac_tmpFile"
        ${LUPRINTF} -Eelp2 "`gettext 'Cannot mount ABE root device <%s> at mount point <%s>.'`" "${ABE_root_logical_bdev}" "${gac_tmpMnt}"
        /bin/rmdir "$gac_tmpMnt"
	return 1
     fi
     /bin/rm -f "$gac_tmpFile"
        
     /bin/echo "(${ABE_hd},${ABE_part},${ABE_slice})" > "${gac_tmpMnt}/${GRUB_root}"

     /sbin/umount "$ABE_root_logical_bdev" 2>"$gac_tmpFile"
     if [ "$?" -ne 0 ]; then
        /bin/cat "$gac_tmpFile"
	/bin/rm -f "$gac_tmpFile"
        ${LUPRINTF} -Eelp2 "`gettext 'Cannot umount ABE root device <%s> at mount point <%s>.'`" "${ABE_root_logical_bdev}" "${gac_tmpMnt}"
	/bin/rmdir "$gac_tmpMnt" > /dev/null 2>&1
	return 1
     fi
     /bin/rm -f "$gac_tmpFile"
     /bin/rmdir "$gac_tmpMnt"
  fi
  
  
  return 0
}

get_be_vtoc()
{
  gbv_beId="$1"
  gbv_beBootDisk="$2"

  ${LUPRINTF} -lp2D - "`gettext 'Getting the vtoc for disk <%s> BE ID <%d>.'`" "${gbv_beBootDisk}" "${gbv_beId}"

  /usr/sbin/prtvtoc -h $gbv_beBootDisk | awk ' { print $1,$2,$3,$4,$5 } ' > /etc/lu/vtoc.$gbv_beId
  if [ $? != 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to obtain vtoc from <%s> for boot environment <%s>.'`" "${gbv_beBootDisk}" "${gbv_beId}"
      exit 2
  fi
}

edit_be_vtoc()
{
  ebv_beId="$1"
  ebv_beRootSlice="$2"
  ebv_tmpVtoc="/tmp/.luactivate.vtoc.$$"
  
  ${LUPRINTF} -lp2D - "`gettext 'Editing the vtoc ROOT tag information for slice <%s> BE ID <%d>.'`" "${ebv_beRootSlice}" "${ebv_beId}"
    
  # Change the existing ROOT tags to 0.
  # ROOT must be read/write so assume 00 in flag field
  awk ' { if ( $2 == "2" ) printf "%s 0 %s %s %s\n",$1,$3,$4,$5
	      else printf "%s %s %s %s %s\n",$1,$2,$3,$4,$5
	      } ' /etc/lu/vtoc.$ebv_beId > $ebv_tmpVtoc 

  # Tag of the slice $ebv_beRootSlice needs to be changed to 0x2
  sed 's/^\([ 	]*'$ebv_beRootSlice'[ 	][ 	]*\)[^ 	]*\(.*\)$/\12\2/g' $ebv_tmpVtoc > /etc/lu/vtoc.$ebv_beId

  /bin/rm -f $ebv_tmpVtoc
}

write_be_vtoc()
{
  wbv_beId="$1"
  wbv_beBootDisk="$2"
  wbv_beName="$3"
  wbv_currBeName="$4"
  wbv_doNotDelay="$5"

  if [ -z "${wbv_doNotDelay}" ] ; then
    # Delay: add proper boot environment changes to delayed update script.
    ${LUPRINTF} -lp2D - "`gettext 'Storing new vtoc information to device <%s> for BE ID <%d> BE <%s> for activate delay update script.'`" "${wbv_beBootDisk}" "${wbv_beId}" "${wbv_beName}"
    /bin/cp /etc/lu/vtoc.$wbv_beId $DELAY_UPD_DIR/vtoc.$wbv_beId.$$
    # Before writing vtoc, verify that the BE can be mounted

    ${LUPRINTF} -lp2D - "`gettext 'Adding boot device vtoc update from BE <%s> to BE ID <%d> BE <%s>.'`" "${wbv_currBeName}" "${wbv_beId}" "${wbv_beName}"

	/bin/cat <<-EOF >> ${DELAY_UPD_SCRIPT}
		#
		# Update i386 vtoc on the boot environment "${wbv_beName}"
		#
		\${LUPRINTF} +X -fl1D - "`gettext 'Live Upgrade: Updating partition ID tag on boot environment <%s> device <%s> to be root slice.'`" "${wbv_beName}" "${wbv_beBootDisk}"
	EOF

    if [ "${wbv_currBeName}" != "${wbv_beName}" ] ; then
	/bin/cat <<-EOF >> ${DELAY_UPD_SCRIPT}
		#
		# Remove root from "${wbv_currBeName}" set root on "${wbv_beName}"
		#
		if [ ! -s "$DELAY_UPD_DIR/vtoc.$wbv_beId.$$" ] ; then
		    \${LUPRINTF} +X -fEel2 "`gettext 'Live Upgrade: New vtoc contents file <%s> missing: the activation is aborted.'`" "$DELAY_UPD_DIR/vtoc.$wbv_beId.$$"
		    exit 1
		fi
		if [ ! -s "/etc/lu/ICF.$wbv_beId" ] ; then
		    \${LUPRINTF} +X -fEel2 "`gettext 'Live Upgrade: Internal Configuration File <%s> missing: the activation is aborted.'`" "/etc/lu/ICF.$wbv_beId"
		    exit 1
		fi
		BE_MOUNT="\`LU_OUTPUT_FORMAT=text ${LUBIN}/lumount -i /etc/lu/ICF.$wbv_beId 2> /dev/null\`"
		if [ "\$?" -ne "0" ] ; then
		    \${LUPRINTF} +X -fEel2 "`gettext 'Live Upgrade: Unable to mount boot environment <%s>: the activation is aborted.'`" "${wbv_beName}"
		    exit 1
		fi
		${LUBIN}/luumount -f -i /etc/lu/ICF.$wbv_beId
	EOF
    fi

	/bin/cat <<-EOF >> ${DELAY_UPD_SCRIPT}
		#
		# Revise vtoc on "${wbv_beBootDisk}"
		#
		/bin/cp /dev/null /tmp/.lu_fmthard_res.$$
		/usr/sbin/fmthard -s $DELAY_UPD_DIR/vtoc.$wbv_beId.$$ $wbv_beBootDisk 2>>/tmp/.lu_fmthard_res.$$ 1>&2
		if [ "\$?" -ne "0" ] ; then
		    \${LUPRINTF} +X -fEel2 "`gettext 'Live Upgrade: Unable to write the vtoc for boot environment <%s> to device <%s>.'`" "${wbv_beName}" "${wbv_beBootDisk}"
		    /bin/cat /tmp/.lu_fmthard_res.$$
		    /bin/rm -f /tmp/.lu_fmthard_res.$$
		    exit 1
		fi
		/bin/rm -f $DELAY_UPD_DIR/vtoc.$wbv_beId.$$
		/bin/rm -f /tmp/.lu_fmthard_res.$$
	EOF

  else
    # Neither delayed update nor oos servicing - apply boot environment changes now.
    ${LUPRINTF} -lp2D - "`gettext 'Updating partition ID tag on boot environment <%s> device <%s> to be root slice.'`" "${wbv_beName}" "${wbv_beBootDisk}"
    /bin/cp /dev/null /tmp/.lu_fmthard_res.$$
    /usr/sbin/fmthard -s /etc/lu/vtoc.$wbv_beId $wbv_beBootDisk >/dev/null 2>>/tmp/.lu_fmthard_res.$$ 1>&2
    if [ $? != 0 ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'Unable to write vtoc to device <%s> boot environment ID <%d> BE <%s>.'`" "${wbv_beBootDisk}" "${wbv_beId}" "${wbv_beName}"
      /bin/cat /tmp/.lu_fmthard_res.$$
      /bin/rm -f /tmp/.lu_fmthard_res.$$
      exit 1
    fi
    /bin/rm -f /tmp/.lu_fmthard_res.$$
  fi
}

write_loader()
{
  wld_bootDisk="$1"
  wld_doNotDelay="$2"
  wld_beName="$3"
  wld_currBeName="$4"

  wld_tmp_file="/tmp/.luactivate.wld.$$"

  ${LUPRINTF} -lp2D - "`gettext 'Storing new loader information to device <%s> BE <%s> for activate delay update script.'`" "${wld_bootDisk}" "${wld_beName}"

  fake_boot="`echo $wld_bootDisk | sed 's/\/dsk\//\/rdsk\//g'`"
  if [ "${LU_SYSTEM_ARCH}" = "sparc" ] ; then
    final_boot="$fake_boot"
  fi
  if [ "${LU_SYSTEM_ARCH}" = "i386" -o "${LU_SYSTEM_ARCH}" = "ppc" ] ; then
    final_boot="`echo $fake_boot | sed 's/s.$/s2/g'`"
  fi
  
  if [ -z "${wld_doNotDelay}" ] ; then
    # Delay: add proper boot environment changes to delayed update script.
    if [ "${LU_SYSTEM_ARCH}" = "sparc" ] ; then
      if [ "$wld_currBeName" != "$wld_beName" ] ; then
	BE_ID="`${LUETCBIN}/ludo get_be_id \"$wld_beName\" 2>&1`"
	if [ $? != 0 ] ; then
	  [ -n "${BE_ID}" ] && ${LUPRINTF} -Eelp2 '%s' "${BE_ID}"
	  ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine boot environment ID for target boot environment <%s>.'`" "${wld_beName}"
	  return 1
	fi

	${LUPRINTF} -lp2D - "`gettext 'Adding sparc boot loader update from BE <%s> to BE <%s> device <%s>.'`" "${wld_currBeName}" "${wld_beName}" "${wld_bootDisk}"

	/bin/cat <<-EOF >> $DELAY_UPD_SCRIPT
		#
		# Switching boot environments on sparc platform: write new bootstrap to disk bootblock
		#
		\${LUPRINTF} +X -fl1D - "`gettext 'Live Upgrade: Updating boot loader for <%s> on boot environment <%s> device <%s> to match OS release.'`" "${LU_HARDWARE_IMPLEMENTATION}" "${wld_beName}" "${final_boot}"
		BE_MOUNT="\`LU_OUTPUT_FORMAT=text ${LUBIN}/lumount -i /etc/lu/ICF.$BE_ID 2> /dev/null\`"
		if [ "\$?" != "0" ] ; then
		    \${LUPRINTF} +X -fEel2 "`gettext 'Live Upgrade: Unable to mount boot environment <%s>: the activation is aborted.'`" "${wld_beName}"
		    exit 1
		fi
		\$BE_MOUNT/usr/sbin/installboot \$BE_MOUNT/usr/platform/${LU_HARDWARE_IMPLEMENTATION}/lib/fs/ufs/bootblk ${final_boot}
		if [ "\$?" != "0" ] ; then
		    \${LUPRINTF} +X -fEel2 "`gettext 'Live Upgrade: Unable to update boot loader for boot environment <%s> on device <%s>: the activation is aborted.'`" "${wld_beName}" "${final_boot}"
		    exit 1
		fi
		${LUBIN}/luumount -f -i /etc/lu/ICF.$BE_ID
	EOF
      fi

	/bin/cat <<-EOF >> $DELAY_UPD_SCRIPT
		\${LUPRINTF} +X -fl1 "`gettext 'Live Upgrade: The boot device for boot environment <%s> is <%s>.'`" "${wld_beName}" "$wld_bootDisk"
	EOF

    fi

    if [ "${LU_SYSTEM_ARCH}" = "i386" ] ; then

      ${LUPRINTF} -lp2D - "`gettext 'Adding i386 boot loader update from BE <%s> to BE <%s> device <%s>.'`" "${wld_currBeName}" "${wld_beName}" "${wld_bootDisk}"

      if [ "$wld_beName" != "$wld_currBeName" ] ; then
	BE_ID="`${LUETCBIN}/ludo get_be_id \"$wld_beName\" 2>&1`"
	if [ $? != 0 ] ; then
	    [ -n "${BE_ID}" ] && ${LUPRINTF} -Eelp2 '%s' "${BE_ID}"
	    ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine boot environment ID for target boot environment <%s>.'`" "${wld_beName}"
	    return 1
	fi

	wld_mntpt=`LU_OUTPUT_FORMAT=text ${LUBIN}/lumount -i /etc/lu/ICF.${BE_ID} 2> $wld_tmp_file`
	if [ "$?" -ne 0 ]; then
           ${LUPRINTF} -Eelp2 "`gettext 'Unable to mount ABE, ID  <%s>.'`" "${BE_ID}"
           /bin/cat "$wld_tmp_file"
           /bin/rm -f "$wld_tmp_file"
           return 1
        fi


	#
        # UNDO any changes made to active flag on hd0 by a prior GRUB activation
	# If switching to DCA boot, if the ABE has a boot partition,
        # set boot partition (if any) on hd0 (boot disk) to active.
        # If the ABE doesn't use a boot partition but is on hd0 (boot disk)
        # then switch active flag to Solaris partition on hd0
        #
        boot_s2=`/bin/echo "$BOOT_RAW_SLICE" | /bin/sed 's/s.$/s2/'`

        /bin/grep -s -v '^#' ${wld_mntpt}/etc/vfstab | /bin/grep "[ 	]/boot[ 	]*pcfs[ 	]" >/dev/null
        if [ "$?" -eq 0 ]; then
	   set_boot_active "$BOOT_RAW_SLICE"  "DELAYED" "NOT_OOS"
	elif [ "$boot_s2" = "$final_boot" ]; then
           set_boot_inactive "$BOOT_RAW_SLICE" "DELAYED" "NOT_OOS"
        fi

        ${LUBIN}/luumount -f -i /etc/lu/ICF.${BE_ID}

        # Do some preprocessing to set active flag
        /bin/echo "$BOOT_RAW_SLICE" | /bin/grep "p0:boot$" > /dev/null 2>&1
        if [ "$?" -eq 0 ]; then
           wld_p0=`/bin/echo "$BOOT_RAW_SLICE" | /bin/sed 's/p0:boot$/p0/g'`
        else
           wld_p0=`/bin/echo "$BOOT_RAW_SLICE" | /bin/sed 's/s.$/p0/g'`
        fi


	/bin/cat <<-EOF >> $DELAY_UPD_SCRIPT
		#
		# Update boot loader for "${wld_beName}" on "${final_boot}"
		#
		\${LUPRINTF} +X -fl1D - "`gettext 'Live Upgrade: Updating boot loader for <%s> on boot environment <%s> device <%s> to match OS release.'`" "${LU_HARDWARE_IMPLEMENTATION}" "${wld_beName}" "${final_boot}"
		BE_MOUNT="\`LU_OUTPUT_FORMAT=text ${LUBIN}/lumount -i /etc/lu/ICF.$BE_ID 2> /dev/null\`"
		if [ "\$?" != "0" ] ; then
		    \${LUPRINTF} +X -fEel2 "`gettext 'Live Upgrade: Unable to mount boot environment <%s>: the activation is aborted.'`" "${wld_beName}"
		    exit 1
		fi
		\$BE_MOUNT/usr/sbin/installboot \$BE_MOUNT/usr/platform/${LU_HARDWARE_IMPLEMENTATION}/lib/fs/ufs/pboot \$BE_MOUNT/usr/platform/${LU_HARDWARE_IMPLEMENTATION}/lib/fs/ufs/bootblk ${final_boot}
		if [ "\$?" != "0" ] ; then
		    \${LUPRINTF} +X -fEel2 "`gettext 'Live Upgrade: Unable to update boot loader for boot environment <%s> on device <%s>: the activation is aborted.'`" "${wld_beName}" "${final_boot}"
		    exit 1
		fi

		# Set boot partition active or inactive as needed
		if [ -f ${DELAY_UPD_DIR}/$MBR -a -s ${DELAY_UPD_DIR}/$MBR ]; then
		   /sbin/fdisk -F ${DELAY_UPD_DIR}/$MBR "$wld_p0" 
		   /bin/rm -f ${DELAY_UPD_DIR}/$MBR
		fi

		${LUBIN}/luumount -f -i /etc/lu/ICF.$BE_ID
	EOF
      fi
	/bin/cat <<-EOF >> $DELAY_UPD_SCRIPT
		\${LUPRINTF} +X -fl1 "`gettext 'Live Upgrade: The boot device for boot environment <%s> is <%s>.'`" "${wld_beName}" "$wld_bootDisk"
	EOF
    fi

  else
    # This function is not called in the context of oos servicing. We handled the delay update case above.
    # This case deals with "flag_u" (called in the context of lucreate)
    ${LUPRINTF} -lp2D - "`gettext 'Updating boot loader for <%s> on boot environment <%s> device <%s> to match OS release.'`" "${LU_HARDWARE_IMPLEMENTATION}" "${wld_beName}" "${wld_bootDisk}"
    if [ "${LU_SYSTEM_ARCH}" = "sparc" ] ; then
      final_boot="$fake_boot"
      if [ "$wld_currBeName" != "$wld_beName" ] ; then
	BE_ID=`${LUETCBIN}/ludo get_be_id "$wld_beName" 2>&1`
	if [ $? != 0 ] ; then
	  [ -n "${BE_ID}" ] && ${LUPRINTF} -Eelp2 '%s' "${BE_ID}"
	  ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine boot environment ID for target boot environment <%s>.'`" "${wld_beName}"
          return 1
	fi

	BE_MOUNT="`LU_OUTPUT_FORMAT=text ${LUBIN}/lumount -i /etc/lu/ICF.$BE_ID 2>${TMP_RESULT_FILE}`"
	if [ $? != 0 ] ; then
	  [ -s "${TMP_RESULT_FILE}" ] && ${LUPRINTF} -elp2 '%R' < "${TMP_RESULT_FILE}"
	  ${LUPRINTF} -Eelp2 "`gettext 'Unable to mount boot environment <%s>.'`" "${wld_beName}"
	  /bin/rm -f "${TMP_RESULT_FILE}"
          return 1
	fi
	/bin/rm -f "${TMP_RESULT_FILE}"

	ERRMSG="`$BE_MOUNT/usr/sbin/installboot $BE_MOUNT/usr/platform/${LU_HARDWARE_IMPLEMENTATION}/lib/fs/ufs/bootblk ${final_boot} 2>&1`"
	if [ $? != 0 ] ; then
	  [ -n "${ERRMSG}" ] && ${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
	  ${LUPRINTF} -Eelp2 "`gettext 'Unable to update boot loader for boot environment <%s> on device <%s>.'`" "${wld_beName}" "${final_boot}"
          return 1
	fi
	${LUBIN}/luumount -f -i /etc/lu/ICF.$BE_ID
      fi
    fi

    if [ "${LU_SYSTEM_ARCH}" = "i386" -o "${LU_SYSTEM_ARCH}" = "ppc" ] ; then
      final_boot="`echo $fake_boot | sed 's/s.$/s2/g'`"
      if [ "$wld_beName" != "$wld_currBeName" ] ; then
	BE_ID=`${LUETCBIN}/ludo get_be_id "$wld_beName" 2>&1`
	if [ $? != 0 ] ; then
	  [ -n "${BE_ID}" ] && ${LUPRINTF} -Eelp2 '%s' "${BE_ID}"
	  ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine boot environment ID for target boot environment <%s>.'`" "${wld_beName}"
          return 1
	fi

	BE_MOUNT="`LU_OUTPUT_FORMAT=text ${LUBIN}/lumount -i /etc/lu/ICF.$BE_ID 2>${TMP_RESULT_FILE}`"
	if [ $? != 0 ] ; then
	  [ -s "${TMP_RESULT_FILE}" ] && ${LUPRINTF} -elp2 '%R' < "${TMP_RESULT_FILE}"
	  ${LUPRINTF} -Eelp2 "`gettext 'Unable to mount boot environment <%s>.'`" "${wld_beName}"
	  /bin/rm -f "${TMP_RESULT_FILE}"
          return 1
	fi
        /bin/rm -f "${TMP_RESULT_FILE}"

	ERRMSG="`$BE_MOUNT/usr/sbin/installboot $BE_MOUNT/usr/platform/${LU_HARDWARE_IMPLEMENTATION}/lib/fs/ufs/pboot $BE_MOUNT/usr/platform/${LU_HARDWARE_IMPLEMENTATION}/lib/fs/ufs/bootblk ${final_boot} 2>&1`"
	if [ $? != 0 ] ; then
	  [ -n "${ERRMSG}" ] && ${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
	  ${LUPRINTF} -Eelp2 "`gettext 'Unable to update boot loader for boot environment <%s> on device <%s>.'`" "${wld_beName}" "${final_boot}"
          return 1
	fi

	#
	# luactivate is called with -u option. Don't attempt to
	# change boot partition's "active" flag
	#

	${LUBIN}/luumount -f -i /etc/lu/ICF.$BE_ID
      fi
    fi       
  fi
  return 0
}

propagate_be_file()
{
  pbf_fileName="$1"

  ${LUPRINTF} -lp2D - "`gettext 'Propagating the file <%s> to all BEs.'`" "${pbf_fileName}"
  # Call luupdall to propagate the file to all BEs.
  ${LUBIN}/luupdall "${pbf_fileName}"
  if [ $? != 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to propagate the file <%s> to all boot environments.'`" "${pbf_fileName}"
    return 1
  fi
  return 0
}
	
################################################################################
# Name:		do_fallback
# Description:	Fallback to previous boot environment (call during single user/maintenance mode only).
# Local Prefix:	<none>
# Arguments:	<none>
# Returns:	0 = successful.
#		1 = failure.
# IMPORTANT NOTES:
#
# do_fallback is called when the system is in single user or maintenance mode;
# there are two primary scenarios:
#
# 1) boot to # mini-root (cdrom, net, alternative disk) to fallback to previous boot environment
# 2) boot single user to current boot environment to fallback to previous boot environment.
#
# In case #1 the live upgrade product is NOT contained within the root file
# system of the currently running system - most probably it is at /mnt but that
# is not guaranteed.
#
# In either case, none of the live upgrade libraries (/usr/lib/lu) or defaults
# (/etc/defaults/lu) have been loaded or are available. ALL calls made within
# this function or in functions called by this function MUST be able to this
# condition.
################################################################################

find_be_mntpt()
{
    foundAnswer=""
    /usr/sbin/mount | /bin/awk '{ print $1, $3}' | while read mntpt bdevice ; do
    if [ -z "${foundAnswer}" -a -f "$mntpt/etc/lu/.CURR_VARS" -a -s "$mntpt/etc/lu/.CURR_VARS" ] ; then
    .  "$mntpt/etc/lu/.CURR_VARS"
    if [ "${BEROOT}" = "${bdevice}" ] ; then
    #Parent BE to fallback found
    gpc_mntpt="$mntpt"
    PBE_root_bdev="`${LUETCBIN}/lurootdev -m \"${gpc_mntpt}\"`"
    ABE_m="`ls -l $bdevice | /bin/sed 's/.*\/devices\//\//g' | sed 's/:.$//g'`"
    PBE_m="`ls -l $PBE_root_bdev | /bin/sed 's/.*\/devices\//\//g' | sed 's/:.$//g'`"
    if [ "$ABE_m" = "$PBE_m" ] ; then
    echo "${mntpt}:$bdevice"
    foundAnswer="yes"
     break
    fi
   fi 
  fi
  done
}

# 
# Mount the GRUB slice (if not already mounted). If the GRUB slice
# has a boot partition mounted off it, unmount the boot partition.
# Note: Don't use the -f flag while umounting boot partition, it
#       will fail (pcfs doesn't support forced unmounts).
#
# Arguments
#	$1 - The logical name for the GRUB slice (may be a /dev/md name)
#	$2 - Name of the results file
#	$3 - A string that indicates if in oos mode (OOS) or not (NOT_OOS)
# Returns
#	1 - on error
#	0 - on success
#	state for unmount_boot_slice() in results file specified in $2
#
mount_boot_slice()
{
      if [ "$#" -ne 3 -o -z "$1" -o -z "$2" -o -z "$3" ]; then
	 ${LUPRINTF} "`gettext 'ERROR: mount_boot_slice(): Invalid arguments.'`"
	 return 1
      fi

      mbs_boot="$1"
      mbs_res="$2"
      mbs_oos="$3"

      mbs_tmp="/tmp/.luactivate.mbs.1.$$"
      mbs_mnted=""
      mbs_mnt=""
      mbs_umnted=""
      mbs_dev=""
      mbs_real=""


      #
      # First mount the boot slice.
      # Boot slice is a /dev path
      #
      mbs_chr="$mbs_boot"
      mbs_boot=`/bin/echo "$mbs_boot" | /bin/sed "s/\/rdsk\//\/dsk\//g"`
      if [ "$?" -ne 0 -o -z "$mbs_boot" ]; then
	 ${LUPRINTF} "`gettext 'ERROR: Cannot determine block device for <%s>.'`" "${mbs_boot}"
	 /usr/bin/rm -f "$mbs_res"
         return 1
      fi

      #
      # mbs_boot could be in the form cXtYdZp0:boot. Change
      # this into the "real" fdisk partition since fstyp doesn't
      # understand the p0:boot name.
      # get_real_boot_partition() only accepts a char device
      # and may be called in OOS mode.
      #
      /bin/echo "$mbs_chr" | /bin/egrep "p0:boot$" > /dev/null 2>&1 
      if [ "$?" -eq 0 ]; then
         mbs_real=`get_real_boot_partition "$mbs_chr"`
      else
         mbs_real="$mbs_chr"
      fi

      if [ "$?" -ne 0 -o -z "$mbs_real" ]; then
	 ${LUPRINTF} "`gettext 'ERROR: Cannot determine real boot partition for <%s>.'`" "${mbs_boot}"
	 /usr/bin/rm -f "$mbs_res"
	 return 1
      fi

      #
      # Maybe called during OOS administration, so check if oos
      # If in OOS mode, don't use lulib functions
      #
      if [ "$mbs_oos" = OOS ]; then
         mbs_fs=`/usr/sbin/fstyp $mbs_real`
      else
         mbs_fs=`lulib_fstyp $mbs_real`
      fi
      if [ "$?" -ne 0 -o -z "$mbs_fs" ]; then
	 ${LUPRINTF} "`gettext 'ERROR: Cannot determine fstype for <%s>.'`" "${mbs_boot}"
	 /usr/bin/rm -f "$mbs_res"
         return 1
      fi

      # Strip off duplicate and trailing /
      if [ "$mbs_boot" != / ]; then
         mbs_boot=`/bin/echo "$mbs_boot" | /bin/sed "s://[/]*:/:g" | /bin/sed "s:/$::g"`
      fi

      #
      # Now check if mbs_boot is already mounted.
      # mbs_boot is a /dev path
      #
      mbs_mnted=""
      mbs_mnt=`/sbin/mount | /bin/nawk -v dev=$mbs_boot ' { if ($3 == dev) {printf("%s\n", $1); exit 6;}}'`
      if [ "$?" -ne 6 ]; then
	 /usr/bin/mkdir -p "$mbs_tmp" 
	 /usr/sbin/mount -F "$mbs_fs" "$mbs_boot" "$mbs_tmp" > /dev/null 2>&1
         if [ "$?" -ne 0 ]; then
	    /usr/bin/rmdir "$mbs_tmp"
	    ${LUPRINTF} "`gettext 'ERROR: Cannot mount <%s>.'`" "${mbs_boot}"
	    /usr/bin/rm -f "$mbs_res"
	    return 1
	 fi
         mbs_mnted=1
         mbs_mnt="$mbs_tmp"
      else
         # Strip off duplicate and trailing /
         if [ "$mbs_mnt" != / ]; then
	    mbs_mnt=`echo $mbs_mnt | /usr/bin/sed 's://[/]*:/:g' | /usr/bin/sed 's:/$::g'` 
	 fi
         if [ "$mbs_mnt" = / ]; then
	    mbs_dev=`/usr/sbin/mount | /usr/bin/nawk -v mnt=/boot ' { if ($1 == mnt) {printf("%s\n", $3); exit 7;}}'`
         else
	    mbs_dev=`/usr/sbin/mount | /usr/bin/nawk -v mnt=${mbs_mnt}/boot ' { if ($1 == mnt) {printf("%s\n", $3); exit 7;}}'`
         fi
         if [ "$?" -eq 7 ]; then
	    #
	    # pcfs does not support forced unmount. So just do a plain umount
	    #
	    /usr/sbin/umount "${mbs_mnt}/boot" > /dev/null 2>&1
	    if [ "$?" -ne 0 ]; then
	       ${LUPRINTF} "`gettext 'ERROR: Cannot umount <%s>.'`" "${mbs_mnt}/boot"
	       /usr/bin/rm -f "$mbs_res"
	       return 1
            fi
	    mbs_umnted=1
	    if [ "$mbs_oos" != OOS ]; then
               ${LUPRINTF} -lp2D - "`gettext 'Unmounted boot partition at <%s>'`" "${mbs_mnt}/boot"
	    fi
	 fi
       fi

       echo "${mbs_mnted}=${mbs_mnt}=${mbs_umnted}=${mbs_dev}" > "$mbs_res"

       return 0
}

#
# Given the output from a prior mount_boot_slice() call
# unmounts the GRUB slice (if it was mounted in mount_boot_slice()
# and mounts the boot partition (if it was unmounted in mount_boot_slice()
#
# Arguments
#	$1  - state from a prior mount_boot_slice()
#	$2  - indicates if invoked during oos (OOS) or not (NOT_OOS)
# Returns
#	Nothing
#
umount_boot_slice()
{

   if [ "$#" -ne 2 -o -z "$1" -o -z "$2" ]; then
      ${LUPRINTF} "`gettext 'ERROR: umount_boot_slice: Invalid arguments.'`"
      return
   fi

   ubs_mnted=`echo $1 | cut -d'=' -f 1`
   ubs_mnt=`echo $1 | cut -d'=' -f 2`
   ubs_umnted=`echo $1 | cut -d'=' -f 3`
   ubs_dev=`echo $1 | cut -d'=' -f 4`

   ubs_oos="$2"

  if [ -n "$ubs_mnted" ]; then
     /usr/sbin/umount "$ubs_mnt" > /dev/null 2>&1
     /usr/bin/rmdir "$ubs_mnt"
     return
  elif [ -n "$ubs_umnted" ]; then
     /usr/sbin/mount -F pcfs "$ubs_dev" "$ubs_mnt"/boot > /dev/null 2>&1
     if [ "$?" -ne 0 ]; then
	${LUPRINTF} "`gettext 'ERROR: Cannot mount boot partition <%s> at <%s>.'`" "$ubs_dev" "${ubs_mnt}/boot"
     elif [ "$ubs_oos" != OOS ]; then
        ${LUPRINTF} -lp2D - "`gettext 'Remounted boot partition at <%s>'`" "${ubs_mnt}/boot"
     fi
  fi

}

do_fallback()
{
  dfb_luupdall=""
  dfb_tmp="/tmp/.luactivate.dfb.1.$$"

  echo ''
  echo "`gettext 'Welcome to the Live Upgrade out of service administration.'`"
  echo "`gettext 'Activating the previous working boot environment.'`"
  echo ''

  yesAnswer="`gettext \"yes\"`"
  noAnswer="`gettext \"no\"`"
  
  ## Now determine to which mount point the root disk of a BE is mounted.
  ## This is done by searching through all of the mount points until <mntpt>/etc/lu/.CURR_VARS
  ## is found - that should be the root slice of the fallback BE.

  dfb_fbinfo="`find_be_mntpt`"

  # Extract the mount point and boot device for the root disk of the BE found.
  dfb_mntpt="`echo ${dfb_fbinfo} | /bin/cut -f1 -d':'`"
  dfb_bdevice="`echo ${dfb_fbinfo} | /bin/cut -f2 -d':'`"

  if [ -z "${dfb_fbinfo}" -o -z "${dfb_mntpt}" -o -z "${dfb_bdevice}" -o ! -s "$dfb_mntpt/etc/lu/.CURR_VARS" -o ! -s "$dfb_mntpt/etc/default/lu" ] ; then
    echo ''
    echo '**********************************************************************'
    echo "`gettext 'Unable to activate the previous working boot environment. You have not mounted the correct root slice containing the previous working boot environment to be activated. Please mount the proper root slice and re-invoke luactivate.'`" | /bin/fold -s -w 75
    echo '**********************************************************************'
    echo ''
    echo "`gettext 'Fallback activation failed.'`"
    return 1
  fi

  # Source in the defaults from the BE to be activated, and set flag that
  # forces the defaults to not be reloaded by a subsequent lu program.

  . ${dfb_mntpt}/etc/default/lu

  # Now, override all of the defaults to operate in this limited
  # single user maintenance mode environment.

  LUBIN="$dfb_mntpt/sbin"

  LU_SYSTEM_ARCH="`/bin/uname -p`"
  LU_HARDWARE_ARCH="`/bin/uname -m`"
  LU_HARDWARE_IMPLEMENTATION="`/bin/uname -i`"

  LU_BE_CONFIG_FILE="$dfb_mntpt/etc/lu/.BE_CONFIG" ; export LU_BE_CONFIG_FILE
  LU_LUTAB_FILE="$dfb_mntpt/etc/lutab" ; export LU_LUTAB_FILE
  COPYLOCK="$dfb_mntpt/etc/lu/COPY_LOCK" ; export COPYLOCK
  CURR_VARS="$dfb_mntpt/etc/lu/.CURR_VARS" ; export CURR_VARS
  ### LU_OPTFS="$dfb_mntpt/etc/lu/optfs" ; export LU_OPTFS
  NEXT_ACTIVE="$dfb_mntpt/etc/lu/.NEXT_ACTIVE" ; export NEXT_ACTIVE
  SYNCKEY="$dfb_mntpt/etc/lu/.SYNCKEY" ; export SYNCKEY

  PATH=${LUBIN}:/etc:/sbin:/usr/bin:/usr/sbin:$PATH ; export PATH

  # Locate luprintf
  if [ -x "${LUETCBIN}/luprintf" ] ; then
    # If luprintf is found, then the only flags turned on are "fold" and
    # "standard output" because it is assumed that in single user mode the
    # simplest output will be preferred. XML output is disabled.
    LUPRINTF="${LUETCBIN}/luprintf +X -f1"
    LUPRINTFN="${LUETCBIN}/luprintf +X -f1n"
  else
    # luprintf is not found - default to echo.
    LUPRINTF='echo'
    LUPRINTFN='echo'
  fi
  
  ## Source in the information about the last (fallback) boot environment:
  ## BEID - i.d. of the boot environment
  ## BENAME - name of the boot environment
  ## BEROOT - root device for the boot environment
  ## BEROOT_FSTYP - "mount" file system type for the BE root device
  ## BEBOOT (x86 only) - the boot slice that was modified for the previous (failed) activation
  ## BELOGICAL (x86 only) - the meta device (if any) encapsulating BEBOOT else same as BEBOOT
  ## BELOG_FSTYP (x86 only) - the filesystem type of BELOGICAL
 
  .  ${CURR_VARS}
  
  ## Make sure that the device found matches what the last (fallback) 
  ## boot environment should be.
  
  if [ "$BEROOT" != "$dfb_bdevice" ] ; then
    # This slice is the root slice of some other BE.
    ${LUPRINTF} ''
    ${LUPRINTF} '%s' '**********************************************************************'
    ${LUPRINTF} ''
    ${LUPRINTF} "`gettext 'ERROR: You mounted device <%s> which is the root slice of some other boot environment. You need to mount device <%s> to mount point <%s> and run luactivate again.'`" "${dfb_bdevice}" "${BEROOT}" "${dfb_mntpt}"
    ${LUPRINTF} ''
    ${LUPRINTF} '%s' '**********************************************************************'
    ${LUPRINTF} ''

    ${LUPRINTF} "`gettext 'Fallback activation failed with errors.'`"
    return 1
  fi

  ## The boot device for this BE matches the root slice for this BE -
  ## Found the correct mount point for the "last active BE". 
  
  ## Confirm with user that fallback should be done.
  
  ${LUPRINTF} "`gettext 'The previous boot environment name is <%s> root is on device <%s>.'`" "${BENAME}" "${BEROOT}"
  /bin/tty -s
  if [ "$?" -eq "0" ] ; then
    theAnswer=""
    while [ "X${theAnswer}" != "X${yesAnswer}" -a "X${theAnswer}" != "X${noAnswer}" ] ; do
      ${LUPRINTFN} "`gettext 'Do you want to fallback to (activate) boot environment <%s> (%s or %s)? '`" "${BENAME}" "${yesAnswer}" "${noAnswer}"
      read theAnswer < `/bin/tty`
      if [ "X${theAnswer}" != "X${yesAnswer}" -a "X${theAnswer}" != "X${noAnswer}" ] ; then
	${LUPRINTF} "`gettext 'ERROR: <%s> is an invalid Choice - valid choices are: <%s> or <%s>.'`" "${theAnswer}" "${yesAnswer}" "${noAnswer}"
      fi
    done
    if [ "X${theAnswer}" != "X${yesAnswer}" ] ; then
      ${LUPRINTF} "`gettext 'Fallback activation cancelled.'`"
      return 1
    fi
  fi

  ${LUPRINTF} "`gettext 'Activating previous boot environment <%s> root is on device <%s>.'`" "${BENAME}" "${BEROOT}"
  
  # dfb_Error: null if no error on fallback; non-null if there is an error
  dfb_Error=""
 
  # For i386, this code switches boot partititions and updates boot path.
  set_boot "$BEROOT" "$dfb_mntpt" "${BENAME}" "yes" "yes"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} "`gettext 'ERROR: Unable to change system boot device to boot from boot environment <%s> device <%s>.'`" "${BENAME}" "${BEROOT}"
    dfb_Error="yes"
  fi
  
  ## Write the old vtoc out to the physical boot disk.
  
  if [ -f "$dfb_mntpt/etc/lu/vtoc.$BEID" -a -s "$dfb_mntpt/etc/lu/vtoc.$BEID" ] ; then
    /bin/cp /dev/null /tmp/.lu_fmthard_res.$$
    ${LUPRINTF} "`gettext 'Updating partition ID tag on boot environment <%s> device <%s> to be root slice.'`" "${BENAME}" "${BEROOT}"
    /usr/sbin/fmthard -s $dfb_mntpt/etc/lu/vtoc.$BEID $BEDISK 2>>/tmp/.lu_fmthard_res.$$ 1>&2
    if [ "$?" -ne "0" ] ; then
      ${LUPRINTF} "`gettext 'ERROR: Unable to write vtoc to device <%s> boot environment id <%s> BE <%s>.'`" "${BEDISK}" "${BEID}" "${BENAME}"
      /bin/cat /tmp/.lu_fmthard_res.$$
      dfb_Error="yes"
    fi
    /bin/rm -f /tmp/.lu_fmthard_res.$$
  else
    ${LUPRINTF} "`gettext 'WARNING: no vtoc image available to update device <%s> boot environment id <%s> BE <%s>.'`" "${BEDISK}" "${BEID}" "${BENAME}"
  fi
  
  ## Write out a new boot loader to the physical disk.
  
  if [ "${LU_SYSTEM_ARCH}" = "sparc" -a -f "$dfb_mntpt/$DELAY_UPD_DIR/bootblk" ] ; then
    ${LUPRINTF} "`gettext 'Updating boot loader on boot environment <%s> device <%s> to match OS release.'`" "${BENAME}" "${BEDISK}"
    /usr/sbin/installboot $dfb_mntpt/$DELAY_UPD_DIR/bootblk ${BEDISK}
    if [ "$?" -ne "0" ] ; then
      ${LUPRINTF} "`gettext 'ERROR: Unable to update boot loader for boot environment <%s> on device <%s>.'`" "${BENAME}" "${BEDISK}"
      dfb_Error="yes"
    fi
  elif [ "${LU_SYSTEM_ARCH}" = "i386" ] ; then
    if [ -f "$dfb_mntpt/$DELAY_UPD_DIR/bootblk" -a -f "$dfb_mntpt/$DELAY_UPD_DIR/pboot" ] ; then

      ${LUPRINTF} "`gettext 'Updating boot loader on boot environment <%s> device <%s> to match OS release.'`" "${BENAME}" "${BEDISK}"
      # Installboot may not be present on GRUB boot BEs, so use a saved copy
      $dfb_mntpt/$DELAY_UPD_DIR/installboot $dfb_mntpt/$DELAY_UPD_DIR/pboot $dfb_mntpt/$DELAY_UPD_DIR/bootblk ${BEDISK}
      if [ "$?" -ne "0" ] ; then
	${LUPRINTF} "`gettext 'ERROR: Unable to update boot loader for boot environment <%s> on device <%s>.'`" "${BENAME}" "${BEDISK}"
	dfb_Error="yes"
      fi

	#
        # UNDO any changes made to active flag on hd0 by a prior GRUB activation
	# If reverting to DCA boot, if the fallback BE has a boot partition,
        # set boot partition (if any) on hd0 (boot disk) to active.
        # If the ABE doesn't use a boot partition but is on hd0 (boot disk)
        # then switch active flag to Solaris partition on hd0
        #
      boot_s2=`/bin/echo "$BEBOOT" | /bin/sed 's/s.$/s2/'`
      /bin/grep -s -v '^#' ${dfb_mntpt}/etc/vfstab | /bin/grep "[ 	]/boot[ 	]*pcfs[ 	]" >/dev/null
      if [ "$?" -eq 0 ]; then
         set_boot_active "$BEBOOT" "NOW" "OOS"
      elif [ "$boot_s2" = "$BEDISK" ]; then
         set_boot_inactive "$BEBOOT" "NOW" "OOS"
      fi 

    elif [ -f "$dfb_mntpt/$DELAY_UPD_DIR/installgrub" ]; then
      # The PBE aka fallback BE is a GRUB BE
      old=`pwd`

      cd  "$dfb_mntpt/$DELAY_UPD_DIR"
      ./installgrub ./stage1 ./stage2  "$BEBOOT"
      if [ "$?" -ne 0 ] ; then
	${LUPRINTF} "`gettext 'ERROR: Unable to install GRUB for boot environment <%s> on device <%s>.'`" "${BENAME}" "${BEBOOT}"
	dfb_Error="yes"
      fi
      cd $old

      # Set the boot menu default to the fallback BE      
      # Ignore any errors
      /bin/rm -f "$dfb_tmp"
      mount_boot_slice "$BELOGICAL" "$dfb_tmp" "OOS"
      if [ ! -f "$dfb_tmp" -o ! -s "$dfb_tmp" ]; then
	${LUPRINTF} "`gettext 'WARNING: Cannot mark BE <%s> as default in GRUB menu on device <%s>.'`" "${BENAME}" "${BEBOOT}"
      else
      	state=`/bin/cat "$dfb_tmp"`
      	mntpt=`/bin/echo "$state" | /bin/cut -d '=' -f2`
      	/bin/cp -p "${dfb_mntpt}/${DELAY_UPD_DIR}/${PBE_BOOT_MENU_FILE}" ${mntpt}/${BOOT_MENU} 
      	/bin/cp -p "${dfb_mntpt}/${DELAY_UPD_DIR}/${PBE_BOOT_MENU_FILE}" ${dfb_mntpt}/${GRUB_backup_menu} 
	dfb_luupdall="yes"
	# If GRUB slice has a ufs filesystem, roll the log
	if [ "$BELOG_FSTYP" = ufs ]; then
	   /usr/sbin/lockfs -f "$mntpt"
	fi
      	umount_boot_slice "$state" "OOS"
	/bin/rm -f "$dfb_tmp"
      fi

      /bin/echo "$BEBOOT" | /bin/egrep "p0:boot$" > /dev/null 2>&1
      if [ "$?" -eq 0 ]; then
	 set_boot_active "$BEBOOT" "NOW" "OOS"
      else
         set_boot_inactive "$BEBOOT" "NOW" "OOS"
      fi
    fi
  else
    ${LUPRINTF} "`gettext 'WARNING: no boot loader available to update device <%s> boot environment id <%s> BE <%s>.'`" "${BEDISK}" "${BEID}" "${BENAME}"
  fi

  ## If the activation was successful, remove all of the files that setup
  ## the system to activate the new boot environment so that if the admin
  ## uses either 'init' or 'shutdown' the new boot environment will not 
  ## be mistakenly reactivated.

  if [ -z "$dfb_Error" ] ; then
    /bin/rm -f ${NEXT_ACTIVE} ${SYNCKEY} ${CURR_VARS} ${COPYLOCK} 2>/dev/null
    /bin/rm -f ${dfb_mntpt}/$DELAY_UPD_DIR/vtoc.* 2>/dev/null
    /bin/rm -f ${dfb_mntpt}/$DELAY_UPD_SCRIPT 2>/dev/null
    /bin/rm -f ${dfb_mntpt}/$DELAY_UPD_SCRIPT_EXEC 2>/dev/null
    /bin/rm -f ${dfb_mntpt}/${DELAY_UPD_DIR}/${MBR} 2>/dev/null
    /bin/rm -f ${dfb_mntpt}/${DELAY_UPD_DIR}/${BOOT_MENU_FILE} 2>/dev/null
    /bin/rm -f ${dfb_mntpt}/${DELAY_UPD_DIR}/${PBE_BOOT_MENU_FILE} 2>/dev/null
    /bin/rm -f ${dfb_mntpt}/${DELAY_UPD_DIR}/installgrub 2>/dev/null
    /bin/rm -f ${dfb_mntpt}/${DELAY_UPD_DIR}/stage1 2>/dev/null
    /bin/rm -f ${dfb_mntpt}/${DELAY_UPD_DIR}/stage2 2>/dev/null
    /bin/rm -f ${dfb_mntpt}/${DELAY_UPD_DIR}/installboot 2>/dev/null
  fi

  ## Activation should be done...
  
  if [ -z "$dfb_Error" ] ; then
    ${LUPRINTF} ''
    ${LUPRINTF} '%s' '**********************************************************************'
    ${LUPRINTF} ''
    ${LUPRINTF} "`gettext 'Successfully activated the previous working boot environment <%s>. You can unmount the root device of the previous working boot environment (via <umount %s>) and reboot the system.'`" "${BENAME}" "${dfb_mntpt}"
    if [ -n "$dfb_luupdall" ]; then
       ${LUPRINTF} ''
       ${LUPRINTF} "`gettext 'After rebooting to the previous working boot environment <%s>, run the following command to update backup menu: /usr/lib/lu/luupdall ${GRUB_backup_menu}.'`" "${BENAME}"
    fi
    ${LUPRINTF} ''
    ${LUPRINTF} '%s' '**********************************************************************'
    ${LUPRINTF} ''
    ${LUPRINTF} "`gettext 'Fallback activation successful.'`"
    return 0
  fi

  # If the following error is displayed to user then it would
  # be better to reinstall the machine, then try out some thing
  # else. We have lost both PBE and ABE.
  ${LUPRINTF} ''
  ${LUPRINTF} '%s' '**********************************************************************'
  ${LUPRINTF} ''
  ${LUPRINTF} "`gettext 'ERROR: Unable to activate the previous working boot environment <%s>. You must repair any problems reported and try activating the boot environment again, or reinstall the system software.'`" "${BENAME}"
  ${LUPRINTF} ''
  ${LUPRINTF} '%s' '**********************************************************************'
  ${LUPRINTF} ''
  ${LUPRINTF} "`gettext 'Fallback activation failed with errors.'`"
  return 1
}

disp_fallback_info()
{
  
  # target would be the Config Asst disk number of previous boot disk.
  # Since eeprom must be changed on a failed BE boot, we can't
  # instruct the user to use Config Asst to direct the boot since
  # conf asst will just use the bootdev in eeprom.
  ABEmaj="`ls -l $ABE_root_bdev | /bin/sed 's/.*\/devices\//\//g' | sed 's/:.$//g'`"
  PBEmaj="`ls -l $PBE_root_bdev | /bin/sed 's/.*\/devices\//\//g' | sed 's/:.$//g'`"
  
  ${LUPRINTF} ''
  ${LUPRINTF} '%s' '**********************************************************************'
  ${LUPRINTF} ''

  ${LUPRINTF} -f1 '%s' "`gettext 'In case of a failure while booting to the target BE, the following process needs to be followed to fallback to the currently working boot environment:'`"
  ${LUPRINTF} ''

  if [ "$ABEmaj" = "$PBEmaj" ] ; then
      if [ "${LU_SYSTEM_ARCH}" = "sparc" ] ; then
	# sparc with 2 BEs on same disk

	### -->1. Enter the PROM monitor (ok prompt).
	### -->
	### -->2. Boot the machine to Single User mode using a different boot device (like the Solaris Install CD or Network). Examples:
	### -->
	### -->     At the PROM monitor (ok prompt):
	### -->     For boot to Solaris CD:  boot cdrom -s
	### -->     For boot to network:     boot net -s
	### -->
	### -->3. Mount the Current BE root slice to some directory (like /mnt). You can use the following command to mount:
	### -->
	### -->     mount -FPBE_root_fstyp PBE_root_bdev /mnt
	### -->
	### -->4. Run <luactivate> utility with out any arguments from the current BE root slice, as shown below:
	### -->
	### -->     /mnt/sbin/luactivate
	### -->
	### -->5. luactivate, activates the previous working boot environment and indicates the result.
	### -->
	### -->6. Exit Single User mode and reboot the machine.

	${LUPRINTF} -f1 "`gettext '1. Enter the PROM monitor (ok prompt).\\n\\n2. Boot the machine to Single User mode using a different boot device (like the Solaris Install CD or Network). Examples:\\n\\n     At the PROM monitor (ok prompt):\\n     For boot to Solaris CD:  boot cdrom -s\\n     For boot to network:     boot net -s\\n\\n3. Mount the Current boot environment root slice to some directory (like /mnt). You can use the following command to mount:\\n\\n     mount -F%s %s /mnt\\n\\n4. Run <luactivate> utility with out any arguments from the current boot environment root slice, as shown below:\\n\\n     /mnt/sbin/luactivate\\n\\n5. luactivate, activates the previous working boot environment and indicates the result.\\n\\n6. Exit Single User mode and reboot the machine.'`" "$PBE_root_fstyp" "$PBE_root_bdev"
      else
	# x86 with 2 BEs on same disk

	### -->1. Do *not* change hard disk order in the BIOS 
	### -->
	### -->2. Boot from the Solaris Install CD or Network
	### -->and bring the system to Single User mode.
	### -->
	### -->3. Mount the Parent BE root slice to some directory (like /mnt). You can 
	### -->use the following command to mount:
	### -->
	### -->     mount -F$PBE_root_fstyp $PBE_root_bdev /mnt
	### -->
	### -->4. Run <luactivate> utility with out any arguments from the Parent BE 
	### -->root slice, as shown below:
	### -->
	### -->     /mnt/sbin/luactivate
	### -->
	### -->5. luactivate, activates the previous working boot environment and 
	### -->indicates the result.
	### -->
	### -->6. Exit Single User mode and reboot the machine.
	### -->

        ${LUPRINTF} -f1 "`gettext '1. Do *not* change *hard* disk order in the BIOS.\\n\\n2. Boot from the Solaris Install CD or Network and bring the system to Single User mode.\\n\\n3. Mount the Parent boot environment root slice to some directory (like /mnt). You can use the following command to mount:\\n\\n     mount -F%s %s /mnt\\n\\n4. Run <luactivate> utility with out any arguments from the Parent boot environment root slice, as shown below:\\n\\n     /mnt/sbin/luactivate\\n\\n5. luactivate, activates the previous working boot environment and indicates the result.\\n\\n6. Exit Single User mode and reboot the machine.\\n\\n'`" "$PBE_root_fstyp" "$PBE_root_bdev"
      fi
  else
    if [ "${LU_SYSTEM_ARCH}" = "sparc" ] ; then
      # sparc with 2 BEs on different disks

      ### -->1. Enter the PROM monitor (ok prompt).
      ### -->
      ### -->2. Change the boot device back to the original BE by typing:
      ### -->
      ### -->     setenv boot-device 
      ### -->
      ### -->3. Boot to the original BE by typing:
      ### -->
      ### -->     boot

      ${LUPRINTF} -f1 "`gettext '1. Enter the PROM monitor (ok prompt).\\n\\n2. Change the boot device back to the original boot environment by typing:\\n\\n     setenv boot-device %s\\n\\n3. Boot to the original boot environment by typing:\\n\\n     boot'`" "`/etc/lib/lu/lubootdev -n $PBE_root_bdev`"
    else
      #
      # x86 with 2 BEs on different disks
      # same instructions as the 1 disk case
      #
	   ${LUPRINTF} -f1 "`gettext '1. Do *not* change *hard* disk order in the BIOS.\\n\\n2. Boot from the Solaris Install CD or Network and bring the system to Single User mode.\\n\\n3. Mount the Parent boot environment root slice to some directory (like /mnt). You can use the following command to mount:\\n\\n     mount -F%s %s /mnt\\n\\n4. Run <luactivate> utility with out any arguments from the Parent boot environment root slice, as shown below:\\n\\n     /mnt/sbin/luactivate\\n\\n5. luactivate, activates the previous working boot environment and indicates the result.\\n\\n6. Exit Single User mode and reboot the machine.\\n\\n'`" "$PBE_root_fstyp" "$PBE_root_bdev"

    fi
  fi

  ${LUPRINTF} ''
  ${LUPRINTF} '%s' '**********************************************************************'
  ${LUPRINTF} ''
}

disp_activate_info()
{
  ${LUPRINTF} ''
  ${LUPRINTF} '%s' '**********************************************************************'
  ${LUPRINTF} ''
  ${LUPRINTF} -f1 "`gettext 'The target boot environment has been activated. It will be used when you reboot. NOTE: You MUST NOT USE the reboot, halt, or uadmin commands. You MUST USE either the init or the shutdown command when you reboot. If you do not use either init or shutdown, the system will not boot using the target BE.'`"
}



#
# This function checks for the presence of an "active" x86 boot
# partition on the disk. If one exists, it is made inactive
# and the Solaris partition is made active instead 
#
# Arguments:
#	$1 - Physical disk slice (may not be a /dev/md name)
#	$2 - when to update (NOW or DELAYED)
#	$3 - Indicates if in oos mode (OOS or NOT_OOS)
# Returns:
#	Nothing 
#
set_boot_inactive()
{

  if [ "$#" -ne 3 -o -z "$1" -o -z "$2" -o -z "$3" ]; then
     ${LUPRINTF} "`gettext 'ERROR: set_boot_inactive(): Invalid arguments.'`"
     return
  fi

  dab_raw_slice="$1"
  dab_when="$2"
  dab_oos="$3"

  dab_tmp1=/tmp/.luactivate.dab.1.$$
  dab_tmp2=/tmp/.luactivate.dab.2.$$

  #
  # dab_raw_slice is a /dev path
  #
  /bin/echo "$dab_raw_slice" | /bin/egrep "p0:boot$" > /dev/null 2>&1
  if [ "$?" -eq 0 ]; then
     dab_p0=`/bin/echo "$dab_raw_slice" | /bin/sed 's/p0:boot$/p0/g'`
  else
     dab_p0=`/bin/echo "$dab_raw_slice" | /bin/sed 's/s.$/p0/g'`
  fi

  /sbin/fdisk -W "$dab_tmp1" "$dab_p0"
  /bin/grep -v \* "$dab_tmp1" | /bin/grep -v '^[	 ]*$' > "$dab_tmp2"
  /bin/rm -f "$dab_tmp1"
  if [ "$dab_oos" != OOS ]; then
     ${LUPRINTF} -lp2D 8 "`gettext 'Read fdisk table for <%s>.'`" "${dab_p0}"
  fi

  #
  # if there is a boot partition on hd? and it is active, make the Solaris
  # partion active.
  #
  /bin/awk ' { if ( $1 == "190" && $2 == "128" ) exit 9; } ' "$dab_tmp2"
  ret1="$?"
  /bin/awk ' { if ( $1 == "130" || $1 == "191" ) exit 10; } ' "$dab_tmp2"
  ret2="$?"
  if [ "$ret1" -eq 9 -a "$ret2" -eq 10 ]; then
    if [ "$dab_oos" != OOS ]; then
       ${LUPRINTF} -lp2D - "`gettext 'Active boot partition found on boot disk <%s>.'`" "${dab_p0}"
    fi
    /bin/awk '{ if ( $1 == "190" ) printf "%s 0 %s %s %s %s %s %s %s %s\n", $1, $3, $4, $5, $6, $7, $8, $9, $10
                else if ( $1 == "130" ) printf "%s 128 %s %s %s %s %s %s %s %s\n", $1, $3, $4, $5, $6, $7, $8, $9, $10
                else if ( $1 == "191" ) printf "%s 128 %s %s %s %s %s %s %s %s\n", $1, $3, $4, $5, $6, $7, $8, $9, $10
                else printf "%s %s %s %s %s %s %s %s %s %s\n", $1, $2, $3, $4, $5, $6, $7, $8, $9, $10
              } ' "$dab_tmp2" > "$dab_tmp1"

    if [ "$dab_oos" != OOS ]; then
       ${LUPRINTF} -lp2D - "`gettext 'Generated fdisk table with deactivated boot partition.'`"
    fi
    if [ "$dab_when" = DELAYED ]; then
	/bin/cp "$dab_tmp1" $DELAY_UPD_DIR/$MBR
        if [ "$dab_oos" != OOS ]; then
           ${LUPRINTF} -lp2D - "`gettext ' Created function for delayed update of fdisk table <%s>.'`" "${dab_p0}"
	fi
    elif [ "$dab_when" = NOW ]; then
        /sbin/fdisk -F "$dab_tmp1" "$dab_p0"
        if [ "$dab_oos" != OOS ]; then
           ${LUPRINTF} -lp2D 8 "`gettext 'Updated fdisk table with deactivated boot partition.'`"
	fi
    fi
  fi

  /bin/rm -f "$dab_tmp1"
  /bin/rm -f "$dab_tmp2"
}

#
# NOTE: This function should only use files in /, since it may be
# called during OOS administration
#
# If there is a "active" Solaris fdisk partition and x86 boot partition
# make the boot partition active
#
# Arguments
#	$1  - Physical GRUB slice (i.e. cannot be /dev/md names
#	$2  - When update should occur: NOW or DELAYED
#	$3  - Is this oos mode (OOS or NOT_OOS)
# Returns
#	Nothing
#
set_boot_active()
{

  if [ "$#" -ne 3 -o -z "$1" -o -z "$2" -o -z "$3" ]; then
     ${LUPRINTF} "`gettext 'ERROR: set_boot_active(): Invalid arguments.'`"
     return
  fi

  acb_raw_slice="$1"
  acb_when="$2"
  acb_oos="$3"

  acb_tmp1=/tmp/.luactivate.acb.1.$$
  acb_tmp2=/tmp/.luactivate.acb.2.$$

  #
  # acb_raw_slice is a /dev path
  #
  /bin/echo "$acb_raw_slice" | /bin/grep "p0:boot$" > /dev/null 2>&1
  if [ "$?" -eq 0 ]; then
     acb_p0=`/bin/echo "$acb_raw_slice" | /bin/sed 's/p0:boot$/p0/g'`
  else
     acb_p0=`/bin/echo "$acb_raw_slice" | /bin/sed 's/s.$/p0/g'`
  fi

  /sbin/fdisk -W "$acb_tmp1" "$acb_p0"
  /bin/grep -v \* "$acb_tmp1" | /bin/grep -v '^[ 	]*$' > "$acb_tmp2"
  /bin/rm -f "$acb_tmp1"
  if [ "$acb_oos" != OOS ]; then
     ${LUPRINTF} -lp2D - "`gettext 'Read fdisk table for <%s>.'`" "${acb_p0}"
  fi

  #
  # If there is an instance of Solaris on the disk that is active AND there is a boot partition
  # make the boot partition active
  #
  /bin/awk ' { if ( $1 == "130" && $2 == "128" ) exit 10
               else if ( $1 == "191" && $2 == "128" ) exit 10
             } ' "$acb_tmp2"
  if [ "$?" -eq 10 ]; then
     if [ "$acb_oos" != OOS ]; then
        ${LUPRINTF} -lp2D - "`gettext 'Active Solaris partition.'`"
     fi
     /bin/awk ' { if ( $1 == "190" && $2 == "0" ) exit 11; }  ' "$acb_tmp2"
     if [ "$?" -eq 11 ]; then
        if [ "$acb_oos" != OOS ]; then
           ${LUPRINTF} -lp2D - "`gettext 'Active Solaris partition and inactive Boot partition.'`"
	fi
        /bin/awk ' { if ( $1 == "190" ) printf "%s 128 %s %s %s %s %s %s %s %s\n", $1, $3, $4, $5, $6, $7, $8, $9, $10
		  else if ( $1 == "130" ) printf "%s 0 %s %s %s %s %s %s %s %s\n", $1, $3, $4, $5, $6, $7, $8, $9, $10
		  else if ( $1 == "191" ) printf "%s 0 %s %s %s %s %s %s %s %s\n", $1, $3, $4, $5, $6, $7, $8, $9, $10
		  else printf "%s %s %s %s %s %s %s %s %s %s\n", $1, $2, $3, $4, $5, $6, $7, $8, $9, $10
	        } ' "$acb_tmp2" > "$acb_tmp1"
        if [ "$acb_oos" = OOS ]; then
           ${LUPRINTF} "`gettext 'Generated fdisk table with active boot partition.'`"
	else
           ${LUPRINTF} -lp1 "`gettext 'Generated fdisk table with active boot partition.'`"
	fi
        if [ "$acb_when" = DELAYED ]; then 
          /bin/cp "$acb_tmp1" ${DELAY_UPD_DIR}/$MBR
          if [ "$acb_oos" != OOS ]; then
             ${LUPRINTF} -lp2D - "`gettext ' Created MBR for delayed set active for fdisk <%s>.'`" "${acb_p0}"
	  fi
        elif [ "$acb_when" = NOW ]; then
	  /sbin/fdisk -F "$acb_tmp1" "$acb_p0"
          if [ "$acb_oos" != OOS ]; then
             ${LUPRINTF} -lp2D 5 "`gettext 'Updated fdisk table with active boot partition.'`"
	  fi
        fi
      fi
  fi

  /bin/rm -f "$acb_tmp1"
  /bin/rm -f "$acb_tmp2"
}


#
# This function sets up the menu.lst for GRUB
#
# NOTE: Rolling the log
# =====================
# Since GRUB cannot roll the UFS log, we must ensure
# that any UFS filesystem entity read by GRUB has its log
# entries rolled before GRUB gets to look at it.
# There are currently 4 such entities:
#
# 1. menu.lst
# 2. multiboot binary
# 3. boot archive
# 4. failsafe archive
# 
# Of these, the boot archive case is already handled by the script
# that creates the boot archive. The multiboot binaries (normal
# and failsafe) are installed by either lucreate or luupgrade.
# Since these scripts have to be followed by an luactivate
# (which invokes the boot archive creation script which rolls
# log for the same filesystem) multiboot is not an issue
# The same applies to the failsafe archive.
# Thus the only entity that needs its log entry rolled is
# menu.lst. We handle this case here and in other functions in
# luactivate by using lockfs
#
#
# Arguments:
#	$1 - The GRUB slice mountpoint
#	$2 - The ABE name
#	$3 - The PBE name
#	$4 - When the menu update actually happens (NOW or DELAYED)
#
# Returns:
#	Nothing
#
setup_menu()
{
  if [ "$#" -ne 4 -o -z "$1" -o -z "$2" -o -z "$3" -o -z "$4" ]; then
     ${LUPRINTF} -Eelp2 "`gettext 'setup_menu(): Invalid arguments.'`"
     return
  fi

  setm_bslice_mntpt="$1"
  setm_ABEname="$2"
  setm_PBEname="$3"
  setm_when="$4"

  setm_boot_menu="${setm_bslice_mntpt}"/"${BOOT_MENU}"
  setm_tmp_menu="/tmp/.luactivate.setm.1.$$"
  setm_tmp_menu2="/tmp/.luactivate.setm.2.$$"
  setm_tmp_menu3="/tmp/.luactivate.setm.3.$$"

  if [ -f "$setm_boot_menu" -a -s "$setm_boot_menu" ]; then
  	/bin/cp -p "$setm_boot_menu" "$setm_tmp_menu"
        ${LUPRINTF} -lp1 "`gettext 'Boot menu exists.'`"
  else
	/bin/touch "$setm_tmp_menu"
        ${LUPRINTF} -lp1 "`gettext 'No boot menu exists. Creating  new menu file '`"
  fi
  ${LUPRINTF} -lp2D - "`gettext 'Created tmp menu file at <%s>'`" "${setm_tmp_menu}"


  # Install the ABE entries. If the entry already exists, we remove
  # it and recreate it. This is so that future changes in the entry
  # added by Live Upgrade can be accomodated.

  #
  # Escape any special characters in BE name written to the menu so that egrep and awk don't choke
  #
  setm_ABEfixedname=`lulib_fix_name $setm_ABEname`

  fixed_menu_hdr="${BOOT_MENU_PREFIX}${setm_ABEfixedname}${BOOT_MENU_HDR_SUFFIX}"
  fixed_menu_ftr="${BOOT_MENU_PREFIX}${setm_ABEfixedname}${BOOT_MENU_FTR_SUFFIX}"
  if [ "$ABE_boot_method" = GRUB ]; then
       /bin/grep "$fixed_menu_hdr" "$setm_tmp_menu" > /dev/null 2>&1
       if [ "$?" -eq 0 ]; then
	  entry_exists=1
	  start=`/usr/bin/awk "/^$fixed_menu_hdr\$/ { print NR }" "$setm_tmp_menu"`
	  stop=`/usr/bin/awk "/^$fixed_menu_ftr\$/ { print NR }" "$setm_tmp_menu"`
	  if [ -z "$stop" ]; then
	     stop=`expr $start + ${LU_GRUB_ENTRY_LEN} - 1`
	  fi
	  /bin/nawk -v "hdr=$start" "NR < hdr {print}" "$setm_tmp_menu" > "$setm_tmp_menu2"
	  /bin/nawk -v "ftr=$stop" "NR > ftr {print}" "$setm_tmp_menu" > "$setm_tmp_menu3"
	  /bin/cp -p "$setm_tmp_menu2" "$setm_tmp_menu"
       else
	  entry_exists=""
       fi

       # Write the header
       echo "${BOOT_MENU_PREFIX}${setm_ABEname}${BOOT_MENU_HDR_SUFFIX}" >> "$setm_tmp_menu"
       echo "$LU_GRUB_ITEM_SEP"  >> "$setm_tmp_menu"

       # Write the entries
       echo title "$setm_ABEname" >> "$setm_tmp_menu"
       echo root "(${ABE_hd},${ABE_part},${ABE_slice})" >> "$setm_tmp_menu" 
       echo kernel "/${MULTI_BOOT}"  >> "$setm_tmp_menu"
       echo module "/${BOOT_ARCHIVE}"  >> "$setm_tmp_menu"
       echo "$LU_GRUB_ITEM_SEP"  >> "$setm_tmp_menu"

       #
       # Install the failsafe archives . This is nothing but
       # the install miniroot. The install always happens in 32 bit
       # so the miniroot has no 64 bit binaries. When booting the
       # miniroot, use only the 32 bit kernel (kernel/unix)
       # The kernel/unix arg to multiboot should precede other options
       #
       echo title "$setm_ABEname" "failsafe" >> "$setm_tmp_menu"
       echo root "(${ABE_hd},${ABE_part},${ABE_slice})" >> "$setm_tmp_menu" 
       echo kernel "/${FAILSAFE_MULTI_BOOT} kernel/unix -s"  >> "$setm_tmp_menu"
       echo module "/${LU_FAILSAFE_ARCHIVE}"  >> "$setm_tmp_menu"
       echo "$LU_GRUB_ITEM_SEP"  >> "$setm_tmp_menu"

       echo "${BOOT_MENU_PREFIX}${setm_ABEname}${BOOT_MENU_FTR_SUFFIX}" >> "$setm_tmp_menu"

       if [ -n "$entry_exists" ]; then
          /bin/cat "$setm_tmp_menu3" >> "$setm_tmp_menu"
       fi

       #
       # Check if a timeout value is already set. If it has been, leave it alone
       # NOTE: the timeout command must precede actual entries
       # NOTE: The syntax "timeout=value" (instead of "timeout value") also works
       #       (but is not documented in GRUB). We handle that form as well
       #
       /bin/egrep "^[ 	]*${LU_GRUB_TIMEOUT_CMD}[ 	=]+[0-9]+[ 	]*" "$setm_tmp_menu" > /dev/null 2>&1
       if [ "$?" -ne 0 ]; then
	  echo "$LU_GRUB_TIMEOUT_CMD" "$LU_GRUB_TIMEOUT_VALUE" > "$setm_tmp_menu2"
	  /bin/cat "$setm_tmp_menu" >> "$setm_tmp_menu2"
	  /bin/cp "$setm_tmp_menu2" "$setm_tmp_menu"  
       fi

       /bin/egrep "^[ 	]*${LU_GRUB_TITLE_CMD}[ 	]+" "$setm_tmp_menu" > "$setm_tmp_menu2"
       ABEentry=`/usr/bin/awk "/^${LU_GRUB_TITLE_CMD} $setm_ABEfixedname\$/ { print NR }" "$setm_tmp_menu2"`

       # Grub starts its menu entry count at zero, so correct for that
       ABEentry=`expr $ABEentry - 1`

       #
       # Set the current ABE as the default entry
       # NOTE: the default command must precede actual entries
       #
       /bin/egrep -v "^[ 	]*${LU_GRUB_DEFAULT_CMD}[ 	=]+[0-9]+[ 	]*" "$setm_tmp_menu" > "$setm_tmp_menu2"
       echo "$LU_GRUB_DEFAULT_CMD" "$ABEentry" > "$setm_tmp_menu"
       /bin/cat "$setm_tmp_menu2" >> "$setm_tmp_menu"

       #
       # If the PBE is a Newboot BE, save the menu.lst. We need it for fallback activation
       #
       if [ "$PBE_boot_method" = GRUB -a -f "$setm_boot_menu" -a -s "$setm_boot_menu" ]; then
	  /bin/cp -p "$setm_boot_menu" "${DELAY_UPD_DIR}/${PBE_BOOT_MENU_FILE}"
       fi

  fi

  #
  # Now install the PBE entries. If the entry already exists, we remove
  # it and recreate it. This is so that future changes in the entry
  # added by Live Upgrade can be accomodated.
  #
  entry_exists=""
  setm_PBEfixedname=`lulib_fix_name $setm_PBEname`

  fixed_menu_hdr="${BOOT_MENU_PREFIX}${setm_PBEfixedname}${BOOT_MENU_HDR_SUFFIX}"
  fixed_menu_ftr="${BOOT_MENU_PREFIX}${setm_PBEfixedname}${BOOT_MENU_FTR_SUFFIX}"
  if [ "$PBE_boot_method" = GRUB ]; then
       /bin/grep "$fixed_menu_hdr" "$setm_tmp_menu" > /dev/null 2>&1
       if [ "$?" -eq 0 ]; then
	  entry_exists=1
	  start=`/usr/bin/awk "/^$fixed_menu_hdr\$/ { print NR }" "$setm_tmp_menu"`
	  stop=`/usr/bin/awk "/^$fixed_menu_ftr\$/ { print NR }" "$setm_tmp_menu"`
	  if [ -z "$stop" ]; then
	     stop=`expr $start + ${LU_GRUB_ENTRY_LEN} - 1`
	  fi
	  /bin/nawk -v "hdr=$start" "NR < hdr {print}" "$setm_tmp_menu" > "$setm_tmp_menu2"
	  /bin/nawk -v "ftr=$stop" "NR > ftr {print}" "$setm_tmp_menu" > "$setm_tmp_menu3"
	  /bin/cp -p "$setm_tmp_menu2" "$setm_tmp_menu"
       else
	  entry_exists=""
       fi

       # Write the header
       echo "${BOOT_MENU_PREFIX}${setm_PBEname}${BOOT_MENU_HDR_SUFFIX}" >> "$setm_tmp_menu"
       echo "$LU_GRUB_ITEM_SEP"  >> "$setm_tmp_menu"

       # Write the entries
       echo title "$setm_PBEname" >> "$setm_tmp_menu"
       echo root "(${PBE_hd},${PBE_part},${PBE_slice})" >> "$setm_tmp_menu" 
       echo kernel "/${MULTI_BOOT}"  >> "$setm_tmp_menu"
       echo module "/${BOOT_ARCHIVE}"  >> "$setm_tmp_menu"
       echo "$LU_GRUB_ITEM_SEP"  >> "$setm_tmp_menu"

       #
       # Install the failsafe archives . This is nothing but
       # the install miniroot. The install always happens in 32 bit
       # so the miniroot has no 64 bit binaries. When booting the
       # miniroot, use only the 32 bit kernel (kernel/unix)
       # The kernel/unix arg to multiboot should precede other options
       #
       echo title "$setm_PBEname" "failsafe" >> "$setm_tmp_menu"
       echo root "(${PBE_hd},${PBE_part},${PBE_slice})" >> "$setm_tmp_menu" 
       echo kernel "/${FAILSAFE_MULTI_BOOT} kernel/unix -s"  >> "$setm_tmp_menu"
       echo module "/${LU_FAILSAFE_ARCHIVE}"  >> "$setm_tmp_menu"
       echo "$LU_GRUB_ITEM_SEP"  >> "$setm_tmp_menu"

       echo "${BOOT_MENU_PREFIX}${setm_PBEname}${BOOT_MENU_FTR_SUFFIX}" >> "$setm_tmp_menu"

       if [ -n "$entry_exists" ]; then
          /bin/cat "$setm_tmp_menu3" >> "$setm_tmp_menu"
       fi
  fi

  ${LUPRINTF} -lp2D - "`gettext 'Updated tmp copy at <%s>'`" "${setm_tmp_menu}" 

  if [ "$setm_when" = DELAYED ]; then
	# Delayed update
	/bin/cp "$setm_tmp_menu" "${DELAY_UPD_DIR}/${BOOT_MENU_FILE}"
	/usr/bin/chmod "$LU_GRUB_MENU_PERM" "${DELAY_UPD_DIR}/${BOOT_MENU_FILE}"
        ${LUPRINTF} -lp2D - "`gettext 'Created menu file for delayed update at <%s>'`" "${DELAY_UPD_DIR}/${BOOT_MENU_FILE}"
  elif [ "$setm_when" = NOW ]; then
  	# Install menu right now
  	if [ ! -d  "${setm_bslice_mntpt}/${GRUB_DIR}" ]; then
       	    /bin/mkdir -p "${setm_bslice_mntpt}/${GRUB_DIR}"
  	fi
	/bin/cp "$setm_tmp_menu" "$setm_boot_menu"
	/usr/bin/chmod "$LU_GRUB_MENU_PERM" "$setm_boot_menu"
	/bin/cp -p "$setm_boot_menu" "$GRUB_backup_menu"
        propagate_be_file "${GRUB_backup_menu}"
        if [ "$?" -ne 0 ] ; then
	   ${LUPRINTF} -Eelp2 "`gettext 'Unable to propagate backup menu <%s> to all boot environments.'`" "$GRUB_backup_menu"
        fi
	# If a ufs filesystem, roll the log for the GRUB slice
	if [ "$BOOT_LOGICAL_FSTYP" = ufs ]; then
	   /usr/sbin/lockfs -f "$setm_bslice_mntpt"
	fi
        ${LUPRINTF} -lp2D - "`gettext 'Installed tmp <%s> as boot menu <%s>'`" "${setm_tmp_menu} ${setm_boot_menu}"
  fi

  /bin/rm -f "$setm_tmp_menu"
  /bin/rm -f "$setm_tmp_menu2"
  /bin/rm -f "$setm_tmp_menu3"
}

#
# Given an ABE mountpoint, create a GRUB archive for that ABE
#
# Argument:
#	$1 - Mount point for ABE
#
# Returns
#	Nothing
#
create_archive()
{
  if [ "$#" -ne 1 -o -z "$1" ]; then
     ${LUPRINTF} -Eelp2 "`gettext 'create_archive(): Invalid arguments.'`"
     return
  fi

  car_ABEmntpt="$1"
  car_tmp1="/tmp/.luactivate.car.1.$$"

  if [ "$ABE_boot_method" != GRUB ]; then
     ${LUPRINTF} -Eelp2 "`gettext 'create_archive: Internal error: Not a GRUB BE.'`"
     return
  fi

  car_rootPhys=`/bin/ls -l "$ABE_root_logical_bdev" | /bin/awk ' { print $11 } ' | /bin/sed 's/.*\/devices\//\//g'`
  car_bootEnv="${car_ABEmntpt}/${LU_GRUB_BOOT_ENV}"

  /bin/rm -f "$car_tmp1"
  /bin/cp -p "$car_bootEnv" "$car_tmp1"
  /bin/egrep -v "^[ 	]*setprop[ 	]+bootpath[ 	]+" "$car_tmp1" > "$car_bootEnv"
  /bin/echo "setprop bootpath $car_rootPhys" >> "$car_bootEnv"

  "${car_ABEmntpt}/${CREATE_RAMDISK}" -R "$car_ABEmntpt" 
}

#
# We have been called in the context of lucreate.
# We are attempting a clone of a GRUB BE
# Don't update GRUB or set the boot partition inactive.
# since we don't want to disrupt the currently active BE
# But do create an archive and update menu
#
update_grub_now()
{
  ugn_ABEname="$1"
  ugn_PBEname="$2"
  ugn_tmp1="/tmp/.luactivate.ugn.1.$$"

  #
  # Called only in the context of luactivate -u
  # For now this is a NOP
  #
  if [ -z "$flag_u" ]; then
     ${LUPRINTF} -Eelp2 "`gettext 'Internal error: Not an immediate operation.'`"
     return 1
  fi

  return 0
}


#
# Setup things (like menu and fdisk active flag) during luactivate
# This will be used later as the system goes down
#
# Arguments:
#	$1 - The ABE name
#	$2 - The PBE name
# Returns:
#	0 - On success
#	1 - On failure
#
setup()
{

  if [ "$#" -ne 2 -o -z "$1" -o -z "$2" ]; then
     ${LUPRINTF} -Eelp2 "`gettext 'setup(): Invalid arguments.'`"
     return 1
  fi

  stp_ABEname="$1"
  stp_PBEname="$2"
  stp_tmp1="/tmp/.luactivate.stp.1.$$"

  #
  # First mount the boot slice
  #
  mount_boot_slice "$BOOT_LOGICAL_SLICE" "$stp_tmp1" "NOT_OOS"
  if [ "$?" -ne 0 -o ! -f "$stp_tmp1" -o ! -s "$stp_tmp1" ]; then
     ${LUPRINTF} -Eelp2 "`gettext 'Unable to mount boot slice <%s>.'`" "${BOOT_LOGICAL_SLICE}"
     return 1
  fi
  stp_state=`/bin/cat "$stp_tmp1"`
  /bin/rm -f "$stp_tmp1"

  stp_bsliceMntpt=`/bin/echo "$stp_state" | /bin/cut -d '=' -f 2`

  setup_menu "$stp_bsliceMntpt" "$stp_ABEname" "$stp_PBEname" "DELAYED"

  umount_boot_slice "$stp_state" "NOT_OOS"

  /bin/echo "$BOOT_RAW_SLICE" | /bin/egrep "p0:boot$" > /dev/null 2>&1
  if [ "$?" -eq 0 ]; then
     set_boot_active "$BOOT_RAW_SLICE" "DELAYED" "NOT_OOS"
  else
     set_boot_inactive "$BOOT_RAW_SLICE" "DELAYED" "NOT_OOS"
  fi
  if [ "$?" -ne 0 ]; then
     ${LUPRINTF} -Eelp2 "`gettext 'Cannot set or unset active flag for <%s>.'`" "${BOOT_RAW_SLICE}"
     return 1
  fi

  return 0
}

#
# Adds commands to the delayed activation script which runs as the
# system is going down following a luactivate. This does the following
#	- Installs GRUB to GRUB slice
#	- Creates the archive on ABE
#	- Installs the menu on GRUB slice
#	- Sets active flag on approriate fdisk partition
#
# Arguments:
#	$1 - ABE name
#
# Returns:
#	0 - on succes
#	1 - on failure
#
create_script()
{
   if [ "$#" -ne 1 -o -z "$1" ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'create_script(): Invalid arguments.'`"
      return 1
   fi

   scr_ABEname="$1"

   scr_tmp1="/tmp/.luactivate.scr.1.$$"

   /bin/cat <<-EOF >> $DELAY_UPD_SCRIPT

	# Mount the ABE
	scr_ABEmntpt=\`LU_OUTPUT_FORMAT=text ${LUBIN}/lumount -i /etc/lu/ICF.$ABE_id 2>$scr_tmp1\` 
	if [ "\$?" -ne 0 ]; then
	   \${LUPRINTF} -fEel2 "`gettext 'Unable to mount ABE <%s>.'`" "$scr_ABEname"
	   /bin/cat "$scr_tmp1"
	   /bin/rm -f "$scr_tmp1"
	   exit 2
	fi
	/bin/rm -f "$scr_tmp1"
	EOF

   ${LUPRINTF} -lp2D 6 "`gettext 'setup delayed mount of ABE '`"

   /bin/cat <<-EOF >> $DELAY_UPD_SCRIPT

        # Install GRUB
	\${scr_ABEmntpt}/${GRUB_INSTALL} \${scr_ABEmntpt}/${GRUB_DIR}/stage1 \${scr_ABEmntpt}/${GRUB_DIR}/stage2 "$BOOT_RAW_SLICE"
	if [ "\$?" -ne 0 ]; then
	   \${LUPRINTF} -fEel2 "`gettext 'Cannot install GRUB to <%s>.'`" "$BOOT_RAW_SLICE"
	   ${LUBIN}/luumount -f -i /etc/lu/ICF.$ABE_id
	   exit 2
	fi
	EOF

   /bin/cat <<-EOF >> $DELAY_UPD_SCRIPT

   	# Create archive
   	scr_rootPhys=\`/bin/ls -l "$ABE_root_logical_bdev" | /bin/awk ' { print \$11 } ' | /bin/sed 's/.*\/devices\//\//g'\`
	if [ "\$?" -ne 0 -o -z \${scr_rootPhys} ]; then
	   \${LUPRINTF} -fEel2 "`gettext 'Cannot set bootpath to <%s>.'`" "\${scr_rootPhys}"
	   ${LUBIN}/luumount -f -i /etc/lu/ICF.$ABE_id
	   exit 2
	fi

	scr_bootEnv="\${scr_ABEmntpt}/${LU_GRUB_BOOT_ENV}"

	# Preserve permissions
	/bin/rm -f "$scr_tmp1"
	/bin/cp -p "\${scr_bootEnv}" "$scr_tmp1"
	/bin/egrep -v "^[ 	]*setprop[ 	]+bootpath[ 	]+" "$scr_tmp1" > "\$scr_bootEnv"
	/bin/echo "setprop bootpath \${scr_rootPhys}" >> "\$scr_bootEnv"
	\${scr_ABEmntpt}/${CREATE_RAMDISK} -R "\$scr_ABEmntpt"
	EOF

   /bin/cat <<-EOF >> $DELAY_UPD_SCRIPT

	# Unmount ABE
	${LUBIN}/luumount -f -i /etc/lu/ICF.$ABE_id
	EOF

   #
   # Do some preprocessing before mounting boot slice
   #

   # Get the boot slice block device
   scr_bsliceBlk=`/bin/echo "$BOOT_LOGICAL_SLICE" | /bin/sed "s/\/rdsk\//\/dsk\//g"`
   if [ "$?" -ne 0 -o -z "$scr_bsliceBlk" ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine boot slice <%s> block device.'`" "${BOOT_LOGICAL_SLICE}"
      exit 2
   fi

   # Strip off duplicate and trailing /
   if [ "$scr_bsliceBlk" != / ]; then
      scr_bsliceBlk=`/bin/echo "$scr_bsliceBlk" | /bin/sed "s://[/]*:/:g" | /bin/sed "s:/$::g"`
   fi

   #
   # BOOT_LOGICAL_SLICE may be a boot partition in the form: cXtYdZp0:boot. However
   # fstyp doesn't understand this form. So change it to reflect the "real" fdisk
   # partition. Note: get_real_boot_partition() only accepts a char device and
   # may be called in OOS mode.
   # 
   /bin/echo "$BOOT_LOGICAL_SLICE" | /bin/egrep "p0:boot$" > /dev/null 2>&1
   if [ "$?" -eq 0 ]; then
      scr_bsliceReal=`get_real_boot_partition "$BOOT_LOGICAL_SLICE"`
   else
      scr_bsliceReal="$BOOT_LOGICAL_SLICE"
   fi

   if [ "$?" -ne 0 -o -z "$scr_bsliceReal" ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine real boot partition for <%s>'`" "${BOOT_LOGICAL_SLICE}"
      return 1
   fi
      
   # Determine fstype. This function is not called during OOS mode, so safe to use lulib_fstyp
   scr_bsliceFstype=`lulib_fstyp "$scr_bsliceReal"`
   if [ "$?" -ne 0 -o -z "$scr_bsliceFstype" ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine boot slice <%s> filesystem type.'`" "${scr_bsliceReal}"
      return 1
   fi

   #
   # Check if the boot slice is mounted. If not, mount it.
   # If the boot-slice is mounted, check for a boot partition
   # mounted off it. If it is, unmount it.
   # Note: Don't use force flag (-f) while unmounting boot partition
   #       It will fail.
   #
   /bin/cat <<-EOF >> $DELAY_UPD_SCRIPT

	# Mount the boot slice
	scr_mnted=""
	scr_tmpMntpt="/tmp/.luactivate.scr.mntpt.1.\$\$"
	scr_bsliceMntpt=\`/sbin/mount | /bin/nawk -v dev=$scr_bsliceBlk ' { if (\$3 == dev) {printf("%s\n", \$1); exit 6;}} '\` 
	if [ "\$?" -ne 6 ]; then 
	   /bin/mkdir -p "\$scr_tmpMntpt"
	   /sbin/mount -F "$scr_bsliceFstype" "$scr_bsliceBlk" "\$scr_tmpMntpt" 2>"$scr_tmp1"
	   if [ "\$?" -ne 0 ]; then
	      /bin/cat "$scr_tmp1"
	      /bin/rm -f "$scr_tmp1"
	      /bin/rmdir "\$scr_tmpMntpt"
	      \${LUPRINTF} +X -fEel2 "`gettext 'Unable to mount boot slice <%s> at mount point <%s>.'`" "${scr_bsliceBlk}" "\${scr_tmpMntpt}"
	      exit 2
	   fi
	   /bin/rm -f "$scr_tmp1"
	   scr_mnted=1
	   scr_bsliceMntpt="\$scr_tmpMntpt"
	else
	    # Strip off duplicate and trailing / from boot slice mount point
	    if [ "\$scr_bsliceMntpt" != / ]; then
	       scr_bsliceMntpt=\`/bin/echo \$scr_bsliceMntpt | /bin/sed 's://[/]*:/:g' | /bin/sed 's:/$::g'\`
	    fi
	    if [ "\$scr_bsliceMntpt" = / ]; then
	       scr_dev=\`/sbin/mount | /bin/nawk -v mnt=/boot ' { if (\$1 == mnt) {printf("%s\n", \$3); exit 7;}} '\`
	    else
	       scr_dev=\`/sbin/mount | /bin/nawk -v mnt=\${scr_bsliceMntpt}/boot ' { if (\$1 == mnt) {printf("%s\n", \$3); exit 7;}}'\`
	    fi
	    if [ "\$?" -eq 7 ]; then
	       /sbin/umount "\${scr_bsliceMntpt}/boot" > /dev/null 2>&1
	       if [ "\$?" -eq 7 ]; then
	          \${LUPRINTF} +X -fEel2 "`gettext 'Unable to unmount boot partition at mount point <%s>.'`" "\${scr_bsliceMntpt}/boot"
	          exit 2
	       fi
	       scr_umnted=1
	      \${LUPRINTF} +X -fIlp1 "`gettext 'Unmounted boot partition at mount point <%s>.'`" "\${scr_bsliceMntpt}/boot"
	    fi
	fi
	EOF

   ${LUPRINTF} -lp2D 6  "`gettext 'setup delayed mount of boot slice and umount of boot partition'`"
	   
   /bin/cat <<-EOF >> $DELAY_UPD_SCRIPT

	# Install menu
	if [ ! -d "\${scr_bsliceMntpt}/${GRUB_DIR}" ]; then
	   /bin/mkdir -p "\${scr_bsliceMntpt}/${GRUB_DIR}"
	fi
	/bin/cp -p "${DELAY_UPD_DIR}/${BOOT_MENU_FILE}" \${scr_bsliceMntpt}/$BOOT_MENU
	/bin/cp -p "${DELAY_UPD_DIR}/${BOOT_MENU_FILE}" "$GRUB_backup_menu"
	${LUBIN}/luupdall "$GRUB_backup_menu"
	if [ "\$?" -ne 0 ]; then
              \${LUPRINTF} +X -fEel2 "`gettext 'Unable to propagate backup menu <%s> to all boot environments.'`" "$GRUB_backup_menu"
	fi
	# Roll the log if GRUB slice is ufs filesystem
	if [ "$BOOT_LOGICAL_FSTYP" = ufs ]; then
	   /usr/sbin/lockfs -f "\${scr_bsliceMntpt}"
	fi
	/bin/rm -f "${DELAY_UPD_DIR}/${BOOT_MENU_FILE}"
	EOF

   /bin/cat <<-EOF >> $DELAY_UPD_SCRIPT

	# Do mount/unmount cleanup
	if [ -n "\$scr_mnted" ]; then
	   /sbin/umount "\$scr_bsliceMntpt" > /dev/null 2>&1
	   /bin/rmdir "\$scr_bsliceMntpt"
	elif [ -n "\$scr_umnted" ]; then
	   /sbin/mount -F pcfs "\$scr_dev" "\${scr_bsliceMntpt}/boot" > /dev/null 2>&1
	   if [ "\$?" -ne 0 ]; then
              \${LUPRINTF} +X -fEel2 "`gettext 'Unable to mount boot partition at <%s>.'`" "\${scr_bsliceMntpt}/boot"
	   fi
	fi
	EOF

   # Do some preprocessing to set active flag
   /bin/echo "$BOOT_RAW_SLICE" | /bin/grep "p0:boot$" > /dev/null 2>&1
   if [ "$?" -eq 0 ]; then
      scr_p0=`/bin/echo "$BOOT_RAW_SLICE" | /bin/sed 's/p0:boot$/p0/g'`
   else
      scr_p0=`/bin/echo "$BOOT_RAW_SLICE" | /bin/sed 's/s.$/p0/g'`
   fi

   /bin/cat <<-EOF >> $DELAY_UPD_SCRIPT

	# Set boot partition active or inactive as needed
	if [ -f ${DELAY_UPD_DIR}/$MBR -a -s ${DELAY_UPD_DIR}/$MBR ]; then
	   /sbin/fdisk -F ${DELAY_UPD_DIR}/$MBR "$scr_p0" 
	   /bin/rm -f ${DELAY_UPD_DIR}/$MBR
	fi
	EOF

   return 0
}

#
# At luactivate time, sets up GRUB so that the next
# active BE is activated as the system goes down. 
#
# Arguments:
#	$1 - ABE name
#	$2 - PBE name
# Returns
#	0 - on success
#	1 - on error
#
update_grub_delayed()
{
   if [ "$#" -ne 2 -o -z "$1" -o -z "$2" ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'update_grub_delayed(): Invalid arguments.'`"
      return 1
   fi

   ugd_ABEname="$1"
   ugd_PBEname="$2"

   setup "$ugd_ABEname" "$ugd_PBEname"
   if [ "$?" -ne 0 ]; then
      return 1
   fi

   create_script "$ugd_ABEname"
   if [ "$?" -ne 0 ]; then
      return 1
   fi

   return 0
}

#
# This function vectors things approriately depending on
# whether we are invoked as "luactivate -u" or not.
# It sets up (or in -u case does immediately) installation
# of the GRUB boot loader.
#
# Arguments:
#	$1 - PBE name
#	$2 - ABE name
#
# Returns
#	0 on success
#	1 on failure
#
update_grub_loader()
{
  if [ "$#" -ne 2 -o -z "$1" -o -z "$2" ]; then
     ${LUPRINTF} -Eelp2 "`gettext 'update_grub_loader(): Invalid arguments.'`"
     return 1
  fi

  ugl_PBEname="$1"
  ugl_ABEname="$2"

  if [ "${LU_SYSTEM_ARCH}" != i386 -o "$ABE_boot_method" != GRUB ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'update_grub_loader: Internal error: Not a GRUB activation.'`"
      return 1
  fi

  #
  # If PBE == ABE, then everything is already installed. Just emit an
  # appropriate message and return
  #
  if [ "$ugl_PBEname" = "$ugl_ABEname" ]; then 
      ${LUPRINTF} -lp2D - "`gettext 'ABE <%s> == PBE <%s>. GRUB loader is already installed'`" "${ugl_ABEname}" "${ugl_PBEname}"
      return 0
  fi

  if [ -n "$flag_u" ]; then
     update_grub_now "$ugl_ABEname" "$ugl_PBEname"
  else
     update_grub_delayed "$ugl_ABEname" "$ugl_PBEname"
  fi

  return "$?"
}

#
# On the first boot after luactivate, the boot archive
# verification service complains about a large
# number of files being "new". This is because
# Live upgrade doesn't create the stat data used by
# bootadm. This is harmless to the system. To avoid
# alarming users, we disable the boot archive
# verification service (on first boot only) after
# luactivate
#
disable_boot_verif_svc()
{
  dbs_abeName="$1"
  dbs_svc="/lib/svc/method/boot-archive"

  if [ "$LU_SYSTEM_ARCH" != i386 ]; then
     return
  fi

  #
  # Mount the ABE
  #
  dbs_mntpt=`${LUBIN}/lumount "${dbs_abeName}"`
  if [ "$?" -ne 0 -o -z "$dbs_mntpt" ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'Cannot mount ABE: <%s>. Cannot disable boot verification svc.'`" "$dbs_abeName"
      return
  fi

  #
  # Disable only if luactivating to a BE with SMF and GRUB boot
  #
  if [ ! -f "${dbs_mntpt}/${dbs_svc}" -o ! -s "${dbs_mntpt}/${dbs_svc}" ]; then 
     ${LUBIN}/luumount -f ${dbs_mntpt}
     return
  fi

  ${LUBIN}/luumount -f ${dbs_mntpt}

  ${LUPRINTF} -lp1 "`gettext 'Modifying boot archive service'`"

  /bin/rm -f "${DELAY_UPD_DIR}/boot-svc" 
  /bin/rm -f "${DELAY_UPD_DIR}/S99lufirstboot" 

   #
   # Step 1: Create boot-svc and start script
   #	     and save them in DELAY_UPD_DIR
   #
  /bin/cat <<-EOF >> ${DELAY_UPD_DIR}/boot-svc
	#!/sbin/sh
	exit 0
	EOF
  /bin/chmod u+x "${DELAY_UPD_DIR}/boot-svc"

  /bin/cat <<-EOF >> ${DELAY_UPD_DIR}/S99lufirstboot
	#!/sbin/sh
	#
	case "\$1" in
	'start')
	         /bin/mv /lu-boot-svc ${dbs_svc}
	         /bin/chmod u+x ${dbs_svc} 
	         /bin/rm -f /etc/rc2.d/S99lufirstboot
	         ;;
	 *)
	         /bin/echo "usage: \$0 start"
	         exit 1
	         ;;
	esac
	exit 0
	EOF
  /bin/chmod u+x "${DELAY_UPD_DIR}/S99lufirstboot"


   #
   # Step 2: Switch boot-archive method with "dummy" script and
   #	     install start script
   /bin/cat <<-EOF  >> $DELAY_UPD_SCRIPT

	# mount the ABE
	dba_mntpt=\`${LUBIN}/lumount $dbs_abeName\`
        if [ "\$?" -ne 0 -o -z "\$dba_mntpt" ]; then
	   \${LUPRINTF} -fEel2 "`gettext 'Unable to mount ABE <%s>.'`" "$dbs_abeName"
	   exit 2
	fi

	/bin/mv "\${dba_mntpt}/${dbs_svc}" "\${dba_mntpt}/lu-boot-svc"
	/bin/mv "${DELAY_UPD_DIR}/boot-svc" "\${dba_mntpt}/${dbs_svc}"
	/bin/mv "${DELAY_UPD_DIR}/S99lufirstboot" "\${dba_mntpt}/etc/rc2.d"

	${LUBIN}/luumount -f \${dba_mntpt}
	EOF
}

#
# Displays the location of the GRUB menu and the filesystem type
# of the device hosting the menu
#
# Arguments:
#	None
# Returns:
#	Nothing
#	
disp_GRUB_menu_location()
{
	if [ -z "$BOOT_LOGICAL_SLICE" -o -z "$BOOT_LOGICAL_FSTYP" ]; then
           ${LUPRINTF} -Eelp2 "`gettext 'disp_GRUB_menu_location(): Missing global values'`"
	   return
        fi

        if [ "$LU_SYSTEM_ARCH" != i386 ]; then
           ${LUPRINTF} -Eelp2 "`gettext 'disp_GRUB_menu_location(): invalid system architecture. <%s>'`" "${LU_SYSTEM_ARCH}"
	   return
	fi

	boot_logical_blk=`/bin/echo "$BOOT_LOGICAL_SLICE" | /bin/sed 's/\/rdsk\//\/dsk\//g'`
	${LUPRINTF} -lp1 "`gettext 'GRUB menu is on device: <%s>.'`" "$boot_logical_blk"
	${LUPRINTF} -lp1 "`gettext 'Filesystem type for menu device: <%s>.'`" "$BOOT_LOGICAL_FSTYP"
}
################################################################################
# Name:		<main>
# Description:	Main code (outside of any function definitions) - executed at script startup.
# Local Prefix:	<none>
# Arguments:	$0...$n = All arguments specified by user on command line that invoked this script.
################################################################################

# Ignore all the signals.
# 1- SIGHUP (hangup)
# 2- SIGINT (user interrupt)
# 3- SIGQUIT (user quit)
# 9- SIGKILL (kill process - can not be caught or ignored :)
# 15- SIGTERM (software termination request)
trap "" 1 2 3 9 15

##########
# If luactivate is invoked in maintenance mode, then it needs to perform
# the out of service administration. We do this by executing '/bin/who -r',
# (Indicates the current run-level of the init process) and see if the
# run-level is "s" or "S" (single user mode) or "1" (system administrator 
# mode) - if so then we are in single user / maintenance mode. If 'who -r'
# does not return any value, then use 'who -a' and attempt to extract
# the run-level. This is for 2.6 systems where 'who -r' in single user mode
# does not return any value...
#
# Output looks like this in single user mode:
#   --> # who -r
#   -->   .       run-level S  Mar 27 19:48     S      0  ?
# Output looks like this in system maintenance mode:
#   --> # who -r
#   -->   .       run-level 1  Mar 28 09:50     1      0  S
# Output looks like this in non-single user mode:
#   --> # who -q
#   -->   .       run-level 3  Mar 24 11:06     3      0  S
##########

initRunLevel="`LANG=C LC_ALL=C /bin/who -r | /bin/awk '{print $3; exit 0}'`"
if [ -z "${initRunLevel}" ] ; then
  initRunlevel="`LANG=C LC_ALL=C /bin/who -a | /bin/awk '{if ($2 == \"run-level\") {print $3; exit 0}}'`"
fi

# if called from luupd_boot with the "-u" option then act as the
# system is not in single user mode - the -u option is used by luupd_boot
# to make immediate changes to a boot environment following a lucreate/lumake
if [ "$1" = "-u" -o "$2" = "-u" ] ; then
  # -u specified - set initRunLevel such that it does not appear to
  # indicate the system is in single user mode
  initRunLevel="xxx"
fi

if [ "${initRunLevel}" = "S" -o "${initRunLevel}" = "s" -o "${initRunLevel}" = "1" ] ; then
  # We are in maintenance mode: prepare for minimal operations.
  # Manually setup environment sufficient to perform the operations required.

  TEXTDOMAIN="SUNW_INSTALL_LU_SCRIPTS" ; export TEXTDOMAIN

  # in single user fallback mode - there is no guarantee that /usr contains
  # live upgrade, so set live upgrade's path variables to /mnt if live
  # upgrade is installed there otherwise set them to /usr

  LUPRINTF='echo'

  if [ -d /mnt/usr/lib/lu ] ; then
    LUBIN='/mnt/usr/lib/lu'
    LUETCBIN='/mnt/etc/lib/lu'
    LUPRINTF='/mnt/etc/lib/lu/luprintf'
  else
    LUBIN='/usr/lib/lu'
    LUETCBIN='/etc/lib/lu'
    LUPRINTF='/etc/lib/lu/luprintf'
  fi

  # Verify that no arguments have been entered and alert user that system is in maintenance mode.

  if [ "${initRunLevel}" = "1" ] ; then
    echo "${LU_PROG_NAME}: ""`gettext 'The system is in system administrator maintenance mode.'`" >&2
  else
    echo "${LU_PROG_NAME}: ""`gettext 'The system is in single user maintenance mode.'`" >&2
  fi

  if [ "$#" -ne "0" ] ; then
    echo "${LU_PROG_NAME}: ""`gettext 'Command line arguments not allowed in maintenance mode: '`""<$*>" >&2
    echo "${LU_PROG_NAME}: ""`gettext 'ERROR: The system is in maintenance mode - luactivate can only be used with no command line options or arguments to fallback to the previously working boot environment.'`" >&2
    echo "${LU_PROG_NAME}: ""`gettext 'USAGE in system maintenance mode: '`${LU_PROG_NAME}" >&2
    exit 2
  fi

  # We are in maintenance mode so do the OOS administration tasks.
  # (This means the system is in single user mode and luactivate is used
  # to "fallback" to the previously activated boot environment).
  do_fallback
  exit "$?"
fi

# Dot the defaults file.

if [ ! -s /etc/default/lu ] ; then
  echo "${LU_PROG_NAME}: ""`gettext 'ERROR: Live Upgrade 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: The Live Upgrade product is not installed properly (${LUBIN}/lulib not found).'`"
  exit 1
fi

. ${LUBIN}/lulib

  ######################################################################################
  ##################### Command line option and argument processing ####################
  ######################################################################################

# Reset all command line parse flags to default values.
flag_g="" # -g - Live Upgrade GRUB slice (slice containing GRUB menu, x86 only)
flag_l="" # -l f - log file path.
flag_n="" # -n "n" - be name.
flag_o="" # -o f - output file path.
flag_s="" # -s - sync flag.
flag_u="" # -u - update now (do not delay).
flag_x="" # -x n - set debug level to n (PRIVATE).

# Validate the command line arguments.

while [ $# -ne 0 ] ; do
  while getopts gl:n:o:usx:X c ; do
    case $c in
      g) # Emits the name of the LU GRUB slice (the slice containing GRUB menu)
	 # x86 only
	 if [ "${LU_SYSTEM_ARCH}" = i386 ]; then
	    flag_g="yes"
	 else
	    ${LUPRINTF} -Eelp2 "`gettext 'The -g option is not a valid option on a <%s> system'`" "${LU_SYSTEM_ARCH}"
	    exit 3
	 fi
	 ;;
      l) # -l f - error log file path.
	 # This overrides the LU_ERROR_LOG_FILE setting read from /etc/default/lu
	 lulib_cannot_duplicate_option "${flag_l}" "${OPTARG}" "-l"
	 ${LUPRINTF} -lp2D - "`gettext 'Verifying that the error log file <%s> specified can be created and appended to.'`" "${OPTARG}"
	 ERRMSG="`${LUPRINTF} -c \"${OPTARG}\" 2>&1`"
	 if [ $? -ne 0 ] ; then
	   [ -n "${ERRMSG}" ] && ${LUPRINTF} -elp2 '%s' "${ERRMSG}"
	   ${LUPRINTF} -Eelp2 "`gettext 'Argument <%s> to -l option may not be created or appended to.'`" "${OPTARG}"
	   exit 3
	 fi
	 flag_l="${OPTARG}"
	 lulib_set_error_log_file "${flag_l}"
	 ;;
      n) # -n "n" - be name.
	 lulib_cannot_duplicate_option "${flag_n}" "${OPTARG}" "-n"
	 flag_n="${OPTARG}"
	 ;;
      o) # -o f - output file path.
	 # This overrides the LU_SESSION_LOG_FILE setting read from /etc/default/lu
	 lulib_cannot_duplicate_option "${flag_o}" "${OPTARG}" "-o"
	 ${LUPRINTF} -lp2D -  "`gettext 'Verifying that the session log file <%s> can be created and appended to.'`" "${OPTARG}"
	 ERRMSG="`${LUPRINTF} -c \"${OPTARG}\" 2>&1`"
	 if [ $? -ne 0 ] ; then
	   [ -n "${ERRMSG}" ] && ${LUPRINTF} -elp2 '%s' "${ERRMSG}"
	   ${LUPRINTF} -Eelp2 "`gettext 'Argument <%s> to -o option may not be created or appended to.'`" "${OPTARG}"
	   exit 3
	 fi
	 flag_o="${OPTARG}"
	 lulib_set_session_log_file "${flag_o}"
	 ;;
      s) # -s - sync flag.
	 flag_s="yes"
	 ;;
      u) # -u - update now (do not delay). (PRIVATE)
	 flag_u="yes"
	 ;;
      x) # -x n - set debug level to n (PRIVATE).
	 # This overrides the default setting read from /etc/default/lu
	 lulib_cannot_duplicate_option "${flag_x}" "${OPTARG}" "-x"
	 /bin/test "${OPTARG}" -ge 0 2>/dev/null
	 if [ $? -gt 1 ] ; then
	   ${LUPRINTF} -Eelp2 "`gettext 'Argument <%s> to -x option is not a number.'`" "${OPTARG}"
	   usage 3
	 fi
	 flag_x="${OPTARG}"
	 lulib_set_debug "${flag_x}"
	 ;;
      X) # -X - set XML output mode.
	  lulib_set_output_format 'xml'
	  ;;
      \?) # unknown - option.
	  usage 3
    esac
  done

  # Found either end of arguments, +option, or non-option argument; shift out
  # what has been processed so far; if a non-option argument is present
  # capture it and continue processing the command line arguments.
  shift `/bin/expr $OPTIND - 1`
  OPTIND=1
  if [ $# -ne 0 -a "$1" = '+X' ] ; then
      # +X - set TEXT output mode.
      lulib_set_output_format 'text'
      shift
  else
    break
  fi
done

# Fixup debug, session log, and error log settings
lulib_fixup_startup_settings

  ######################################################################################
  ############ Validate all command line arguments and options as possible #############
  ######################################################################################

FULL_COMMAND_LINE="${LU_PROG_NAME} $*"

# Validate the number of arguments.
if [ $# -gt 1 ] ; then
  ${LUPRINTF} -Eelp2 "`gettext 'The boot environment name should be enclosed in single quotes, like %c%s%c.'`" "'" "$*" "'"
  usage 3
fi

# Check for existence and non-zero size of lutab file.

if [ ! -f ${LU_LUTAB_FILE} -o ! -s ${LU_LUTAB_FILE} ] ; then
  ${LUPRINTF} -Eelp2 "`gettext 'No boot environments are configured on this system.'`"
  exit 1
fi

# If -u not specified (do not update now) then delayed update
# requested - check to see if a BE is currently active - if so cannot
# activate a BE yet.
if [ -z "${flag_u}" ] ; then
  lulib_check_any_be_busy
  if [ $? -ne 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'A boot environment is busy with another operation: unable to activate.'`"
    exit 1
  fi
fi


# Name of target BE (ABE).
if [ -n "${flag_n}" -a -z "$1" ] ; then
  BE_NAME="${flag_n}"
elif [ -z "${flag_n}" -a -n "$1" ] ; then
  BE_NAME="$1"
elif [ -z "${flag_n}" -a -z "$1" ] ; then
  BE_NAME=""
else
  ${LUPRINTF} -Eelp2 "`gettext 'You must specify the boot environment to activate either with the <-n> option or by providing the boot environment name on the command line, but not both.'`"
  usage 3
fi

# Determine the name of current BE (PBE).
CURR_BE="`lulib_lucurr`"
if [ $? != 0 ] ; then
  ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine the name of the current active boot environment.'`"
  exit 1
fi

  ######################################################################################
  ############## If no BE name, then show name of BE that will boot next ###############
  ######################################################################################

if [ -z "${BE_NAME}" -a -z "$flag_g" ] ; then
  # Display the name of BE that will be active upon next reboot.
  # echo "Following BE will be active upon next reboot of the machine:"
  if [ -f $NEXT_ACTIVE ] ; then
    ${LUPRINTF} -lp2D - "`gettext 'Requested name of active BE on next reboot: returning next BE activated <%s>.'`" "`/bin/head -1 ${NEXT_ACTIVE}`"
    /bin/cat "${NEXT_ACTIVE}"
  else
    ${LUPRINTF} -lp2D - "`gettext 'Requested name of active BE on next reboot: returning current BE <%s>.'`" "${CURR_BE}"
    echo "$CURR_BE"
  fi
  exit 0
fi

  ######################################################################################
  ###########################  If x86, get GRUB slice  ################################
  ######################################################################################
if [ "${LU_SYSTEM_ARCH}" = i386 ]; then

   #
   # This section of the code is not invoked during OOS.
   # Safe to use lulib functions.
   #
   output=`lulib_update_grub_slice`
   if [ "$?" -ne 0 -o -z "$output" ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'Cannot determine GRUB slice.'`"
      exit 1
   fi

   BOOT_RAW_SLICE=`echo $output | cut -d'=' -f 1`
   BOOT_LOGICAL_SLICE=`echo $output | cut -d'=' -f 2`
   BOOT_LOGICAL_FSTYP=`echo $output | cut -d'=' -f 3`
   BOOT_SLICE_IS_PART=`echo $output | cut -d'=' -f 4`
   boot_real_slice=`echo $output | cut -d'=' -f 5`
   BOOT_LOGICAL_BLK=`echo $output | cut -d'=' -f 6`
fi

  ######################################################################################
  ##########################  If x86, handle the -g option #############################
  ######################################################################################
if [ "$flag_g" = "yes" ]; then
   disp_GRUB_menu_location
   exit 0
fi

  ######################################################################################
  ############### Get the configuration of the current boot environment ################
  ######################################################################################

get_pbe_config "${CURR_BE}" "" ""
if [ $? != 0 ] ; then
  ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine the configuration of the current boot environment <%s>.'`" "${CURR_BE}"
  exit 2
fi

  ######################################################################################
  ########## If -u is not specified (do not update now), handle special cases. #########
  ######################################################################################

if [ -z "${flag_u}" ] ; then
  # No -u specified - delayed update.

  # Validate the given BE name. 
  lulib_validate_be "${BE_NAME}"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to activate boot environment <%s>.'`" "${BE_NAME}"
    exit 1
  fi

  # If the BE to be activated is not the current BE, mount the BE and
  # perform appropriate synchronization and validity checks.

  if [ "$BE_NAME" != "$CURR_BE" ] ; then
    # Unset failed flag - set on any failure to unmount BE and exit with failure.
    failed=''

    # Mount the BE to be activated.
    SYNCBE_ID=`${LUETCBIN}/ludo get_be_id "$BE_NAME" 2>&1`
    if [ $? != 0 ] ; then
      [ -n "${SYNCBE_ID}" ] && ${LUPRINTF} -Eelp2 '%s' "${SYNCBE_ID}"
      ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine boot environment ID of target boot environment <%s>.'`" "${BE_NAME}"
      exit 1
    fi
    SYNCMTPT="`LU_OUTPUT_FORMAT=text ${LUBIN}/lumount -i /etc/lu/ICF.${SYNCBE_ID} 2>${TMP_RESULT_FILE}`"
    if [ "$?" -ne "0" ] ; then
      [ -s "${TMP_RESULT_FILE}" ] && ${LUPRINTF} -elp2 '%R' < "${TMP_RESULT_FILE}"
      ${LUPRINTF} -Eelp2 "`gettext 'Unable to mount the boot environment <%s>.'`" "${BE_NAME}"
      /bin/rm -f "${TMP_RESULT_FILE}"
      exit 1
    fi
    /bin/rm -f "${TMP_RESULT_FILE}"

    ${LUPRINTF} -lp2D - "`gettext 'Mounted ABE<%s> at <%s>.'`" "${BE_NAME}" "${SYNCMTPT}"

    # If synchronization is requested, set the synchronization key file.
    if [ -n "${flag_s}" ] ; then
      ${LUPRINTF} -lp1S ${LU_SYSLOG_FACILITY}.${LU_SYSLOG_PRIORITY} "`gettext 'A Live Upgrade Sync operation will be performed on startup of boot environment <%s>.'`" "${BE_NAME}"
      echo "${CURR_BE}" >$SYNCMTPT/${SYNCKEY}
    fi

    # Check to see if the BE is partially upgraded.
    check_os_on_be "${SYNCMTPT}"
    [ "$?" -ne '0' ] && failed='yes'

    # Check for any file synchronization problems.
    check_sync_issues "${SYNCMTPT}"

    # Unmount the BE to be activated.
    ${LUBIN}/luumount -f -i /etc/lu/ICF.${SYNCBE_ID}

    # If checks failed, exit.
    if [ -n "${failed}" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'Unable to activate boot environment <%s>.'`" "${BE_NAME}"
      exit 1
    fi
  fi

  if [ -f $NEXT_ACTIVE ] ; then
    grep "^${BE_NAME}$" $NEXT_ACTIVE >/dev/null
    if [ $? -eq 0 ] ; then 
      ${LUPRINTF} -Wlp1 "`gettext 'Boot environment <%s> is already activated.'`" "${BE_NAME}"
      exit 0
    fi
    # See if we are reverting to the CURR_BE. If we are, then just
    # remove any older activation data. We need not do anything
    # to make the CURR_BE active other than removing OTHER_BE's
    # activation data.
    if [ "$BE_NAME" = "$CURR_BE" ] ; then
      ${LUPRINTF} -lp1 "`gettext 'Activating the current boot environment <%s> for next reboot.'`" "${CURR_BE}"
      # We don't need delay and fallback data
      /bin/rm -f /etc/lu/DelayUpdate/vtoc.*
      /bin/rm -f /etc/lu/DelayUpdate/boot.*
      /bin/rm -f /etc/lu/DelayUpdate/${MBR}
      /bin/rm -f /etc/lu/DelayUpdate/${BOOT_MENU_FILE}
      /bin/rm -f /etc/lu/DelayUpdate/${PBE_BOOT_MENU_FILE}
      /bin/rm -f /etc/lu/DelayUpdate/installgrub
      /bin/rm -f /etc/lu/DelayUpdate/stage1
      /bin/rm -f /etc/lu/DelayUpdate/stage2
      /bin/rm -f /etc/lu/DelayUpdate/installboot
      /bin/rm -f /etc/lu/DelayUpdate/activate.sh /etc/lu/DelayUpdate/exec_activate.sh
      
      # Store the required PBE variables in the file /etc/lu/.CURR_VARS
      # ? Why do we need the CURR_VARS file if activating current BE ?
      echo "BEID=$PBE_id" >$CURR_VARS
      echo "BEDISK=$PBE_boot_disk" >>$CURR_VARS
      echo "BENAME=$CURR_BE" >>$CURR_VARS
      echo "BEROOT=$PBE_root_bdev" >>$CURR_VARS
      echo "BEROOT_FSTYP=$PBE_root_fstyp" >>$CURR_VARS
      if [ "$LU_SYSTEM_ARCH" = "i386" ]; then
         echo "BEBOOT=$BOOT_RAW_SLICE" >>$CURR_VARS
         echo "BELOGICAL=$BOOT_LOGICAL_SLICE" >>$CURR_VARS
         echo "BELOG_FSTYP=$BOOT_LOGICAL_FSTYP" >>$CURR_VARS
      fi
      
      # Propagate the BE variables file to all BEs.
      propagate_be_file "${CURR_VARS}"
      if [ "$?" -ne "0" ] ; then
	${LUPRINTF} -Eelp2 "`gettext 'Unable to propagate fallback information to all boot environments.'`"
	exit 1
      fi
      
      # Store name of the BE to be activated upon reboot in the file .NEXT_ACTIVE
      echo "$CURR_BE" > $NEXT_ACTIVE

      if [ "$LU_SYSTEM_ARCH" = i386 -a "$ABE_boot_method" = GRUB ]; then
         disp_GRUB_menu_location
      fi

      ${LUPRINTF} -lp1S ${LU_SYSLOG_FACILITY}.${LU_SYSLOG_PRIORITY} "`gettext 'The current boot environment <%s> has been activated for the next reboot.'`" "${CURR_BE}"
      exit 0
    fi
  else
    # Since the last boot, no-one has done an active. In this case,
    # if lucurr is BE_NAME then we must be trying to
    # re-activate the current BE. 
    if [ "$BE_NAME" = "$CURR_BE" ] ; then
      ${LUPRINTF} -Wlp1 "`gettext 'Boot environment <%s> is already activated.'`" "${BE_NAME}"
      exit 0
    fi
  fi

  # No -u specified - delayed update: destroy any previous delayed
  # update luactivate and create new delayed update script

  # Create/truncate the script file and set "LU_PROG_NAME"
  create_delayupdate_script "${FULL_COMMAND_LINE}"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} "`gettext 'Unable to create the delayed update script: cannot activate boot environment <%s>.'`" "${CURR_BE}"
    exit 1
  fi
fi


  ######################################################################################
  ################# Get the configuration of the next boot environment #################
  ######################################################################################

get_abe_config "${BE_NAME}"
if [ $? != 0 ] ; then
  ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine the configuration of the target boot environment <%s>.'`" "${BE_NAME}"
  exit 2
fi

  ######################################################################################
  ################ Update vtoc and OS loader on target boot environment ################
  ######################################################################################

# No need to update the VTOC if it is a veritas encapsulated boot
# disk; this is because Veritas does strange things with the vtoc and
# we dont want to destroy the encapsulation. So it is assumed that if
# the target root of a BE is a Veritas encapsulated drive, 1) it has
# only one root parititon on it, and 2) it is already marked as the
# boot partition. To change this we need to work with Veritas to figure
# out how to handle the situation where a physical drive has more than
# one encapsulated boot partition in it...
dont_write_vtoc=""
echo "${ABE_root_logical_bdev}" | grep "^/dev/vx/dsk/" > /dev/null 2>&1
if [ "$?" -eq "0" ] ; then
  dont_write_vtoc="yes"
fi

${LUPRINTF} -lp2D - "`gettext 'Veritas root ? <%s>.'`" "${dont_write_vtoc}"

#
# NOTE: GRUB boot doesn't need the ROOT tag in VTOC. This allows us to
#       switch GRUB boot BEs without modifying VTOC. We still go through
#	all the steps however a) for compatibility b) to simplify the code
#

if [ "$BE_NAME" = "$CURR_BE" ] ; then
  ${LUPRINTF} -lp1 "`gettext 'Activating the current boot environment <%s> for next reboot.'`" "${CURR_BE}"

  if [ -z "${dont_write_vtoc}" ] ; then
    # Obtain the vtoc of PBE boot disk
    get_be_vtoc $PBE_id $PBE_boot_disk

    # Edit vtoc of the PBE boot disk, so that PBE ROOT and STAND are active
    edit_be_vtoc $PBE_id $PBE_root_slice

    # Write the vtoc to PBE boot disk.
    write_be_vtoc $PBE_id $PBE_boot_disk "${CURR_BE}" "${CURR_BE}" "${flag_u}"
  else
    ${LUPRINTF} -Welp2 "`gettext 'Assuming vtoc on logical device <%s> already has slice <%s> tagged as BOOT slice.'`" "${ABE_root_logical_bdev}" "${ABE_root_bdev}"
  fi

  # Write appropriate loader to the disk. Since CURR_BE = BE_NAME
  # this does nothing except emit a few messages
  if [ "$LU_SYSTEM_ARCH" = i386 -a "$ABE_boot_method" = GRUB ]; then
     if [ -z "$BOOT_SLICE_IS_PART" ]; then
        update_grub_loader "${CURR_BE}" "${BE_NAME}"
     fi
  else
     write_loader $PBE_root_bdev "${flag_u}" "${BE_NAME}" "${CURR_BE}"
  fi

  if [ $? != 0 ] ; then
     ${LUPRINTF} -Eelp2 "`gettext 'Unable to write bootstrap information to root slice <%s> of current boot environment <%s>.'`" "${PBE_root_bdev}" "${CURR_NAME}"
     exit 1
  fi
else
  if [ -z "${dont_write_vtoc}" ] ; then
    # Obtain the vtoc of PBE boot disk
    get_be_vtoc $PBE_id $PBE_boot_disk

    # Obtain the vtoc of ABE boot disk
    get_be_vtoc $ABE_id $ABE_boot_disk

    # Edit vtoc of the ABE boot disk, so that ABE ROOT and STAND are active
    edit_be_vtoc $ABE_id $ABE_root_slice

    # Write the vtoc to ABE boot disk.
    write_be_vtoc $ABE_id $ABE_boot_disk "${BE_NAME}" "${CURR_BE}" "${flag_u}"
  else
    ${LUPRINTF} -Welp2 "`gettext 'Assuming vtoc on logical device <%s> already has slice <%s> tagged as BOOT slice.'`" "${ABE_root_logical_bdev}" "${ABE_root_bdev}"
  fi

  # Now check if the ABE-Root slice is not mounted and is mountable.
  chk_mount $ABE_root_logical_bdev $ABE_root_fstyp "${BE_NAME}"
  if [ $? -ne 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The root slice <%s> of the target boot environment <%s> is not available.'`" "${ABE_ROOT_DEV}" "${BE_NAME}"
    exit 1
  fi
  
  # Write appropriate loader on to the disk.
  if [ "$LU_SYSTEM_ARCH" = i386 -a "$ABE_boot_method" = GRUB ]; then
      if [ -z "$BOOT_SLICE_IS_PART" ]; then
         update_grub_loader "${CURR_BE}" "${BE_NAME}"
      fi
  else
      write_loader $ABE_root_bdev "${flag_u}" "${BE_NAME}" "${CURR_BE}"
  fi

  if [ "$?" -ne 0 ] ; then
     ${LUPRINTF} -Eelp2 "`gettext 'Unable to write bootstrap information to root slice <%s> of target boot environment <%s>.'`" "${ABE_root_bdev}" "${BE_NAME}"
     exit 1
  fi
fi


  ######################################################################################
  ##################### Create and propagate fallback information ######################
  ######################################################################################

if [ -z "${flag_u}" ] ; then
  # Store the required PBE variables in the file /etc/lu/.CURR_VARS
  echo "BEID=$PBE_id" >$CURR_VARS
  echo "BEDISK=$PBE_boot_disk" >>$CURR_VARS
  echo "BENAME=$CURR_BE" >>$CURR_VARS
  echo "BEROOT=$PBE_root_bdev" >>$CURR_VARS
  echo "BEROOT_FSTYP=$PBE_root_fstyp" >>$CURR_VARS
  if [ "$LU_SYSTEM_ARCH" = "i386" ]; then
     echo "BEBOOT=$BOOT_RAW_SLICE" >>$CURR_VARS
     echo "BELOGICAL=$BOOT_LOGICAL_SLICE" >>$CURR_VARS
     echo "BELOG_FSTYP=$BOOT_LOGICAL_FSTYP" >>$CURR_VARS
  fi

  # Propagate the BE variables file to all BEs.
  propagate_be_file "${CURR_VARS}"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to propagate fallback information to all boot environments.'`"
    exit 1
  fi
fi

  ######################################################################################
  ########################## Delayed update final processing ###########################
  ######################################################################################

if [ -z "${flag_u}" ] ; then
  # -u is not specified (delayed update):
  # 1. Change the system boot parameters.
  # 2. Display activate/fallback information.
  # 3. Create the delayed update execution script.
  if [ "$BE_NAME" = "$CURR_BE" ] ; then
    set_boot "$PBE_root_bdev" "" "${BE_NAME}" "" ""
  else
    set_boot "$ABE_root_bdev" "" "${BE_NAME}" "" ""
  fi
fi

#
# Boot partition (if any) has been saved. Safe to install GRUB on it now
#
if [ "$LU_SYSTEM_ARCH" = i386 -a "$ABE_boot_method" = GRUB -a -n "$BOOT_SLICE_IS_PART" ]; then
   update_grub_loader "${CURR_BE}" "${BE_NAME}"
   if [ "$?" -ne 0 ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'Failed to update GRUB slice <%s>.'`" "$BOOT_RAW_SLICE"
      exit 1
   fi
fi

if [ -z "${flag_u}" ]; then
  # Store name of the BE to be activated upon reboot in the file .NEXT_ACTIVE
  echo "$BE_NAME" > $NEXT_ACTIVE

  # Display activate and fallback information.
  if [ "$BE_NAME" != "$CURR_BE" ] ; then
    disp_activate_info
    disp_fallback_info 
  fi

  if [ "$LU_SYSTEM_ARCH" = i386 ]; then
     disable_boot_verif_svc "$BE_NAME"
  fi

  # Create the delayed update execution processing script
  create_delayupdate_exec_script "${BE_NAME}" "${FULL_COMMAND_LINE}"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to create shutdown execute script; unable to activate boot environment <%s>.'`" "${BE_NAME}"
    /bin/rm -f "${DELAY_UPD_SCRIPT}" "${DELAY_UPD_SCRIPT_EXEC}"  
    exit 1
  fi

  if [ "$LU_SYSTEM_ARCH" = i386 -a "$ABE_boot_method" = GRUB ]; then
     disp_GRUB_menu_location
  fi
  ${LUPRINTF} -lp1 "`gettext 'Activation of boot environment <%s> successful.'`" "${BE_NAME}"
fi

exit 0
