#!/bin/ksh

#################################################################################################
#
# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#	Copyright 1992-95 AT&T Global Information Solutions
#
# ident	"@(#)luupgrade.sh	5.82	09/07/30 SMI"
#
# luupgrade is used to perform a variety of software installation and
# upgrade functions to a target (inactive) boot environment:
# 
# --> Upgrade operating system.
# --> Install operating system from flash archive.
# --> Add, remove, check, and get information on packages.
# --> Add and remove patches.
# --> Check installation media and report contents found.
# --> Install applications.
# 
# It is intended to be called once an ABE is created and populated,
# allowing the system administrator to perform necessary operating
# system and application installation and upgrade operations.
#
# USAGE: luupgrade [-u | -f | -p | -r | -P | -R | -i | -c] [-l error_log] \
#		[-o outfile] [-N] [additional / optional / required parameters]:
# OS Upgrade:      luupgrade -u -n "target_BE_name" [-l error_log] [-o outfile] \
#		[-N] [-D] -s source_os_image_path [-j profile_path]
# Flash Upgrade:   luupgrade -f -n "target_BE_name" [-l error_log] [-o outfile] \
#		[-N] [-D] -s source_os_image_path (-a archives | -j profile_path | -J "profile")
# Add Packages:    luupgrade -p -n "target_BE_name" [-l error_log] [-o outfile] \
#		[-N] ((-s | -d) source_packages_path) [-O "pkgadd_options"] [-a pkg_admin_file] \
#		[pkginst [pkginst...]]
# Remove Packages: luupgrade -P -n "target_BE_name" [-l error_log] [-o outfile] \
#		[-N] [-O "pkgadd_options"] pkginst [pkginst...]
# Check Packages:  luupgrade -C -n "target_BE_name" [-l error_log] [-o outfile] \
#		[-N] [-O "pkgchk_options"] [pkginst [pkginst...]]
# Package Info:    luupgrade -I -n "target_BE_name" [-l error_log] [-o outfile] \
#		[-N] [-O "pkginfo_options"] [pkginst [pkginst...]]
# Add Patches:     luupgrade -t -n "target_BE_name" [-l error_log] [-o outfile] \
#		[-N] -s source_patches_path  [-O "patchadd_options"] [patchname [patchname...]]
# Remove Patches:  luupgrade -T -n "target_BE_name" [-l error_log] [-o outfile] \
#		[-N] [-O "patchrm_options"] patchname [patchname...]
# Run Installer:   luupgrade -i -n "target_BE_name" [-l error_log] [-o outfile] \
#		[-N] -s install_image_path [-O "installer_options"]
# Check Media:     luupgrade -c [-l error_log] [-o outfile] -s image_path
#
# Returns: 	0 - operation successful.
#		1 - operation failed: failure to perform specific operation requested.
#		2 - operation failed: unexpected failure outside of requested operation.
#		3 - operation failed: command line / user request error.
#		4 - operation failed: script interrupted (by HUP INT QUIT KILL TERM).
#		5 - operation failed: live upgrade product installation problem.
#
################################################################################

################################################################################
# Operating System distribution media format expected by this script:
# 
# DIR:  media
#       	---> base directory for Solaris distribution
# FILE: media/.cdtoc 
#		---> table of contents for media (see cdtoc(4))
# DIR:  media/Solaris*/Product
#		---> product main directory (from .cdtoc file)
# DIR:  media/Solaris*/Patches
#		---> product patches directory
# DIR:  media/MU
#		---> multiple update main directory
# FILE: media/MU/install_mu
#		---> multiple update installer
# DIR:  media/.install_config
#		---> used to detect that installable os is located here
# DIR:  media/Solaris*/Tools
#		---> mini-root tools directory
# DIR:  media/Solaris*/Tools/Boot/usr/snadm/lib
#		---> library directory for pfinstall
# DIR:  media/Solaris*/Tools/Boot/usr/sbin/install.d
#		---> directory where pfinstall is located
# FILE: media/Solaris*/Tools/Boot/usr/sbin/install.d/pfinstall
#		---> pfinstall executable
# DIR:  media/Solaris*/Tools/Boot/usr/sbin/install.d/install_config
#		---> directory where installation scripts can be found
# DIR:  media/Solaris*/Tools/Boot/usr/sbin/install.d/install_config/patch_finish
#		---> post-os upgrade/install patch installation script
#
################################################################################

# disable error on unset variable reference in case set in global environment
set +o nounset

# Script global variables.

LU_PROG_FULL_PATH="$0"
LU_PROG_NAME="`basename ${LU_PROG_FULL_PATH}`"; export LU_PROG_NAME
MEDIAROOTMOUNTPOINT="/a"
UPGRADE_PROFILE="/etc/lu/solaris_profile"
FLASH_PROFILE="/etc/lu/solaris_flash_profile"
FLASH_UPDATE_PROFILE="/etc/lu/solaris_flash_update_profile"
COPYLOCK_CAN_BE_DELETED=""
AIM_BEBOOTMNT=""
MAIL_SUBJECT=""
MAIL_DISABLE=""
MAX_PATCHES_FROM_FILE="1000"
LU_BOOTENV="platform/i86pc/boot/solaris/bootenv.rc"
LU_MINIROOT_DIR="boot"
LU_MINIROOT_PATH=""
LU_MINIROOT_DEVICE=""
LU_MINIROOT_FSTYPE=""
LU_MINIROOT_MNTPT=""
LU_MINIROOT_CPIO="lu.cpio"
LU_MINIROOT_UNCOMPRESSED=""
LU_WIZARD_MNTPT=""
LU_WIZARD_FSTYPE=""
LU_WIZARD_ARCHIVE_PRESENT=0
TMP_WIZARD_ARCHIVE=""
INSTALL_FAILSAFE_ON=""
TMP_FAILSAFE_KERNEL=""
TMP_FAILSAFE_ARCHIVE=""
TMP_FAILSAFE_KERNEL_TYPE=""

# Locations of files created by pfinstall.

PFINSTALL_INSTALL_LOG="/var/sadm/system/logs/install_log"
PFINSTALL_UPGRADE_CLEANUP="/var/sadm/system/data/upgrade_cleanup"
PFINSTALL_UPGRADE_FAILED_PKGADDS="/var/sadm/system/data/upgrade_failed_pkgadds"
PFINSTALL_UPGRADE_LOG="/var/sadm/system/logs/upgrade_log"
PFINSTALL_PACKAGES_TO_BE_ADDED="/var/sadm/system/data/packages_to_be_added"

# Location of patch database.

PATCH_DATABASE_FILE="/var/sadm/patch/.patchDB"

# Used to remember how to backup and restore lu state.

BLUS_BACKUP_FILENAME=""
BLUS_BE_ICF=""
BLUS_BE_NAME=""
BLUS_BOOT_MNT=""
BLUS_RESTORE_FILE=""

# Used to remember how to backup and restore vfstab file.

VFST_BACKUP_FILENAME=""
VFST_BE_ICF=""
VFST_BE_NAME=""
VFST_BOOT_MNT=""
VFST_REAL_FILENAME=""
VFST_RESTORE_FILE=""

# profile keywords to disallow
PROFILE_DISALLOW_KEYWORDS="root_device boot_device filesys fdisk dontuse \
partitioning usedisk layout_constraint noreboot"

FLASH_INSTALL_PROFILE_DISALLOW_KEYWORDS="root_device boot_device filesys fdisk dontuse \
partitioning usedisk layout_constraint noreboot"

FLASH_UPDATE_PROFILE_DISALLOW_KEYWORDS="root_device boot_device filesys fdisk dontuse \
partitioning usedisk layout_constraint noreboot"

# All temporary files (that must be deleted when script starts and when it exits) 
# are defined below.

ABE_ICF="/tmp/.luupgrade.icf1.$$"
PBE_ICF="/tmp/.luupgrade.icf2.$$"
COMBINED_ICF="/tmp/.luupgrade.icf3.$$"
MOUNT_ERRLOG="/tmp/.luupgrade.mounterr.$$"
AT_ERRLOG="/tmp/.luupgrade.aterr.$$"
MAIL_LOGFILE="/tmp/.luupgrade.mail.$$"
MOUNT_SCAN_LOGFILE="/tmp/.luupgrade.mountscan.$$"
GREP_SCAN_LOGFILE="/tmp/.luupgrade.grepscan.$$"
GREP_SCAN2_LOGFILE="/tmp/.luupgrade.grepscan2.$$"
VOLMGT_SCAN_LOGFILE="/tmp/.luupgrade.volmgrscan.$$"
INSTPROG_LOGFILE="/tmp/.luupgrade.instprog.$$"
INSTPROG2_LOGFILE="/tmp/.luupgrade.instprog.$$"
BEICF_BACKUP="/tmp/.luupgrade.beicf.$$"
PFINSTALL_LOGFILE="/tmp/.luupgrade.pfinstall.log.$$"
PATCHFINISH_SCRIPT="/tmp/.luupgrade.patchfinish.$$"
PATCH_LOGFILE="/tmp/.luupgrade.patch.log.$$"
TMPFILE="/tmp/.luupgrade.tmp.$$"
TMPTRANS="/tmp/.luupgrade.translist.tmp.$$"
PROGRESS_REPORT_FILE="/tmp/.luupgrade.progrpt.tmp.$$"
TMP_RESULT_FILE="/tmp/.luupgrade.results.tmp.$$"
TMP_UPGRADE_PROFILE="/tmp/.luupgrade.profile.upgrade.$$"
TMP_FLASH_PROFILE="/tmp/.luupgrade.profile.flash.$$"
TMP_SORT_FLASH_PROFILE_1="/tmp/.luupgrade.profile.flash.sort.1.$$"
TMP_SORT_FLASH_PROFILE_2="/tmp/.luupgrade.profile.flash.sort.2.$$"
TMP_MENU_LST="/etc/lu/luupgrade.tmp.menu.lst.$$"

# This variable is used to remove all temp files when script starts and exits.
# ---> WHEN ADDING A TEMPORARY FILE ABOVE MAKE SURE YOU ADD IT TO THIS LIST!!!

ALL_TEMP_FILES="${PBE_ICF} ${ABE_ICF} ${COMBINED_ICF} ${MOUNT_ERRLOG} \
${AT_ERRLOG} ${MAIL_LOGFILE} ${MOUNT_SCAN_LOGFILE} ${GREP_SCAN_LOGFILE} \
${GREP_SCAN2_LOGFILE} ${VOLMGT_SCAN_LOGFILE} ${INSTPROG_LOGFILE} \
${TMP_UPGRADE_PROFILE} ${TMP_FLASH_PROFILE} \
${INSTPROG2_LOGFILE} ${BEICF_BACKUP} ${PATCHFINISH_SCRIPT} ${PFINSTALL_LOGFILE} \
${TMPFILE} ${PATCH_LOGFILE} ${TMPTRANS} ${PROGRESS_REPORT_FILE} ${TMP_RESULT_FILE} \
${TMP_MENU_LST}"

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

usage()
{
  ${LUPRINTF} -p2 "`gettext 'USAGE: %s [ -u | -f | -p | -r | -P | -R | -i | -c ] \
[ -l error_log ] [ -o outfile ] [ -N ] [ -X ] \
[ additional optional and required parameters ]:'`" "${LU_PROG_NAME}"

  ${LUPRINTF} -2 "`gettext 'OS Upgrade:      %s -u -n BE_name \
[ -l error_log ] [ -o outfile ] [ -N ] [ -X ] [ -D ] \
-s source_os_image_path [ -j profile_path ]'`" "${LU_PROG_NAME}"

  ${LUPRINTF} -2 "`gettext 'Flash Upgrade:   %s -f -n BE_name \
[ -l error_log ] [ -o outfile ] [ -N ] [ -X ] [ -D ] \
-s source_os_image_path ( -a archives | -j \
 profile_path | -J profile )'`" "${LU_PROG_NAME}"

  ${LUPRINTF} -2 "`gettext 'Add Packages:    %s -p -n BE_name \
[ -l error_log ] [ -o outfile ] [ -N ] [ -X ] \
( ( -s|-d ) source_packages_path ) [ -a pkg_admin_file ] \
[ -O pkgadd_options ] [ pkginst [ pkginst... ] ]'`" "${LU_PROG_NAME}"

  ${LUPRINTF} -2 "`gettext 'Remove Packages: %s -P -n BE_name \
[ -l error_log ] [ -o outfile ] [ -N ] [ -X ] \
[ -O pkgadd_options ] pkginst [ pkginst... ]'`" "${LU_PROG_NAME}"

  ${LUPRINTF} -2 "`gettext 'Check Packages:  %s -C -n BE_name \
[ -l error_log ] [ -o outfile ] [ -N ] [ -X ] \
[ -O pkgchk_options ] [ pkginst [ pkginst... ] ]'`" "${LU_PROG_NAME}"

  ${LUPRINTF} -2 "`gettext 'Package Info:    %s -I -n BE_name \
[ -l error_log ] [ -o outfile ] [ -N ] [ -X ] \
[ -O pkginfo_options ] [ pkginst [ pkginst... ] ]'`" "${LU_PROG_NAME}"

  ${LUPRINTF} -2 "`gettext 'Add Patches:     %s -t -n BE_name \
[ -l error_log ] [ -o outfile ] [ -N ] [ -X ] -s source_patches_path \
[ -O patchadd_options ] \
[ patchname [ patchname... ] ]'`" "${LU_PROG_NAME}"

  ${LUPRINTF} -2 "`gettext 'Remove Patches:  %s -T -n BE_name \
[ -l error_log ] [ -o outfile ] [ -N ] [ -X ] \
[ -O patchrm_options ] patchname [ patchname... ]'`" "${LU_PROG_NAME}"

  ${LUPRINTF} -2 "`gettext 'Run Installer:   %s -i -n BE_name \
[ -l error_log ] [ -o outfile ] [ -N ] [ -X ] -s install_image_path \
[ -O installer_options ]'`" "${LU_PROG_NAME}"

  ${LUPRINTF} -2 "`gettext 'Check Media:     %s -c \
[ -l error_log ] [ -o outfile ] [ -X ] -s image_path'`" "${LU_PROG_NAME}"

  ${LUPRINTF} -Ip2 "`gettext 'Any BE_name or options should be enclosed in single quotes.'`"

  if [ -z "$1" ] ; then
    exit_script 3
  fi
  exit_script "$1"
}

# Simple helper function used throughout this script.  Creates and
# sorts ICF entries into a canonical form.  Note that entries must be
# grouped by zone first, and can then be ordered by mount point.
create_icf()
{
	$LUBIN/lumk_iconf "$1" | sort -t: -k 6,6 -k 2,2
}

################################################################################
# Name:		checkZoneSupport		
# Description:	Check if the ABE and CBE are compatible with respect to zones.
#		If the alternate boot enviornment supports zone and the
#		current boot environement does not support, then they are incompatible. 
# Local Prefix:	czs_
# Arguments:	$1 = Name of the alternate boot environment.
#		$2 = The absolute path where the ABE is mounted.
# Returns:	0 - In case ABE and CBE are compatible.
#		1 - ABE and CBE are incompatible.
################################################################################

checkZoneSupport()
{
	czs_beName="$1"
	czs_bootMnt="$2"

	# debugging information
	${LUPRINTF} -lp2D - "`gettext 'Check zone capability of boot environment <%s> mounted at <%s>.'`" "${czs_beName}" "${czs_bootMnt}"

	# If currently running Envrionment is S9 or earlier and target root environment is
	# S10 or later, then do not allow this operation. This is to ensure proper installation
	# of non-global zones.

	# return 0 if the current boot environment supports non-global zones
	[ -f /etc/zones/index ] && return 0
	${LUPRINTF} -lp2D 2 "`gettext 'Current system does not support non-global zones.'`"

	# return 0 if the target boot environment does not support non-global zones
	[ -f ${czs_bootMnt}/etc/zones/index ] || return 0
	${LUPRINTF} -lp2D 2 "`gettext 'Target system requires support for non-global zones.'`"

	# the current boot environment does not support non-global zones and the
	# target boot environment does support non-global zones - output error
	# message and return 1

	${LUPRINTF} -Eelp2 "`gettext 'The boot environment <%s> supports non-global zones.\
The current boot environment does not support non-global zones. Releases prior to \
Solaris 10 cannot be used to maintain Solaris 10 and later releases that include \
support for non-global zones. You may only execute the specified operation on a \
system with Solaris 10 (or later) installed.'`" "${czs_beName}"

	return 1
}

################################################################################
# Name:		interruptHandler
# Description:	Handle an armed shell "trap"
# Local Prefix:	<none>
# Arguments:	<none>
# Example:      trap "interruptHandler" 1 2 3 9 15
# Returns:	call script cleanup function with exit code "4"
################################################################################

interruptHandler()
{
  # Reset all traps to be ignored so that termination can take place
  # without further interrupts

  # 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

  # Output indication of interrupt processed
  ${LUPRINTF} -Ilp2 "`gettext 'Interrupted (Signal received): cleaning up...'`"

  # Cause script to cleanup and exit with exit code '4'
  exit_script 4
}

################################################################################
# Name:		exit_script
# Description:	Perform cleanup operations and exit this script.
# Local Prefix:	<none>
# Arguments:	$1 = optional exit value for script ("" or none is = "0")
# Example:      exit_script "0"
# Returns:	<none>
################################################################################

exit_script()
{
  # Restore the vfstab file.

  restore_vfstab_file

  # Umount the abe.

  abe_umount

  # unmount the miniroot
  umount_miniroot

  # Remove any temporary mount points that may have been placed in /tmp

  for dname in `/usr/sbin/mount | /bin/grep '^/tmp/.alt.' | /bin/awk ' { print $1 } '` ; do
    lulib_unmount_pathname $dname 2>/dev/null 1>&2
    if [ "$?" = "0" ] ; then
      /bin/rmdir $dname 2>/dev/null 1>&2
    fi
  done

  # Remove the copy lock.

  copylock_delete

  # Send the mail log file.

  maillog_send ""

  # Remove all temporary files only if debugging is not enabled;
  # otherwise, leave them behind for possible debugging purposes.

  if [ "$LU_DEBUG" -eq "0" ] ; then
    /bin/rm -f ${ALL_TEMP_FILES}
  else
    tempnames=""
    for tempname in ${ALL_TEMP_FILES} ; do
      if [ -f "${tempname}" ] ; then
	tempnames="$tempname $tempnames"
      fi
    done
    if [ -n "${tempnames}" ] ; then
      ${LUPRINTF} -lp2D - "`gettext 'Because debugging is enabled, these \
temporary files were not removed: <%s>.'`" "${tempnames}"
    fi
  fi

  # Exit.

  if [ -z "$1" ] ; then
    exit 0
  fi
  exit $1
}

################################################################################
# Name:		add_auto_os_patches
# Description:	Execute the automatic operating system patch installation script 
#		from an install media
# Local Prefix:	aaop_
# Arguments:	$1 = boot environment name (e.g. "be1").
#		$2 = boot environment mount point (e.g. /.alt.01234).
#		$3 = media install configuration directory 
#			(e.g. latest/Solaris_x/Tools/Boot/usr/sbin/install.d/install_config).
#		$4 = media install patches directory (e.g. latest/Solaris_x/Patches).
#		$5 = upgrade log file on boot environment 
#			(e.g. /.alt.01234/var/sadm/system/logs/upgrade_log).
#		$6 = no execute mode flag ("" if not no execute mode).
#		$7 = file to hold contents of patch add log
#		$8 = install media directory.
# Example:      add_auto_os_patches "${beName}" "${boot_mnt}" "${toolsInstallConfig}" 
#		"${patchdir}" "${boot_mnt}/var/sadm/system/logs/upgrade_log" 
#		"${noExecuteMode}" "${installMediaPath}"
# Returns:	0 - successful.
#		1 - failure.
################################################################################

add_auto_os_patches()
{
  aaop_beName="$1"
  aaop_bootMnt="$2"
  aaop_installConfigDir="$3"
  aaop_patchesDir="$4"
  aaop_upgradeLogFile="$5"
  aaop_noExecuteMode="$6"
  aaop_autoPatchLogfile="$7"
  aaop_installMediaPath="$8"

  # Locate the patch_finish script.
  aaop_patchFinishScript="${aaop_installConfigDir}/patch_finish"

  # If an upgrade log file was specified, create an "-a file" option
  # to be used with luprintf. Leaving it blank causes no append to be done.
  aaop_aflg=""
  [ -n "${aaop_upgradeLogFile}" ] && aaop_aflg="-a ${aaop_upgradeLogFile}"

  # If no auto patch log file specified, direct results to /dev/null.
  aaop_autoPatchLogFile=${aaop_autoPatchLogFile:=/dev/null}

  aaop_ret=0
  if [ -f "${aaop_patchFinishScript}" -a -s "${aaop_patchFinishScript}" ] ; then
    ${LUPRINTF} -lp1 ${aaop_aflg} "`gettext 'Adding operating system patches to the BE <%s>.'`" "${aaop_beName}"

    # Determine if the patch_finish script accepts arguments (S9 and later); 
    # if so, then patch_finish can be called directly; otherwise it must be
    # edited to change references to "/cdrom" (S8U7 and earlier). Because the
    # previously released patch_finish scripts cannot be changed, must examine
    # existing patch_finish script. If it is a shell script and does not have
    # the getopts call, it is the old script without the command line interface.
    # If it is not a shell script, or if it is a shell script and it does have
    # the getopts call, it has the new command line interface.

    aaop_patchScriptOld=''
    /bin/fgrep 'getopts' ${aaop_patchFinishScript} 1>/dev/null 2>&1 || aaop_patchScriptOld='yes'
    /bin/head -1 ${aaop_patchFinishScript} | /bin/fgrep '#!/sbin/sh' 1>/dev/null 2>&1 || aaop_patchScriptOld=''

    if [ -n "${aaop_patchScriptOld}" ] ; then
      # Old patch script - must use sed to edit it and then run the modified copy.
      /bin/sed "s%SOL_PATCHDIR=.*%SOL_PATCHDIR=${aaop_patchesDir}%g;s%INSTALLROOT=.*%INSTALLROOT=${aaop_bootMnt}%g;s%SI_OSNAME=\(.*\)/cdrom/.cdtoc%SI_OSNAME=\1${aaop_installMediaPath}/.cdtoc%g" < ${aaop_patchFinishScript} > ${PATCHFINISH_SCRIPT}
      if [ "$?" -ne "0" ] ; then
	${LUPRINTF} -Eelp2 "`gettext 'Unable to modify the operating system patch installation script <%s>.'`" "${aaop_patchFinishScript}"
	return 1
      fi
      # patchadd does not work on an ABE /export/root. 
      # Must chroot. Exception: because an OS upgrade may use
      # volmgt, we can't do a chroot. A previous check
      # would have aborted the upgrade if a non-OS upgrade
      # attempted to use a device under volmgt.
      if [ -n "${aaop_noExecuteMode}" ] ; then
	${LUPRINTF} -lp1 "`gettext 'Execute Command <%s>.'`" "${aaop_patchFinishScript}"
	aaop_ret=0
      elif [ -n "${aaop_upgradeLogFile}" ] ; then
	/bin/sh ${PATCHFINISH_SCRIPT} 2>&1 | tee -a "${aaop_upgradeLogFile}" 1>${aaop_autoPatchLogFile}
	aaop_ret=$?
      else
	/bin/sh ${PATCHFINISH_SCRIPT} 1>${aaop_autoPatchLogFile} 2>&1
	aaop_ret=$?
      fi
    else
      # New patch script - call directly with command line arguments -R and -c.
      if [ -n "${aaop_noExecuteMode}" ] ; then
	${LUPRINTF} -lp1 "`gettext 'Execute Command <%s>.'`" "${aaop_patchFinishScript} -R \"${aaop_bootMnt}\" -c \"${aaop_installMediaPath}\""
      elif [ -n "${aaop_upgradeLogFile}" ] ; then
	${aaop_patchFinishScript} -R "${aaop_bootMnt}" -c "${aaop_installMediaPath}" 2>&1 | tee -a "${aaop_upgradeLogFile}" 1>${aaop_autoPatchLogFile}
	aaop_ret=$?
      else
	${aaop_patchFinishScript} -R "${aaop_bootMnt}" -c "${aaop_installMediaPath}" 1>${aaop_autoPatchLogFile} 2>&1
	aaop_ret=$?
      fi
    fi
  else
    ${LUPRINTF} -lp2D - ${aaop_aflg} "`gettext 'No default operating system patches present on media - no patches automatically applied to the BE.'`"
  fi

  return ${aaop_ret}
}

################################################################################
# Name:		make_at_command
# Description:	Construct a command line that will schedule an upgrade that can be given to 'at'.
# Local Prefix:	mac_
# Arguments:	$1 = boot environment name (e.g. "be1").
#		$2 = media mount point to upgrade operating system from.
# Example:      make_at_command "${beName}" "${media}" | /bin/at -m "$attime"
# Returns:	<none>
################################################################################

make_at_command()
{
  mac_beName="$1"
  mac_media="$2"

  if [ -n "$1" -a -d "${mac_media}" ] ; then
    echo "
	  if [ -s /etc/default/lu ]
	  then
		  . /etc/default/lu
	  else
		  LUBIN=/usr/lib/lu
		  COPYLOCK=/etc/lu/COPY_LOCK
	  fi
	  . \$LUBIN/lulib
	  # Avoid race with any scheduled copy
	  sleep 240
	  while [ 1 ]
	  do
		  if [ -f \${COPYLOCK} ]
		  then
			  . \${COPYLOCK}
			  if [ \"\$CL_STATUS\" = \"SCHEDULED\" ]
			  then
				  echo \"\`gettext 'ERROR: The Live Upgrade Copy did not start at the expected time. Upgrade aborted.'\`\" | tee -a /etc/lu/lu.log
				  exit 2
			  elif [ \"\$CL_STATUS\" = \"UPGRADING\" ]
			  then
				  echo \"\`gettext 'ERROR: It appears that another Live Upgrade upgrade is running.'\`\" >& 2
				  echo \"\`gettext 'This scheduled upgrade will be aborted.'\`\" | tee -a /etc/lu/lu.log
				  exit 2
			  elif [ \"\$CL_STATUS\" = \"ACTIVE\" ]
			  then
				  sleep 299
				  continue
			  else
				   echo \"\`gettext 'ERROR: Unknown Copy Lock status. The scheduled upgrade will be aborted.'\`\" | tee -a /etc/lu/lu.log
				  exit 2
			  fi
		  else
			  break
		  fi
	  done
	  status=\`${LUETCBIN}/ludo get_be_status_from_be_name \"${mac_beName}\"\`
	  if [ \"\$status\" != \"C\" ]
	  then
		  echo \"\`gettext 'ERROR: Target BE is not Complete.'\`\" >& 2
		  exit 1
	  fi
	  $LUBIN/luupgrade -u -n \"${mac_bename}\" -s ${mac_media} >> /etc/lu/lu.log 2>&1
	  "
    ${LUPRINTF} -lp2D - "`gettext 'Constructed command to upgrade the BE <%s> from media <%s>.'`" "${mac_beName}" "${mac_media}"
  else
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to construct command to upgrade the BE <%s> from media <%s>.'`" "${mac_beName}" "${mac_media}"
  fi
}

################################################################################
# Name:		abe_icfMount
# Description:	Mount a single ABE that can be automatically umounted when the script exits.
# Local Prefix:	aim_
# Arguments:	$1 = ICF file to use to mount the boot environment.
# Example:	abe_icfMount "${ICF_FILE}"
# Returns:	0 - successful.
#		1 - failure.
# Side Effects: AIM_BEBOOTMNT is set to the mount point of the just mounted BE (e.g. /.alt.1234)
################################################################################

abe_icfMount()
{
  aim_beIcf="$1"

  if [ -f "${BEICF_BACKUP}" -a -s "${BEICF_BACKUP}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Internal logic error (requested to mount BE from <%s> when BE already mounted).'`" "${aim_beIcf}"
    return 1
  fi
  AIM_BEBOOTMNT=""
  ERRMSG="`/bin/cp \"${aim_beIcf}\" \"${BEICF_BACKUP}\" 2>&1`"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to create backup copy of file <%s> on <%s>.'`" "${aim_beIcf}" "${BEICF_BACKUP}"
    return 1
  fi
  aim_beBootMnt="`LU_OUTPUT_FORMAT=text $LUBIN/lumount -i \"${BEICF_BACKUP}\" \"${MEDIAROOTMOUNTPOINT}\" 2>${TMP_RESULT_FILE}`"
  if [ "$?" -ne "0" ] ; then
    /bin/rm -f ${BEICF_BACKUP}
    [ -s "${TMP_RESULT_FILE}" ] && ${LUPRINTF} -elp2 '%R' < "${TMP_RESULT_FILE}"
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to mount ABE disk slices: <%s %s>.'`" "${aim_beBootMnt}" "`/bin/cat ${TMPFILE}`"
    return 1
  fi
  AIM_BEBOOTMNT=${aim_beBootMnt}
  ${LUPRINTF} -lp2D - "`gettext 'Mounting ABE from ICF file <%s> to mount point <%s>.'`" "${BEICF_BACKUP}" "${AIM_BEBOOTMNT}"
  return 0
}

################################################################################
# Name:		abe_checkMounted
# Description:	Check to see if a BEs root slice is mounted at an expected mount point. If it
#		is not, cause the BEs slices to be mounted.
# Local Prefix:	acm_
# Arguments:	$1 = ICF file to use for the boot environment to be mounted.
# Example:	abe_believeMounted "${ICF_FILE}"
# Returns:	0 - successful.
#		1 - failure.
################################################################################

abe_checkMounted()
{
  acm_beIcf="$1"

  # See if the root file system for the BE is mounted at the expected
  # media root mount point. If it is not, cause it to be mounted for
  # other operations that depend on it being available.
  ${LUETCBIN}/ludo get_root_slice_from_mntpt "${MEDIAROOTMOUNTPOINT}" 2>/dev/null 1>&2
  if [ "$?" -eq "0" ] ; then
    ${LUPRINTF} -lp2D - "`gettext 'Boot environment mount check: still mounted at <%s>'`" \
"${MEDIAROOTMOUNTPOINT}"
    abe_believeMounted "${acm_beIcf}" "${MEDIAROOTMOUNTPOINT}"
  else
    ${LUPRINTF} -lp2D - "`gettext 'Boot environment mount check: remounting at <%s>'`" \
"${MEDIAROOTMOUNTPOINT}"
    abe_icfMount "${acm_beIcf}"
  fi

  ${LUPRINTF} -lp2D - "`gettext 'ABE slices (re)mounted at <%s>.'`" "${MEDIAROOTMOUNTPOINT}"

  return "$?"
}

################################################################################
# Name:		abe_believeMounted
# Description:	Believe that the an ABE specified by an ICF file has been mounted (trust me).
# Local Prefix:	abm_
# Arguments:	$1 = ICF file to use to believe that the boot environment is mounted.
#		$2 = mount point to believe the BE is mounted on
# Example:	abe_believeMounted "${ICF_FILE}"
# Returns:	0 - successful.
#		1 - failure.
################################################################################

abe_believeMounted()
{
  abm_beIcf="$1"
  abm_beMntPt="$2"

  if [ -f "${BEICF_BACKUP}" -a -s "${BEICF_BACKUP}" ] ; then
    /bin/cmp -s "${BEICF_BACKUP}" "${abm_beIcf}"
    [ $? -eq 0 ] && return 0
    ${LUPRINTF} -Eelp2 "`gettext 'Internal logic error (requested to believe \
BE mounted from <%s> but BE already mounted from <%s>).'`" "${abm_beIcf}" "${BEICF_BACKUP}"
    return 1
  fi
  ERRMSG="`/bin/cp \"${abm_beIcf}\" \"${BEICF_BACKUP}\" 2>&1`"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to create backup copy of file <%s> on \
<%s>.'`" "${abm_beIcf}" "${BEICF_BACKUP}"
    return 1
  fi
  AIM_BEBOOTMNT="${abm_beMntPt}"
  ${LUPRINTF} -lp2D - "`gettext 'Believe that ABE mounted from ICF file <%s> to \
mount point <%s>.'`" "${BEICF_BACKUP}" "${AIM_BEBOOTMNT}"
  return 0
}

################################################################################
# Name:		abe_umount
# Description:	Unmount a single ABE that may have been previously mounted with abe_icfMount.
# Local Prefix:	abu_
# Arguments:	<none>
# Example:	abe_umount
# Returns:	From luumount:
#		0 - successful.
#		1 - failure.
#		2 - failure.
# Side Effects:	AIM_BEBOOTMNT is set to the null string
################################################################################

abe_umount()
{
  abu_ret="0"
  if [ -f "${BEICF_BACKUP}" -a -s "${BEICF_BACKUP}" ] ; then
    ${LUPRINTF} -lp2D - "`gettext 'Unmounting ABE mount point <%s> from ICF file <%s>.'`" "${AIM_BEBOOTMNT}" "${BEICF_BACKUP}"
    ${LUBIN}/luumount -f -i ${BEICF_BACKUP}
    abu_ret="$?"
    /bin/rm -f ${BEICF_BACKUP}
  fi
  AIM_BEBOOTMNT=""
  return ${abu_ret}
}

################################################################################
# Name:		backup_vfstab_file
# Description:	Backup an BE's vfstab file so that it can be restored after upgrade operations.
# Local Prefix:	bvft_
# Arguments:	$1 = mount point for vfstab file (e.g. /.alt.01234).
#		$2 = boot environment name.
#		$3 = boot environment ICF file (for luumount/lumount on restore).
# Example:	backup_vfstab_file "${BOOT_MNT}" "${BE_NAME}" "${BE_ICF}"
# Returns:	0 - successful.
#		1 - failure to backup the original VFSTAB file.
#		2 - previous backup present - manual intervention required.
################################################################################

backup_vfstab_file()
{
  bvtf_bootMnt="$1"
  bvtf_beName="$2"
  bvtf_abeIcf="$3"

  if [ -f "${bvtf_bootMnt}/etc/vfstab.pf2" -a -s "${bvtf_bootMnt}/etc/vfstab.pf2" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Live upgrade has detected that a previous \
operating system upgrade operation may have been interrupted: a backup vfstab \
file exists on the BE to be upgraded. You must first manually use lumount to \
mount the BE (by executing the command <lumount %s>), then cd to the /etc \
directory on the BE just mounted, then examine the files vfstab and vfstab.pf2 \
and determine which file is the correct vfstab file for the BE. If vfstab.pf2 \
is the correct contents, execute the command </bin/mv vfstab.pf2 vfstab>. If \
vfstab is the correct contents, execute the command </bin/rm vfstab.pf2>. Then \
unmount the BE by executing the command <luumount %s> and run %s again.'`" \
"${bvtf_beName}" "${bvtf_beName}" "${LU_PROG_NAME}"
    return 2
  fi

  ERRMSG="`/bin/cp -p \"${bvtf_bootMnt}/etc/vfstab\" \"${bvtf_bootMnt}/etc/vfstab.pf2\" 2>&1`"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to save backup copy of vfstab file <%s> on BE <%s>.'`" "${bvtf_bootMnt}/etc/vfstab" "${bvtf_bootMnt}/etc/vfstab.pf2"
    return 1
  fi

  VFST_BE_ICF="${bvtf_abeIcf}"
  VFST_BACKUP_FILENAME="/etc/vfstab.pf2"
  VFST_BE_NAME="${bvtf_beName}"
  VFST_BOOT_MNT="${bvtf_bootMnt}"
  VFST_REAL_FILENAME="/etc/vfstab"
  VFST_RESTORE_FILE="yes"
  return 0
}

################################################################################
# Name:		change_vfstab_bootmnt
# Description:	Change the mount point at which the backup vfstab file can be found - this is
#		done because pfinstall changes the mount point from where it was originally
#		mounted (from /.alt.* to /a).
# Local Prefix:	<none>
# Arguments:	<none>
# Example:	change_vfstab_bootmnt "${BOOT_MNT}"
# Returns:	<none>
################################################################################

change_vfstab_bootmnt()
{
  VFST_BOOT_MNT="$1"
}

################################################################################
# Name:		restore_vfstab_file
# Description:	Restore a BE's backup vfstab file.
# Local Prefix:	vfst_
# Arguments:	
# Example:	restore_vfstab_file
# Returns:	0 - successful.
#		1 - failure to restore backup of original VFSTAB file.
################################################################################

restore_vfstab_file()
{
  rvft_restore_errs="0"
  if [ -n "${VFST_RESTORE_FILE}" ] ; then
    # The vfstab file needs to be restored; algorithm:
    # 1. check to see if backup file found:
    #    --> if not: umount and remount BE as its mount point may have changed (pfinstall does this...).
    # 2. check to see if backup file found:
    #    --> if not: then remount failed or the backup copy could not be found.
    #    --> else: restore the backup file to the original vfstab file.

    if [ ! -f "${VFST_BOOT_MNT}/${VFST_BACKUP_FILENAME}" ] ; then
      abe_umount
      $LUBIN/luumount -f -i ${VFST_BE_ICF} >/dev/null 2>&1
      abe_icfMount ${VFST_BE_ICF}
      if [ "$?" -ne "0" ] ; then
	${LUPRINTF} -Eelp2 "`gettext 'Unable to remount the target BE to restore vfstab file <%s>.'`" "${VFST_BE_NAME}"
	rvft_restore_errs="1"
      else
	VFST_BOOT_MNT="${AIM_BEBOOTMNT}"
      fi
    fi

    if [ ! -f "${VFST_BOOT_MNT}/${VFST_BACKUP_FILENAME}" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'Unable to locate backup copy of the target BEs /etc/vfstab file.'`"
      rvft_restore_errs="1"
    else
      ${LUPRINTF} -lp2D - "`gettext 'Restoring VFSTAB file <%s> to <%s>.'`" "${VFST_BOOT_MNT}/${VFST_BACKUP_FILENAME}" "${VFST_BOOT_MNT}/${VFST_REAL_FILENAME}"
      ERRMSG="`/bin/rm -f \"${VFST_BOOT_MNT}/${VFST_REAL_FILENAME}.pf1\" 2>&1`"
      ERRMSG="${ERRMSG} `/bin/mv -f \"${VFST_BOOT_MNT}/${VFST_REAL_FILENAME}\" \"${VFST_BOOT_MNT}/${VFST_REAL_FILENAME}.pf1\" 2>&1`"
      ERRMSG="${ERRMSG} `/bin/mv -f \"${VFST_BOOT_MNT}/${VFST_BACKUP_FILENAME}\" \"${VFST_BOOT_MNT}/${VFST_REAL_FILENAME}\" 2>&1`"
      if [ "$?" -ne "0" ] ; then
	rvft_restore_errs="1"
	${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
	${LUPRINTF} -Eelp2 "`gettext 'Problems restoring ABE vfstab file.'`"
      fi
      /bin/rm -f "${VFST_BOOT_MNT}/${VFST_REAL_FILENAME}.pf1"
    fi

    if [ "${rvft_restore_errs}" -ne "0" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'Live upgrade was unable to restore the \
/etc/vfstab file on the BE. You must manually use lumount to mount the BE (by \
executing the command <lumount %s>), then cd to the /etc directory on the BE \
just mounted, then examine the files vfstab and vfstab.pf2 and determine which \
file is the correct vfstab file for the BE. If vfstab.pf2 is the correct \
contents, execute the command </bin/mv vfstab.pf2 vfstab>. If vfstab is the \
correct contents, execute the command </bin/rm vfstab.pf2>. In most cases, \
vfstab.pf2 will be the correct vfstab file to use. Then unmount the BE by \
executing the command <luumount %s>.'`" "${VFST_BE_NAME}" "${VFST_BE_NAME}"
    fi

  fi
  VFST_BACKUP_FILENAME=""
  VFST_BE_NAME=""
  VFST_REAL_FILENAME=""
  VFST_RESTORE_FILE=""
  # DO NOT RESET VFST_BOOT_MNT - EXPECTED AS SIDE EFFECT OF CALLING RESTORE....

  return ${rvft_restore_errs}
}

################################################################################
# Name:		maillog_addFile
# Description:	Add the contents of a file to the mail log file.
# Local Prefix:	maf_
# Arguments:	$1 = name of text file to include in mail log file.
#		$2 = single comment line to be appended to the mail log file before the contents
#			of the text file is included.
# Example:      maillog_addFile "${PFINSTALL_LOGFILE}" "`gettext 'pfinstall diagnostics output'`"
# Returns:	<none>
################################################################################

maillog_addFile()
{
  maf_fileName="$1"
  maf_comments="$2"
  if [ -n "${MAILLOGTO}" -a -f "${maf_fileName}" -a -s "${maf_fileName}" ] ; then
    ${LUPRINTF} +X -a "${MAIL_LOGFILE}" "%s: %s\n" "`/bin/date`" "${maf_comments}" 1>${TMPFILE} 2>&1
    if [ "$?" -ne "0" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'Unable to append results for <%s> from file \
<%s> to mail log file <%s>: <%s>.'`" "${maf_comments}" "${maf_fileName}" \
"${MAIL_LOGFILE}" "`/bin/cat ${TMPFILE}`"
    else
      /bin/cat ${maf_fileName} >> ${MAIL_LOGFILE}
    fi
  fi
}

################################################################################
# Name:		maillog_setSubject
# Description:	Set the subject line to be used when the mail log file is sent.
# Local Prefix:	<none>
# Arguments:	$1 = text of subject line to be used when the mail log file is sent.
# Example:      maillog_setSubject "`gettext 'Upgrade Successful.'`"
# Returns:	<none>
################################################################################

maillog_setSubject()
{
  MAIL_SUBJECT="$1"
}

################################################################################
# Name:		maillog_send
# Description:	Send the mail log file if it exists, is non-zero in length, and the "MAILLOGTO"
#		global environment variable is set.
# Local Prefix:	<none>
# Arguments:	<none>
# Example:      maillog_send
# Returns:	<none>
################################################################################

maillog_send()
{
  if [ -n "${MAILLOGTO}" -a -f "${MAIL_LOGFILE}" -a -s "${MAIL_LOGFILE}" -a -z "${MAIL_DISABLE}" ] ; then
    if [ -z "${MAIL_SUBJECT}" ] ; then
      MAIL_SUBJECT="$*"
    fi
    ERRMSG=`/bin/mailx -s "\`gettext 'Live Upgrade Log: '\` ${MAIL_SUBJECT}" ${MAILLOGTO} < ${MAIL_LOGFILE} 2>&1`
    if [ "$?" -ne "0" ] ; then
      ${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
      ${LUPRINTF} -Eelp2 "`gettext 'Warning: unable to send the maillog file to <%s>.'`" "${MAILLOGTO}"
    fi
    /bin/rm -f "${MAIL_LOGFILE}"
  fi
}

################################################################################
# Name:		checkUserUpgradeProfile
# Description:	check file to see if it can be used in an upgrade profile
# Local Prefix:	cpf_
# Arguments:	$1 = name of file to verify.
# Example:      checkUserUpgradeProfile "${dug_profilePath}"
# Returns:	0 - successful.
#		1 - failure.
################################################################################

checkUserUpgradeProfile()
{
  cpf_fileName="$1"

  # make sure file exists
  if [ ! -f "${cpf_fileName}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The profile <%s> does not exist or is not a file.'`" \
"${cpf_fileName}"
    return 1
  fi

  # make sure the file appears to be an upgrade profile
  ${LUBIN}/lucomm_del "${cpf_fileName}" | /bin/head -1 | \
/bin/egrep -s '^[ 	]*install_type[ 	]*upgrade[ 	]*$' 1>/dev/null
  if [ $? -ne 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The first line of file <%s> is not \
<install_type upgrade>'`" "${cpf_fileName}"
    return 1
  fi

  # make sure no incompatible keywords are present
  for KW in ${PROFILE_DISALLOW_KEYWORDS} ; do
    /bin/egrep -s "^[ 	]*${KW}" "${cpf_fileName}" 1>/dev/null
    if [ $? -eq 0 ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'The profile <%s> may not contain any \
<%s> keywords.'`" "${cpf_fileName}" "${KW}"
      return 1
    fi
  done

  return 0
}

################################################################################
# Name:		checkUserFlashProfile
# Description:	check file to see if it can be used in a flash profile
# Local Prefix:	cpf_
# Arguments:	$1 = name of file to verify.
# Example:      checkUserFlashProfile "${dfi_profilePath}"
# Returns:	0 - successful.
#		1 - failure.
################################################################################

checkUserFlashProfile()
{
  cuf_fileName="$1"

  # make sure file exists
  if [ ! -f "${cuf_fileName}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The profile <%s> does not exist or is not a file.'`" \
"${cuf_fileName}"
    return 1
  fi
  # make sure the file appears to be an flash profile
  ${LUBIN}/lucomm_del "${cuf_fileName}" | /bin/head -1 | \
    /bin/egrep -s '^[	]*install_type[ 	]*flash_install[ 	]*$' 1>/dev/null
  if [ $? -eq 0 ] ; then
    FLASH_TYPE="install"
    # make sure no incompatible keywords are present
    for KW in ${FLASH_INSTALL_PROFILE_DISALLOW_KEYWORDS} ; do
	/bin/egrep -s "^[ 	]*${KW}" "${cuf_fileName}" 1>/dev/null
	if [ $? -eq 0 ] ; then
	${LUPRINTF} -Eelp2 "`gettext 'The profile <%s> may not contain any \
          <%s> keywords.'`" "${cuf_fileName}" "${KW}"
	return 1
	fi
    done
    return 0
 fi

  # make sure the file appears to be an flash profile
  ${LUBIN}/lucomm_del "${cuf_fileName}" | /bin/head -1 | \
    /bin/egrep -s '^[	]*install_type[ 	]*flash_update[ 	]*$' 1>/dev/null
  if [ $? -eq 0 ] ; then
    FLASH_TYPE="update"
    # make sure no incompatible keywords are present
    for KW in ${FLASH_UPDATE_PROFILE_DISALLOW_KEYWORDS} ; do
	/bin/egrep -s "^[ 	]*${KW}" "${cuf_fileName}" 1>/dev/null
	if [ $? -eq 0 ] ; then
	${LUPRINTF} -Eelp2 "`gettext 'The profile <%s> may not contain any \
          <%s> keywords.'`" "${cuf_fileName}" "${KW}"
	return 1
	fi
    done
    return 0
 fi

 ${LUPRINTF} -Eelp2 "`gettext 'The first line of file <%s> is not \
	    <install_type flash_install or flash_update>'`" "${cuf_fileName}"
 return 1
}

################################################################################
# Name:		copylock_create
# Description:	Create a copy lock file; complain if it already exists or it can not be created.
# Local Prefix:	clc_
# Arguments:	$1 = variable name to set 
#		$2 = variable value to set variable name to
#		$3 = "yes" if ok to delete copylock when script exits; "" if not ok to delete
# Example:      copylock_create "CL_STATUS" "UPDATING" "yes"
# Returns:	0 - succeeded - copylock created.
#		1 - failed.
################################################################################

copylock_create()
{
  clc_variableName="$1"
  clc_variableValue="$2"
  clc_canDelete="$3"
  if [ -f "${COPYLOCK}" -a -s "${COPYLOCK}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to create copy lock for operation; \
a copy lock already exists: <%s>.'`" "`/bin/cat ${COPYLOCK}`"
    return 1
  fi
  ${LUPRINTF} +X -a ${COPYLOCK} "%s=\"%s\"" "${clc_variableName}" "${clc_variableValue}"
  clc_ret="$?"
  COPYLOCK_CAN_BE_DELETED="${clc_canDelete}"
  return "${clc_ret}"
}

################################################################################
# Name:		copylock_append
# Description:	Append to a copy lock file; complain if it does not exist or it can not be updated.
# Local Prefix:	cla_
# Arguments:	$1 = variable name to set 
#		$2 = variable value to set variable name to
# Example:      copylock_append "CL_TARGET_BE" "${beName}"
# Returns:	0 - succeeded - copylock updated.
#		1 - failed.
################################################################################

copylock_append()
{
  cla_variableName="$1"
  cla_variableValue="$2"
  if [ ! -f "${COPYLOCK}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Internal logic error (copy lock file does not exist).'`"
    return 1
  fi
  ${LUPRINTF} +X -a ${COPYLOCK} "%s=\"%s\"" "${cla_variableName}" "${cla_variableValue}"
  cla_ret="$?"
  return "${cla_ret}"
}

################################################################################
# Name:		copylock_delete
# Description:	If the copylock file exists and can be deleted, delete it.
# Local Prefix:	<none>
# Arguments:	<none>
# Example:      copylock_delete
# Returns:	<none>
################################################################################

copylock_delete()
{
  if [ -n "${COPYLOCK_CAN_BE_DELETED}" -a -f "${COPYLOCK}" ] ; then
    /bin/rm -f ${COPYLOCK}
  fi
  COPYLOCK_CAN_BE_DELETED=""
}

################################################################################
# Name:		resolve_transfer_list
# Description:	Process the transfer list.  The transfer list
#                  contains two entries per line.  This routine
#                  reads each line.  If the first entry resolves
#                  to a number of entries, then multiple entries
#                  are output to the resulting file.
# Local Prefix:	rtl_
# Arguments:	$1 - The transfer list to process
# Example:         resolve_transfer_list /etc/lu/lu_transfer_list
# Returns:	0 on success, non-zero otherwise.  The new transferlist
#                  is output to stdout, for use in backquoted expressions.
################################################################################
resolve_transfer_list()
{
  rtl_list="$1"
  ${LUBIN}/lucomm_del ${rtl_list} | while read fpattern pkg type; do

    # if 'type' field is of type MERGE, parse out the mergescript
    # and prepend miniroot location.
    ttype=`echo ${type} | /bin/cut -d: -f1`
    if [ "${ttype}" = "MERGE" ] ; then
	mergescript=`echo ${type} | /bin/cut -d: -f2`
	type="${ttype}:${dfi_miniroot}/${mergescript}"
    fi

    flist=`/bin/ls ${fpattern} 2> /dev/null`
    # we don't include files that aren't on the system
    if [ $? = 0 ] ; then
	for i in ${flist} ; do
	  if [ "$dfi_tltcap" = "yes" ] ; then
	    echo "$i $pkg $type" >> ${TMPTRANS}
	  else
	    echo "$i $pkg" >> ${TMPTRANS}
	  fi
        done
    fi
  done

  # add the name_service.xml entry only if pfinstall
  # supports the transfer list types (tlt) capability
  if [ "$dfi_tltcap" = "yes" ]; then
    echo "/var/svc/profile/name_service.xml SUNWcsr MERGE:${dfi_miniroot}/usr/sbin/install.d/mergescripts/merge_name_service" >> ${TMPTRANS}
  fi

  # add some extra entries that can't be properly expressed
  # in a static list.  If no domain, ignore these entries.
  DN=`/bin/domainname 2> /dev/null`
  if [ $? = 0 -a -n "$DN" ] ; then
    if [ "$dfi_tltcap" = "yes" ] ; then
	echo "/var/yp/binding/$DN SUNWnisr OVERWRITE" >> ${TMPTRANS}
	echo "/var/yp/binding/$DN/ypservers SUNWnisr OVERWRITE" >> ${TMPTRANS}
    else
	echo "/var/yp/binding/$DN SUNWnisr" >> ${TMPTRANS}
	echo "/var/yp/binding/$DN/ypservers SUNWnisr" >> ${TMPTRANS}
    fi
	
  fi
  echo ${TMPTRANS}
  return 0
}

################################################################################
# Name:		do_checkMiniroot
# Description:	Scan media location and determine path to miniroot.
# Local Prefix: dmr_
# Arguments:	$1 = media mount point to check.
# Returns:      0 = check was successful. - location is output to stdout
#		3 = user input error.
################################################################################
do_checkMiniroot()
{

  dmr_media="$1"

  if [ ! -d "${dmr_media}" ] ; then
    ${LUPRINTF} -Eel2 "`gettext 'The media directory does not exist (%s).'`" "${dmr_media}"b
    return 2
  fi

  # find the media cd table of contents: if not found, can not figure version,
  # so cannot use it to flash a BE
  dmr_media_cdtoc="${dmr_media}/.cdtoc"
  if [ ! -f "${dmr_media_cdtoc}" -o ! -s "${dmr_media_cdtoc}" ] ; then
    ${LUPRINTF} -Eel2 "`gettext 'The media is not a recognized installation media.'`"
    return 2
  fi

  # Looks like standard format media with a table of contents;
  # Locate the various subdirectories in the media we expect of a Solaris distribution.

  dmr_errorsFound=""
  dmr_cdtoc_prodname="`/bin/grep '^PRODNAME=' ${dmr_media_cdtoc} | /bin/head -1 | /bin/sed 's/PRODNAME=//'`"
  dmr_cdtoc_prodvers="`/bin/grep '^PRODVERS=' ${dmr_media_cdtoc} | /bin/head -1 | /bin/sed 's/PRODVERS=//'`"
  dmr_cdtoc_proddir="`/bin/grep '^PRODDIR=' ${dmr_media_cdtoc} | /bin/head -1 | /bin/sed 's/PRODDIR=//'`"
  dmr_media_proddir="${dmr_media}/${dmr_cdtoc_proddir}"
  dmr_media_toolsDir="`dirname ${dmr_media_proddir}`/Tools"

  if [ -z "${dmr_cdtoc_prodname}" ] ; then
    ${LUPRINTF} -Eel2 "`gettext 'The media table of contents does not define a product name.'`"
    dmr_errorsFound="1"
  fi
  if [ -z "${dmr_cdtoc_prodvers}" ] ; then
    ${LUPRINTF} -Eel2 "`gettext 'The media table of contents does not define a product version.'`"
    dmr_errorsFound="1"
  fi
  if [ -z "${dmr_cdtoc_proddir}" ] ; then
    ${LUPRINTF} -Eel2 "`gettext 'The media table of contents does not define a product top-level directory.'`"
    dmr_errorsFound="1"
  fi
  if [ -n "${dmr_cdtoc_proddir}" ] ; then
    if [ ! -d "${dmr_media_toolsDir}" ] ; then
      ${LUPRINTF} -Eel2 "`gettext 'The media product tools directory does not exist.'`"
      dmr_errorsFound="1"
    fi
  fi

  if [ -n "${dmr_errorsFound}" ] ; then
    ${LUPRINTF} -Eel2 "`gettext 'The media does not contain a usable flash install image.'`"
    return 2
  fi

  ######################################################################################
  ########## Verify that the miniroot exists  ##########################################
  ######################################################################################
  dmr_miniroot=${dmr_media_toolsDir}/Boot

  lulib_validate_is_directory_not_empty "${dmr_miniroot}"
  if [ $? -ne 0 ] ; then
    ${LUPRINTF} -Eel2 "`gettext 'The install root does not exist or is empty'`"
    return 3
  fi

  # check to see if it has a version of pfinstall that knows about live flash.
  dmr_libDir="${dmr_miniroot}/usr/snadm/lib"
  dmr_ldLibraryPath="${dmr_libDir}"
  [ -n "${LD_LIBRARY_PATH}" ] && dmr_ldLibraryPath="${dmr_ldLibraryPath}:${LD_LIBRARY_PATH}"
  dmr_pfinstallDir="${dmr_miniroot}/usr/sbin/install.d"

  LD_LIBRARY_PATH=${dmr_ldLibraryPath} ${dmr_pfinstallDir}/pfinstall -F test 1> /dev/null 2>&1
  dmr_ret="$?"


  if [ "${dmr_ret}" != 3 ] ; then
    ${LUPRINTF} -Eel2 "`gettext 'The media is not a recognized Live-Flash-enabled miniroot.'`"
    return 2
  fi

  # print it out for consumption by others
  ${LUPRINTF} -1 "%s" "${dmr_miniroot}"
  return 0
}

################################################################################
# Name:		do_checkMedia
# Description:	Scan media location and determine what operations might be possible.
# Local Prefix: dcm_
# Arguments:	$1 = media mount point to check.
# Returns:      0 = check was successful.
#		3 = user input error.
################################################################################

do_checkMedia()
{
  # extract command line arguments

  dcm_media="$1"

  # reset all variables used in this function

  dcm_cdtoc_proddir=""
  dcm_cdtoc_prodname=""
  dcm_cdtoc_prodvers=""
  dcm_curdir=""
  dcm_foundSomething=""
  dcm_installerCount=""
  dcm_installerList=""
  dcm_media_basedir=""
  dcm_media_patchdir=""
  dcm_media_toolsDir=""
  dcm_media_toolsInstallConfig=""
  dcm_packageCount=""
  dcm_packageList=""

  # compute default locations from media start

  dcm_media_cdtoc="${dcm_media}/.cdtoc"
  dcm_media_mu="${dcm_media}/MU"
  dcm_media_installmu="${dcm_media_mu}/install_mu"

  # output debugging herald

  ${LUPRINTF} -lp2D - "`gettext 'Check media <%s>.'`" "${dcm_media}"

  # Validate that the media specified can be accessed

  lulib_validate_is_directory_not_empty "${dcm_media}"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The path specified by the <-s> option is not the location of valid Solaris media.'`"
    return 3
  fi
  # Locate the media table of contents and extract directory and file names and product information

  if [ -f "${dcm_media}/.cdtoc" -a -s "${dcm_media}/.cdtoc" ] ; then
    ${LUPRINTF} -lp1 "`gettext 'The media is a standard Solaris media.'`"
    if [ -d "${dcm_media}/.install_config" ] ; then
      ${LUPRINTF} -lp1 "`gettext 'The media contains an operating system upgrade image.'`"
    fi

    if [ -d "${dcm_media}/.install" -a -x "${dcm_media}/installer" ] ; then
      ${LUPRINTF} -lp1 "`gettext 'The media contains a standard media installer which can be run.'`"
    fi

    dcm_cdtoc_prodname="`/bin/grep '^PRODNAME=' ${dcm_media_cdtoc} | /bin/head -1 | /bin/sed 's/PRODNAME=//'`"
    dcm_cdtoc_prodvers="`/bin/grep '^PRODVERS=' ${dcm_media_cdtoc} | /bin/head -1 | /bin/sed 's/PRODVERS=//'`"
    dcm_cdtoc_proddir="`/bin/grep '^PRODDIR=' ${dcm_media_cdtoc} | /bin/head -1 | /bin/sed 's/PRODDIR=//'`"
    if [ -z "${dcm_cdtoc_prodname}" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'The media does not define a product name.'`"
      dcm_cdtoc_prodname="`gettext 'unknown'`"
    fi
    if [ -z "${dcm_cdtoc_prodvers}" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'The media does not define a product version.'`"
      dcm_cdtoc_prodvers="`gettext 'unknown'`"
    fi
    if [ -z "${dcm_cdtoc_proddir}" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'The media does not define a product top-level directory.'`"
    elif [ ! -d "${dcm_media}/${dcm_cdtoc_proddir}" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'The media product directory <%s> does not exist.'`" "${dcm_cdtoc_proddir}"
    else
      ${LUPRINTF} -lp1 "`gettext 'The media contains <%s> version <%s>.'`" "${dcm_cdtoc_prodname}" "${dcm_cdtoc_prodvers}"
      dcm_foundSomething="yes"
    fi
    if [ -n "${dcm_cdtoc_proddir}" ] ; then
      dcm_media_basedir="`dirname ${dcm_media}/${dcm_cdtoc_proddir}`"
      dcm_media_patchdir="${dcm_media_basedir}/Patches"
      if [ -d "${dcm_media_patchdir}" ] ; then
	dcm_media_patchCount=`/bin/ls -1 "${dcm_media_patchdir}" 2>/dev/null | /bin/wc -l 2>/dev/null`
	if [ "${dcm_media_patchCount}" -ne '0' ] ; then
	  ${LUPRINTF} -lp1 "`gettext 'The media contains <%s> patches for the product.'`" ${dcm_media_patchCount}
	fi
      fi
      dcm_media_toolsDir="${dcm_media_basedir}/Tools"
      dcm_media_toolsInstallConfig="${dcm_media_toolsDir}/Boot/usr/sbin/install.d/install_config"
      if [ -f "${dcm_media_toolsInstallConfig}/patch_finish" -a -s "${dcm_media_toolsInstallConfig}/patch_finish" ] ; then
	${LUPRINTF} -lp1 "`gettext 'The media contains an automatic patch installation script.'`"
      fi
    fi
  else
    ${LUPRINTF} -lp1 "`gettext 'The media is not a recognized installation media.'`"
  fi

  # Find the MU installer and directory

  if [ -d "${dcm_media_mu}" ] ; then
    ${LUPRINTF} -lp1 "`gettext 'The media contains an upgrade patch directory.'`"
    dcm_foundSomething="yes"
  fi

  if [ -x "${dcm_media_installmu}" ] ; then
    ${LUPRINTF} -lp1 "`gettext 'The media contains an upgrade patch installer <%s>.'`" "install_mu"
    dcm_foundSomething="yes"
  fi

  # Find all executables and installable packages

  dcm_installerList=""
  dcm_installerCount="0"
  dcm_packageList=""
  dcm_packageCount="0"
  dcm_curdir="`/bin/pwd`"
  cd ${dcm_media}
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to access directory <%s>.'`" "${dcm_media}"
  else
    for dcm_itemCandidate in * ; do
      if [ -f "${dcm_itemCandidate}" -a -s "${dcm_itemCandidate}" -a -x "${dcm_itemCandidate}" -a "${dcm_itemCandidate}" != "installer" ] ; then
	if [ -z "$dcm_installerList" ] ; then
	  dcm_installerList="${dcm_itemCandidate}"
	else
	  dcm_installerList="${dcm_installerList} ${dcm_itemCandidate}"
	fi
	dcm_installerCount="`/bin/expr ${dcm_installerCount} + 1`"
      else 
	/usr/sbin/pkgchk -d "${dcm_media}" "${dcm_itemCandidate}" 1>/dev/null 2>&1
	if [ "$?" -eq "0" ] ; then
	  if [ -z "${dcm_packageList}" ] ; then
	    dcm_packageList="${dcm_itemCandidate}"
	  else
	    dcm_packageList="${dcm_packageList} ${dcm_itemCandidate}"
	  fi
	dcm_packageCount="`/bin/expr ${dcm_packageCount} + 1`"
	dcm_foundSomething="yes"
	fi
      fi
    done
  fi

  if [ ! -z "${dcm_installerList}" ] ; then
    ${LUPRINTF} -lp1 "`gettext 'The media contains %d possible alternative installation programs: <%s>.'`" "${dcm_installerCount}" "${dcm_installerList}"
  fi

  if [ ! -z "${dcm_packageList}" ] ; then
    ${LUPRINTF} -lp1 "`gettext 'The media contains %d software packages: <%s>.'`" "${dcm_packageCount}" "${dcm_packageList}"
  fi

  if [ -z "${dcm_foundSomething}" ] ; then
    ${LUPRINTF} -lp1 "`gettext 'The media does not contain any recognized products, patches, or packages.'`"
  fi

  return 0
}

################################################################################
# Name:		reconfigure_devices
# Description:	Reconfigures devices on a BE.  We run different sets of binaries based
#		on what we can find in the PBE.
# Local Prefix: drd_
# Arguments:	$1 = media mount point to reconfigure
#		$2 = BE name
# Returns:      0 = reconfiguration was successful.
#		2 = internal error
################################################################################
reconfigure_devices()
{
  drd_media="$1"
  drd_beName="$2"

  ${LUPRINTF} -lp2D - "`gettext 'Reconfiguring devices for BE <%s>'`" "${drd_beName}"

  # reconfigure devices.  We first look for the latest and greatest
  # tools to do this.  Failing that, we fall back to what was used
  # on older OS's, since we might be running on such a system.
  if [ -x /usr/sbin/devfsadm ] ; then
    ${LUPRINTF} -lp2D - "`gettext 'Reconfiguring devices using devfsadm'`"
    /usr/sbin/devfsadm -R ${drd_media} > /dev/null 2>&1
    if [ $? != 0 ] ; then
	${LUPRINTF} -Eelp2 "`gettext 'Unable to reconfigure devices (devfsadm) for BE <%s>.'`" "${drd_beName}"
	return 2
    fi
  elif [ -x /usr/sbin/drvconfig ] ; then
    ${LUPRINTF} -lp2D - "`gettext 'Reconfiguring devices using devlinks'`"

    /usr/sbin/drvconfig -R ${drd_media} > /dev/null 2>&1
    if [ $? != 0 ] ; then
	${LUPRINTF} -Eelp2 "`gettext 'Unable to reconfigure devices (drvconfig) for BE <%s>.'`" "${drd_beName}"
	return 2
    fi

    /usr/sbin/devlinks -r ${drd_media} -t ${drd_media}/etc/devlink.tab > /dev/null 2>&1
    if [ $? != 0 ] ; then
	${LUPRINTF} -Eelp2 "`gettext 'Unable to reconfigure devices (devlinks) for BE <%s>.'`" "${drd_beName}"
	return 2
    fi

    /usr/sbin/disks -r ${drd_media} > /dev/null 2>&1
    if [ $? != 0 ] ; then
	${LUPRINTF} -Eelp2 "`gettext 'Unable to reconfigure devices (disks) for BE <%s>.'`" "${drd_beName}"
	return 2
    fi

    /usr/sbin/ports -r ${drd_media} > /dev/null 2>&1
    if [ $? != 0 ] ; then
	${LUPRINTF} -Eelp2 "`gettext 'Unable to reconfigure devices (ports) for BE <%s>.'`" "${drd_beName}"
	return 2
    fi
  else
	${LUPRINTF} -Eelp2 "`gettext 'Unable to reconfigure devices for BE <%s>.  Cannot find devfsadm or drvconfig'`" "${drd_beName}"
  fi

  # and force a reconfiguration boot
  touch ${drd_media}/reconfigure > /dev/null 2>&1
  if [ $? != 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to force reconfiguration boot for BE <%s>.'`" "${drd_beName}"
    return 2
  fi

  # everythign worked  
  return 0
}

################################################################################
# Name:		create_be_mountpoints
# Description:	Make sure that all devices that can be mounted on a BE have mount points
#		(directories) created in the BEs root file system.
# Local Prefix: cbm_
# Arguments:	$1 = media mount point where BEs root file system is mounted
# Returns:      0 = mount points created
#		1 = mount points not created
################################################################################
create_be_mountpoints()
{
  cbm_bootMnt="$1"
  cbm_vfstab="${cbm_bootMnt}/etc/vfstab"

  ${LUPRINTF} -lp2D 1 "`gettext 'create_be_mountpoints: bootMnt <%s> vfstab <%s>.'`" "${cbm_bootMnt}" "${cbm_vfstab}"

  # If vfstab file does not exist or is empty then no work to do
  if [ ! -f "${cbm_vfstab}" -o ! -s "${cbm_vfstab}" ] ; then
    ${LUPRINTF} -lp2D 1 "`gettext 'vfstab file does not exist on target BE: no mount points created.'`"
    return 0
  fi

  # vfstab file has contents - find all mountable filesystems and make sure
  # that the BE has directories for each mount point. Format of vfstab file is:
  # 
  # ---> device       device       mount      FS      fsck    mount      mount
  # ---> to mount     to fsck      point      type    pass    at boot    options

  ${LUBIN}/lucomm_del "${cbm_vfstab}" | while read line ; do
    ${LUPRINTF} -lp2D 3 "`gettext 'vfstab line: <%s>.'`" "${line}"
    set $line
    cbm_v_mntdev="$1"
    cbm_v_fsckdev="$2"
    cbm_v_mntpt="$3"
    cbm_v_fstype="$4"
    cbm_v_fsckpass="$5"
    cbm_v_mntatboot="$6"

    ${LUPRINTF} -lp2D 2 "`gettext 'mntdev <%s> fsckdev <%s> mntpt <%s> fstype <%s> fsckpass <%s> mntatboot <%s>.'`" \
     "${cbm_v_mntdev}" "${cbm_v_fsckdev}" "${cbm_v_mntpt}" "${cbm_v_fstype}" "${cbm_v_fsckpass}" "${cbm_v_mntatboot}"

    # Skip if mount point does not begin with "/" and have at least one
    # character after it.
    cbm_x="`echo \"${cbm_v_mntpt}\" | /bin/egrep -c '^/.' 2>/dev/null`"
    if [ "${cbm_x}" != "1" ] ; then
      ${LUPRINTF} -lp2D 2 "`gettext 'Skipping device <%s> mount point <%s>: does not begin with </?>.'`" "${cbm_v_mntdev}" "${cbm_v_mntpt}"
      continue
    fi

    # Skip if fstype is not one that live upgrade supports.
    for cbm_for_fstype in ${LU_SUPPORTED_FILE_SYSTEM_TYPES} FSTYPE_NOT_FOUND ; do
      if [ "${cbm_v_fstype}" = "${cbm_for_fstype}" ] ; then
	break
      fi
    done

    # Skip if the file system type is not recognized.
    if [ -z "${cbm_v_fstype}" -o "${cbm_for_fstype}" = "FSTYPE_NOT_FOUND" ] ; then
      ${LUPRINTF} -lp2D 2 "`gettext 'Skipping device <%s> mount point <%s>: fstype <%s> not supported.'`" "${cbm_v_mntdev}" "${cbm_v_mntpt}" "${cbm_v_fstype}"
      continue
    fi

    # If the mount point does not already exist, create it.
    if [ ! -d "${cbm_bootMnt}${cbm_v_mntpt}" ] ; then
      ${LUPRINTF} -lp2D 1 "`gettext 'Creating device <%s> mount point <%s>.'`" "${cbm_v_mntdev}" "${cbm_bootMnt}${cbm_v_mntpt}"
      ERRMSG="`/bin/mkdir -p \"${cbm_bootMnt}${cbm_v_mntpt}\"`"
      if [ "$?" -ne "0" ] ; then
	${LUPRINTF} -Elp2D - "`gettext 'Cannot create mount point <%s>: %s.'`" "${cbm_bootMnt}${cbm_v_mntpt}" "${ERRMSG}"
      fi
    else
      ${LUPRINTF} -lp2D 2 "`gettext 'Skipping device <%s> mount point <%s>: mount point already exists.'`" "${cbm_v_mntdev}" "${cbm_v_mntpt}"
    fi
  done

  return 0
}


################################################################################
# Name:		update_x86boot
# Description:	Reconfigures boot-path setting on a BE, based on the currently-active BE.
# Local Prefix: u86_
# Arguments:	$1 = media mount point to reconfigure
#		$2 = BE name
# Returns:      0 = reconfiguration was successful.
#		2 = internal error
################################################################################
update_x86boot()
{
  u86_bootMnt="$1"
  u86_beName="$2"

  # check root filesystem type
  ${LUETCBIN}/ludo filter_nonsystem ${ABE_ICF} > ${COMBINED_ICF}
  u86_abeRootSlice=`/bin/awk -F: '$2 == "/" && $6 == "" {printf "%s\n", $3 }' \
    < ${COMBINED_ICF} | /bin/sed 's/\/dev\/dsk\///g'`
  [ -x /sbin/zfs ] && /sbin/zfs list -Ho name "$u86_abeRootSlice" > /dev/null 2>&1
  if [ $? = 0 ]; then
      # zfs root does not need the bootpath set
      return 0
  fi

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

  ${LUPRINTF} -lp2D - "`gettext 'update_x86Boot: <%s> <%s>'`" "u86_bootMnt: ${u86_bootMnt}" "u86_beName: ${u86_beName}"

  # this is done in 3 steps:
  # 1. Nuke old [ABE]/boot/bootenv.rc, since it likely contains bogus settings
  # 2. Copy [PBE]/boot/bootenv.rc contents to [ABE]/boot/bootenv.rc
  # 3. Update boot-path settings in [ABE]/boot/bootenv.rc
  # if we don't do this, the ABE will most likely have an invalid
  # bootenv.rc and will not boot.

  # first do some checks
  if [ ! -f "${u86_bootMnt}/boot/solaris/bootenv.rc" -o ! -s "${u86_bootMnt}/boot/solaris/bootenv.rc" ] ; then
        ${LUPRINTF} -Eelp2 "`gettext 'ERROR: No /boot information <%s> found \
for BE <%s>.  Boot device settings cannot be updated.  The BE is unbootable.'`" \
"${u86_bootMnt}/boot/solaris/bootenv.rc" "${u86_beName}"
	return 2
  fi

  # 
  # now update the file
  # Since luupgrade will always operate on a GRUB aka newboot BE: in the mirrored
  # case it is okay to have logical (md) paths as the bootpath 
  # DCA boot aka legacy cannot handle (md) paths in the boot path.
  # 
  #
  u86_dsk=`/bin/cat ${u86_bootMnt}/etc/vfstab | /bin/grep -v "^#" | /bin/awk ' { if($3 == "/") { print $1 } } '`

  ${LUPRINTF} -lp2D - "u86_dsk: ${u86_dsk}"
  if [  -z "${u86_dsk}" ] ; then
        ${LUPRINTF} -Eelp2 "`gettext 'ERROR: Boot device for BE <%s> Cannot be determined.'`" "${u86_beName}"
	return 2
  fi
  u86_dev=`/bin/ls -l ${u86_bootMnt}/${u86_dsk} | /bin/sed 's/.*\/devices\//\//g'`
  if [  -z "${u86_dev}" ] ; then
        ${LUPRINTF} -Eelp2 "`gettext 'ERROR: Boot device specifier for BE <%s> Cannot be determined.'`" "${u86_beName}"
	return 2
  fi
  u86_rc=${u86_bootMnt}/boot/solaris/bootenv.rc
  u86_rc_pbe=/boot/solaris/bootenv.rc
  /bin/grep -v "setprop bootpath" ${u86_rc_pbe} > ${u86_rc}.tmp 2>/dev/null
  u86_old=`/bin/grep "setprop bootpath" ${u86_rc} 2> /dev/null | /bin/awk '{print $3}'`
  u86_new=${u86_dev}
  ${LUPRINTF} -lp2D - "`gettext 'Old boot-path: <%s>.'`" "${u86_old}"
  ${LUPRINTF} -lp2D - "`gettext 'New boot-path: <%s>.'`" "${u86_new}"
  echo "setprop bootpath ${u86_new}" >> ${u86_rc}.tmp
  /bin/cp ${u86_rc}.tmp ${u86_rc}
  /bin/rm -f ${u86_rc}.tmp

  return 0
}

#
# This function modifies mount point of
# boot partition to /stubboot in ABE vfstab
# 
modify_x86_boot_entry()
{
    dxbe_bootMnt="$1"

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

    ${LUPRINTF} -lp2D - "`gettext 'Checking for x86 boot entry in ABE vfstab.'`"

    /bin/grep -s -v '^#' "${dxbe_bootMnt}/etc/vfstab" | /bin/grep "[	]/boot[	]*pcfs[	]" >/dev/null
    if [ "$?" -ne 0 ]; then
    	${LUPRINTF} -lp2D - "`gettext 'No x86 /boot entry in ABE vfstab.'`"
        return 0
    fi

    ${LUPRINTF} -lp2D - "`gettext 'Found x86 /boot entry in ABE vfstab.'`"

    DXBE_TMP_FILE="/tmp/.luupgrade.dxbe.$$"

    ERRMSG=`/bin/cp -p "${dxbe_bootMnt}/etc/vfstab" "$DXBE_TMP_FILE" 2>&1`
    if [ "$?" -ne 0 ]; then
        ${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
        ${LUPRINTF} -Eelp2 "`gettext 'Cannot copy vfstab file <%s>.'`" "${dxbe_bootMnt}/etc/vfstab"
        return 1
    fi

    /bin/grep -s -v "[	]/boot[	]*pcfs[	]" "$DXBE_TMP_FILE" >  "${dxbe_bootMnt}/etc/vfstab"
    if [ "$?" -ne 0 ]; then
        ${LUPRINTF} -Eelp2 "`gettext 'Cannot delete boot entry from vfstab file <%s>.'`" "${dxbe_bootMnt}/etc/vfstab"
        /bin/cp -p "$DXBE_TMP_FILE" "${dxbe_bootMnt}/etc/vfstab" 2>&1
        return 1
    fi

    dxbe_entry=`/bin/grep -v '^#' "$DXBE_TMP_FILE" | /bin/grep "[	]/boot[	]*pcfs[	]"`
    dxbe_e1=`echo "$dxbe_entry" | /bin/awk '{print $1}'` 
    dxbe_e2=`echo "$dxbe_entry" | /bin/awk '{print $2}'` 
    dxbe_e3=`echo "$dxbe_entry" | /bin/awk '{print $3}' | /bin/sed 's/\/boot/\/stubboot/g'`
    dxbe_e4=`echo "$dxbe_entry" | /bin/awk '{print $4}'` 
    dxbe_e5=`echo "$dxbe_entry" | /bin/awk '{print $5}'` 
    dxbe_e6=`echo "$dxbe_entry" | /bin/awk '{print $6}' | /bin/sed 's/no/yes/g'` 
    dxbe_e7=`echo "$dxbe_entry" | /bin/awk '{print $7}'` 

    # Create /stubboot on ABE if it does not exist
    /bin/mkdir -p "${dxbe_bootMnt}/stubboot"

    echo "$dxbe_e1	$dxbe_e2	$dxbe_e3	$dxbe_e4	$dxbe_e5	$dxbe_e6	$dxbe_e7" >> "${dxbe_bootMnt}/etc/vfstab"

    ${LUPRINTF} -lp1 "`gettext 'Modified boot partition entry in ABE vfstab.'`"

    /bin/rm -f "$DXBE_TMP_FILE"

    return 0
}

delete_x86_boot_backing()
{
    dxbp_bootMnt="$1"

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

    #
    # First delete the ABE's boot partition
    #
    ${LUPRINTF} -lp2D - "`gettext 'Deleting x86 boot backing on ABE.'`"

    #
    # We may or may not have umounted ABE's boot partition
    # 
    lulib_unmount_pathname "${dxbp_bootMnt}/boot" 2>/dev/null
    if [ "$?" -ne 0 ]; then 
        ${LUPRINTF} -lp2D 4 "`gettext 'ABE x86 boot partition is not mounted.'`"
    fi
    /usr/sbin/lofiadm -d ${dxbp_bootMnt}/etc/lu/.dd_x86_boot_copy 2>/dev/null
    if [ "$?" -ne 0 ]; then 
        ${LUPRINTF} -lp2D 4 "`gettext 'ABE x86 boot backing is not a lofi device.'`"
    fi

    /bin/rm -f ${dxbp_bootMnt}/etc/lu/.dd_x86_boot_copy
    if [ "$?" -ne 0 ]; then
        ${LUPRINTF} -Eelp2 "`gettext 'failed to delete ABE x86 boot backing.'`"
    else
        ${LUPRINTF} -lp1 "`gettext 'ABE boot partition backing deleted.'`"
    fi

    # The existing (pre-newboot) code, as a side effect refreshed PBE's
    # /etc/lu/.dd_x86_boot_copy with the boot partition contents.
    # We do the same here to preserve that behavior
    ${LUPRINTF} -lp2D - "`gettext 'Checking for x86 boot partition on PBE.'`"

    /bin/grep -s -v '^#' /etc/vfstab | /bin/grep "[	]/boot[	]*pcfs[	]" >/dev/null
    if [ "$?" -ne 0 ]; then
    	${LUPRINTF} -lp2D - "`gettext 'No x86 boot partition on PBE.'`"
        return 0
    fi

    DXBP_TMP_FILE="/tmp/.luupgrade.dxbp.$$"
    DXBP_TMP_FILE1="/tmp/.luupgrade.dxbp1.$$"

    ${LUPRINTF} -lp2D - "`gettext 'x86 boot partition exists on PBE.'`"

    diskid="`/bin/grep -s -v '^#' /etc/vfstab | /bin/grep \"[	]/boot[	]*pcfs[	]\" | awk '{print $1}' | sed -e 's:p0\:boot::g'`"
    diskid="`basename $diskid`"
    /usr/sbin/fdisk -W "${DXBP_TMP_FILE}" /dev/rdsk/${diskid}p0
    /bin/grep -v \* "${DXBP_TMP_FILE}" | /bin/grep -v '^[ 	]*$' > ${DXBP_TMP_FILE1}
    /bin/rm -f "${DXBP_TMP_FILE}"

    num=1
    while read id act bhead bcyl ehead ecyl rsect numsect
    do
       if [ ! -z "$id" ]; then
          if [ "$id" -eq "190" ]; then
              bootpart_id=/dev/rdsk/${diskid}p${num}
              ${LUPRINTF} -lp1 "`gettext 'PBE <%s> boot partition is <%s>.'`" "${CURR_BE}" "$bootpart_id"

              ${LUPRINTF} -lp1 "`gettext 'saving PBE boot partition.'`"
              ERRMSG="`/bin/dd if=$bootpart_id of=/etc/lu/.dd_x86_boot_copy 2>&1`"
              if [ "$?" -ne "0" ]; then
                 ${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
                 ${LUPRINTF} -Eelp2 "`gettext 'Unable to save copy of active BE <%s> X86 boot partition.'`" "${CURR_BE}" "${bootpart_id}"

    		 /bin/rm -f "${DXBP_TMP_FILE}"
		 /bin/rm -f "${DXBP_TMP_FILE1}"
                 return 1
              fi
          fi
       fi
       num=`expr $num + 1`
    done < ${DXBP_TMP_FILE1}

    /bin/rm -f "${DXBP_TMP_FILE}"
    /bin/rm -f "${DXBP_TMP_FILE1}"

    ${LUPRINTF} -lp2D - "`gettext 'saved PBE boot partition copy in <%s>.'`" "/etc/lu/.dd_x86_boot_copy"

    return 0
}

install_latest_GRUB()
{
   ilg_abemntpt="$1"
   ilg_abename="$2"

   ilg_tmp1="/tmp/.luupgrade.ilg.tmp1"
   ilg_tmp2="/tmp/.luupgrade.ilg.tmp2"
   ilg_old_PBE=""

   /bin/rm -f "$ilg_tmp1"
   /bin/rm -f "$ilg_tmp2"

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

   if [ ! -f "${ilg_abemntpt}/boot/grub/capability" -o  ! -s "${ilg_abemntpt}/boot/grub/capability" ]; then
      ${LUPRINTF} -lp1 "`gettext 'ABE GRUB has no capability information. Skipping GRUB upgrade.'`"
      return 0
   fi
   /bin/grep "VERSION=" "${ilg_abemntpt}/boot/grub/capability" > "$ilg_tmp1" 2>/dev/null
   if [ "$?" -ne 0 ]; then
      ${LUPRINTF} -lp1 "`gettext 'ABE GRUB has no versioning information. Skipping GRUB upgrade.'`"
      return 0
   fi

   ABE_version=`/bin/cat "$ilg_tmp1" | cut -d '=' -f 2` 2>/dev/null
   if [ "$?" -ne 0 ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'Error parsing GRUB version for ABE <%s>'`" "${ilg_abename}"
      /bin/rm -f "$ilg_tmp1"
      /bin/rm -f "$ilg_tmp2"
      return 2
   fi
   
   if [ ! -f "/etc/lu/capability" -o  ! -s "/etc/lu/capability" ]; then
      ${LUPRINTF} -lp1 "`gettext 'PBE GRUB has no capability information.'`"
      ilg_old_PBE=1
   fi
   /bin/grep "VERSION=" "/etc/lu/capability" > "$ilg_tmp2" 2>/dev/null
   if [ "$?" -ne 0 ]; then
      ${LUPRINTF} -lp1 "`gettext 'PBE GRUB has no versioning information.'`"
      ilg_old_PBE=1
   fi

   if [ -z "$ilg_old_PBE" ]; then
      PBE_version=`/bin/cat "$ilg_tmp2" | cut -d '=' -f 2` 2>/dev/null
      if [ "$?" -ne 0 ]; then
         ${LUPRINTF} -Eelp2 "`gettext 'Error parsing GRUB version for PBE <%s>'`" "${CURR_BE}"
   	 /bin/rm -f "$ilg_tmp1"
   	 /bin/rm -f "$ilg_tmp2"
         return 2
      fi
      if [ "$PBE_version" -ge "$ABE_version" ]; then
         ${LUPRINTF} -lp1 "`gettext 'PBE GRUB is same as or newer than ABE GRUB. Skipping GRUB update.'`"
         return 0
      fi
   fi

   ${LUPRINTF} -lp1 "`gettext 'ABE GRUB is newer than PBE GRUB. Updating GRUB.'`"

   /bin/cp "${ilg_abemntpt}"/sbin/installgrub /etc/lu/installgrub.findroot
   ret1="$?"
   /bin/cp "${ilg_abemntpt}"/boot/grub/stage1 /etc/lu/stage1.findroot
   ret2="$?"
   /bin/cp "${ilg_abemntpt}"/boot/grub/stage2 /etc/lu/stage2.findroot
   ret3="$?"
   /bin/cp "${ilg_abemntpt}"/boot/grub/capability /etc/lu/GRUB_capability
   ret4="$?"

   if [ "$ret1" -ne 0 -o "$ret2" -ne 0 -o "$ret3" -ne 0 -o "$ret4" -ne 0 ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'Error updating GRUB on PBE <%s>'`" "${CURR_BE}"
      return 2
   fi

   /bin/rm -f "$ilg_tmp1"
   /bin/rm -f "$ilg_tmp2"

   ${LUPRINTF} -lp1 "`gettext 'GRUB update was successfull.'`"

   return 0
}

configure_failsafe()
{
  cfg_miniMntpt="$1"
  cfg_beName="$2"

  cfg_tmp1=/tmp/.luupgrade.cfg.1.$$
  cfg_tmp2=/tmp/.luupgrade.cfg.2.$$

  #
  # Setting this flag ensures that configured failsafe and
  # multiboot are copied to the ABE in umount_miniroot()
  #
  INSTALL_FAILSAFE_ON="$cfg_beName"

  #
  # On SPARC architecture only need to configure INSTALL_FAILSAFE_ON variable
  # and rest of the following configuration is not applicable.
  #
  if [ "${LU_SYSTEM_ARCH}" != i386 ]; then
     return 0
  fi

  ${LUPRINTF} -lp1 "`gettext 'Configuring failsafe for system.'`"

  cfg_pbenv="/boot/solaris/bootenv.rc"
  if [ ! -f "$cfg_pbenv" ]; then
     ${LUPRINTF} -Eelp2 "`gettext 'Parent BE is missing boot settings file <%s>.'`" "${cfg_pbenv}"
     return 0
  fi

  cfg_bootenv="${cfg_miniMntpt}/boot/solaris/bootenv.rc"
  if [ -f "$cfg_bootenv" ]; then
     /bin/egrep -v "^[ 	]*setprop[ 	]+console[ 	]+" $cfg_bootenv > $cfg_tmp1
     /bin/egrep -v "^[ 	]*setprop[ 	]+input-device[ 	]+" $cfg_tmp1 > $cfg_tmp2
     /bin/egrep -v "^[ 	]*setprop[ 	]+output-device[ 	]+" $cfg_tmp2 > $cfg_tmp1
     /bin/rm -f $cfg_tmp2
  else
     # Not a fatal error
     ${LUPRINTF} -Welp2 "`gettext 'Default failsafe is missing boot settings file <%s>.'`" "${cfg_bootenv}"
     /bin/rm -f $cfg_tmp1
     /bin/rm -f $cfg_tmp2
  fi

  pbeSetting=`/bin/egrep "^[ 	]*setprop[ 	]+console[ 	]+" ${cfg_pbenv} | /bin/awk '{print $3}'`
  if [ -n "$pbeSetting" ]; then
     /bin/echo "setprop console $pbeSetting" >> $cfg_tmp1
  fi

  pbeSetting=`/bin/egrep "^[ 	]*setprop[ 	]+input-device[ 	]+" ${cfg_pbenv} | /bin/awk '{print $3}'`
  if [ -n "$pbeSetting" ]; then
     /bin/echo "setprop input-device $pbeSetting" >> $cfg_tmp1
  fi

  pbeSetting=`/bin/egrep "^[ 	]*setprop[ 	]+output-device[ 	]+" ${cfg_pbenv} | /bin/awk '{print $3}'`
  if [ -n "$pbeSetting" ]; then
     /bin/echo "setprop output-device $pbeSetting" >> $cfg_tmp1
  fi

  /bin/cp "$cfg_tmp1" "$cfg_bootenv" 
  /bin/rm -f $cfg_tmp1

  ${LUPRINTF} -lp1 "`gettext 'Failsafe configuration is complete.'`"
  return 0
}

install_failsafe()
{
  inf_beName="$1"

  inf_mntpt="/tmp/.luupgrade.inf.$$"

  ${LUPRINTF} -lp1 "`gettext 'Installing failsafe'`"

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

    if [ "${TMP_FAILSAFE_KERNEL_TYPE}" != multiboot -a "${TMP_FAILSAFE_KERNEL_TYPE}" != unix ]; then
       ${LUPRINTF} -Eelp2 "`gettext 'Cannot determine failsafe kernel type <%s>.'`" "${TMP_FAILSAFE_KERNEL_TYPE}"
       return 1
    fi

    if [  ! -f "${TMP_FAILSAFE_KERNEL}" -o ! -s "${TMP_FAILSAFE_KERNEL}" ]; then 
       ${LUPRINTF} -Eelp2 "`gettext 'Cannot find failsafe kernel <%s>.'`" "${TMP_FAILSAFE_KERNEL}"
       return 1
    fi

    if [  ! -f "${TMP_FAILSAFE_ARCHIVE}" -o ! -s "${TMP_FAILSAFE_ARCHIVE}" ]; then 
       ${LUPRINTF} -Eelp2 "`gettext 'Cannot find failsafe archive <%s>.'`" "${TMP_FAILSAFE_ARCHIVE}"
       return 1
    fi

    #
    # The failsafe archive is uncompressed at this point
    # Compress it before copying over to ABE
    #
    /bin/gzip "${TMP_FAILSAFE_ARCHIVE}" > /dev/null
    if [ "$?" -ne 0 ]; then 
       ${LUPRINTF} -Eelp2 "`gettext 'Cannot compress failsafe archive.'`"
       return 1
    fi

    if [  ! -f "${TMP_FAILSAFE_ARCHIVE}.gz" -o ! -s "${TMP_FAILSAFE_ARCHIVE}.gz" ]; then 
       ${LUPRINTF} -Eelp2 "`gettext 'Cannot find compressed failsafe archive.'`"
       return 1
    fi
  fi

  /bin/mkdir -p  "$inf_mntpt"
  inf_mntpt=`LU_OUTPUT_FORMAT=text $LUBIN/lumount -Z "$inf_beName" "$inf_mntpt"`
  if [ "$?" -ne 0 ]; then
     ${LUPRINTF} -Eelp2 "`gettext 'Unable to mount boot environment <%s>.'`" "${inf_beName}"
     /bin/rmdir "$inf_mntpt" > /dev/null 2>&1
     return 1
  fi

  if [ "${LU_SYSTEM_ARCH}" = i386 ]; then
    if [ "$TMP_FAILSAFE_KERNEL_TYPE" = multiboot ]; then
       inf_dir=`/bin/dirname ${inf_mntpt}/${FAILSAFE_MULTI_BOOT}`
       /bin/mkdir -p "$inf_dir"
       /bin/cp -p "${TMP_FAILSAFE_KERNEL}" "${inf_mntpt}/${FAILSAFE_MULTI_BOOT}"
    elif [ "$TMP_FAILSAFE_KERNEL_TYPE" = unix ]; then
       inf_dir=`/bin/dirname ${inf_mntpt}/${FAILSAFE_DBOOT_UNIX}`
       /bin/mkdir -p "$inf_dir"
       /bin/cp -p "${TMP_FAILSAFE_KERNEL}" "${inf_mntpt}/${FAILSAFE_DBOOT_UNIX}"
    fi
    ret1="$?"
    #
    # if running 64 bit and the 64 bit miniroot archive exists then
    # use it as the failsafe
    #
    kisa=`isainfo -k`
    if [ "$kisa" = "amd64" -a -f "${LU_MINIROOT_PATH}/amd64/${LU_MINIROOT_ARCHIVE}" ] ; then
       /bin/mkdir -p "${inf_mntpt}/${LU_FAILSAFE64_DIR}"
       /bin/cp -p "${TMP_FAILSAFE_ARCHIVE}.gz" "${inf_mntpt}/${LU_FAILSAFE64_ARCHIVE}"
       # make sure that if there was a 32 bit archive that it is removed
       rm -f "${inf_mntpt}/${LU_FAILSAFE_ARCHIVE}"
    else
      /bin/cp -p "${TMP_FAILSAFE_ARCHIVE}.gz" "${inf_mntpt}/${LU_FAILSAFE_ARCHIVE}"
    fi
    ret2="$?"
  else		# SPARC
    if [ -d "$LU_MINIROOT_PATH" ]; then 	# image has a new-boot
      /bin/cp -p "$LU_MINIROOT_PATH/$LU_MINIROOT_ARCHIVE" \
          "${inf_mntpt}/platform/${LU_HARDWARE_ARCH}/failsafe"
      ret1="$?"
    fi
    ret2=0	# For SPARC fake ret2 status
  fi

  $LUBIN/luumount -f "$inf_beName" > /dev/null 2>&1
  /bin/rmdir "$inf_mntpt" > /dev/null 2>&1

  if [ "$ret1" -eq 0 -a "$ret2" -eq 0 ]; then
     ${LUPRINTF} -lp1 "`gettext 'Failsafe install is complete.'`"
     return 0
  else
     ${LUPRINTF} -Eelp2 "`gettext 'Failsafe install failed.'`"
     return 1
  fi
}

#
# With GRUB boot, systems no longer have a boot partition.
# For the ABE, if it has a boot partition, copy the contents
# into /boot on the ABE root filesystem before invoking pfinstall.
#
# Arguments:
#	$1 - mountpoint of the ABE
#	$2 - boot partition device (in c-t-d-p0:boot format). This may or
#	     may not exist. It must be a block (/dsk/) device.
# Returns
#	0 on success
#	1 on failure
#
convert_x86_boot_partition()
{
   #
   # Check args. Argument 2 is optional.
   #
   if [ "$#" -ne 2 -o -z "$1" ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'convert_x86_boot_partition: Invalid arguments.'`"
      return 1
   fi

   cxb_abeMntpt="$1"
   cxb_abeBoot="$2"

   UMNTED=""
   cxb_x86_boot_copy="/tmp/.luupgrade.cxb.1.$$"
   cxb_tmpBootMnt="/tmp/.luupgrade.cxb.2.$$"
   cxb_tmp="/tmp/.luupgrade.cxb.3.$$"
   


   #
   # First check if the ABE has a boot partition. if it doesn't we don't
   # anything to do so just return success
   #
   if [ -z "$cxb_abeBoot" ]; then
      return 0
   fi


   if [ -z "$cxb_abeMntpt" ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'ABE mountpoint not specified.'`"
      return 1
   fi

   echo "$cxb_abeBoot" | /bin/grep "/dsk/" > /dev/null 2>&1
   if [ "$?" -ne 0 ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'Argument <%s> is not a block device.'`" "$cxb_abeBoot"
      return 1
   fi

   ${LUPRINTF} -lp1 "`gettext 'Converting x86 boot partition on ABE'`"

   cxb_abeBootChar=`/bin/echo "$cxb_abeBoot" | /bin/sed "s/\/dsk\//\/rdsk\//g"`
   lulib_get_real_boot_partition "$cxb_abeBootChar" "$cxb_tmp"
   if [ "$?" -ne 0 ]; then 
      ${LUPRINTF} -Eelp2 "`gettext 'Cannot determine real boot partition for: <%s>.'`" "$cxb_abeBootChar"
      /bin/rm -f "$cxb_tmp"
      return 1
   fi
   cxb_abeBootReal=`/bin/cat "$cxb_tmp"`
   /bin/rm -f "$cxb_tmp"

   # Check if the x86 boot fdisk partition is mounted. If it is, unmount it
   cxb_abeBootMnt=`/sbin/mount | /bin/nawk -v dev=$cxb_abeBoot ' { if ($3 == dev) {printf("%s\n", $1); exit 8;}}'`
   if [ "$?" -eq 8 -a -n "$cxb_abeBootMnt" ]; then
      lulib_unmount_pathname "$cxb_abeBootMnt"
      if [ "$?" -ne 0 ]; then
         ${LUPRINTF} -Eelp2 "`gettext 'cannot unmount: <%s>.'`" "$cxb_abeBoot"
         return 1
      fi
      UMNTED=1
   fi

   # unmount the lofi-mounted ABE boot partition backing file
   lulib_unmount_pathname "${cxb_abeMntpt}/boot"
   if [ "$?" -ne 0 ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'Unable to umount X86 boot device at <%s>.'`" "${cxb_abeMntpt}/boot"
      if [ -n "$UMNTED" ]; then
         /sbin/mount -F pcfs "$cxb_abeBoot" "$cxb_abeBootMnt"
      fi
      return 1
   fi

   # remove file from lofi control
   /usr/sbin/lofiadm -d "${cxb_abeMntpt}/etc/lu/.dd_x86_boot_copy"
   if [ "$?" -ne 0 ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'Unable to lofi delete X86 boot device at <%s>.'`" "${cxb_abeMntpt}/etc/lu/.dd_x86_boot_copy"
      if [ -n "$UMNTED" ]; then
         /sbin/mount -F pcfs "$cxb_abeBoot" "$cxb_abeBootMnt"
      fi
      return 1
   fi

   # Save the current contents of the x86 boot partition
   /bin/dd if="$cxb_abeBootReal" of="$cxb_x86_boot_copy" > /dev/null 2>&1
   if [ "$?" -ne 0 ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'cannot save x86 boot partition: <%s>.'`" "$cxb_abeBootReal"
      if [ -n "$UMNTED" ]; then
         /sbin/mount -F pcfs "$cxb_abeBoot" "$cxb_abeBootMnt"
      fi
      return 1
   fi

   # Copy the ABE's boot partition contents to the boot partition
   /bin/dd if="${cxb_abeMntpt}/etc/lu/.dd_x86_boot_copy" of="$cxb_abeBootReal" > /dev/null 2>&1
   if [ "$?" -ne 0 ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'cannot copy ABE x86 boot partition: <%s>.'`" "$cxb_abeBootReal"
      /bin/dd if="$cxb_x86_boot_copy" of="$cxb_abeBootReal"  > /dev/null 2>&1
      if [ -n "$UMNTED" ]; then
         /sbin/mount -F pcfs "$cxb_abeBoot" "$cxb_abeBootMnt"
      fi
      return 1
   fi

   # Now mount the boot partition
   /bin/mkdir -p "$cxb_tmpBootMnt"
   /sbin/mount -F pcfs "$cxb_abeBoot" "$cxb_tmpBootMnt"
   if [ "$?" -ne 0 ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'cannot mount ABE x86 boot partition: <%s>.'`" "$cxb_abeBoot"
      /bin/rmdir "$cxb_tmpBootMnt"
      /bin/dd if="$cxb_x86_boot_copy" of="$cxb_abeBootReal"  > /dev/null 2>&1
      if [ -n "$UMNTED" ]; then
         /sbin/mount -F pcfs "$cxb_abeBoot" "$cxb_abeBootMnt"
      fi
      return 1
   fi

   /bin/mkdir -p "${cxb_abeMntpt}/boot"
   old_path=`pwd`
   cd "$cxb_tmpBootMnt"
   /bin/find . -mount \! -type s -print 2>"$cxb_tmp" | /bin/cpio -pcdum "${cxb_abeMntpt}/boot" 2>&1
   if [ "$?" -ne "0" ]; then
      ${LUPRINTF} -Eelp2 '%s' "${cxb_tmp}"
      /bin/rm -f "$cxb_tmp"
      ${LUPRINTF} -Eelp2 "`gettext 'Unable to copy boot partition to ABE root filesystem.'`"
      cd "$old_path" 
      lulib_unmount_pathname "$cxb_tmpBootMnt"
      /bin/rmdir "$cxb_tmpBootMnt"
      /bin/dd if="$cxb_x86_boot_copy" of="$cxb_abeBootReal"  > /dev/null 2>&1
      if [ -n "$UMNTED" ]; then
         /sbin/mount -F pcfs "$cxb_abeBoot" "$cxb_abeBootMnt"
      fi
      return 1
   fi

   cd "$old_path"

   cxb_errors=0
   lulib_unmount_pathname "$cxb_tmpBootMnt"
   if [ "$?" -ne 0 ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'Unable to umount temporary mount of <%s>.'`" "$cxb_abeBoot"
      cxb_errors=1
   fi
   /bin/rmdir "$cxb_tmpBootMnt"
   /bin/dd if="$cxb_x86_boot_copy" of="$cxb_abeBootReal"  > /dev/null 2>&1
   if [ "$?" -ne 0 ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'Unable to restore content of boot partition <%s>.'`" "$cxb_abeBoot"
      cxb_errors=1
   fi
   if [ -n "$UMNTED" ]; then
      /sbin/mount -F pcfs "$cxb_abeBoot" "$cxb_abeBootMnt"
      if [ "$?" -ne 0 ]; then
         ${LUPRINTF} -Eelp2 "`gettext 'Unable to mount boot partition <%s>.'`" "$cxb_abeBoot"
         cxb_errors=1
      fi
   fi

   return "$cxb_errors"
}

################################################################################
# Name:		do_flashInstall
# Description:	Flash operating system installation.
# Local Prefix:	dfi_
# Arguments:	$1 = current BE
#		$2 = boot environment name to install flash on.
#		$3 = path to profile template to use ("" if none).
#		$4 = profile template to use ("" if none).
#		$5 = no execute mode ("" if not enabled).
#		$6 = dry run mode ("" if not enabled).
#		$7 = media mount point for flash installation source.
#		$8 = flash archives ("" if profile in use)
# Returns:
################################################################################
do_flashInstall()
{
  dfi_beCurr="$1"
  dfi_beName="$2"
  dfi_profilePath="$3"
  dfi_profile="$4"
  dfi_noExecuteMode="$5"
  dfi_dryRunMode="$6"
  dfi_media="$7"
  dfi_archives="$8"

  ${LUPRINTF} -lp2D - "`gettext 'Flash Install CURR_BE <%s> BE <%s> Profile \
Path <%s> Profile <%s> NoExecuteMode <%s> DryRun <%s> Media <%s> Archives <%s>.'`" \
"${dfi_beCurr}" "${dfi_beName}" "${dfi_profilePath}" "${dfi_profile}" \
"${dfi_noExecuteMode}" "${dfi_dryRunMode}" "${dfi_media}" "${dfi_archives}"

  ######################################################################################
  ########## Verify that the media has a Solaris Operating System Image on it ##########
  ######################################################################################

  ${LUPRINTF} -lp1 "`gettext 'Validating the contents of the media <%s>.'`" "${dfi_media}"

  lulib_validate_is_directory_not_empty "${dfi_media}"
  if [ $? -ne 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The Flash option (-f) option requires that you \
specify the OS media location with the <-s> option.'`"
    return 3
  fi

  # find the media cd table of contents: if not found, can not figure version,
  # so cannot use it to flash a BE
  dfi_media_cdtoc="${dfi_media}/.cdtoc"
  if [ ! -f "${dfi_media_cdtoc}" -o ! -s "${dfi_media_cdtoc}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media <%s> is not a recognized installation media.'`" "${dfi_media}"
    return 2
  fi

  ${LUPRINTF} -lp1 "`gettext 'The media is a standard Solaris media.'`"

  # Looks like standard format media with a table of contents;
  # Locate the various subdirectories in the media we expect of a Solaris distribution.

  dfi_errorsFound=""
  dfi_cdtoc_prodname="`/bin/grep '^PRODNAME=' ${dfi_media_cdtoc} | /bin/head -1 | /bin/sed 's/PRODNAME=//'`"
  dfi_cdtoc_prodvers="`/bin/grep '^PRODVERS=' ${dfi_media_cdtoc} | /bin/head -1 | /bin/sed 's/PRODVERS=//'`"
  dfi_cdtoc_proddir="`/bin/grep '^PRODDIR=' ${dfi_media_cdtoc} | /bin/head -1 | /bin/sed 's/PRODDIR=//'`"
  dfi_media_proddir="${dfi_media}/${dfi_cdtoc_proddir}"
  dfi_media_toolsDir="`dirname ${dfi_media_proddir}`/Tools"
  if [ "${LU_SYSTEM_ARCH}" = "i386" ]; then
      dfi_media_bootLoaderDir="${dfi_media_toolsDir}/Boot/boot/grub"
  else
      dfi_media_bootLoaderDir=""
  fi

  ${LUPRINTF} -lp2D - "`gettext 'Product Name <%s> Version <%s>.'`" "${dfi_cdtoc_prodname}" "${dfi_cdtoc_prodvers}"
  ${LUPRINTF} -lp2D - "`gettext 'Install Tools Directory <%s>.'`" "${dfi_media_toolsDir}" 
  ${LUPRINTF} -lp2D - "`gettext 'Media Bootloader Directory <%s>.'`" "${dfi_media_bootLoaderDir}"

  if [ -z "${dfi_cdtoc_prodname}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media table of contents does not define a product name.'`"
    dfi_errorsFound="1"
  fi
  if [ -z "${dfi_cdtoc_prodvers}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media table of contents does not define a product version.'`"
    dfi_errorsFound="1"
  fi
  if [ -z "${dfi_cdtoc_proddir}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media table of contents does not define a product top-level directory.'`"
    dfi_errorsFound="1"
  fi
  if [ -n "${dfi_cdtoc_proddir}" ] ; then
    if [ ! -d "${dfi_media_toolsDir}" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'The media product tools directory <%s> does not exist.'`" "${dfi_media_toolsDir}"
      dfi_errorsFound="1"
    fi
  fi

  if [ "${LU_SYSTEM_ARCH}" = "i386" ]; then
    if [ ! -d "${dfi_media_bootLoaderDir}" ]; then 
      ${LUPRINTF} -Eelp2 "`gettext 'The media Boot loader directory <%s> does not exist.'`" "${dfi_media_bootLoaderDir}"
      dfi_errorsFound="1"
    fi
  fi

  if [ -n "${dfi_errorsFound}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media <%s> does not contain a usable flash install image.'`" "${dfi_media}"
    return 2
  fi

  ######################################################################################
  ########## Verify that the miniroot exists  ##########################################
  ######################################################################################
  dfi_miniroot=${dfi_media_toolsDir}/Boot

  ${LUPRINTF} -lp1 "`gettext 'Validating the contents of the miniroot <%s>.'`" "${dfi_miniroot}"

  lulib_validate_is_directory_not_empty "${dfi_miniroot}"
  if [ $? -ne 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The Flash option (-f) requires that you specify a \
valid os media image with the <-s> option.'`"
    return 3
  fi

  #
  # verify that the ABE has /boot.  If it does not then we cannot flash the
  # ABE because we will not be able to make it bootable.
  #
  dfi_ret=0
  if [ "${LU_SYSTEM_ARCH}" = "i386" -a \( ! -f "/${LU_BOOTENV}" -o ! -s "/${LU_BOOTENV}" \) ] ; then
        ${LUPRINTF} -Eelp2 "`gettext 'ERROR: This machine does not have <%s> (required on \
x86).  ABE cannot be flashed'`" "/${LU_BOOTENV}"
	return 2
  fi

	######################################################################################
	####################### Determine which pfinstall root to use ########################
	######################################################################################

	${LUPRINTF} -lp1 "`gettext 'Locating the flash install program.'`"

	dfi_libDir="${dfi_miniroot}/usr/snadm/lib"
	dfi_pfinstallDir="${dfi_miniroot}/usr/sbin/install.d"

	lulib_validate_is_directory "${dfi_libDir}"
	if [ "$?" -ne "0" ] ; then
		${LUPRINTF} -Eelp2 "`gettext 'The pfinstall library directory <%s> does not exist.'`" "${dfi_libDir}"
		return 2
	fi

	lulib_validate_is_directory_not_empty "${dfi_pfinstallDir}"
	if [ "$?" -ne "0" ] ; then
		${LUPRINTF} -Eelp2 "`gettext 'The pfinstall product directory <%s> does not exist.'`" "${dfi_pfinstallDir}"
		return 2
	fi

	dfi_pfinstallExecutable="${dfi_pfinstallDir}/pfinstall"
	if [ ! -x "${dfi_pfinstallExecutable}" ] ; then
		${LUPRINTF} -Eelp2 "`gettext 'The pfinstall product <%s> does not exist or is not executable.'`" "${dfi_pfinstallExecutable}"
		return 2
	fi

	# yes, /usr/sbin needs to be in the LD_LIBRARY_PATH.  It's for sys-unconfig.
	dfi_sbinDir="${dfi_miniroot}/usr/sbin"
	dfi_ldLibraryPath="${dfi_libDir}:${dfi_sbinDir}"
	[ -n "${LD_LIBRARY_PATH}" ] && dfi_ldLibraryPath="${dfi_ldLibraryPath}:${LD_LIBRARY_PATH}"

	${LUPRINTF} -lp2D - "`gettext 'Flash install program to use is <%s>.'`" "${dfi_pfinstallExecutable}"

	# Determine if this pfinstall supports the upgrade_mountpoint and/or
	# the transfer_list_types capabilities.  The "-a" option to pfinstall
	# (as of S10B27/S9U4) supports inquiring pfinstall for its
	# "capabilities". The new "upgrade_mountpoint" capability allows
	# mounting of file systems to be bypassed when doing a flash update.
	# The "transfer_list_types" capability supports a third column in the
	# transfer list file which indicates the type of transfer to perform.
	# To check for these, run
	# 'pfinstall -a sw:upgrade_mountpoint,transfer_list_types' - if it
	# does not return '3' or does not return '<capability_name>=true' then
	# that new capability is NOT implemented
	

	dfi_umcap=""
	dfi_tltcap=""
	dfi_pfcap="`LD_LIBRARY_PATH=${dfi_ldLibraryPath} ${dfi_pfinstallExecutable} -a sw:upgrade_mountpoint,transfer_list_types 2>/dev/null`"

	if [ "$?" -eq "3" ]; then
	    for cap in $dfi_pfcap; do
		if [ "$cap" = "upgrade_mountpoint=true" ] ; then
		    ${LUPRINTF} -lp2D - "`gettext '<%s> implements sw:upgrade_mount capability.'`" \
		    "${dfi_pfinstallExecutable}"
		    dfi_umcap="yes"
		elif [ "$cap" = "transfer_list_types=true" ] ; then
		    ${LUPRINTF} -lp2D - "`gettext '<%s> implements sw:transfer_list_types capability.'`" \
		    "${dfi_pfinstallExecutable}"
		    dfi_tltcap="yes"
		fi
	    done
	fi

	if [ "${dfi_umcap}" != "yes" ] ; then
	    ${LUPRINTF} -lp2D - "`gettext '<%s> does NOT implement sw:upgrade_mount capability.'`" \
	    "${dfi_pfinstallExecutable}"
	fi

	if [ "${dfi_tltcap}" != "yes" ] ; then
	    ${LUPRINTF} -lp2D - "`gettext '<%s> does NOT implement sw:transfer_list_types capability.'`" \
	    "${dfi_pfinstallExecutable}"
	fi


	######################################################################################
	############ Check for copylock and fail if one exists.  Currently you can only ######
	############ schedule a flash install if no other operation is pending (including ####
	############ a scheduled copy for our BE  ############################################
	######################################################################################

	## Check to see if a copy lock exists. If so then:
	## 1- if any operation is scheduled on any BE, fail
	## 2- only if no operations are scheduled will we succeed

	${LUPRINTF} -lp1 "`gettext 'Checking for existence of previously scheduled Live Upgrade requests.'`"

	lulib_validate_lulock
	if [ -f "${COPYLOCK}" -a -s "${COPYLOCK}" ] ; then
		. ${COPYLOCK}
		if [ "${dfi_beName}" = "$CL_TARGET_BE" ]; then
			${LUPRINTF} -Eelp2 "`gettext 'A Live Upgrade Copy Lock exists: Status <%s> Source BE <%s> Target BE <%s>.'`" "${CL_STATUS}" "${CL_SOURCE_BE}" "${CL_TARGET_BE}"
			${LUPRINTF} -Eelp2 "`gettext 'A Live Upgrade Copy operation is schedule for this BE <%s>. You cannot flash this BE until the previous operation completes.'`" "${CL_TARGET_BE}"
			return 2
		fi
	fi
	## No copy operation is (or has been) scheduled: do the flash; create copy lock and allow it to be deleted on exit.

	copylock_create "CL_STATUS" "FLASHING" "yes"
	dfi_ret="$?"
	if [ "${dfi_ret}" -eq "0" ] ; then
		copylock_append "CL_TARGET_BE" "${dfi_beName}"
		dfi_ret="$?"
	fi
	if [ "${dfi_ret}" -ne "0" ] ; then
		${LUPRINTF} -Eelp2 "`gettext 'Unable to create copy lock file: unable to flash the BE <%s>.'`" "${dfi_beName}"
		return 2
	fi

	######################################################################################
	######### Verify that the upgrade media mount point exists and is a directory ########
	######################################################################################

	# Make sure the media root mount point exists and is a directory.
	if [ ! -d ${MEDIAROOTMOUNTPOINT} ] ; then
		# Mount point is not a directory.
		if [ -r ${MEDIAROOTMOUNTPOINT} ] ; then
			# its a readable file!!
			${LUPRINTF} -Eelp2 "`gettext 'Media root mount point <%s> exists and is not a \
directory. Please remove or rename the file and try again.'`" "${MEDIAROOTMOUNTPOINT}"
			return 2
		fi
		# Attempt to create the media root mount point.
		/bin/mkdir ${MEDIAROOTMOUNTPOINT}
		if [ ! -d ${MEDIAROOTMOUNTPOINT} ] ; then
			# Could not create the mount point!
			${LUPRINTF} -Eelp2 "`gettext 'ERROR: Media root mount point <%s> could not be \
created.'`" "${MEDIAROOTMOUNTPOINT}"
			return 2
		fi
	fi

  ######################################################################################
  ####################### Construct the profile to use  ################################
  ######################################################################################

  ${LUPRINTF} -lp1 "`gettext 'Constructing flash profile to use.'`"

  ## Construct a pfinstall flash profile:
  ## - copy the default flash profile ${FLASH_PROFILE} to ${TMP_FLASH_PROFILE}
  ## - if the user specified -j profile file to use, append that;
  ## - else if user specified -J 'profile' on command line, append that;
  ## - otherwise, if user specified -a 'archives', append them.
  ## At end, ${TMP_FLASH_PROFILE} will have the path to the template to use 
  ## for flashing a BE.

  FLASH_TYPE="install"

  # if profile path was specified, validate it
  if [ -n "${dfi_profilePath}" ] ; then
    checkUserFlashProfile "${dfi_profilePath}"
    if [ $? -ne 0 ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'The file <%s> can not be used as a \
flash install profile.'`" "${dfi_profilePath}"
      return 2
    fi
  fi



  if [ $FLASH_TYPE = "install" ] ; then

	### #
	#   #
	### #
	#   #
	#   #

	# Make sure default flash profile exists
	if [ ! -f "${FLASH_PROFILE}" ] ; then
		${LUPRINTF} -Eelp2 "`gettext 'The default flash profile <%s> does not \
exist.'`" "${FLASH_PROFILE}"
		return 2
	fi

	# Create the upgrade profile to use starting with the default profile
	ERRMSG="`${LUBIN}/lucomm_del ${FLASH_PROFILE} > ${TMP_FLASH_PROFILE}`"
	if [ "$?" -ne "0" ] ; then
		${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
		${LUPRINTF} -Eelp2 "`gettext 'Cannot create temporary profile <%s> from \
<%s>.'`" "${TMP_FLASH_PROFILE}" "${FLASH_PROFILE}"
		return 2
	fi

	# if profile path was specified, copy it in place
	if [ -n "${dfi_profilePath}" ] ; then
		ERRMSG="`${LUBIN}/lucomm_del ${dfi_profilePath} | \
/bin/egrep -v '^[ 	]*install_type[ 	]*flash_install[ 	]*$' >> ${TMP_FLASH_PROFILE}`"
		if [ "$?" -ne "0" ] ; then
			${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
			${LUPRINTF} -Eelp2 "`gettext 'Cannot append flash profile <-j %s> to <%s>.'`" \
			"${dfi_profilePath}" "${TMP_FLASH_PROFILE}"
			return 2
		fi
	elif [ -n "${dfi_profile}" ] ; then
		# literal profile was specified, echo it in place
		echo "${dfi_profile}" >> ${TMP_FLASH_PROFILE}
	elif [ -n "${dfi_media}" ] ; then
		# path to actual flash archive(s) were given.  Use them if they exist
		for dfi_flar in `echo ${dfi_archives}` ; do
			if [ ! -f "${dfi_flar}" -o ! -s "${dfi_flar}" ] ; then
				${LUPRINTF} -Eelp2 "`gettext 'The archive <%s> can not be found.'`" "${dfi_flar}"
				return 3
			else
				${LUPRINTF} +X -a "${TMP_FLASH_PROFILE}" "archive_location local_file %s" "${dfi_flar}"
			fi
		done
	else
		${LUPRINTF} -Eelp2 "`gettext 'The -f option must specify an archive set (-a), profile path (-j), or literal profile (-J) to use'`"
		return 3
	fi

	# at this point, the profile template has been completed and is in ${TMP_FLASH_PROFILE}

	${LUPRINTF} -lp2D - "`gettext 'Flash profile is <%s>.'`" \
	"${TMP_FLASH_PROFILE}"

	######################################################################################
	################## Create partition information for flash profile   ##################
	######################################################################################

	${LUPRINTF} -lp1 "`gettext 'Creating flash profile for BE <%s>.'`" "${dfi_beName}"

	# Create ICF file for the current be.
	create_icf $dfi_beCurr > $PBE_ICF
	if [ $? -ne 0 ] ; then
		${LUPRINTF} -Eelp2 "`gettext 'Unable to determine disk partition configuration \
information for current BE <%s>.'`" "${dfi_beCurr}"
		return 2
	fi

	# Create ICF file for the target be.  Filter out shared filesystems.
	create_icf $dfi_beName > $ABE_ICF
	if [ $? -ne 0 ] ; then
		${LUPRINTF} -Eelp2 "`gettext 'Unable to determine disk partition configuration \
information for BE <%s>.'`" "${dfi_beName}"
		return 2
	fi

	${LUETCBIN}/ludo filter_shared_and_swap ${PBE_ICF} ${ABE_ICF} > ${COMBINED_ICF}

	# Add in the slices of the target BE for pfinstall to make and mount.
	${LUPRINTF} +X -a "${TMP_FLASH_PROFILE}" "partitioning explicit"

	#
        # The following code splits the ICF file to retrieve 2 fields, which will be a mirror
        # name and mountpoint where the mirror is mounted. For each entry that is a mirror,
        # it retreieves all the submirrors and for every submirror, it gets the corresponding
        # slice. This data is needed to build the filesys profile keyword. Similar algorithm
        # is applied to get the slices of the metadb replicas.
        # Local customisation is added in the end, to the temporary flash profile so that
        # svm.save and svm.cleanup scripts get executed.
        #

        /usr/bin/cat "${COMBINED_ICF}" | /bin/nawk -F":" '{ n = split ($3, path, $2); printf("%s %s\n", path[n], $2)}' |
        while read line mount
        do
		line=`/usr/bin/basename $line`
		dfi_string=`/usr/sbin/metastat -p 2>/dev/null | /bin/nawk -F" " -v mirr="$line" \
		    '{ if ($1 == mirr && $2 == "-m") {printf("%s %s", $3, $4);}}'`
		dfi_mpath_1=`/bin/echo "$dfi_string" |/bin/cut -d ' ' -f 1`
		dfi_mpath_2=`/bin/echo "$dfi_string" |/bin/cut -d ' ' -f 2`

		if [ -z "$dfi_mpath_1" -a -z "$dfi_mpath_2" ]; then
			if [ "$mount" = "-" ]; then
				echo "filesys $line existing swap" >> $TMP_FLASH_PROFILE
			else
				echo "filesys $line existing $mount" >> $TMP_FLASH_PROFILE
			fi
			continue
		fi
		dfi_meta_1=`/usr/bin/basename "$dfi_mpath_1"`
		dfi_meta_2=`/usr/bin/basename "$dfi_mpath_2"`

		if [ -n "$dfi_meta_1" -a -n "$dfi_meta_2" ]; then
			dfi_mslice1=`/usr/sbin/metastat -p 2>/dev/null | /bin/nawk -F" " -v submirr="$dfi_meta_1"  \
			    '{ if ($1 == submirr && $2 == "1") {printf("%s", $4);}}'`
			dfi_mslice2=`/usr/sbin/metastat -p 2>/dev/null | /bin/nawk -F" " -v submirr="$dfi_meta_2"  \
			    '{ if ($1 == submirr && $2 == "1") {printf("%s", $4);}}'`
			dfi_mslice_b1=`/usr/bin/basename "$dfi_mslice1"`
			dfi_mslice_b2=`/usr/bin/basename "$dfi_mslice2"`
			if [ -n "$dfi_mslice1" -a -n "$dfi_mslice2" ]; then
				mnt_pt="$mount"
				mirr="$line"
                        	if [ "$mnt_pt" = "-" ]; then
					echo "filesys mirror:$mirr $dfi_mslice_b1 $dfi_mslice_b2 8192 swap" >> $TMP_FLASH_PROFILE
				elif [ "$mnt_pt" = "/" ]; then
					echo "filesys mirror:$mirr $dfi_mslice_b1 $dfi_mslice_b2  existing $mnt_pt" \
					    >> $TMP_FLASH_PROFILE
				else
					echo "filesys mirror:$mirr $dfi_mslice_b1 $dfi_mslice_b2 existing $mnt_pt" \
					    >> $TMP_FLASH_PROFILE
				fi
			elif [ -n "$dfi_mslice1" -a -z "$dfi_mslice2" ]; then
				mnt_pt="$mount"
				mirr="$line"
				if [ "$mnt_pt" = "-" ]; then
					echo "filesys mirror:$mirr $dfi_mslice_b1 8192 swap" >> $TMP_FLASH_PROFILE
				elif [ "$mnt_pt" = "/" ]; then
					echo "filesys mirror:$mirr $dfi_mslice_b1 existing $mnt_pt" \
					    >> $TMP_FLASH_PROFILE
				else
					echo "filesys mirror:$mirr $dfi_mslice_b1 existing $mnt_pt" \
					    >> $TMP_FLASH_PROFILE
				fi
			fi
		fi
	done
        /usr/sbin/metadb 2>/dev/null | /usr/bin/nawk -F " " ' { if(NR != 1) { print $NF; }}' |
        while read dfi_metadb
        do
		if [ -n "$dfi_metadb" ]; then
                	dfi_metadb_b=`/usr/bin/basename "$dfi_metadb"`
                	echo "metadb  ${dfi_metadb_b} size 8192 count 1" >> $TMP_FLASH_PROFILE
		fi
        done

        echo "local_customization /etc/flash/postdeployment" >> $TMP_FLASH_PROFILE
        echo "local_customization /etc/flash/predeployment" >> $TMP_FLASH_PROFILE

	/usr/bin/sort -u < $TMP_FLASH_PROFILE > $TMP_SORT_FLASH_PROFILE_1
	/bin/grep '^install_type' $TMP_SORT_FLASH_PROFILE_1 > $TMP_SORT_FLASH_PROFILE_2
	/bin/grep -v '^install_type' $TMP_SORT_FLASH_PROFILE_1 >> $TMP_SORT_FLASH_PROFILE_2

	/usr/bin/mv $TMP_SORT_FLASH_PROFILE_2 $TMP_FLASH_PROFILE
	if [ $? -ne 0 ] ; then
		${LUPRINTF} -Eelp2 "`gettext 'Unable to create flash profile, mv(1) command failed'`"
                return 4
        fi

	/bin/rm -f  $TMP_SORT_FLASH_PROFILE_1

	# Now massage lu_transfer_list to resolve wildcards that might appear in the
	# transferlist.
	dfi_transList=`resolve_transfer_list /etc/lu/lu_transfer_list`
	if [ "$?" != 0 ] ; then
		# Could not make the transfer list
		${LUPRINTF} -Eelp2 "`gettext 'ERROR: Unable to generate transfer list.'`"
		return 2
	fi

	######################################################################################
	############################### --> DO THE FLASH <-- #################################
	######################################################################################

	# N.B. pfinstall expects to mount all of the slices defined in the target o.s.'s vfstab file
	# when it exits these slices remain mounted. For this reason we first need to umount the
	# BE file systems we previously mounted so pfinstall's mounts will not fail. We need to
	# take this into account after pfinstall exits so that we can clean up properly.

	# Setup common pfins1<tall arguments:
	# -L path - root mount point where target boot environment will be mounted (should be /a!).
	# profile - the profile to use to drive the upgrade.
	# -x n - debugging level (1..9 is on).
	#
	# Return codes from pfinstall are:
	# EXIT_INSTALL_SUCCESS_REBOOT     0	(successful - system rebooted)
	# EXIT_INSTALL_SUCCESS_NOREBOOT   1	(successful - system not rebooted)
	# EXIT_INSTALL_FAILURE            2	(An error occurred)

	dfi_pfComArgs="-L ${MEDIAROOTMOUNTPOINT} -p / -t ${dfi_transList} -o ${dfi_miniroot} ${TMP_FLASH_PROFILE}"
	if [ "$LU_DEBUG" -ne "0" ] ; then
		dfi_pfComArgs="-x 10 ${dfi_pfComArgs}"
	fi

	${LUPRINTF} -lp2D - "`gettext 'Using profile <%s>:\n**********\n%R\n**********\n'`" \
"${TMP_FLASH_PROFILE}" < "${TMP_FLASH_PROFILE}"

	### --> THIS CODE IS EXECUTED FOR "NO EXECUTE MODE" ONLY.. <--- ###
	### --> MUST MAKE SURE IT SYNCS UP WITH THE REAL CODE TOO. <--- ###

	if [ -n "${dfi_noExecuteMode}" ] ; then
		${LUPRINTF} -lp1 "`gettext 'Performing the operating system flash of the BE <%s>.'`" "${dfi_beName}"
		${LUPRINTF} -lp1 "`gettext 'Execute Command: <%s>.'`" "${dfi_pfinstallExecutable} ${dfi_pfComArgs}"
		# no patch install - this isn't a normal install, it's flash.
		return 0
	fi

	# Mount the target BE slices.
	abe_icfMount ${ABE_ICF}
	if [ "$?" != "0" ] ; then
		${LUPRINTF} -Eelp2 "`gettext 'Unable to mount the BE <%s>.'`" "${dfi_beName}"
		return 2
	fi
	dfi_bootMnt="${AIM_BEBOOTMNT}"

        ${LUPRINTF} -lp2D -  "`gettext 'ABE slices mounted at <%s>.'`" "${dfi_bootMnt}"

	# Save the GRUB menu (if any) on the ABE
	if [ "${LU_SYSTEM_ARCH}" = i386 -a -z "${dfi_dryRunMode}" ] ; then
	   save_menu "${dfi_bootMnt}" "${dfi_beName}"
	   if [ "$?" -ne 0 ] ; then
	      ${LUPRINTF} -Eelp2 "`gettext 'Unable to save GRUB menu on BE <%s>.'`" "${dfi_beName}"
	      return 2
	   fi
        fi

	# Unmount so pfinstall can do mount.
	abe_umount
	if [ "$?" -ne "0" ] ; then
		${LUPRINTF} -Eelp2 "`gettext 'Unable to unmount the BE <%s>.'`" "${dfi_beName}"
		return 2
	fi

	# Prepare to run pfinstall
	if [ -z "${dfi_dryRunMode}" ] ; then
		# Not dry run mode: actually do the pfinstall
		${LUPRINTF} -lp1 "`gettext 'Performing the operating system flash install of the BE <%s>.'`" "${dfi_beName}"
		${LUPRINTF} -lp1 "`gettext 'CAUTION: Interrupting this process may leave the boot environment unstable or unbootable.'`"

		${LUPRINTF} +X -a "${MAIL_LOGFILE}" "`gettext '%s: Performing the operating system flash install of the BE <%s>.'`" "`/bin/date`" "${dfi_beName}"
	else
		# It IS dry run mode: add -D (simulate) option to pfinstall
		dfi_pfComArgs="-D ${dfi_pfComArgs}"
		${LUPRINTF} -lp1 "`gettext 'Simulating the operating system flash install of the BE <%s>.'`" "${dfi_beName}"

		${LUPRINTF} +X -a "${MAIL_LOGFILE}" "`gettext '%s: Simulating the operating system flash install of the BE <%s>.'`" "`/bin/date`" "${dfi_beName}"
	fi

	${LUPRINTF} -lp2D - "`gettext 'Executing: <%s>.'`" "${dfi_pfinstallExecutable} ${dfi_pfComArgs} 2>&1 1>${PFINSTALL_LOGFILE}"
	${LUPRINTF} +X -a "${MAIL_LOGFILE}" "`gettext '%s: Using: %s'`" "`/bin/date`" "${dfi_pfinstallExecutable} ${dfi_pfComArgs}"

	# yes, /usr/sbin needs to be in the LD_LIBRARY_PATH.  It's for sys-unconfig.
	dfi_sbinDir="${dfi_miniroot}/usr/sbin"
	dfi_ldLibraryPath="${dfi_libDir}:${dfi_sbinDir}"
	[ -n "${LD_LIBRARY_PATH}" ] && dfi_ldLibraryPath="${dfi_ldLibraryPath}:${LD_LIBRARY_PATH}"

	# First run pfinstall with the '-r' option and progress reporting enabled;
	# then check to see the results to determine whether or not this pfinstall
	# supports the -r option and progress reporting.
	/bin/rm -f "${PROGRESS_REPORT_FILE}" 2>/dev/null 1>&2
	LD_LIBRARY_PATH=${dfi_ldLibraryPath} ${dfi_pfinstallExecutable} -r "${PROGRESS_REPORT_FILE}" ${dfi_pfComArgs} 1>${PFINSTALL_LOGFILE} 2>&1 &
	dfi_pfPid="$!"
	if [ -z "${_LU_OUTPUT_XML_}" ] ; then
		${LUETCBIN}/ludo 'report_progress' "${dfi_pfPid}" "${PROGRESS_REPORT_FILE}" \
			'text' "`gettext 'Extracting Flash Archive: %s%% completed'`" \
			'flash-extract' &
	else
		${LUETCBIN}/ludo 'report_progress' "${dfi_pfPid}" "${PROGRESS_REPORT_FILE}" \
			'xml' "${LU_PROG_NAME}" 'flash-extract' &
	fi
	fg "${dfi_pfPid}"
	dfi_ret="$?"

	# If the return code is "0" and the progress report file was NOT found then
	# this pfinstall is one that does not support the '-r' option. Rerun without
	# the -r option and any progress reporting.
	if [[ "${dfi_ret}" -eq "0" && ! -e "${PROGRESS_REPORT_FILE}" ]] ; then
		LD_LIBRARY_PATH=${dfi_ldLibraryPath} ${dfi_pfinstallExecutable} ${dfi_pfComArgs} 1>${PFINSTALL_LOGFILE} 2>&1
		dfi_ret="$?"
	fi

	# The return code for pfinstall when installing a flash archive
	# is '0' on success - any other code is a failure. In this case
	# stat_pfinstall can be set directly from pfinstall's return code.
	stat_pfinstall="${dfi_ret}"

	# if pfinstall returned any result > 1 then it failed - even though we continue
	# no patches will be added or any other work will be done - the reason we continue
	# is in the case where pfinstall may have mounted the file systems for the target
	# boot environment (probably on /a) in which case we need to do some special
	# work to restore the original vfstab file...

	if [ -n "${dfi_dryRunMode}" ] ; then
		# This was just a simulation of what would have been done.
		if [ "${stat_pfinstall}" -ne "0" ] ; then
			${LUPRINTF} -Eelp2 "`gettext 'The flash install simulation failed; pfinstall returned these diagnostics:\n%R'`" < ${PFINSTALL_LOGFILE}
			${LUPRINTF} -pa "${MAIL_LOGFILE}" "`gettext '%s: The flash simulation failed:'`" "`/bin/date`"
			maillog_addFile "${PFINSTALL_LOGFILE}" "`gettext 'pfinstall diagnostics output'`"
		else
			${LUPRINTF} -lp1 "`gettext 'The operating flash install simulation completed.'`"
			if [ -f "${PFINSTALL_LOGFILE}" -a -s "${PFINSTALL_LOGFILE}" ] ; then
				if [ "${LU_DEBUG}" -ne "0" ] ; then
					${LUPRINTF} -lp2D - "`gettext 'pfinstall returned these results:\n%R'`" < ${PFINSTALL_LOGFILE}
				fi
				maillog_addFile "${PFINSTALL_LOGFILE}" "`gettext 'The flash simulation completed; pfinstall results:'`"
			fi
		fi
	else
		# This was NOT a simulation but a real installation - report it as such
		if [ "${stat_pfinstall}" -ne "0" ] ; then
			${LUPRINTF} -Eelp2 "`gettext 'The flash install failed; pfinstall returned these diagnostics:\n%R'`" < ${PFINSTALL_LOGFILE}
			${LUPRINTF} -pa "${MAIL_LOGFILE}" "`gettext '%s: The flash failed:'`" "`/bin/date`"
			maillog_addFile "${PFINSTALL_LOGFILE}" "`gettext 'pfinstall diagnostics output'`"
		 else
			${LUPRINTF} -lp1 "`gettext 'The operating system flash install completed.'`"
			if [ -f "${PFINSTALL_LOGFILE}" -a -s "${PFINSTALL_LOGFILE}" ] ; then
				if [ "${LU_DEBUG}" -ne "0" ] ; then
					${LUPRINTF} -lp2D - "`gettext 'pfinstall returned these results:\n%R'`" < ${PFINSTALL_LOGFILE}
				fi
				maillog_addFile "${PFINSTALL_LOGFILE}" "`gettext 'The flash install completed; pfinstall results:'`"
			fi
		fi
	fi

	# ABE will now be mounted on ${MEDIAROOTMOUNTPOINT}.
	# Change the location where we believe the ABEs backup vfstab file is located.
	# Make believe we mounted the ABEs slices (pfinstall should have done this for us).
	dfi_bootMnt=${MEDIAROOTMOUNTPOINT}
	change_vfstab_bootmnt "${dfi_bootMnt}"

	# Make sure that the ABEs root slice is mounted on the expected mount point.
	abe_checkMounted "${ABE_ICF}"
	if [ "$?" -ne "0" ] ; then
		${LUPRINTF} -Eelp2 "`gettext 'Problem remounting the BE <%s>.'`" "${dfi_beName}"
	fi

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

	# Restore the GRUB menu (if any) on the ABE
	if [ "${LU_SYSTEM_ARCH}" = i386 -a -z "${dfi_dryRunMode}" ] ; then
	   restore_menu "${dfi_bootMnt}" "${dfi_beName}"
	   if [ "$?" -ne 0 ] ; then
	      ${LUPRINTF} -Eelp2 "`gettext 'Unable to restore GRUB menu on BE <%s>.'`" "${dfi_beName}"
	      return 2
	   fi
        fi

	# If not in dry run mode, and the pfinstall was successful,
	# do work necessary to cleanup after the flash installation.

	if [ -z "${dfi_dryRunMode}" -a "${stat_pfinstall}" -eq "0" ] ; then
		# The BE now contains the contents of the flash archive; there may be
		# file systems that were configured into the BE that do not have mount
		# points in the flash archive. Add all mount points now.
		create_be_mountpoints "${MEDIAROOTMOUNTPOINT}"

		# reconfigure the device tree
		reconfigure_devices "${dfi_bootMnt}" "${dfi_beName}"
    
		if [ $? != 0 ] ; then
			${LUPRINTF} -Eelp2 "`gettext 'Unable to reconfigure devices for BE <%s>.'`" "${dfi_beName}"
			return 2
		fi
    
		/bin/cp ${LU_LUTAB_FILE} ${dfi_bootMnt}/etc
		/bin/cp -r /etc/lu ${dfi_bootMnt}/etc
		/bin/rm -f ${dfi_bootMnt}/${COPYLOCK}

		# Unmount the boot environment just flashed
		abe_umount

  		${LUPRINTF} -lp2D - "`gettext 'ABE unmounted.'`"

		# Make the new boot environment bootable
		$LUBIN/lumkboot -i "${ABE_ICF}" -n "${dfi_beName}"
		if [ $? -ne 0 ] ; then
			${LUPRINTF} -Eelp2 "`gettext 'Unable to make boot environment <%s> bootable.'`" "${dfi_beName}"
			return 2
		fi

		# Mark the new boot environment as complete
		$LUBIN/lustat_set -n "${dfi_beName}" -s 'C'
		if [ $? -ne 0 ] ; then
			${LUPRINTF} -Eelp2 "`gettext 'Unable to mark boot environment <%s> complete.'`" "${dfi_beName}"
			return 2
		fi

		dfi_bootMnt=`LU_OUTPUT_FORMAT=text $LUBIN/lumount $dfi_beName "${MEDIAROOTMOUNTPOINT}" 2>${TMP_RESULT_FILE}`
		if [ $? -ne 0 ] ; then
			[ -s "${TMP_RESULT_FILE}" ] && ${LUPRINTF} -elp2 '%R' < "${TMP_RESULT_FILE}"
			${LUPRINTF} -Eelp2 "`gettext 'Unable to mount boot environment <%s>.'`" "${dfi_beName}"
			return 2
		fi
  		${LUPRINTF} -lp2D - "`gettext 'ABE mounted at <%s>.'`"  "${dfi_bootMnt}"

		# now update the eeprom settings on the ABE if we are on x86.
		if [ "${LU_SYSTEM_ARCH}" = "i386" ] ; then
			${LUPRINTF} -lp "`gettext 'Updating boot-path on ABE <%s>.'`" "${dfi_beName}"
			#
			# The following just updates boot-path setting in bootenv.rc
			#
			update_x86boot ${dfi_bootMnt} ${dfi_beName}
			if [ $? != 0 ] ; then
			   ${LUPRINTF} -Eelp2 "`gettext 'Unable to update x86 boot partition  devices for BE <%s>.'`" "${dfi_beName}"
			   return 2
			fi
			#
			# The following installs the latest GRUB from the ABE in the PBE
			#
			install_latest_GRUB "${dfi_bootMnt}" "${dfi_beName}"
			if [ "$?" -ne 0 ] ; then
			   ${LUPRINTF} -Eelp2 "`gettext 'Unable to install latest GRUB from ABE <%s>.'`" "${dfi_beName}"
			   return 2
			fi
    			#
    			# Customize the failsafe console setting based on PBE settings.
    			#
    			configure_failsafe "$LU_MINIROOT_MNTPT" "$dfi_beName" 
		fi

    
		delete_x86_boot_backing "$dfi_bootMnt"
		if [ "$?" -ne 0 ]; then
			stat_pfinstall="2"
		fi
		modify_x86_boot_entry "$dfi_bootMnt"
		if [ "$?" -ne 0 ]; then
			stat_pfinstall="2"
		fi

		# If the install log exists then add the contents of the upgrade log file 
		# to the mail log file.  This probably didn't happen unless the flash 
		# archive didn't overwrite the install log
    
		if [ -f "${dfi_bootMnt}${PFINSTALL_INSTALL_LOG}" -a -s "${dfi_bootMnt}${PFINSTALL_INSTALL_LOG}" ] ; then
			maillog_addFile "${dfi_bootMnt}${PFINSTALL_INSTALL_LOG}" "`gettext 'Target BE install log file results:'`"
		fi

		$LUBIN/luumount -f "$dfi_beName" 2>/dev/null 1>&2
	else
		abe_umount
	fi

	# The flash installation is finished. Output completion status and return.

	if [ "${stat_pfinstall}" -ne "0" ] ; then
		${LUPRINTF} -lp1 "`gettext 'The Solaris flash install of the BE <%s> failed.'`" "${dfi_beName}"
		maillog_setSubject "`gettext 'Flash FAILED (Solaris flash install failed).'`"
		return 1
	fi
	${LUPRINTF} -lp1 "`gettext 'The Live Flash Install of the boot environment <%s> is complete.'`" "${dfi_beName}"
	maillog_setSubject "`gettext 'Flash install Completed.'`"
	return 0

  else

	### #  #
	#   #  #
	### #  #
	#   #  #
	#    ##

	# proceed with flash_update

	# Make sure default flash profile exists

	if [ ! -f "${FLASH_UPDATE_PROFILE}" ] ; then
		${LUPRINTF} -Eelp2 "`gettext 'The default flash_update profile <%s> does not \
exist.'`" "${FLASH_UPDATE_PROFILE}"
		return 2
	fi

	# Create the upgrade profile to use starting with the default profile
	ERRMSG="`${LUBIN}/lucomm_del ${FLASH_UPDATE_PROFILE} > ${TMP_FLASH_PROFILE}`"
	if [ "$?" -ne "0" ] ; then
		${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
		${LUPRINTF} -Eelp2 "`gettext 'Cannot create temporary profile <%s> from \
<%s>.'`" "${TMP_FLASH_PROFILE}" "${FLASH_UPDATE_PROFILE}"
		return 2
	fi

	# if profile path was specified, validate it and copy it in place
	ERRMSG="`${LUBIN}/lucomm_del ${dfi_profilePath} | \
/bin/egrep -v '^[ 	]*install_type[ 	]*flash_update[ 	]*$' >> ${TMP_FLASH_PROFILE}`"
	if [ "$?" -ne "0" ] ; then
		${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
		${LUPRINTF} -Eelp2 "`gettext 'Cannot append flash profile <-j %s> to <%s>.'`" \
		"${dfi_profilePath}" "${TMP_FLASH_PROFILE}"
		return 2
	fi

	# at this point, the profile template has been completed and is in ${TMP_FLASH_PROFILE}

	${LUPRINTF} -lp2D - "`gettext 'Flash profile is <%s>.'`" \
	"${TMP_FLASH_PROFILE}"

	# Create ICF file for the target be and filter out all "non-system" file systems.

	create_icf $dfi_beName > $ABE_ICF
	if [ $? -ne 0 ] ; then
		${LUPRINTF} -Eelp2 "`gettext 'Unable to determine disk partition configuration information for BE <%s>.'`" "${dfi_beName}"
		return 2
	fi

	${LUETCBIN}/ludo filter_nonsystem ${ABE_ICF} > ${COMBINED_ICF}

	# Create new upgrade profile and add in the root slice of the target BE.

	dfi_abeRootSlice=`${LUETCBIN}/ludo get_root_slice_from_be_name ${dfi_beName}`

	if [ -z "${dfi_abeRootSlice}" ] ; then
		${LUPRINTF} -Eelp2 "`gettext 'Unable to determine root slice for BE <%s>.'`" "${dfi_beName}"
		return 2
	fi

	${LUPRINTF} -lp2D - "`gettext 'Root device for update is <%s>.'`" "${dfi_abeRootSlice}"

	# If pfinstall implements the sw:upgrade_mountpoint capability, do NOT place
	# the root_device directive into the update profile. This is because if the
	# pfinstall sw:upgrade_mountpoint is implemented, and -L is specified with
	# no root_device in the profile, pfinstall assumes that all file systems are
	# already mounted at the -L location

	if [ -z "${dfi_umcap}" ] ; then
	  ${LUPRINTF} +X -a "${TMP_FLASH_PROFILE}" "root_device %s" "${dfi_abeRootSlice}"
	  ${LUPRINTF} -lp2D - "`gettext '<root_device %s> added to update profile <%s>.'`" \
      "${dfi_abeRootSlice}" "${TMP_FLASH_PROFILE}"
	else
	  ${LUPRINTF} -lp2D - "`gettext 'root_device NOT ADDED to update profile.'`"
	fi

	# Mount the target BE slices.
	abe_icfMount ${ABE_ICF}
	if [ "$?" != "0" ] ; then
		${LUPRINTF} -Eelp2 "`gettext 'Unable to mount the BE <%s>.'`" "${dfi_beName}"
		return 2
	fi
	dfi_bootMnt="${AIM_BEBOOTMNT}"

        # At this point we have mounted the ABE including boot partition (if any)
        ${LUPRINTF} -lp2D - "`gettext 'ABE slices mounted at <%s>.'`" "${dfi_bootMnt}"

	# Save the GRUB menu (if any) on the ABE
	if [ "${LU_SYSTEM_ARCH}" = i386 -a -z "${dfi_dryRunMode}" ] ; then
	   save_menu "${dfi_bootMnt}" "${dfi_beName}"
	   if [ "$?" -ne 0 ] ; then
	      ${LUPRINTF} -Eelp2 "`gettext 'Unable to save GRUB menu on BE <%s>.'`" "${dfi_beName}"
	      return 2
	   fi
        fi

        # Check if ABE uses a boot partition before changing vfstab
        dfi_bootPart=""
        if [ "${LU_SYSTEM_ARCH}" = "i386" ] ; then
            ${LUPRINTF} -lp1 "`gettext 'Checking for x86 boot partition on ABE.'`"
            /bin/grep -s -v '^#' "${dfi_bootMnt}/etc/vfstab" | /bin/grep "[	]/boot[	]*pcfs[	]" >/dev/null 2>&1
            if [ "$?" -eq 0 ]; then
                dfi_bootPart=`/bin/grep -s -v '^#' "${dfi_bootMnt}/etc/vfstab" | /bin/grep "[ 	]/boot[ 	]*pcfs[ 	]" | /usr/bin/awk '{print $1}'`
                ${LUPRINTF} -lp1 "`gettext 'x86 boot partition exists on ABE <%s>'`" "${dfi_beName}"
            fi
        fi

	# Backup the target ABE's vfstab file.

	backup_vfstab_file "${dfi_bootMnt}" "${dfi_beName}" "${ABE_ICF}"
	dfi_ret="$?"
	if [ "${dfi_ret}" -ne "0" ] ; then
		if [ "${dfi_ret}" -eq "1" ] ; then
			${LUPRINTF} -Eelp2 "`gettext 'Unable to save backup copy of vfstab file for BE <%s>.'`" "${dfi_beName}"
		fi
		return 2
	fi

	#--> At this point, the exit_script() code will automagically restore the       <--#
	#--> target boot environments vfstab file if it has not already been restored.  <--#
	#--> Because of this, there is no reason to include "restore_vfstab_file" calls <--#
	#--> before each error return from this function.                               <--#

	# Replace the target ABE's vfstab file with the one we created which only
	# has the "system" file systems on it. The "-I" option means do not include
	# any filesystems that are not mentioned in the ICF file.

	${LUBIN}/luedvfstab -i "${COMBINED_ICF}" -m "${dfi_bootMnt}" -n "${dfi_beName}" -I

	if [ "$?" -ne "0" ] ; then
		${LUPRINTF} -Eelp2 "`gettext 'Unable to create revised vfstab file on BE.'`"
		return 2
	else
		${LUPRINTF} -lp2D - "`gettext 'boot environment <%s> temporary vfstab file:\
\n**********************************\n%R\n**********************************'`" \
"${dfi_beName}" < ${dfi_bootMnt}/etc/vfstab
	fi

	#
        # Do processing only for x86 boot partition on intel platforms
	# Before pfinstall runs, copy the contents of the ABE boot
	# partition and write it onto the ABE's root filesystem at <mntpt>/boot.
	#
        if [ "${LU_SYSTEM_ARCH}" = "i386" ] ; then
	   convert_x86_boot_partition "$dfi_bootMnt" "$dfi_bootPart"
	   if [ "$?" -ne 0 ]; then
	      ${LUPRINTF} -Eelp2 "`gettext 'Unable to convert X86 boot partition.'`"
	      return 1
	   fi
        fi

	######################################################################################
	############################### --> DO THE FLASH <-- #################################
	######################################################################################

	# N.B. pfinstall expects to mount all of the slices defined in the target o.s.'s vfstab file
	# when it exits these slices remain mounted. For this reason we first need to umount the
	# BE file systems we previously mounted so pfinstall's mounts will not fail. We need to
	# take this into account after pfinstall exits so that we can clean up properly.

	# Setup common pfins1<tall arguments:
	# -L path - root mount point where target boot environment will be mounted (should be /a!).
	# profile - the profile to use to drive the upgrade.
	# -x n - debugging level (1..9 is on).
	#
	# Return codes from pfinstall are:
	# EXIT_INSTALL_SUCCESS_REBOOT     0	(successful - system rebooted)
	# EXIT_INSTALL_SUCCESS_NOREBOOT   1	(successful - system not rebooted)
	# EXIT_INSTALL_FAILURE            2	(An error occurred)


	dfi_pfComArgs="-L ${MEDIAROOTMOUNTPOINT} -p / -o ${dfi_miniroot} ${TMP_FLASH_PROFILE}"
	if [ "$LU_DEBUG" -ne "0" ] ; then
		dfi_pfComArgs="-x 10 ${dfi_pfComArgs}"
	fi

	${LUPRINTF} -lp2D - "`gettext 'Using profile <%s>:\n**********\n%R\n**********\n'`" \
"${TMP_FLASH_PROFILE}" < "${TMP_FLASH_PROFILE}"

	### --> THIS CODE IS EXECUTED FOR "NO EXECUTE MODE" ONLY.. <--- ###
	### --> MUST MAKE SURE IT SYNCS UP WITH THE REAL CODE TOO. <--- ###

	if [ -n "${dfi_noExecuteMode}" ] ; then
		${LUPRINTF} -lp1 "`gettext 'Performing the operating system flash of the BE <%s>.'`" "${dfi_beName}"
		${LUPRINTF} -lp1 "`gettext 'Execute Command: <%s>.'`" "${dfi_pfinstallExecutable} ${dfi_pfComArgs}"
		# no patch install - this isn't a normal install, it's flash.
		return 0
	fi

	# If the pfinstall sw:upgrade_mountpoint capability is implemented, the
	# mounting of file systems by pfinstall has already been disabled because
	# the "root_slice" directive has not been placed into the pfinstall
	# update profile. If the sw:upgrade_mountpoint capability is implemented,
	# there is no need to unmount the abe file systems before calling pfinstall

	if [ "${dfi_umcap}" = "yes" ] ; then
	  ${LUPRINTF} -lp2D - "`gettext 'Boot environment <%s> remains mounted at <%s>.'`" \
      "${dfi_beName}" "${MEDIAROOTMOUNTPOINT}"
	else
	  # pfinstall sw:upgrade_mountpoint capability IS NOT IMPLEMENTED.
	  # Unmount so pfinstall can do mount.
	  abe_umount
	  if [ "$?" -ne "0" ] ; then
	    ${LUPRINTF} -Eelp2 "`gettext 'Unable to unmount the BE <%s>.'`" "${dfi_beName}"
	    return 2
	  fi
	  ${LUPRINTF} -lp2D - "`gettext 'Boot environment <%s> has been unmounted.'`" \
      "${dfi_beName}"
	fi

	# Prepare to run pfinstall
	if [ -z "${dfi_dryRunMode}" ] ; then
		# Not dry run mode: actually do the pfinstall
		${LUPRINTF} -lp1 "`gettext 'Performing the operating system flash update of the BE <%s>.'`" "${dfi_beName}"
		${LUPRINTF} -lp1 "`gettext 'CAUTION: Interrupting this process may leave the boot environment unstable or unbootable.'`"
		${LUPRINTF} +X -a "${MAIL_LOGFILE}" "`gettext '%s: Performing the operating system flash update of the BE <%s>.'`" "`/bin/date`" "${dfi_beName}"
	else
		# It IS dry run mode: add -D (simulate) option to pfinstall
		dfi_pfComArgs="-D ${dfi_pfComArgs}"
		${LUPRINTF} -lp1 "`gettext 'Simulating the operating system flash update of the BE <%s>.'`" "${dfi_beName}"

		${LUPRINTF} +X -a "${MAIL_LOGFILE}" "`gettext '%s: Simulating the operating system flash update of the BE <%s>.'`" "`/bin/date`" "${dfi_beName}"
	fi

	${LUPRINTF} -lp2D - "`gettext 'Executing: <%s>.'`" "${dfi_pfinstallExecutable} ${dfi_pfComArgs} 2>&1 1>${PFINSTALL_LOGFILE}"
	${LUPRINTF} +X -a "${MAIL_LOGFILE}" "`gettext '%s: Using: %s'`" "`/bin/date`" "${dfi_pfinstallExecutable} ${dfi_pfComArgs}"

	# yes, /usr/sbin needs to be in the LD_LIBRARY_PATH.  It's for sys-unconfig.
	dfi_sbinDir="${dfi_miniroot}/usr/sbin"
	dfi_ldLibraryPath="${dfi_libDir}:${dfi_sbinDir}"
	[ -n "${LD_LIBRARY_PATH}" ] && dfi_ldLibraryPath="${dfi_ldLibraryPath}:${LD_LIBRARY_PATH}"

	# First run pfinstall with the '-r' option and progress reporting enabled;
	# then check to see the results to determine whether or not this pfinstall
	# supports the -r option and progress reporting.
	/bin/rm -f "${PROGRESS_REPORT_FILE}" 2>/dev/null 1>&2
	LD_LIBRARY_PATH=${dfi_ldLibraryPath} ${dfi_pfinstallExecutable} -r "${PROGRESS_REPORT_FILE}" ${dfi_pfComArgs} 1>${PFINSTALL_LOGFILE} 2>&1 &
	dfi_pfPid="$!"
	if [ -z "${_LU_OUTPUT_XML_}" ] ; then
		${LUETCBIN}/ludo 'report_progress' "${dfi_pfPid}" "${PROGRESS_REPORT_FILE}" \
			'text' "`gettext 'Extracting Flash Archive: %s%% completed'`" \
			'flash-extract' &
	else
		${LUETCBIN}/ludo 'report_progress' "${dfi_pfPid}" "${PROGRESS_REPORT_FILE}" \
			'xml' "${LU_PROG_NAME}" 'flash-extract' &
	fi
	fg "${dfi_pfPid}"
	dfi_ret="$?"

	# If the return code is "0" and the progress report file was NOT found then
	# this pfinstall is one that does not support the '-r' option. Rerun without
	# the -r option and any progress reporting.
	if [[ "${dfi_ret}" -eq "0" && ! -e "${PROGRESS_REPORT_FILE}" ]] ; then
		LD_LIBRARY_PATH=${dfi_ldLibraryPath} ${dfi_pfinstallExecutable} ${dfi_pfComArgs} 1>${PFINSTALL_LOGFILE} 2>&1
		dfi_ret="$?"
	fi

	# The return code for pfinstall when installing a flash archive
	# is '0' on success - any other code is a failure. In this case
	# stat_pfinstall can be set directly from pfinstall's return code.
	stat_pfinstall="${dfi_ret}"

	# if pfinstall returned any result > 1 then it failed - even though we continue
	# no patches will be added or any other work will be done - the reason we continue
	# is in the case where pfinstall may have mounted the file systems for the target
	# boot environment (probably on /a) in which case we need to do some special
	# work to restore the original vfstab file...

	if [ -n "${dfi_dryRunMode}" ] ; then
		# This was just a simulation of what would have been done.
		if [ "${stat_pfinstall}" -ne "0" ] ; then
			${LUPRINTF} -Eelp2 "`gettext 'The flash update simulation failed; pfinstall returned these diagnostics:\n%R'`" < ${PFINSTALL_LOGFILE}
			${LUPRINTF} -pa "${MAIL_LOGFILE}" "`gettext '%s: The flash simulation failed:'`" "`/bin/date`"
			maillog_addFile "${PFINSTALL_LOGFILE}" "`gettext 'pfinstall diagnostics output'`"
		else
			${LUPRINTF} -lp1 "`gettext 'The operating flash update simulation completed.'`"
			if [ -f "${PFINSTALL_LOGFILE}" -a -s "${PFINSTALL_LOGFILE}" ] ; then
				if [ "${LU_DEBUG}" -ne "0" ] ; then
					${LUPRINTF} -lp2D - "`gettext 'pfinstall returned these results:\n%R'`" < ${PFINSTALL_LOGFILE}
				fi
				maillog_addFile "${PFINSTALL_LOGFILE}" "`gettext 'The flash simulation completed; pfinstall results:'`"
			fi
		fi
	else
		# This was NOT a simulation but a real installation - report it as such
		if [ "${stat_pfinstall}" -ne "0" ] ; then
			${LUPRINTF} -Eelp2 "`gettext 'The flash update failed; pfinstall returned these diagnostics:\n%R'`" < ${PFINSTALL_LOGFILE}
			${LUPRINTF} -pa "${MAIL_LOGFILE}" "`gettext '%s: The flash failed:'`" "`/bin/date`"
			maillog_addFile "${PFINSTALL_LOGFILE}" "`gettext 'pfinstall diagnostics output'`"
		 else
			${LUPRINTF} -lp1 "`gettext 'The operating system flash update completed.'`"
			if [ -f "${PFINSTALL_LOGFILE}" -a -s "${PFINSTALL_LOGFILE}" ] ; then
				if [ "${LU_DEBUG}" -ne "0" ] ; then
					${LUPRINTF} -lp2D - "`gettext 'pfinstall returned these results:\n%R'`" < ${PFINSTALL_LOGFILE}
				fi
				maillog_addFile "${PFINSTALL_LOGFILE}" "`gettext 'The flash update completed; pfinstall results:'`"
			fi
		fi
	fi

	# ABE will now be mounted on ${MEDIAROOTMOUNTPOINT}.
	# Change the location where we believe the ABEs backup vfstab file is located.
	# Make believe we mounted the ABEs slices (pfinstall should have done this for us).
	dfi_bootMnt=${MEDIAROOTMOUNTPOINT}
	change_vfstab_bootmnt "${dfi_bootMnt}"

	# Make sure that the ABEs root slice is mounted on the expected mount point.
	abe_checkMounted "${ABE_ICF}"
	if [ "$?" -ne "0" ] ; then
		${LUPRINTF} -Eelp2 "`gettext 'Problem remounting the BE <%s>.'`" "${dfi_beName}"
	fi

        ${LUPRINTF} -lp2D - "`gettext 'ABE is mounted at <%s>.'`" "$dfi_bootMnt"

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

	# Restore the GRUB menu (if any) on the ABE
	if [ "${LU_SYSTEM_ARCH}" = i386 -a -z "${dfi_dryRunMode}" ] ; then
	   restore_menu "${dfi_bootMnt}" "${dfi_beName}"
	   if [ "$?" -ne 0 ] ; then
	      ${LUPRINTF} -Eelp2 "`gettext 'Unable to restore GRUB menu on BE <%s>.'`" "${dfi_beName}"
	      return 2
	   fi
        fi

	# If not in dry run mode, and the pfinstall was successful,
	# do work necessary to cleanup after the flash installation.

	if [ -z "${dfi_dryRunMode}" -a "${stat_pfinstall}" -eq "0" ] ; then

		restore_vfstab_file
		dfi_bootMnt=${VFST_BOOT_MNT}

		# The BE now contains the contents of the flash archive; there may be
		# file systems that were configured into the BE that do not have mount
		# points in the flash archive. Add all mount points now.
		create_be_mountpoints "${MEDIAROOTMOUNTPOINT}"

		# reconfigure the device tree
		reconfigure_devices "${dfi_bootMnt}" "${dfi_beName}"
    
		if [ $? != 0 ] ; then
			${LUPRINTF} -Eelp2 "`gettext 'Unable to reconfigure devices for BE <%s>.'`" "${dfi_beName}"
			return 2
		fi
    
		/bin/cp ${LU_LUTAB_FILE} ${dfi_bootMnt}/etc
		/bin/cp -r /etc/lu ${dfi_bootMnt}/etc
		/bin/rm -f ${dfi_bootMnt}/${COPYLOCK}


		# Unmount the boot environment just flashed
		abe_umount

  		${LUPRINTF} -lp2D - "`gettext 'ABE unmounted.'`"

		# Make the new boot environment bootable
		$LUBIN/lumkboot -i "${ABE_ICF}" -n "${dfi_beName}"
		if [ $? -ne 0 ] ; then
			${LUPRINTF} -Eelp2 "`gettext 'Unable to make boot environment <%s> bootable.'`" "${dfi_beName}"
			return 2
		fi

		# Mark the new boot environment as complete
		$LUBIN/lustat_set -n "${dfi_beName}" -s 'C'
		if [ $? -ne 0 ] ; then
			${LUPRINTF} -Eelp2 "`gettext 'Unable to mark boot environment <%s> complete.'`" "${dfi_beName}"
			return 2
		fi

		dfi_bootMnt=`LU_OUTPUT_FORMAT=text $LUBIN/lumount $dfi_beName "${MEDIAROOTMOUNTPOINT}" 2>${TMP_RESULT_FILE}`
		if [ $? -ne 0 ] ; then
			[ -s "${TMP_RESULT_FILE}" ] && ${LUPRINTF} -elp2 '%R' < "${TMP_RESULT_FILE}"
			${LUPRINTF} -Eelp2 "`gettext 'Unable to mount boot environment <%s>.'`" "${dfi_beName}"
			return 2
		fi
  		${LUPRINTF} -lp2D - "`gettext 'ABE mounted at <%s>.'`"  "${dfi_bootMnt}"

		# now update the eeprom settings on the ABE if we are on x86.
		if [ "${LU_SYSTEM_ARCH}" = "i386" ] ; then
			${LUPRINTF} -lp "`gettext 'Updating boot-path on ABE <%s>.'`" "${dfi_beName}"
			#
			# The following just updates boot-path setting in bootenv.rc
			#
			update_x86boot ${dfi_bootMnt} ${dfi_beName}
			if [ $? != 0 ] ; then
			   ${LUPRINTF} -Eelp2 "`gettext 'Unable to update x86 boot partition  devices for BE <%s>.'`" "${dfi_beName}"
			   return 2
			fi

			#
			# The following installs the latest GRUB from the ABE in the PBE
			#
			install_latest_GRUB "${dfi_bootMnt}" "${dfi_beName}"
			if [ "$?" -ne 0 ] ; then
			   ${LUPRINTF} -Eelp2 "`gettext 'Unable to install latest GRUB from ABE <%s>.'`" "${dfi_beName}"
			   return 2
			fi

    			#
    			# Customize the failsafe console setting based on PBE settings.
    			#
    			configure_failsafe "$LU_MINIROOT_MNTPT" "$dfi_beName" 
			if [ "$?" -ne 0 ] ; then
			   ${LUPRINTF} -Eelp2 "`gettext 'Unable to configure failsafe for ABE <%s>.'`" "${dfi_beName}"
			   return 2
			fi
		fi
    
		delete_x86_boot_backing "$dfi_bootMnt"
		if [ "$?" -ne 0 ]; then
			stat_pfinstall="2"
		fi
		modify_x86_boot_entry "$dfi_bootMnt"
		if [ "$?" -ne 0 ]; then
			stat_pfinstall="2"
		fi

		# If the install log exists then add the contents of the upgrade log file 
		# to the mail log file.  This probably didn't happen unless the flash 
		# archive didn't overwrite the install log
    
		if [ -f "${dfi_bootMnt}${PFINSTALL_INSTALL_LOG}" -a -s "${dfi_bootMnt}${PFINSTALL_INSTALL_LOG}" ] ; then
			maillog_addFile "${dfi_bootMnt}${PFINSTALL_INSTALL_LOG}" "`gettext 'Target BE install log file results:'`"
		fi

		$LUBIN/luumount -f "${dfi_beName}" 2>/dev/null 1>&2
	else
		abe_umount
	fi

	# The flash installation is finished. Output completion status and return.

	if [ "${stat_pfinstall}" -ne "0" ] ; then
		${LUPRINTF} -lp1 "`gettext 'The Solaris flash update of the BE <%s> failed.'`" "${dfi_beName}"
		maillog_setSubject "`gettext 'Flash FAILED (Solaris flash update failed).'`"
		return 1
	fi
	${LUPRINTF} -lp1 "`gettext 'The Live Flash Update of the boot environment <%s> is complete.'`" "${dfi_beName}"
	maillog_setSubject "`gettext 'Flash Update Completed.'`"
	return 0

  fi

}

################################################################################
# Name:		do_runInstaller
# Description:	Run installer on boot environment from specified media.
# Local Prefix:	dri_
# Arguments:	$1 = boot environment name to run installer against.
#		$2 = no execute mode ("" if not enabled).
#		$3 = optional arguments for installer ("" if none).
#		$4 = media mount point to run installer from.
#		$5 = command arguments to pass to installer on command line ("" if none).
# Returns:
################################################################################

do_runInstaller()
{
  dri_beName="$1"
  dri_noExecuteMode="$2"
  dri_optArgs="$3"
  dri_media="$4"
  dri_cmdArgs="$5"


  ${LUPRINTF} -lp2D - "`gettext 'Run installer BE <%s> NoExecuteMode <%s> Installer Args <%s %s> Media <%s>.'`" "${dri_beName}" "${dri_noExecuteMode}" "${dri_optArgs}" "${dri_cmdArgs}" "${dri_media}"

  ######################################################################################
  ################### Verify that the media has an installer present ###################
  ######################################################################################

  ${LUPRINTF} -lp1 "`gettext 'Validating the contents of the media <%s>.'`" "${dri_media}"
  lulib_validate_is_directory_not_empty "${dri_media}"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The run installer (-i) option requires that you specify the installer to run location with the <-s> option.'`"
    return 3
  fi

  dri_media_cdtoc="${dri_media}/.cdtoc"
  if [ ! -f "${dri_media_cdtoc}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media <%s> is not a recognized installation media.'`" "${dri_media}"
    return 2
  fi

  ${LUPRINTF} -lp1 "`gettext 'The media is a standard Solaris media.'`"

  # Looks like standard format media with a table of contents;
  # Locate the various subdirectories in the media we expect of a Solaris distribution.

  dri_errorsFound=""
  dri_cdtoc_prodname="`/bin/grep '^PRODNAME=' ${dri_media_cdtoc} | /bin/head -1 | /bin/sed 's/PRODNAME=//'`"
  dri_cdtoc_prodvers="`/bin/grep '^PRODVERS=' ${dri_media_cdtoc} | /bin/head -1 | /bin/sed 's/PRODVERS=//'`"
  dri_cdtoc_proddir="`/bin/grep '^PRODDIR=' ${dri_media_cdtoc} | /bin/head -1 | /bin/sed 's/PRODDIR=//'`"
  dri_media_proddir="${dri_media}/${dri_cdtoc_proddir}"
  dri_media_installDir="${dri_media}/.install"
  dri_media_installer="${dri_media}/installer"

  ${LUPRINTF} -lp2D - "`gettext 'Product Name <%s> Version <%s>.'`" "${dri_cdtoc_prodname}" "${dri_cdtoc_prodvers}"
  ${LUPRINTF} -lp2D - "`gettext 'Product Packages Directory <%s>.'`" "${dri_media_proddir}"
  ${LUPRINTF} -lp2D - "`gettext 'Install Directory <%s>'`" "${dri_media_installDir}"
  ${LUPRINTF} -lp2D - "`gettext 'Installer <%s>'`" "${dri_media_installer}"

  if [ -z "${dri_cdtoc_prodname}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media table of contents does not define a product name.'`"
    dri_errorsFound="1"
  fi
  if [ -z "${dri_cdtoc_prodvers}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media table of contents does not define a product version.'`"
    dri_errorsFound="1"
  fi
  if [ -z "${dri_cdtoc_proddir}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media table of contents does not define a product top-level directory.'`"
    dri_errorsFound="1"
  fi
  if [ ! -d "${dri_media_installDir}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media product install directory <%s> is missing.'`" "${dri_media_installDir}"
    dri_errorsFound="1"
  fi
  if [ ! -x "${dri_media_installer}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media product installer <%s> does not exist.'`" "${dri_media_installer}"
    dri_errorsFound="1"
  fi

  if [ -n "${dri_errorsFound}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media <%s> does not contain an operating system upgrade image.'`" "${dri_media}"
    return 2
  fi

  ${LUPRINTF} -lp1 "`gettext 'The media contains a standard Solaris installer.'`"

  ${LUPRINTF} -lp1 "`gettext 'The media contains <%s> version <%s>.'`" "${dri_cdtoc_prodname}" "${dri_cdtoc_prodvers}"

  cd "${dri_media}"

  ######################################################################################
  ########################## Mount the target boot environment #########################
  ######################################################################################

  ${LUPRINTF} -lp1 "`gettext 'Mounting BE <%s>.'`" "${dri_beName}"

  # Create ICF file for the target be and filter out all "non-system" file systems.
  create_icf $dri_beName > $ABE_ICF
  if [ $? -ne 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine disk partition configuration information for BE <%s>.'`" "${dri_beName}"
    return 2
  fi

  ${LUETCBIN}/ludo filter_nonsystem ${ABE_ICF} > ${COMBINED_ICF}

  # Mount the target BE slices.
  abe_icfMount ${ABE_ICF}
  if [ "$?" != "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to mount BE <%s>.'`" "${dri_beName}"
    return 2
  fi
  dri_bootMnt="${AIM_BEBOOTMNT}"

  ######################################################################################
  ############### Locate "/usr/java/bin/java" on target boot environment ###############
  ######################################################################################

  # If the ABE contains a /usr/java, and /usr/java/bin/java exists and is an executable,
  # pass in "-java" followed by path to ABE /usr/java to the installer.

  dri_javaArgs=""
  dri_javaDir="${dri_bootMnt}/usr/java"
  dri_javaCmd="${dri_javaDir}/bin/java"

  if [ -d "${dri_javaDir}" -a -f "${dri_javaCmd}" -a -x "${dri_javaCmd}" ] ; then
    dri_javaVersion="`${dri_javaCmd} -version 2>&1 | /bin/head -1`"
    dri_javaArgs="-java ${dri_javaDir}"
    ${LUPRINTF} -lp2D - "`gettext 'ABE Java at <%s> arg <%s> version <%s>'`" \
    "${dri_javaDir}" "${dri_javaArgs}" "${dri_javaVersion}"
  fi

  ######################################################################################
  ################################# Run the Installer ##################################
  ######################################################################################

  # Setup installer arguments:
  # -R path - Define the full path name of a directory to use as the root-path.
  #
  # Return code from installer are:
  # 0  - Successful execution.
  # >0 - Failure.
  #
  # Because of various issues an installation may appear to be successful ($? == 0)
  # when infact there were problems. To deal with this, the fact that the installer
  # generated any output is used to determine whether or not to notify the system
  # administrator about a possible problem.

  dri_installComArgs="${dri_javaArgs} ${dri_optArgs} -R ${dri_bootMnt} ${dri_cmdArgs}"

  ${LUPRINTF} -lp1 "`gettext 'Running installer on BE <%s>.'`" "${dri_beName}"
  if [ -n "${dri_noExecuteMode}" ] ; then
    ${LUPRINTF} -lp1 "`gettext 'Execute command: <%s>.'`" "${dri_media_installer} ${dri_installComArgs}"
  else
    PKG_INSTALL_ROOT="${dri_bootMnt}" ${dri_media_installer} ${dri_installComArgs}
  fi

  if [ -z "${dri_dryRunMode}" ] ; then

	# reset flag indicating whether or not there are log files to review

	dri_reviewFiles=""

	# Determine if package instance data needs to be refreshed:
	# If running a Solaris release that does not support zones, and upgrading to a
	# Solaris release that does support zones, upgrade package instance data on the abe. 

	sourceRelease=$(lulib_normalize_os_version "$(/bin/uname -r)")

	targetRelease=$(lulib_normalize_os_version 5.$(/bin/grep '^VERSION=' \
		${dri_bootMnt}/var/sadm/system/admin/INST_RELEASE | \
		/bin/sed 's/VERSION=//'))

	${LUPRINTF} -lp2D - "`gettext 'OS Releases: current <%s> upgraded <%s>.'`" \
		"${sourceRelease}" "${targetRelease}"

	# If upgrading to release that supports zones from one that does not,
	# make sure all package instance data is updated on the ABE.

	if [[ "${sourceRelease}" -le 51000 && "${targetRelease}" -ge 51000 ]] ; then
		# Update package information on the ABE

		${LUPRINTF} -lp1 -a "${dri_bootMnt}${PFINSTALL_UPGRADE_LOG}" \
"`gettext 'Updating package information on boot environment <%s>.'`" "${dri_beName}"

		${LUETCBIN}/ludo update_package_instance_data "${dri_media}"\
		    "${dri_bootMnt}" 2>> "${dri_bootMnt}${PFINSTALL_UPGRADE_LOG}"

		if [ "$?" -ne "0" ] ; then

			${LUPRINTF} -Eelp2 -a "${dri_bootMnt}${PFINSTALL_UPGRADE_LOG}" \
"`gettext 'Unable to update package instance information on boot environment <%s>.'`" "${dri_beName}"

		else

			${LUPRINTF} -lp1 -a "${dri_bootMnt}${PFINSTALL_UPGRADE_LOG}" \
"`gettext 'Package information successfully updated on boot environment <%s>.'`" "${dri_beName}"

		fi
	fi

    ###
    ### Review all log files and output appropriate messages.
    ###

    # If the upgrade log exists let the user know where the upgrade log is.

    if [ -f "${dri_bootMnt}${PFINSTALL_UPGRADE_LOG}" -a -s "${dri_bootMnt}${PFINSTALL_UPGRADE_LOG}" ] ; then

      ${LUPRINTF} -fIlp1 "`gettext 'The file <%s> on boot environment <%s> \
contains a log of the upgrade operation.'`" "${PFINSTALL_UPGRADE_LOG}" \
"${dri_beName}"

      ${LUPRINTF} -fIlp1 "`gettext '<%s> contains a log of the upgrade operation.'`" "${PFINSTALL_UPGRADE_LOG}"
      dri_reviewFiles="yes"
    fi

    # If the upgrade cleanup exists and it then add the contents of the upgrade
    # cleanup file to the mail log file. Also, let the user know where the 
    # upgrade cleanup is.

    if [ -f "${dri_bootMnt}${PFINSTALL_UPGRADE_CLEANUP}" -a -s "${dri_bootMnt}${PFINSTALL_UPGRADE_CLEANUP}" ] ; then

      ${LUPRINTF} -fIlp1 "`gettext 'The file <%s> on boot environment <%s> \
contains a log of cleanup operations required.'`" "${PFINSTALL_UPGRADE_CLEANUP}" \
"${dri_beName}"

      dri_reviewFiles="yes"
    fi

    # If the failed package log exists add the contents of the failed package log
    # file to the mail log file. Also, let the user know where the failed
    # package log is.

    if [ -f "${dri_bootMnt}${PFINSTALL_UPGRADE_FAILED_PKGADDS}" -a -s "${dri_bootMnt}${PFINSTALL_UPGRADE_FAILED_PKGADDS}" ] ; then
      ${LUPRINTF} -Welp2 "`gettext '<%d> packages failed to install properly \
on boot environment <%s>.'`" "`/bin/cat ${dri_bootMnt}${PFINSTALL_UPGRADE_FAILED_PKGADDS} | \
/bin/wc -l`" "${dri_beName}"

      ${LUPRINTF} -fIlp1 "`gettext 'The file <%s> on boot environment <%s> \
contains a list of packages that failed to upgrade or install properly.'`" \
"${PFINSTALL_UPGRADE_FAILED_PKGADDS}" "${dri_beName}"

      dri_reviewFiles="yes"
    fi

    # If the packages to be added log exists add the contents of the packages 
    # to be added log file to the mail log file. Also, let the user know
    # where the packages to be added log is.

    if [ -f "${dri_bootMnt}${PFINSTALL_PACKAGES_TO_BE_ADDED}" -a -s "${dri_bootMnt}${PFINSTALL_PACKAGES_TO_BE_ADDED}" ] ; then
      ${LUPRINTF} -Welp2 "`gettext '<%d> packages must be installed on boot environment <%s>.'`" \
"`/bin/grep -c '^PKG=' ${dri_bootMnt}${PFINSTALL_PACKAGES_TO_BE_ADDED}`" "${dri_beName}"

      ${LUPRINTF} -fIlp1 "`gettext 'The file <%s> on boot environment <%s> \
contains a list of packages that must be installed on the boot environment \
for the upgrade to be complete. The packages in this list were not present \
on the media that was used to upgrade this boot environment.'`" \
"${PFINSTALL_PACKAGES_TO_BE_ADDED}" "${dri_beName}"

      ${LUPRINTF} -fIlp1 "`gettext 'If the boot environment was upgraded using \
one media of a multiple media distribution, for example the Solaris CD media, \
you must continue the upgrade process with the next media. Complete the \
upgrade by using the luupgrade <-i> option to install the next media of the \
distribution. Failure to complete the upgrade process with all media of the \
software distribution makes the boot environment unstable.'`"
      dri_reviewFiles="yes"
    fi

    # If files were listed, request that user review the file contents.
    if [ -n "${dri_reviewFiles}" ] ; then
      ${LUPRINTF} -fIlp1 "`gettext 'Review the files listed above. Remember \
that all of the files are located on boot environment <%s>. Before you \
activate boot environment <%s>, determine if any additional system maintenance \
is required or if additional media of the software distribution must be \
installed.'`" "${dri_beName}" "${dri_beName}"
    fi

  fi

  # Unmount the target boot environment

  ${LUPRINTF} -lp1 "`gettext 'Unmounting BE <%s>.'`" "${dri_beName}"
  abe_umount
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to unmount BE <%s>.'`" "${dri_beName}"
  fi

  ${LUPRINTF} -lp1 "`gettext 'The installer run on boot environment <%s> is complete.'`" "${dri_beName}"

  return 0
}

################################################################################
# Name:		do_addPackages
# Description:	Add packages on boot environment from specified media.
# Local Prefix:	dap_
# Arguments:	$1 = boot environment name to add packages to.
#		$2 = no execute mode ("" if not enabled).
#		$3 = optional arguments for pkgadd ("" if none).
#		$4 = media mount point to run pkgadd from.
#		$5 = command arguments to pass to pkgadd on command line ("" if none).
# Returns:	0 = success.
#		1 = failure.
#		2 = media access problems.
#		3 = user input error.
################################################################################

do_addPackages()
{
  dap_beName="$1"
  dap_noExecuteMode="$2"
  dap_optArgs="$3"
  dap_media="$4"
  dap_cmdArgs="$5"

  ${LUPRINTF} -lp2D - "`gettext 'Add packages BE <%s> Media <%s> NoExecuteMode \
<%s> Pkgadd Args <%s %s> '`" "${dap_beName}" "${dap_media}" \
"${dap_noExecuteMode}" "${dap_optArgs}" "${dap_cmdArgs}"

  ######################################################################################
  ##################### Verify that the media has packages present #####################
  ######################################################################################

  # Packages can either be contained in a directory, or in a file that has
  # packages in "package stream" format. If a directory is passed in make 
  # sure it has contents. If a file is passed in, leave it to pkgadd to
  # determine if it is valid.
  if [ ! -f "${dap_media}" ] ; then
    ${LUPRINTF} -lp1 "`gettext 'Validating the contents of the media <%s>.'`" "${dap_media}"
    lulib_validate_is_directory_not_empty "${dap_media}"
    if [ $? -ne 0 ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'The add packages (-p) option requires that \
you specify the packages location with the <-s> option.'`"
      return 3
    fi

    cd "${dap_media}"
  fi

  ######################################################################################
  ######### Verify that any packages specified on the command line are present #########
  ######################################################################################

  # If package media is a directory and arguments given, make sure
  # the arguments exist and are directories.
  if [ -d "${dap_media}" -a -n "${dap_cmdArgs}" ] ; then
    dap_packagesNotFound=""
    for dap_packageRequested in ${dap_cmdArgs} ; do
      dap_packageFound=""
      if [ -d "${dap_media}/${dap_packageRequested}" ] ; then
	/usr/sbin/pkgchk -d "${dap_media}" "${dap_packageRequested}" 1>/dev/null 2>&1
	if [ "$?" -eq "0" ] ; then
	    dap_packageFound="yes"
	else
	  dap_packagesNotFound="${dap_packageRequested} ${dap_packagesNotFound}"
	fi
      fi
    done
    if [ -n "${dap_packagesNotFound}" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'The media <%s> does not contain these requested packages: <%s>.'`" "${dap_media}" "${dap_packagesNotFound}"
      return 2
    fi
  fi

  ######################################################################################
  ########################## Mount the target boot environment #########################
  ######################################################################################

  ${LUPRINTF} -lp1 "`gettext 'Mounting the BE <%s>.'`" "${dap_beName}"

  # Create ICF file for the target be and filter out all "non-system" file systems.
  create_icf $dap_beName > $ABE_ICF
  if [ $? -ne 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine disk partition configuration information for BE <%s>.'`" "${dap_beName}"
    return 2
  fi

  ${LUETCBIN}/ludo filter_nonsystem ${ABE_ICF} > ${COMBINED_ICF}

  # Mount the target BE slices.
  abe_icfMount ${ABE_ICF}
  if [ "$?" != "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to mount the BE <%s>.'`" "${dap_beName}"
    return 2
  fi
  dap_bootMnt="${AIM_BEBOOTMNT}"

  # check for zones capability
  checkZoneSupport "${dap_beName}" "${dap_bootMnt}"
  [ $? -ne 0 ] && return 1

  ######################################################################################
  ################################## Add the packages ##################################
  ######################################################################################

  # Setup command pkgadd arguments:
  # -M Do not use the BE's etc/vfstab file for determining the mount points.
  # -R path - Define the full path name of a directory to use as the root-path.
  # -d Install or copy a package from device (full path to directory).
  # -v Trace all of the scripts that get executed by pkgadd.
  #
  # Return code from pkgadd are:
  # 0  - Successful execution.
  # 1  - Fatal error.
  # 2  - Warning.
  # 3  - Interruption.
  # 4  - Administration.
  # 5  - Administration. Interaction is required.  Do  not  use  pkgadd -n.
  # 10 - Reboot after installation of all packages.
  # 20 - Reboot after installation of this package.

  dap_pkgaddComArgs="${dap_optArgs} -M -R ${dap_bootMnt} -d ${dap_media} ${dap_cmdArgs}"
  if [ "$LU_DEBUG" -ne "0" ] ; then
    dap_pkgaddComArgs="-v $dap_pkgaddComArgs"
  fi

  ${LUPRINTF} -lp1 "`gettext 'Adding packages to the BE <%s>.'`" "${dap_beName}"
  if [ -n "${dap_noExecuteMode}" ] ; then
    ${LUPRINTF} -lp1 "`gettext 'Execute command: <%s>.'`" "/usr/sbin/pkgadd ${dap_pkgaddComArgs}"
    dap_ret="0"
  else
    /usr/sbin/pkgadd ${dap_pkgaddComArgs} 
    dap_ret="$?"
  fi

  ${LUPRINTF} -lp1 "`gettext 'Unmounting the BE <%s>.'`" "${dap_beName}"
  abe_umount
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to unmount the BE <%s>.'`" "${dap_beName}"
  fi

  case "${dap_ret}" in 
    0|10|20|3|13|23) # Successful execution, Reboot After Installation of all packages, Reboot after installation of this package, Interruption.
       ${LUPRINTF} -lp1 "`gettext 'The package add to the BE <%s> completed.'`" "${dap_beName}"
       return 0
       ;;
    1|11|21) # Fatal error.
       ${LUPRINTF} -lp1 "`gettext 'The package add to the BE <%s> failed with a Fatal Error.'`" "${dap_beName}"
       return 1
       ;;
    2|12|22) # Warning.
       ${LUPRINTF} -lp1 "`gettext 'The package add to the BE <%s> completed with Warnings.'`" "${dap_beName}"
       return 0
       ;;
    4|14|24) # Administration.
       ${LUPRINTF} -lp1 "`gettext 'The package add to the BE <%s> failed because Administrative action is required.'`" "${dap_beName}"
       return 1
       ;;
    5|15|25) # Administration. Interaction is required.  Do  not  use  pkgadd -n.
       ${LUPRINTF} -lp1 "`gettext 'The package add to the BE <%s> failed because Administrative Interaction is required (do not use the pkgadd -n option).'`" "${dap_beName}"
       return 1
       ;;
    *) # unknown result
       ${LUPRINTF} -lp1 "`gettext 'The package add to the BE <%s> failed (with result code <%s>).'`" "${dap_ret}"
       return 1
       ;;
  esac

  return 0
}

################################################################################
# Name:		do_addPatches
# Description:	Add patches to the boot environment from specified media.
# Local Prefix:	dpa_
# Arguments:	$1 = boot environment name to add patches to.
#		$2 = no execute mode ("" if not enabled).
#		$3 = optional arguments for patchadd ("" if none).
#		$4 = media mount point to run patchadd from.
#		$5 = command arguments to pass to patchadd on command line ("" if none).
# Returns: 
#		0 = success.
#		1 = failure.
#		2 = media access problems.
#		3 = user input error.
################################################################################

do_addPatches()
{
  dpa_beName="$1"
  dpa_noExecuteMode="$2"
  dpa_optArgs="$3"
  dpa_media="$4"
  dpa_cmdArgs="$5"

  ${LUPRINTF} -lp2D - "`gettext 'Add patches BE <%s> Media <%s> NoExecuteMode <%s> patchadd Args <%s %s> '`" "${dpa_beName}" "${dpa_media}" "${dpa_noExecuteMode}" "${dpa_optArgs}" "${dpa_cmdArgs}"

  ######################################################################################
  ###################### Verify that the media has patches present #####################
  ######################################################################################

  ${LUPRINTF} -lp1 "`gettext 'Validating the contents of the media <%s>.'`" "${dpa_media}"
  lulib_validate_is_directory_not_empty "${dpa_media}"
  if [ $? -ne 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The add patches (-P) option requires that you specify the patches location with the <-s> option.'`"
    return 3
  fi

  cd "${dpa_media}"
  dpa_patchList=""
  dpa_patchCount="0"
  for dpa_patchCandidate in ??* ; do
    if [ -d "${dpa_patchCandidate}" -a '(' -f "${dpa_patchCandidate}/.diPatch" -o -f "${dpa_patchCandidate}/installpatch" ')' ] ; then
      if [ -z "${dpa_patchList}" ] ; then
	dpa_patchList="${dpa_patchCandidate}"
      else
	dpa_patchList="${dpa_patchList} ${dpa_patchCandidate}"
      fi
      dpa_patchCount="`/bin/expr ${dpa_patchCount} + 1`"
    fi
  done

  if [ "${dpa_patchCount}" -eq "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media <%s> does not contain any software patches that can be installed.'`" "${dpa_media}"
    return 2
  fi

  ${LUPRINTF} -lp1 "`gettext 'The media contains %d software patches that can be added.'`" "${dpa_patchCount}"
  ${LUPRINTF} -lp2D - "`gettext 'The media contains these %d software patches that can be added: <%s>.'`" "${dpa_patchCount}" "${dpa_patchList}"

  ######################################################################################
  ###### If any files are specified, extract any patches contained in those files ######
  ######################################################################################

  if [ -n "${dpa_cmdArgs}" ] ; then
    dpa_newCmdArgs=""
    for dpa_patchRequested in ${dpa_cmdArgs} ; do
      if [ -f "${dpa_media}/${dpa_patchRequested}" -a -s "${dpa_media}/${dpa_patchRequested}" ] ; then
	${LUPRINTF} -lp2D - "`gettext 'Adding patches from file <%s>.'`" "${dpa_media}/${dpa_patchRequested}"
	if [ "`/bin/wc -w < \"${dpa_media}/${dpa_patchRequested}\" 2>/dev/null`" -gt "${MAX_PATCHES_FROM_FILE}" ] ; then
	  ${LUPRINTF} -Eelp2 "`gettext 'The file <%s> can not be used because it has too many possible patch names (over %d).'`" "${dpa_media}/${dpa_patchRequested}" "${MAX_PATCHES_FROM_FILE}"
	  return 3
	fi
	dpa_newCmdArgs="${dpa_newCmdArgs} `/bin/cat ${dpa_media}/${dpa_patchRequested}`"
      else
	dpa_newCmdArgs="${dpa_newCmdArgs} ${dpa_patchRequested}"
      fi
    done
    dpa_cmdArgs="${dpa_newCmdArgs}"
  fi

  ######################################################################################
  ######### Verify that any patches specified on the command line are present #########
  ######################################################################################

  if [ -n "${dpa_cmdArgs}" ] ; then
    # One of more patches specified - verify they really exist
    dpa_patchesNotFound=""
    for dpa_patchRequested in ${dpa_cmdArgs} ; do
      dpa_patchFound=""
      for dpa_patchCandidate in ${dpa_patchList} ; do
	if [ "${dpa_patchRequested}" = "${dpa_patchCandidate}" ] ; then
	  dpa_patchFound="yes"
	  break
	fi
      done
      if [ -z "${dpa_patchFound}" ] ; then
	dpa_patchesNotFound="${dpa_patchRequested} ${dpa_patchesNotFound}"
      fi
    done
    if [ -n "${dpa_patchesNotFound}" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'The media <%s> does not contain these requested patches: <%s>.'`" "${dpa_media}" "${dpa_patchesNotFound}"
      return 2
    fi
  else
    # No patches specified - assume all patches are to be added
    ${LUPRINTF} -lp1 "`gettext 'All %s patches will be added because you did not specify any specific patches to add.'`" "${dpa_patchCount}"
    dpa_cmdArgs="${dpa_patchList}"
  fi

  ######################################################################################
  ########################## Mount the target boot environment #########################
  ######################################################################################

  ${LUPRINTF} -lp1 "`gettext 'Mounting the BE <%s>.'`" "${dpa_beName}"

  # Create ICF file for the target be and filter out all "non-system" file systems.
  create_icf $dpa_beName > $ABE_ICF
  if [ $? -ne 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine disk partition configuration information for BE <%s>.'`" "${dpa_beName}"
    return 2
  fi

  ${LUETCBIN}/ludo filter_nonsystem ${ABE_ICF} > ${COMBINED_ICF}

  # Mount the target BE slices.
  abe_icfMount ${ABE_ICF}
  if [ "$?" != "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to mount the BE <%s>.'`" "${dpa_beName}"
    return 2
  fi
  dpa_bootMnt="${AIM_BEBOOTMNT}"

  # check for zones capability
  checkZoneSupport "${dpa_beName}" "${dpa_bootMnt}"
  [ $? -ne 0 ] && return 1

  ######################################################################################
  ################################## Add the patches ##################################
  ######################################################################################

  # Setup command patchadd arguments:
  # -R path - Define the full path name of a directory to use as the root-path.
  # -M patch_dir patch_id ... | patch_dir patch_list
  #
  # Return code from patchadd are:
  # 0  - Successful execution.
  # >0 - Failure.

  dpa_patchaddComArgs="${dpa_optArgs} -R ${dpa_bootMnt} -M ${dpa_media} ${dpa_cmdArgs}"

  ${LUPRINTF} -lp1 "`gettext 'Adding patches to the BE <%s>.'`" "${dpa_beName}"
  if [ -n "${dpa_noExecuteMode}" ] ; then
    ${LUPRINTF} -lp1 "`gettext 'Execute command: <%s>.'`" "/usr/sbin/patchadd ${dpa_patchaddComArgs}"
    dpa_ret="0"
  else
    /usr/sbin/patchadd ${dpa_patchaddComArgs}
    dpa_ret="$?"
  fi

  ${LUPRINTF} -lp1 "`gettext 'Unmounting the BE <%s>.'`" "${dpa_beName}"
  abe_umount
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to unmount the BE <%s>.'`" "${dpa_beName}"
  fi

  case "${dpa_ret}" in 
    0) # Successful execution, Reboot After Installation of all patches, Reboot after installation of this patch.
       ${LUPRINTF} -lp1 "`gettext 'The patch add to the BE <%s> completed.'`" "${dpa_beName}"
       return 0
       ;;
    *) # unknown result
       ${LUPRINTF} -lp1 "`gettext 'The patch add to the BE <%s> failed (with result code <%s>).'`" "${dpa_beName}" "${dpa_ret}"
       return 1
       ;;
  esac

  return 0
}

################################################################################
# Name:		do_removePackages
# Description:	Remove packages from boot environment.
# Local Prefix:	drp_
# Arguments:	$1 = boot environment name to remove packages from.
#		$2 = no execute mode ("" if not enabled).
#		$3 = optional arguments for pkgrm ("" if none).
#		$4 = command arguments to pass to pkgrm on command line ("" if none).
# Returns: 
#		0 = success.
#		1 = failure.
#		2 = media access problems.
#		3 = user input error.
################################################################################

do_removePackages()
{
  drp_beName="$1"
  drp_noExecuteMode="$2"
  drp_optArgs="$3"
  drp_cmdArgs="$4"

  ${LUPRINTF} -lp2D - "`gettext 'Remove packages BE <%s> NoExecuteMode <%s> Pkgrm Args <%s %s>.'`" "${drp_beName}" "${drp_noExecuteMode}" "${drp_optArgs}" "${drp_cmdArgs}"

  ######################################################################################
  ########################## Mount the target boot environment #########################
  ######################################################################################

  ${LUPRINTF} -lp1 "`gettext 'Mounting the BE <%s>.'`" "${drp_beName}"

  # Create ICF file for the target be and filter out all "non-system" file systems.
  create_icf $drp_beName > $ABE_ICF
  if [ $? -ne 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine disk partition configuration information for BE <%s>.'`" "${drp_beName}"
    return 2
  fi

  ${LUETCBIN}/ludo filter_nonsystem ${ABE_ICF} > ${COMBINED_ICF}

  # Mount the target BE slices.
  abe_icfMount ${ABE_ICF}
  if [ "$?" != "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to mount the BE <%s>.'`" "${drp_beName}"
    return 2
  fi
  drp_bootMnt="${AIM_BEBOOTMNT}"

  # check for zones capability
  checkZoneSupport "${drp_beName}" "${drp_bootMnt}"
  [ $? -ne 0 ] && return 1

  ######################################################################################
  ######## Verify that any packages specified on the command line are installed ########
  ######################################################################################

  if [ -n "${drp_cmdArgs}" ] ; then
    drp_packagesNotFound=""
    for drp_packageRequested in ${drp_cmdArgs} ; do
      /bin/pkginfo -R "${drp_bootMnt}" -q "${drp_packageRequested}"
      if [ "$?" -ne "0" ] ; then
	drp_packagesNotFound="${drp_packageRequested} ${drp_packagesNotFound}"
      fi
    done
    if [ -n "${drp_packagesNotFound}" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'The BE <%s> does not have these packages installed: <%s>.'`" "${drp_beName}" "${drp_packagesNotFound}"
      return 2
    fi
  fi

  ######################################################################################
  ################################ Remove the packages #################################
  ######################################################################################

  # Setup command pkgrm arguments:
  # -M Do not use the BE's etc/vfstab file for determining the mount points.
  # -R path - Define the full path name of a directory to use as the root-path.
  # -v Trace all of the scripts that get executed by pkgrm.
  #
  # Return code from pkgrm are:
  # 0  - Successful execution.
  # >0 - Failure.

  drp_pkgrmComArgs="${drp_optArgs} -M -R ${drp_bootMnt} ${drp_cmdArgs}"
  if [ "$LU_DEBUG" -ne "0" ] ; then
    drp_pkgrmComArgs="-v $drp_pkgrmComArgs"
  fi

  ${LUPRINTF} -lp1 "`gettext 'Removing packages from the BE <%s>.'`" "${drp_beName}"
  if [ -n "${drp_noExecuteMode}" ] ; then
    ${LUPRINTF} -lp1 "`gettext 'Execute command: <%s>.'`" "/usr/sbin/pkgrm ${drp_pkgrmComArgs}"
    drp_ret="0"
  else
    /usr/sbin/pkgrm ${drp_pkgrmComArgs}
    drp_ret="$?"
  fi

  ${LUPRINTF} -lp1 "`gettext 'Unmounting the BE <%s>.'`" "${drp_beName}"
  abe_umount
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to unmount the BE <%s>.'`" "${drp_beName}"
  fi

  case "${drp_ret}" in 
    0) # Successful.
       ${LUPRINTF} -lp1 "`gettext 'The package remove from the BE <%s> completed.'`" "${drp_beName}"
       return 0
       ;;
    *) # unknown result
       ${LUPRINTF} -lp1 "`gettext 'The package remove from the BE <%s> failed (with result code <%s>).'`" "${drp_beName}" "${drp_ret}"
       return 1
       ;;
  esac

  return 0
}

################################################################################
# Name:		do_infoPackages
# Description:	Obtain information on packages from boot environment.
# Local Prefix:	dip_
# Arguments:	$1 = boot environment name to retrieve information on packages from.
#		$2 = no execute mode ("" if not enabled).
#		$3 = optional arguments for pkginfo ("" if none).
#		$4 = command arguments to pass to pkginfo on command line ("" if none).
# Returns: 
#		0 = success.
#		1 = failure.
#		2 = media access problems.
#		3 = user input error.
################################################################################

do_infoPackages()
{
  dip_beName="$1"
  dip_noExecuteMode="$2"
  dip_optArgs="$3"
  dip_cmdArgs="$4"

  ${LUPRINTF} -lp2D - "`gettext 'Information on packages BE <%s> NoExecuteMode <%s> Pkginfo Args <%s %s>.'`" "${dip_beName}" "${dip_noExecuteMode}" "${dip_optArgs}" "${dip_cmdArgs}"

  ######################################################################################
  ########################## Mount the target boot environment #########################
  ######################################################################################

  ${LUPRINTF} -lp1 "`gettext 'Mounting the BE <%s>.'`" "${dip_beName}"

  # Create ICF file for the target be and filter out all "non-system" file systems.
  create_icf $dip_beName > $ABE_ICF
  if [ $? -ne 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine disk partition configuration information for BE <%s>.'`" "${dip_beName}"
    return 2
  fi

  ${LUETCBIN}/ludo filter_nonsystem ${ABE_ICF} > ${COMBINED_ICF}

  # Mount the target BE slices.
  abe_icfMount ${ABE_ICF}
  if [ "$?" != "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to mount the BE <%s>.'`" "${dip_beName}"
    return 2
  fi
  dip_bootMnt="${AIM_BEBOOTMNT}"

  ######################################################################################
  ################################ Get the package info ################################
  ######################################################################################

  # Setup command pkginfo arguments:
  # -R path - Define the full path name of a directory to use as the root-path.
  #
  # Return code from pkginfo are:
  # 0  - Successful execution.
  # >0 - Failure.

  dip_pkginfoComArgs="${dip_optArgs} -R ${dip_bootMnt} ${dip_cmdArgs}"

  ${LUPRINTF} -lp1 "`gettext 'Retrieving package information from the BE <%s>.'`" "${dip_beName}"
  if [ -n "${dip_noExecuteMode}" ] ; then
    ${LUPRINTF} -lp1 "`gettext 'Execute command: <%s>.'`" "/bin/pkginfo ${dip_pkginfoComArgs}"
    dip_ret="0"
  else
    /bin/pkginfo ${dip_pkginfoComArgs}
    dip_ret="$?"
  fi

  ${LUPRINTF} -lp1 "`gettext 'Unmounting the BE <%s>.'`" "${dip_beName}"
  abe_umount
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to unmount the BE <%s>.'`" "${dip_beName}"
  fi

  case "${dip_ret}" in 
    0) # Successful.
       ${LUPRINTF} -lp1 "`gettext 'The package information from the BE <%s> completed.'`" "${dip_beName}"
       return 0
       ;;
    *) # unknown result
       ${LUPRINTF} -lp1 "`gettext 'The package information from the BE <%s> failed (with result code <%s>).'`" "${dip_beName}" "${dip_ret}"
       return 1
       ;;
  esac

  return 0
}

################################################################################
# Name:		do_checkPackages
# Description:	Check on packages from boot environment.
# Local Prefix:	dcp_
# Arguments:	$1 = boot environment name to check on packages from.
#		$2 = no execute mode ("" if not enabled).
#		$3 = optional arguments for pkgchk ("" if none).
#		$4 = command arguments to pass to pkgchk on command line ("" if none).
# Returns: 
#		0 = success.
#		1 = failure.
#		2 = media access problems.
#		3 = user input error.
################################################################################

do_checkPackages()
{
  dcp_beName="$1"
  dcp_noExecuteMode="$2"
  dcp_optArgs="$3"
  dcp_cmdArgs="$4"

  ${LUPRINTF} -lp2D - "`gettext 'Checking packages BE <%s> NoExecuteMode <%s> Pkgchk Args <%s %s>.'`" "${dcp_beName}" "${dcp_noExecuteMode}" "${dcp_optArgs}" "${dcp_cmdArgs}"

  ######################################################################################
  ########################## Mount the target boot environment #########################
  ######################################################################################

  ${LUPRINTF} -lp1 "`gettext 'Mounting the BE <%s>.'`" "${dcp_beName}"

  # Create ICF file for the target be and filter out all "non-system" file systems.
  create_icf $dcp_beName > $ABE_ICF
  if [ $? -ne 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine disk partition configuration information for BE <%s>.'`" "${dcp_beName}"
    return 2
  fi

  ${LUETCBIN}/ludo filter_nonsystem ${ABE_ICF} > ${COMBINED_ICF}

  # Mount the target BE slices.
  abe_icfMount ${ABE_ICF}
  if [ "$?" != "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to mount the BE <%s>.'`" "${dcp_beName}"
    return 2
  fi
  dcp_bootMnt="${AIM_BEBOOTMNT}"

  # check for zones capability
  checkZoneSupport "${dcp_beName}" "${dcp_bootMnt}"
  [ $? -ne 0 ] && return 1


  ######################################################################################
  ################################ Check the packages ##################################
  ######################################################################################

  # Setup command pkgchk arguments:
  # -R path - Define the full path name of a directory to use as the root-path.
  #
  # Return code from pkgchk are:
  # 0  - Successful execution.
  # >0 - Failure.

  dcp_pkgchkComArgs="${dcp_optArgs} -R ${dcp_bootMnt} ${dcp_cmdArgs}"

  if [ "$LU_DEBUG" -ne "0" ] ; then
    dcp_pkgchkComArgs="-v $dcp_pkgchkComArgs"
  fi

  ${LUPRINTF} -lp1 "`gettext 'Checking packages from the BE <%s>.'`" "${dcp_beName}"
  if [ -n "${dcp_noExecuteMode}" ] ; then
    ${LUPRINTF} -lp1 "`gettext 'Execute command: <%s>.'`" "/usr/sbin/pkgchk ${dcp_pkgchkComArgs}"
    dcp_ret="0"
  else
    /usr/sbin/pkgchk ${dcp_pkgchkComArgs}
    dcp_ret="$?"
  fi

  ${LUPRINTF} -lp1 "`gettext 'Unmounting the BE <%s>.'`" "${dcp_beName}"
  abe_umount
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to unmount the BE <%s>.'`" "${dcp_beName}"
  fi

  case "${dcp_ret}" in 
    0) # Successful.
       ${LUPRINTF} -lp1 "`gettext 'The package information from the BE <%s> completed.'`" "${dcp_beName}"
       return 0
       ;;
    *) # unknown result
       ${LUPRINTF} -lp1 "`gettext 'The package information from the BE <%s> failed (with result code <%s>).'`" "${dcp_beName}" "${dcp_ret}"
       return 1
       ;;
  esac

  return 0
}

################################################################################
# Name:		do_removePatches
# Description:	Remove patches from boot environment.
# Local Prefix:	dpr_
# Arguments:	$1 = boot environment name to remove patches from.
#		$2 = no execute mode ("" if not enabled).
#		$3 = optional arguments for patchrm ("" if none).
#		$4 = command arguments to pass to patchrm on command line ("" if none).
# Returns: 
#		0 = success.
#		1 = failure.
#		2 = media access problems.
################################################################################

do_removePatches()
{
  dpr_beName="$1"
  dpr_noExecuteMode="$2"
  dpr_optArgs="$3"
  dpr_cmdArgs="$4"

  ${LUPRINTF} -lp2D - "`gettext 'Remove patches BE <%s> NoExecuteMode <%s> Patchrm Args <%s %s>.'`" "${dpr_beName}" "${dpr_noExecuteMode}" "${dpr_optArgs}" "${dpr_cmdArgs}"

  ######################################################################################
  ########################## Mount the target boot environment #########################
  ######################################################################################

  ${LUPRINTF} -lp1 "`gettext 'Mounting the BE <%s>.'`" "${dpr_beName}"

  # Create ICF file for the target be and filter out all "non-system" file systems.
  create_icf $dpr_beName > $ABE_ICF
  if [ $? -ne 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine disk partition configuration information for BE <%s>.'`" "${dpr_beName}"
    return 2
  fi

  ${LUETCBIN}/ludo filter_nonsystem ${ABE_ICF} > ${COMBINED_ICF}

  # Mount the target BE slices.
  abe_icfMount ${ABE_ICF}
  if [ "$?" != "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to mount the BE <%s>.'`" "${dpr_beName}"
    return 2
  fi
  dpr_bootMnt="${AIM_BEBOOTMNT}"

  # check for zones capability
  checkZoneSupport "${dpr_beName}" "${dpr_bootMnt}"
  [ $? -ne 0 ] && return 1

  ######################################################################################
  ################################ Remove the patches ##################################
  ######################################################################################

  # Setup command patchrm arguments:
  # -R path - Define the full path name of a directory to use as the root-path.
  #
  # Return code from patchrm are:
  # 0  - Successful execution.
  # >0 - Failure.

  ${LUPRINTF} -lp1 "`gettext 'Removing patches from the BE <%s>.'`" "${dpr_beName}"
  for pArgs in ${dpr_cmdArgs}
  do
    dpr_patchrmComArgs="${dpr_optArgs} -R ${dpr_bootMnt} ${pArgs}"
    if [ -n "${dpr_noExecuteMode}" ] ; then
      ${LUPRINTF} -lp1 "`gettext 'Execute command: <%s>.'`" "/usr/sbin/patchrm ${dpr_patchrmComArgs}"
      dpr_ret="0"
    else
      /usr/sbin/patchrm ${dpr_patchrmComArgs}
      dpr_ret="$?"
    fi
  done

  ${LUPRINTF} -lp1 "`gettext 'Unmounting the BE <%s>.'`" "${dpr_beName}"
  abe_umount
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to unmount the BE <%s>.'`" "${dpr_beName}"
  fi

  case "${dpr_ret}" in 
    0) # Successful.
       ${LUPRINTF} -lp1 "`gettext 'The patch remove from the BE <%s> completed.'`" "${dpr_beName}"
       return 0
       ;;
    *) # unknown result
       ${LUPRINTF} -lp1 "`gettext 'The patch remove from the BE <%s> failed.'`"
       return 1
       ;;
  esac

  return 0
}

################################################################################
# Name:		do_upgradeOs
# Description:	Upgrade operating system on boot environment.
# Local Prefix:	dug_
# Arguments:	$1 = target boot environment name to upgrade operating system on.
#		$2 = upgrade profile template ("" to use default profile).
#		$3 = no execute mode ("" if not enabled).
#		$4 = media mount point to upgrade operating system from.
#		$5 = current boot environment name of operating system running.
#		$6 = dry run mode ("" if not enabled).
# Returns: 
#		0 = success.
#		1 = failure.
#		2 = media access problems.
#		3 = user input error.
################################################################################

do_upgradeOs()
{
  dug_beName="$1"
  dug_profilePath="$2"
  dug_noExecuteMode="$3"
  dug_media="$4"
  dug_pbeName="$5"
  dug_dryRunMode="$6"

  ${LUPRINTF} -lp2D - "`gettext 'Upgrade Operating System of BE <%s> from Media <%s> NoExecuteMode <%s> DryRunMode <%s>.'`" "${dug_beName}" "${dug_media}" "${dug_noExecuteMode}" "${dug_dryRunmode}"

  ######################################################################################
  ########## Verify that the media has a Solaris Operating System Image on it ##########
  ######################################################################################

  ${LUPRINTF} -lp1 "`gettext 'Validating the contents of the media <%s>.'`" "${dug_media}"

  lulib_validate_is_directory_not_empty "${dug_media}"
  if [ $? -ne 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The OS upgrade (-u) option requires that you specify the OS media location with the <-s> option.'`"
    return 3
  fi
  # find the media cd table of contents: if not found, can not upgrade from this media

  dug_media_cdtoc="${dug_media}/.cdtoc"
  if [ ! -f "${dug_media_cdtoc}" -o ! -s "${dug_media_cdtoc}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media <%s> is not a recognized installation media.'`" "${dug_media}"
    return 2
  fi

  ${LUPRINTF} -lp1 "`gettext 'The media is a standard Solaris media.'`"

  # Looks like standard format media with a table of contents;
  # Locate the various subdirectories in the media we expect of a Solaris distribution.

  dug_errorsFound=""
  dug_cdtoc_prodname="`/bin/grep '^PRODNAME=' ${dug_media_cdtoc} | /bin/head -1 | /bin/sed 's/PRODNAME=//'`"
  dug_cdtoc_prodvers="`/bin/grep '^PRODVERS=' ${dug_media_cdtoc} | /bin/head -1 | /bin/sed 's/PRODVERS=//'`"
  dug_cdtoc_proddir="`/bin/grep '^PRODDIR=' ${dug_media_cdtoc} | /bin/head -1 | /bin/sed 's/PRODDIR=//'`"
  dug_media_proddir="${dug_media}/${dug_cdtoc_proddir}"
  dug_media_installConfig="${dug_media}/.install_config"
  dug_media_toolsDir="`dirname ${dug_media_proddir}`/Tools"
  dug_media_platformFile="${dug_media_toolsDir}/Boot/lu.platforms"
  dug_media_toolsInstallConfig="${dug_media_toolsDir}/Boot/usr/sbin/install.d/install_config"
  dug_media_basedir="`dirname ${dug_media}/${dug_cdtoc_proddir}`"
  dug_media_patchdir="${dug_media_basedir}/Patches"
  if [ "${LU_SYSTEM_ARCH}" = "i386" ]; then
      dug_media_bootLoaderDir="${dug_media_toolsDir}/Boot/boot/grub"
  else
      dug_media_bootLoaderDir=""
  fi

  ${LUPRINTF} -lp2D - "`gettext 'Product Name <%s> Version <%s>.'`" "${dug_cdtoc_prodname}" "${dug_cdtoc_prodvers}"
  ${LUPRINTF} -lp2D - "`gettext 'Product Base Directory <%s>.'`" "${dug_media_basedir}"
  ${LUPRINTF} -lp2D - "`gettext 'Product Packages Directory <%s>.'`" "${dug_media_proddir}"
  ${LUPRINTF} -lp2D - "`gettext 'Product Patches Directory <%s>.'`" "${dug_media_patchdir}"
  ${LUPRINTF} -lp2D - "`gettext 'Install Configuration Directory <%s>'`" "${dug_media_installConfig}"
  ${LUPRINTF} -lp2D - "`gettext 'Install Tools Directory <%s>.'`" "${dug_media_toolsDir}" 
  ${LUPRINTF} -lp2D - "`gettext 'Install Platform Support File <%s>.'`" "${dug_media_platformFile}"
  ${LUPRINTF} -lp2D - "`gettext 'Install Tools Config Directory <%s>.'`" "${dug_media_toolsInstallConfig}"
  ${LUPRINTF} -lp2D - "`gettext 'Media BootLoader Directory <%s>.'`" "${dug_media_bootLoaderDir}"

  if [ -z "${dug_cdtoc_prodname}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media table of contents does not define a product name.'`"
    dug_errorsFound="1"
  fi
  if [ -z "${dug_cdtoc_prodvers}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media table of contents does not define a product version.'`"
    dug_errorsFound="1"
  fi
  if [ -z "${dug_cdtoc_proddir}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media table of contents does not define a product top-level directory.'`"
    dug_errorsFound="1"
  fi
  if [ ! -d "${dug_media_installConfig}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media product install configuration directory <%s> is missing.'`" "${dug_media_installConfig}"
    dug_errorsFound="1"
  fi
  if [ -n "${dug_cdtoc_proddir}" ] ; then
    if [ ! -d "${dug_media_proddir}" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'The media product directory <%s> does not exist.'`" "${dug_media_proddir}"
      dug_errorsFound="1"
    fi
    if [ ! -d "${dug_media_toolsDir}" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'The media product tools directory <%s> does not exist.'`" "${dug_media_toolsDir}"
      dug_errorsFound="1"
    fi
    if [ ! -d "${dug_media_toolsInstallConfig}" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'The media product tools installation directory <%s> does not exist.'`" "${dug_media_toolsInstallConfig}"
      dug_errorsFound="1"
    fi
    if [ "${LU_SYSTEM_ARCH}" = "i386" ]; then
        if [ ! -d "${dug_media_bootLoaderDir}" ]; then
            ${LUPRINTF} -Eelp2 "`gettext 'The media bootloader directory <%s> does not exist.'`" "${dug_media_bootLoaderDir}"
            dug_errorsFound="1"
	fi
    fi
  fi

  if [ -n "${dug_errorsFound}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The media <%s> does not contain an operating system upgrade image.'`" "${dug_media}"
    return 2
  fi

  ${LUPRINTF} -lp1 "`gettext 'The media contains an operating system upgrade image.'`"

  ${LUPRINTF} -lp1 "`gettext 'The media contains <%s> version <%s>.'`" "${dug_cdtoc_prodname}" "${dug_cdtoc_prodvers}"

  if [ -d "${dug_media_patchdir}" ] ; then
    dug_media_patchCount=`/bin/ls -1 "${dug_media_patchdir}" 2>/dev/null | /bin/wc -l 2>/dev/null`
    if [ "${dug_media_patchCount}" -ne '0' ] ; then
      ${LUPRINTF} -lp1 "`gettext 'The media contains <%s> patches for the product.'`" ${dug_media_patchCount}
    fi
  fi

  ######################################################################################
  ####################### Determine if version can be updated to #######################
  ######################################################################################

  lulib_is_upgrade_supported "${dug_cdtoc_prodvers}"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -fEelp2 "`gettext 'This version of Live Upgrade is unable to \
upgrade to <%s> version <%s>. Only upgrades to <%s> version <%s> are supported \
by this version of Live Upgrade. To upgrade to <%s> version <%s>, remove Live \
Upgrade from the currently running system, and then install Live Upgrade from \
the <%s> version <%s> install media. Then use Live Upgrade to upgrade boot \
environment <%s>.'`" "${dug_cdtoc_prodname}" "${dug_cdtoc_prodvers}" \
"${dug_cdtoc_prodname}" "${LU_BUILT_FOR_SOLARIS_VERSION}" "${dug_cdtoc_prodname}" \
"${dug_cdtoc_prodvers}" "${dug_cdtoc_prodname}" "${dug_cdtoc_prodvers}" "${dug_beName}"
    return 1
  fi

  ######################################################################################
  ########################### Determine if platform is EOLed ###########################
  ######################################################################################

  # This verifies that the processor specific hardware architecture (such
  # sun, sun4c, sun4d, sun4m, sun4u, etc.) is directly supported
  # by this release of Live Upgrade.

  lulib_is_platform_supported "${dug_cdtoc_prodvers}"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -fEelp2 "`gettext 'This system hardware architecture <%s> is not \
supported by <%s> version <%s>.'`" "${LU_HARDWARE_ARCH}" "${dug_cdtoc_prodname}" \
"${dug_cdtoc_prodvers}"
    return 1
  fi

  # Verify that the hardware platform implementation has support in the
  # new operating environment to upgrade to

  if [ -f "${dug_media_platformFile}" -a -s "${dug_media_platformFile}" ] ; then
    if /bin/grep ${LU_HARDWARE_IMPLEMENTATION} ${dug_media_platformFile} > /dev/null 2>&1; then
      ${LUPRINTF} -lp2D - "`gettext 'Platform <%s> is supported by <%s> version <%s>.'`" \
      "${LU_HARDWARE_IMPLEMENTATION}" "${dug_cdtoc_prodname}" "${dug_cdtoc_prodvers}"
    else
      ${LUPRINTF} -fEelp2 "`gettext 'This system hardware platform <%s> is not \
  supported by <%s> version <%s>.'`" "${LU_HARDWARE_IMPLEMENTATION}" \
  "${dug_cdtoc_prodname}" "${dug_cdtoc_prodvers}"
      return 1
    fi
  fi

  ######################################################################################
  ####################### Construct the profile to use  ################################
  ######################################################################################

  ${LUPRINTF} -lp1 "`gettext 'Constructing upgrade profile to use.'`"

  ## Construct a pfinstall upgrade profile:
  ## - copy the default upgrade profile ${UPGRADE_PROFILE} to ${TMP_UPGRADE_PROFILE}
  ## - if the user specified a profile to use, append that to ${TMP_UPGRADE_PROFILE}
  ## At end, ${TMP_UPGRADE_PROFILE} will have the path to the template to use 
  ## for upgrading.

  # Make sure default upgrade profile exists
  if [ ! -f "${UPGRADE_PROFILE}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The default upgrade profile <%s> does not \
exist.'`" "${UPGRADE_PROFILE}"
    return 2
  fi

  # Create the upgrade profile to use starting with the default profile
  ERRMSG="`${LUBIN}/lucomm_del ${UPGRADE_PROFILE} > ${TMP_UPGRADE_PROFILE}`"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
    ${LUPRINTF} -Eelp2 "`gettext 'Cannot create temporary profile <%s> from \
<%s>.'`" "${TMP_UPGRADE_PROFILE}" "${UPGRADE_PROFILE}"
    return 2
  fi

  # If user specified profile, append it to the end of the default profile
  if [ -n "${dug_profilePath}" ] ; then
    checkUserUpgradeProfile "${dug_profilePath}"
    if [ $? -ne 0 ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'The file <%s> can not be used as an \
upgrade profile.'`" "${dug_profilePath}"
      return 2
    fi

    ERRMSG="`${LUBIN}/lucomm_del ${dug_profilePath} | \
/bin/egrep -v '^[ 	]*install_type[ 	]*upgrade[ 	]*$' >> ${TMP_UPGRADE_PROFILE}`"
    if [ "$?" -ne "0" ] ; then
      [ -n "${ERRMSG}" ] && ${LUPRINTF} -Eelp2 '%s' "${ERRMSG}" 
      ${LUPRINTF} -Eelp2 "`gettext 'Cannot append upgrade profile <-j %s> to <%s>.'`" \
 "${dug_profilePath}" "${TMP_UPGRADE_PROFILE}"
      return 2
    fi
  fi

  ${LUPRINTF} -lp2D - "`gettext 'Upgrade profile is <%s>.'`" \
"${TMP_UPGRADE_PROFILE}"

  ######################################################################################
  ####################### Determine which pfinstall root to use ########################
  ######################################################################################

  ${LUPRINTF} -lp1 "`gettext 'Locating the operating system upgrade program.'`"

  dug_libDir="${dug_media_toolsDir}/Boot/usr/snadm/lib"
  dug_pfinstallDir="${dug_media_toolsDir}/Boot/usr/sbin/install.d"

  lulib_validate_is_directory "${dug_libDir}"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The pfinstall library directory does not exist.'`"
    return 2
  fi

  lulib_validate_is_directory_not_empty "${dug_pfinstallDir}"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The pfinstall product directory does not exist.'`"
    return 2
  fi

  dug_pfinstallExecutable="${dug_pfinstallDir}/pfinstall"
  if [ ! -x "${dug_pfinstallExecutable}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The pfinstall product <%s> does not exist or is not executable.'`" "${dug_pfinstallExecutable}"
    return 2
  fi

  # Create a library path for use when pfinstall is run
  dug_ldLibraryPath="${dug_libDir}"
  [ -n "${LD_LIBRARY_PATH}" ] && dug_ldLibaryPath="${dug_ldLibraryPath}:${LD_LIBRARY_PATH}"

  ${LUPRINTF} -lp2D - "`gettext 'Upgrade program to use is <%s>.'`" "${dug_pfinstallExecutable}"

  # Determine if this pfinstall supports the upgrade_mountpoint capability
  # The "-a" option to pfinstall (as of S10B27/S9U4) supports inquiring
  # pfinstall for its "capabilities". The new "upgrade_mountpoint" capability
  # allows mounting of file systems to be bypassed when doing an upgrade.
  # To check for this, run 'pfinstall -a sw:upgrade_mountpoint' - if it
  # does not return '3' or does not return 'upgrade_mountpoint=true' then
  # this new capability is NOT implemented

  dug_umcap="`LD_LIBRARY_PATH=${dug_ldLibraryPath} ${dug_pfinstallExecutable} -a sw:upgrade_mountpoint 2>/dev/null`"
  if [ "$?" -ne "3" -o "${dug_umcap}" != "upgrade_mountpoint=true" ] ; then
    ${LUPRINTF} -lp2D - "`gettext '<%s> does NOT implement sw:upgrade_mount capability.'`" \
"${dug_pfinstallExecutable}"
    dug_umcap=""
  else
    ${LUPRINTF} -lp2D - "`gettext '<%s> implements sw:upgrade_mount capability.'`" \
"${dug_pfinstallExecutable}"
    dug_umcap="yes"
  fi

  # Find the parse dynamic cluster toc script.
  dug_pdcExecutable="${dug_media_toolsDir}/Boot/usr/sbin/install.d/parse_dynamic_clustertoc"
  if [ ! -x "${dug_pdcExecutable}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The program <%s> does not exist or is not executable.'`" "${dug_pdcExecutable}"
    return 2
  fi

  ${LUPRINTF} -lp2D - "`gettext 'clustertoc parse program to use is <%s>.'`" "${dug_pdcExecutable}"

  # Find the parse packages to be added script. The location moved in s10;
  # search the new location first and if not found search the older location.
  # Search order:
  # 1--> /Boot/usr/lib/install/data/wizards/bin
  # 2--> /Boot/webstart/wizards/bin

  dug_pptbaExecutable="${dug_media_toolsDir}/Boot/usr/lib/install/data/wizards/bin/parsePackagesToBeAdded"
  if [ ! -x "${dug_pptbaExecutable}" ] ; then
    if [ -x ${dug_media_toolsDir}/Boot/webstart/wizards/bin/parsePackagesToBeAdded ] ; then
      dug_pptbaExecutable="${dug_media_toolsDir}/Boot/webstart/wizards/bin/parsePackagesToBeAdded"
    fi
  fi

  # Indicate decision made.
  if [ -x "${dug_pptbaExecutable}" ] ; then
    ${LUPRINTF} -lp2D - "`gettext 'parse packages to be added program to use is <%s>.'`" "${dug_pptbaExecutable}"
  else
    ${LUPRINTF} -Welp2 "`gettext 'The parse packages to be added program <%s> does not exist or is not executable.'`" "${dug_pptbaExecutable}"
    dug_pptbaExecutable=''
  fi

  ######################################################################################
  ############ Check for copylock and schedule delayed update if necessary #############
  ######################################################################################

  ## Check to see if a copy lock exists. If so then:
  ## 1- if an operation other than a scheduled copy exists, a BE is busy: do not allow any operation to be performed.
  ## 2- if an operation is scheduled on another BE besides our target, do not allow any operation to be performed.
  ## 3- only if a copy for our target BE is scheduled, then add to that an upgrade operation.

  ${LUPRINTF} -lp1 "`gettext 'Checking for existence of previously scheduled Live Upgrade requests.'`"

  lulib_validate_lulock
  if [ -f "${COPYLOCK}" -a -s "${COPYLOCK}" ]
  then
    . ${COPYLOCK}
    if [ "$CL_STATUS" != "SCHEDULED" ] ; then
      # If a scheduled copy exists, we can only schelude an
      # OS upgrade. Only an OS upgrade can be scheduled since
      # other upgrade may be interactive.
      ${LUPRINTF} -Eelp2 "`gettext 'A Live Upgrade Copy Lock exists: Status <%s> Source BE <%s> Target BE <%s>.'`" "${CL_STATUS}" "${CL_SOURCE_BE}" "${CL_TARGET_BE}"
      ${LUPRINTF} -Eelp2 "`gettext 'A boot environment is busy with another operation.'`"
      return 2
    fi
    
    if [ "${dug_beName}" != "$CL_TARGET_BE" ]; then
      ${LUPRINTF} -Eelp2 "`gettext 'A Live Upgrade Copy Lock exists: Status <%s> Source BE <%s> Target BE <%s>.'`" "${CL_STATUS}" "${CL_SOURCE_BE}" "${CL_TARGET_BE}"
      ${LUPRINTF} -Eelp2 "`gettext 'A Live Upgrade Copy operation is schedule for another BE. An Upgrade operation for another BE can not be peformed or scheduled until this copy is complete.'`"
      return 2
    fi
    
    # A copy has been scheduled for this BE so the upgrade can now
    # be scheduled to occur after the copy.
    ${LUPRINTF} -lp1 "`gettext 'A Live Upgrade Copy operation is scheduled on this BE at <%s>\nThe upgrade operation will be scheduled to occur after the copy is completed.'`" "${CL_EXEC_TIME}"
    attime=`echo "$CL_EXEC_TIME" | /bin/awk ' { { hm = substr( $4, 1, 5) } { printf "%s %s %s\n", hm, $2, $3 } } '`
      make_at_command "${dug_beName}" "${dug_media}" | /bin/at -m "$attime + 16 minutes" \
       > /tmp/${AT_ERRLOG} 2>&1
    if [ "$?" != "0" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'Attempt to schedule the upgrade at the specified time failed.'`"
      return 2
    fi
    /bin/grep INFO /tmp/${AT_ERRLOG} > /dev/null 2>&1
    if [ $? = 0 ]; then
      AT_JOB_TIME=`/bin/grep INFO /tmp/${AT_ERRLOG} | /bin/cut -d" " -f6-`
    else
      /bin/grep -i job /tmp/${AT_ERRLOG} > /dev/null 2>&1
      if [ $? = 0 ] ; then
	AT_JOB_TIME=`/bin/grep job /tmp/${AT_ERRLOG} | /bin/cut -d" " -f4-`
      else
	AT_JOB_TIME="CANNOT DETERMINE"
      fi
    fi
    AT_JOB_NUM=`/bin/awk '{ 
      for (i=0; i <= NF; i++)
	{
	  if ( $i == "Job" || $i == "job" )
	    { 
	      i++
	      print $i 
	      exit 0
            }
	}
      }' /tmp/${AT_ERRLOG}`
    if [ -f "${COPYLOCK}" ] ; then
      copylock_append "CL_UPGRADE_EXEC_TIME" "$AT_JOB_TIME"
      copylock_append "CL_UPGRADE_AT_JOB_NUM" "$AT_JOB_NUM"
    fi
    ${LUPRINTF} -lp1 "`gettext 'The upgrade has been scheduled to occur after: <%s>.'`" "${AT_JOB_TIME}"
    return 0
  fi

  ## No copy operation is (or has been) scheduled: do the upgrade; create copy lock and allow it to be deleted on exit.

  copylock_create "CL_STATUS" "UPDATING" "yes"
  dug_ret="$?"
  if [ "${dug_ret}" -eq "0" ] ; then
    copylock_append "CL_TARGET_BE" "${dug_beName}"
    dug_ret="$?"
  fi
  if [ "${dug_ret}" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to create copy lock file: unable to upgrade the BE <%s>.'`" "${dug_beName}"
    return 2
  fi

  ######################################################################################
  ################## Create partition information for upgrade profile ##################
  ######################################################################################

  ${LUPRINTF} -lp1 "`gettext 'Creating upgrade profile for BE <%s>.'`" "${dug_beName}"

  # Create ICF file for the target be and filter out all "non-system" file systems.
  create_icf $dug_beName > $ABE_ICF
  if [ $? -ne 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine disk partition configuration information for BE <%s>.'`" "${dug_beName}"
    return 2
  fi

  ${LUETCBIN}/ludo filter_nonsystem ${ABE_ICF} > ${COMBINED_ICF}

  # Create new upgrade profile and add in the root slice of the target BE.
  dug_abeRootSlice=`/bin/awk -F: '$2 == "/" && $6 == "" {printf "%s\n", $3 }' \
    < ${COMBINED_ICF} | /bin/sed 's/\/dev\/dsk\///g'`
  if [ -z "${dug_abeRootSlice}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine root slice for BE <%s>.'`" "${dug_beName}"
    return 2
  fi
  ${LUPRINTF} -lp2D - "`gettext 'Root device for upgrade is <%s>.'`" "${dug_abeRootSlice}"

  # If pfinstall implements the sw:upgrade_mountpoint capability, do NOT place
  # the root_device directive into the upgrade profile. This is because if the
  # pfinstall sw:upgrade_mountpoint is implemented, and -L is specified with
  # no root_device in the profile, pfinstall assumes that all file systems are
  # already mounted at the -L location

  if [ -z "${dug_umcap}" ] ; then
    ${LUPRINTF} +X -a "${TMP_UPGRADE_PROFILE}" "root_device %s" "${dug_abeRootSlice}"
    ${LUPRINTF} -lp2D - "`gettext '<root_device %s> added to upgrade profile <%s>.'`" \
"${dug_abeRootSlice}" "${TMP_UPGRADE_PROFILE}"
  else
    ${LUPRINTF} -lp2D - "`gettext 'root_device NOT ADDED to upgrade profile.'`"
  fi

  # Mount the target BE slices.
  abe_icfMount ${ABE_ICF}
  if [ "$?" != "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to mount the BE <%s>.'`" "${dug_beName}"
    return 2
  fi
  dug_bootMnt="${AIM_BEBOOTMNT}"

  # At this point we have mounted the ABE including boot partition (if any)
  ${LUPRINTF} -lp2D - "`gettext 'ABE slices mounted at <%s>.'`" "${dug_bootMnt}"

  # Save the GRUB menu (if any) on the ABE
  if [ "${LU_SYSTEM_ARCH}" = i386 -a -z "${dug_dryRunMode}" ] ; then
     save_menu "${dug_bootMnt}" "${dug_beName}"
     if [ "$?" -ne 0 ] ; then
        ${LUPRINTF} -Eelp2 "`gettext 'Unable to save GRUB menu on BE <%s>.'`" "${dug_beName}"
        return 2
     fi
  fi

  # Check if ABE uses a boot partition before changing vfstab
  dug_bootPart=""
  if [ "${LU_SYSTEM_ARCH}" = "i386" ] ; then
       ${LUPRINTF} -lp1 "`gettext 'Checking for x86 boot partition on ABE.'`"
      /bin/grep -s -v '^#' "${dug_bootMnt}/etc/vfstab" | /bin/grep "[	]/boot[	]*pcfs[	]" >/dev/null 2>&1
      if [ "$?" -eq 0 ]; then
          dug_bootPart=`/bin/grep -s -v '^#' "${dug_bootMnt}/etc/vfstab" | /bin/grep "[ 	]/boot[ 	]*pcfs[ 	]" | /usr/bin/awk '{print $1}'`
          ${LUPRINTF} -lp1 "`gettext 'x86 boot partition exists on ABE <%s>'`" "$dug_beName"
      fi
  fi

  # Backup the target ABE's vfstab file.

  backup_vfstab_file "${dug_bootMnt}" "${dug_beName}" "${ABE_ICF}"
  dug_ret="$?"
  if [ "${dug_ret}" -ne "0" ] ; then
    if [ "${dug_ret}" -eq "1" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'Unable to save backup copy of vfstab file for BE <%s>.'`" "${dug_beName}"
    fi
    return 2
  fi

  #--> At this point, the exit_script() code will automagically restore the       <--#
  #--> target boot environments vfstab file if it has not already been restored.  <--#
  #--> Because of this, there is no reason to include "restore_vfstab_file" calls <--#
  #--> before each error return from this function.                               <--#

  # Replace the target ABE's vfstab file with the one we created which only
  # has the "system" file systems on it. The "-I" option means do not include
  # any filesystems that are not mentioned in the ICF file.

  ${LUBIN}/luedvfstab -i "${COMBINED_ICF}" -m "${dug_bootMnt}" -n "${dug_beName}" -I

  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to create revised vfstab file on BE.'`"
    return 2
  else
    ${LUPRINTF} -lp2D - "`gettext 'boot environment <%s> temporary vfstab file:\
\n**********************************\n%R\n**********************************'`" \
"${dug_beName}" < ${dug_bootMnt}/etc/vfstab
  fi
	#
        # Do processing only for x86 boot partition on intel platforms
	# Before pfinstall runs, copy the contents of the ABE boot
	# partition and write it onto the ABE's root filesystem at <mntpt>/boot.
	#
        if [ "${LU_SYSTEM_ARCH}" = "i386" ] ; then
	   convert_x86_boot_partition "$dug_bootMnt" "$dug_bootPart"
	   if [ "$?" -ne 0 ]; then
	      ${LUPRINTF} -Eelp2 "`gettext 'Unable to convert X86 boot partition.'`"
	      return 1
	   fi
        fi

  ######################################################################################
  ######### Verify that the upgrade media mount point exists and is a directory ########
  ######################################################################################

  # Make sure the media root mount point exists and is a directory.
  if [ ! -d ${MEDIAROOTMOUNTPOINT} ] ; then
    # Mount point is not a directory.
    if [ -r ${MEDIAROOTMOUNTPOINT} ] ; then
      # its a readable file!!
      ${LUPRINTF} -Eelp2 "`gettext 'Media root mount point <%s> exists and is not a directory. Please remove or rename the file and try again.'`" "${MEDIAROOTMOUNTPOINT}"
      return 2
    fi
    # Attempt to create the media root mount point.
    /bin/mkdir ${MEDIAROOTMOUNTPOINT}
    if [ ! -d ${MEDIAROOTMOUNTPOINT} ] ; then
      # Could not create the mount point!
      ${LUPRINTF} -Eelp2 "`gettext 'ERROR: Media root mount point <%s> could not be created.'`" "${MEDIAROOTMOUNTPOINT}"
      return 2
    fi
  fi

  ######################################################################################
  ############################### --> DO THE UPGRAGE <-- ###############################
  ######################################################################################

  # N.B. pfinstall expects to mount all of the slices defined in the target o.s.'s vfstab file
  # when it exits these slices remain mounted. For this reason we first need to umount the
  # BE file systems we previously mounted so pfinstall's mounts will not fail. We need to
  # take this into account after pfinstall exits so that we can clean up properly.

  # Setup common pfinstall arguments:
  # -L path - root mount point where target boot environment will be mounted (must be /a)
  # -c path - location where the upgrade media can be located.
  # profile - the profile to use to drive the upgrade.
  # -x n - debugging level (1..9 is on).
  #
  # Return codes from pfinstall are:
  # EXIT_INSTALL_SUCCESS_REBOOT     0	(successful - system rebooted)
  # EXIT_INSTALL_SUCCESS_NOREBOOT   1	(successful - system not rebooted)
  # EXIT_INSTALL_FAILURE            2	(An error occurred)
  # ???                             3   (test capability return code)

  dug_pfComArgs="-L ${MEDIAROOTMOUNTPOINT} -c ${dug_media} ${TMP_UPGRADE_PROFILE}"
  if [ "$LU_DEBUG" -ne "0" ] ; then
    dug_pfComArgs="-x 10 ${dug_pfComArgs}"
  fi

  ${LUPRINTF} -lp2D - "`gettext 'Using profile <%s>:\n**********\n%R\n**********\n'`" \
"${TMP_UPGRADE_PROFILE}" < "${TMP_UPGRADE_PROFILE}"

  ### --> THIS CODE IS EXECUTED FOR "NO EXECUTE MODE" ONLY.. <--- ###
  ### --> MUST MAKE SURE IT SYNCS UP WITH THE REAL CODE TOO. <--- ###

  if [ -n "${dug_noExecuteMode}" ] ; then
    ${LUPRINTF} -lp1 "`gettext 'Performing the operating system upgrade of the BE <%s>.'`" "${dug_beName}"
    ${LUPRINTF} -lp1 "`gettext 'Execute Command: <%s>.'`" "${dug_pfinstallExecutable} ${dug_pfComArgs}"
    add_auto_os_patches "${dug_beName}" "${dug_bootMnt}" "${dug_media_toolsInstallConfig}" \
"${dug_media_patchdir}" "${dug_bootMnt}${PFINSTALL_UPGRADE_LOG}" "${dug_noExecuteMode}" \
"${PATCH_LOGFILE}" "${dug_media}"
    return 0
  fi
  
  # If the pfinstall sw:upgrade_mountpoint capability is implemented, the
  # mounting of file systems by pfinstall has already been disabled because
  # the "root_slice" directive has not been placed into the pfinstall
  # upgrade profile. If the sw:upgrade_mountpoint capability is implemented,
  # there is no need to unmount the abe file systems before calling pfinstall

  if [ "${dug_umcap}" = "yes" ] ; then
    ${LUPRINTF} -lp2D - "`gettext 'Boot environment <%s> remains mounted at <%s>.'`" \
"${dug_beName}" "${MEDIAROOTMOUNTPOINT}"
  else
    # pfinstall sw:upgrade_mountpoint capability IS NOT IMPLEMENTED.
    # Unmount so pfinstall can do mount.
    abe_umount
    if [ "$?" -ne "0" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'Unable to unmount the BE <%s>.'`" "${dug_beName}"
      return 2
    fi
    ${LUPRINTF} -lp2D - "`gettext 'Boot environment <%s> has been unmounted.'`" \
"${dug_beName}"
  fi

  # Determine the locale to pass in to parse_dynamic_clustertoc

  if [ -n "${LANG}" ] ; then
    PDC_LOCALE="${LANG}"
  elif [ -n "${LOCALE}" ] ; then
    PDC_LOCALE="${LOCALE}"
  else
    PDC_LOCALE="C"
  fi

  # take the existing local stripping off any trailing "_xxx" and ".xxx"
  # so zh_TW.BIG5 becomes "zh" and "ko.UTF-8" becomes "ko"

  PDC_LOCALE="`echo "${PDC_LOCALE}" | /bin/cut -f1 -d'_' | /bin/cut -f1 -d'.'`"

  ${LUPRINTF} -lp2D - "`gettext 'Locale lang <%s> locale <%s> passed to <%s> is <%s>'`" \
"${LANG}" "${LOCALE}" "${dug_pdcExecutable}" "${PDC_LOCALE}"

  # parse the clustertoc to form the final clustertoc that pfinstall will read
  ${LUPRINTF} -lp1 "`gettext 'Determining packages to install or upgrade for BE <%s>.'`" "${dug_beName}"
  ${dug_pdcExecutable} -c "${dug_media}" -l "${PDC_LOCALE}"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to parse software table of contents.'`"
    return 2
  fi

  # Before running pfinstall, remove the patch database - this forces
  # the patch database to be recreated the next time any patch command
  # is executed. This is done because the upgrade process itself does
  # not attempt to update or remove the patch database, and it is 
  # rendered out of sync with the OS once the OS is upgraded.
  #  ? This is not right - we may have unmounted the ABE at this point
  if [ -f "${dug_bootMnt}/${PATCH_DATABASE_FILE}" -a -z "${dug_dryRunMode}" ] ; then
    /bin/rm -f "${dug_bootMnt}/${PATCH_DATABASE_FILE}" 2>/dev/null
  fi

  # Prepare to run pfinstall
  if [ -z "${dug_dryRunMode}" ] ; then
    # Not dry run mode: actually do the pfinstall
    ${LUPRINTF} -flp1 "`gettext 'Performing the operating system upgrade of the BE <%s>.'`" "${dug_beName}"
    ${LUPRINTF} -flp1 "`gettext 'CAUTION: Interrupting this process may leave the boot environment unstable or unbootable.'`"

    ${LUPRINTF} +X -a "${MAIL_LOGFILE}" "`gettext '%s: Performing the operating system upgrade of the BE <%s>.'`" "`/bin/date`" "${dug_beName}"
  else
    # It IS dry run mode: add -D (simulate) option to pfinstall
    dug_pfComArgs="-D ${dug_pfComArgs}"
    ${LUPRINTF} -lp1 "`gettext 'Simulating the operating system upgrade of the BE <%s>.'`" "${dug_beName}"

    ${LUPRINTF} +X -a "${MAIL_LOGFILE}" "`gettext '%s: Simulating the operating system upgrade of the BE <%s>.'`" "`/bin/date`" "${dug_beName}"
  fi

  ${LUPRINTF} -lp2D - "`gettext 'Executing: <%s>.'`" "${dug_pfinstallExecutable} ${dug_pfComArgs} 2>&1 1>${PFINSTALL_LOGFILE}"
  ${LUPRINTF} +X -a "${MAIL_LOGFILE}" "`gettext '%s: Using: %s'`" "`/bin/date`" "${dug_pfinstallExecutable} ${dug_pfComArgs}"

  # First run pfinstall with the '-r' option and progress reporting enabled;
  # then check to see the results to determine whether or not this pfinstall
  # supports the -r option and progress reporting.

  /bin/rm -f "${PROGRESS_REPORT_FILE}" 2>/dev/null 1>&2
  LD_LIBRARY_PATH=${dug_ldLibraryPath} ${dug_pfinstallExecutable} -r "${PROGRESS_REPORT_FILE}" ${dug_pfComArgs} 1>${PFINSTALL_LOGFILE} 2>&1 &
  dug_pfPid="$!"
  if [ -z "${_LU_OUTPUT_XML_}" ] ; then
    ${LUETCBIN}/ludo 'report_progress' "${dug_pfPid}" "${PROGRESS_REPORT_FILE}" \
      'text' "`gettext 'Upgrading Solaris: %s%% completed'`" \
      'solaris-upgrade' &
  else
    ${LUETCBIN}/ludo 'report_progress' "${dug_pfPid}" "${PROGRESS_REPORT_FILE}" \
      'xml' "${LU_PROG_NAME}" 'solaris-upgrade' &
  fi
  fg "${dug_pfPid}"
  dug_ret="$?"

  # If the return code is "0" and the progress report file was NOT found then
  # this pfinstall is one that does not support the '-r' option. Rerun without
  # the -r option and any progress reporting.
  if [[ "${dug_ret}" -eq "0" && ! -e "${PROGRESS_REPORT_FILE}" ]] ; then
    LD_LIBRARY_PATH=${dug_ldLibraryPath} ${dug_pfinstallExecutable} ${dug_pfComArgs} 1>${PFINSTALL_LOGFILE} 2>&1
    dug_ret="$?"
  fi

  # Normalize the return code from pfinstall - unlike flash, for upgrade pfinstall
  # returns '0' or '1' on success - any other value is a failure:
  # 0 - success but need to reboot
  # 1 - success no need to reboot
  # otherwise... error
  # set stat_pfinstall to "0" if 0 or 1, otherwise set to real code
  stat_pfinstall="${dug_ret}"
  if [ "${dug_ret}" -eq "1" ] ; then
    stat_pfinstall="0"
  fi

  # if pfinstall returned any result > 1 then it failed - even though we continue
  # no patches will be added or any other work will be done - the reason we continue
  # is in the case where pfinstall may have mounted the file systems for the target
  # boot environment (probably on /a) in which case we need to do some special
  # work to restore the original vfstab file...

  if [ -n "${dug_dryRunMode}" ] ; then
    # This was just a simulation of what would have been done.
    if [ "${stat_pfinstall}" -ne "0" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'The upgrade simulation failed; pfinstall returned these diagnostics:\n%R'`" < ${PFINSTALL_LOGFILE}
      ${LUPRINTF} -pa "${MAIL_LOGFILE}" "`gettext '%s: The upgrade simulation failed:'`" "`/bin/date`"
      maillog_addFile "${PFINSTALL_LOGFILE}" "`gettext 'pfinstall diagnostics output'`"
    else
      ${LUPRINTF} -lp1 "`gettext 'The operating system upgrade simulation is complete.'`"
      if [ -f "${PFINSTALL_LOGFILE}" -a -s "${PFINSTALL_LOGFILE}" ] ; then
	if [ "${LU_DEBUG}" -ne "0" ] ; then
	  ${LUPRINTF} -lp2D - "`gettext 'pfinstall returned these results:\n%R'`" < ${PFINSTALL_LOGFILE}
	fi
	maillog_addFile "${PFINSTALL_LOGFILE}" "`gettext 'The upgrade simulation completed; pfinstall results:'`"
      fi
    fi
  else
    # This was NOT a simulation but a real installation - report it as such
    if [ "${stat_pfinstall}" -ne "0" ] ; then
      ${LUPRINTF} -Eelp2 "`gettext 'Installation of the packages from this media \
of the media failed; pfinstall returned these diagnostics:\n%R'`" < ${PFINSTALL_LOGFILE}
      ${LUPRINTF} -pa "${MAIL_LOGFILE}" "`gettext '%s: The upgrade failed:'`" "`/bin/date`"
      maillog_addFile "${PFINSTALL_LOGFILE}" "`gettext 'pfinstall diagnostics output'`"
    else
      ${LUPRINTF} -lp1 "`gettext 'Installation of the packages from this \
media is complete.'`"
      if [ -f "${PFINSTALL_LOGFILE}" -a -s "${PFINSTALL_LOGFILE}" ] ; then
	if [ "${LU_DEBUG}" -ne "0" ] ; then
	  ${LUPRINTF} -lp2D - "`gettext 'pfinstall returned these results:\n%R'`" < ${PFINSTALL_LOGFILE}
	fi
	maillog_addFile "${PFINSTALL_LOGFILE}" "`gettext 'The upgrade completed; pfinstall results:'`"
      fi
    fi
  fi

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

  # ABE will now be mounted on ${MEDIAROOTMOUNTPOINT}.
  # Change the location where we believe the ABEs backup vfstab file is located.
  # Make believe we mounted the ABEs slices (pfinstall should have done this for us).

  dug_bootMnt=${MEDIAROOTMOUNTPOINT}
  change_vfstab_bootmnt "${dug_bootMnt}"

  # Make sure that the ABEs root slice is mounted on the expected mount point.
  abe_checkMounted "${ABE_ICF}"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Problem remounting the BE <%s>.'`" "${dug_beName}"
  fi

  ${LUPRINTF} -lp2D - "`gettext 'ABE is mounted at <%s>.'`" "$dug_bootMnt"

  # Restore the GRUB menu (if any) on the ABE
  if [ "${LU_SYSTEM_ARCH}" = i386 -a -z "${dug_dryRunMode}" ] ; then
     restore_menu "${dug_bootMnt}" "${dug_beName}"
     if [ "$?" -ne 0 ] ; then
        ${LUPRINTF} -Eelp2 "`gettext 'Unable to restore GRUB menu on BE <%s>.'`" "${dug_beName}"
        return 2
     fi
  fi
  ######################################################################################
  ############################ Update package instance data ############################
  ######################################################################################

  # Determine if package instance data needs to be refreshed:
  # If running a Solaris release that does not support zones, and upgrading to a
  # Solaris release that does support zones, upgrade package instance data on the abe. 

  if [ "${stat_pfinstall}" -eq "0" ] ; then
	sourceRelease=$(lulib_normalize_os_version "$(/bin/uname -r)")

	targetRelease=$(lulib_normalize_os_version 5.$(/bin/grep '^VERSION=' \
		${dug_bootMnt}/var/sadm/system/admin/INST_RELEASE | \
		/bin/sed 's/VERSION=//'))

	${LUPRINTF} -lp2D - "`gettext 'OS Releases: current <%s> upgraded <%s>.'`" \
		"${sourceRelease}" "${targetRelease}"

	# If upgrading to release that supports zones from one that does not,
	# make sure all package instance data is updated on the ABE.

	if [[ "${sourceRelease}" -le 51000 && "${targetRelease}" -ge 51000 ]] ; then
		if [ -n "${dug_dryRunMode}" ] ; then
			# dry run mode - just report what would have been done.

			${LUPRINTF} -lp1 -a "${dug_bootMnt}${PFINSTALL_UPGRADE_LOG}" \
"`gettext 'Simulating update of package information on boot environment <%s>.'`" "${dug_beName}"

		else
			# real installation - update package information

			${LUPRINTF} -lp1 -a "${dug_bootMnt}${PFINSTALL_UPGRADE_LOG}" \
"`gettext 'Updating package information on boot environment <%s>.'`" "${dug_beName}"

			${LUETCBIN}/ludo update_package_instance_data \
	"${dug_media}" "${dug_bootMnt}" 2>> "${dug_bootMnt}${PFINSTALL_UPGRADE_LOG}"

			if [ "$?" -ne "0" ] ; then

				${LUPRINTF} -Eelp2 -a "${dug_bootMnt}${PFINSTALL_UPGRADE_LOG}" \
"`gettext 'Unable to update package instance information on boot environment <%s>.'`" "${dug_beName}"

				stat_pfinstall=2
			else

				${LUPRINTF} -lp1 -a "${dug_bootMnt}${PFINSTALL_UPGRADE_LOG}" \
"`gettext 'Package information successfully updated on boot environment <%s>.'`" "${dug_beName}"

			fi
		fi
	fi
  fi

  ######################################################################################
  ############################## Apply patches if needed ###############################
  ######################################################################################

  # run parse packages to be added script.
  if [ "${stat_pfinstall}" -eq "0" -a -n "${dug_pptbaExecutable}" ] ; then
    ERRMSG=`${dug_pptbaExecutable} -R "${dug_bootMnt}" -c "${dug_media}"`
    if [ $? -ne 0 ] ; then
      stat_pfinstall=2
    fi
    if [ "${stat_pfinstall}" -ne "0" ] ; then
      [ -n "${ERRMSG}" ] && ${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
      ${LUPRINTF} -Eelp2 "`gettext 'Unable to parse packages to be added.'`"
    fi
  fi

  # Add in any operating system patches
  stat_addPatches=0
  if [ -z "${dug_dryRunMode}" ] ; then
    if [ "$stat_pfinstall" -eq "0" ] ; then
      [ -f "${PATCH_LOGFILE}" ] && /bin/rm -f "${PATCH_LOGFILE}"
      add_auto_os_patches "${dug_beName}" "${dug_bootMnt}" "${dug_media_toolsInstallConfig}" "${dug_media_patchdir}" "${dug_bootMnt}${PFINSTALL_UPGRADE_LOG}" "${dug_noExecuteMode}" "${PATCH_LOGFILE}" "${dug_media}"
      stat_addPatches="$?"
      if [ "${stat_addPatches}" -ne "0" ] ; then
	${LUPRINTF} -Eelp2 "`gettext 'The operating system patch installation failed; patch installation returned these diagnostics:\n%R'`" < ${PATCH_LOGFILE}
	${LUPRINTF} -pa "${MAIL_LOGFILE}" "`gettext '%s: The operating system patch installation failed:'`" "`/bin/date`"
	maillog_addFile "${PATCH_LOGFILE}" "`gettext 'patch installation diagnostics output'`"
      else
	${LUPRINTF} -lp1 "`gettext 'The operating system patch installation is complete.'`"
	if [ -f "${PATCH_LOGFILE}" -a -s "${PATCH_LOGFILE}" ] ; then
	  if [ "${LU_DEBUG}" -ne "0" ] ; then
	    ${LUPRINTF} -lp2D - "`gettext 'patch installation returned these results:\n%R'`" < ${PATCH_LOGFILE}
	  fi
	  maillog_addFile "${PATCH_LOGFILE}" "`gettext 'The operating system patch installation completed; patch installation results:'`"
	fi
      fi
    fi
  fi

  [ -f "${PATCH_LOGFILE}" ] && /bin/rm -f "${PATCH_LOGFILE}"

  if [ -z "${dug_dryRunMode}" ] ; then
    #
    # Before the run of pfinstall, we umounted boot partition
    # and copied its contents into /boot on the root filesystem
    # We now go ahead and remove the backing file (.dd_x86_boot_copy)
    # Newboot enabled OS doesn't use boot partitions
    #
    delete_x86_boot_backing "$dug_bootMnt"
    if [ "$?" -ne 0 ] ; then
      stat_pfinstall="2"
    fi

    #
    # The following installs the latest GRUB from the ABE in the PBE
    #
    install_latest_GRUB "${dug_bootMnt}" "${dug_beName}"
    if [ "$?" -ne 0 ] ; then
       ${LUPRINTF} -Eelp2 "`gettext 'Unable to install latest GRUB from ABE <%s>.'`" "${dug_beName}"
       stat_pfinstall="2"
    fi

    #
    # Customize the failsafe console setting based on PBE settings.
    #
    configure_failsafe "$LU_MINIROOT_MNTPT" "$dug_beName" 
    if [ "$?" -ne 0 ] ; then
       ${LUPRINTF} -Eelp2 "`gettext 'Unable to configure failsafe for ABE <%s>.'`" "${dug_beName}"
       stat_pfinstall="2"
    fi
  fi

  # All upgrades and patch adds are completed - restore the target
  # boot environments vfstab file.

  restore_vfstab_file
  dug_bootMnt=${VFST_BOOT_MNT}
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2a "${MAIL_LOGFILE}" "`gettext 'Failed to restore vfstab file on the BE <%s>.'`" "${dug_beName}"
  fi

  if [ -z "${dug_dryRunmode}" ] ; then

    #
    # Now that vfstab file has been restored, set bootpath based on vfstab
    # and modify boot partition entry in it.
    #
    update_x86boot "$dug_bootMnt" "$dug_beName"
    if [ "$?" -ne 0 ] ; then
      stat_pfinstall="2"
    fi
    modify_x86_boot_entry "$dug_bootMnt"
    if [ "$?" -ne 0 ] ; then
      stat_pfinstall="2"
    fi

    ###
    ### Review all log files and output appropriate messages.
    ###

    dug_reviewFiles=""
    dug_partialInstall=""

    # If the upgrade log exists, add the contents of the upgrade log file to 
    # the mail log file. Also, let the user know where the upgrade log is.

    if [ -f "${dug_bootMnt}${PFINSTALL_UPGRADE_LOG}" -a -s "${dug_bootMnt}${PFINSTALL_UPGRADE_LOG}" ] ; then
      maillog_addFile "${dug_bootMnt}${PFINSTALL_UPGRADE_LOG}" \
"`gettext 'Target BE upgrade log file results:'`"

      ${LUPRINTF} -fIlp1 "`gettext 'The file <%s> on boot environment <%s> \
contains a log of the upgrade operation.'`" "${PFINSTALL_UPGRADE_LOG}" "${dug_beName}"

      dug_reviewFiles="yes"
    fi

    # If the upgrade cleanup exists add the contents of the upgrade cleanup 
    # file to the mail log file. Also, let the user know where the upgrade 
    # cleanup is.

    if [ -f "${dug_bootMnt}${PFINSTALL_UPGRADE_CLEANUP}" -a -s "${dug_bootMnt}${PFINSTALL_UPGRADE_CLEANUP}" ] ; then

      maillog_addFile "${dug_bootMnt}${PFINSTALL_UPGRADE_CLEANUP}" \
"`gettext 'Target BE upgrade cleanup file results:'`"

      ${LUPRINTF} -fIlp1 "`gettext 'The file <%s> on boot environment <%s> \
contains a log of cleanup operations required.'`" \
"${PFINSTALL_UPGRADE_CLEANUP}" "${dug_beName}"

      dug_reviewFiles="yes"
    fi

    # If the failed package log exists add the contents of the failed package 
    # log file to the mail log file. Also, let the user know where the failed
    # package log is.

    if [ -f "${dug_bootMnt}${PFINSTALL_UPGRADE_FAILED_PKGADDS}" -a -s "${dug_bootMnt}${PFINSTALL_UPGRADE_FAILED_PKGADDS}" ] ; then
      maillog_addFile "${dug_bootMnt}${PFINSTALL_UPGRADE_FAILED_PKGADDS}" \
"`gettext 'Target BE packages that failed to upgrade log file results:'`"

      ${LUPRINTF} -Welp2 "`gettext '<%d> packages failed to install properly \
on boot environment <%s>.'`" "`/bin/cat ${dug_bootMnt}${PFINSTALL_UPGRADE_FAILED_PKGADDS} | \
/bin/wc -l`" "${dug_beName}"

      ${LUPRINTF} -fIlp1 "`gettext 'The file <%s> on boot environment <%s> \
contains a list of packages that failed to upgrade or install properly.'`" \
"${PFINSTALL_UPGRADE_FAILED_PKGADDS}" "${dug_beName}"

      dug_reviewFiles="yes"
      dug_partialInstall="yes"
    fi

    if [ -f "${dug_bootMnt}${PFINSTALL_PACKAGES_TO_BE_ADDED}" -a -s "${dug_bootMnt}${PFINSTALL_PACKAGES_TO_BE_ADDED}" ] ; then

      ${LUPRINTF} -Welp2 "`gettext '<%d> additional packages must be installed \
on boot environment <%s>.'`" "`/bin/grep -c '^PKG=' \
${dug_bootMnt}${PFINSTALL_PACKAGES_TO_BE_ADDED}`" "${dug_beName}"

      ${LUPRINTF} -fIlp1 "`gettext 'The file <%s> on boot environment <%s> \
contains a list of packages that must be installed on the boot environment \
for the upgrade to be complete. The packages in this list were not present \
on the media that was used to upgrade this boot environment.'`" \
"${PFINSTALL_PACKAGES_TO_BE_ADDED}" "${dug_beName}"

      ${LUPRINTF} -fIlp1 "`gettext 'If the boot environment was upgraded using \
one media of a multiple media distribution, for example the Solaris CD media, \
you must continue the upgrade process with the next media. Complete the \
upgrade by using the luupgrade <-i> option to install the next media of the \
distribution. Failure to complete the upgrade process with all media of the \
software distribution makes the boot environment unstable.'`"
      dug_reviewFiles="yes"
      dug_partialInstall="yes"
    fi

    # If files were listed, request that user review the file contents.
    if [ -n "${dug_reviewFiles}" ] ; then
      ${LUPRINTF} -fIlp1 "`gettext 'Review the files listed above. Remember \
that all of the files are located on boot environment <%s>. Before you \
activate boot environment <%s>, determine if any additional system maintenance \
is required or if additional media of the software distribution must be \
installed.'`" "${dug_beName}" "${dug_beName}"
    fi

  fi

  # Unmount the target boot environment

  abe_umount
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to unmount the boot environment <%s>.'`" "${dug_beName}"
  fi
  
  if [ $stat_pfinstall -ne 0 ] ; then
    ${LUPRINTF} -lp1 "`gettext 'The Solaris upgrade of the boot environment <%s> failed.'`" "${dug_beName}"
    maillog_setSubject "`gettext 'Solaris upgrade FAILED.'`"
    return 1
  elif [ $stat_addPatches != 0 ] ; then
    ${LUPRINTF} -lp1 "`gettext 'The Solaris upgrade completed but the automatic \
patch installation to the boot environment <%s> failed.'`" "${dug_beName}"
    maillog_setSubject "`gettext 'Solaris upgrade FAILED (Solaris upgrade \
successful but patch installation FAILED).'`"
    return 1
  elif [ -n "${dug_partialInstall}" ] ; then
    ${LUPRINTF} -lp1 "`gettext 'The Solaris upgrade of the boot environment <%s> is partially complete.'`" "${dug_beName}"
    maillog_setSubject "`gettext 'Solaris upgrade is partially complete.'`"
    return 0
  fi
  ${LUPRINTF} -lp1 "`gettext 'The Solaris upgrade of the boot environment <%s> is complete.'`" "${dug_beName}"
  maillog_setSubject "`gettext 'Solaris upgrade is complete.'`"
  return 0
}

#
# The lax argument does less strict checking. This is for
# do_checkMedia() which may or may not be run on media with miniroot
#
mount_miniroot()
{
	mmr_media="$1"
	mmr_lax="$2"

	if [ -z "$mmr_media" ]; then
		${LUPRINTF} -Eelp2 "`gettext 'No media path provided.'`"
		exit_script 2
	fi

	if [ ! -d "$mmr_media" ]; then
		${LUPRINTF} -Eelp2 "`gettext 'The media directory does not exist <%s>.'`" "$mmr_media"
		exit_script 2
	fi

	# Find cdtoc
	mmr_media_cdtoc="${mmr_media}/.cdtoc"
 	if [ ! -f "$mmr_media_cdtoc" -o ! -s "$mmr_media_cdtoc" ]; then
		if [ -n "$mmr_lax" ]; then
			return
		fi
		${LUPRINTF} -Eelp2 "`gettext 'The media is not recognized installation media <%s>.'`" "$mmr_media"
		exit_script 2
	fi

	# Find miniroot mount point i.e. Solaris_?/Tools/Boot
	mmr_cdtoc_proddir="`/bin/grep '^PRODDIR=' ${mmr_media_cdtoc} | /bin/head -1 | /bin/sed 's/PRODDIR=//'`"
	mmr_media_proddir="${mmr_media}/${mmr_cdtoc_proddir}"
	mmr_media_toolsdir="`dirname ${mmr_media_proddir}`/Tools"
	LU_MINIROOT_MNTPT="`dirname ${mmr_media_proddir}`/Tools/Boot"

	if [ ! -d "$LU_MINIROOT_MNTPT" ]; then
		${LUPRINTF} -Eelp2 "`gettext 'The media miniroot mountpoint does not exist <%s>.'`" "$LU_MINIROOT_MNTPT"
		LU_MINIROOT_MNTPT=""
		exit_script 2
	fi

	LU_MINIROOT_PATH="${mmr_media}/${LU_MINIROOT_DIR}"

	if [ "$LU_SYSTEM_ARCH" = i386 ]; then
		# Locate compressed miniroot
		if [ ! -f "${LU_MINIROOT_PATH}/${LU_MINIROOT_ARCHIVE}" -o ! -s "${LU_MINIROOT_PATH}/${LU_MINIROOT_ARCHIVE}" ]; then
			${LUPRINTF} -Eelp2 "`gettext 'The media miniroot archive does not exist <%s>.'`" "${LU_MINIROOT_PATH}/${LU_MINIROOT_ARCHIVE}"
			exit_script 2
		fi

		${LUPRINTF} -lp1 "`gettext 'Uncompressing miniroot'`"
		TMP_FAILSAFE_ARCHIVE="/tmp/${LU_MINIROOT_ARCHIVE}.$$"

		# if the current kernel is 64 bit then use the 64 bit miniroot
		# as the failsafe archive if it exists
		#
		kisa=`isainfo -k`
		if [ "$kisa" = "amd64" -a -f "${LU_MINIROOT_PATH}/amd64/${LU_MINIROOT_ARCHIVE}" ] ; then
		    /usr/bin/gzcat "${LU_MINIROOT_PATH}/amd64/${LU_MINIROOT_ARCHIVE}" > "${TMP_FAILSAFE_ARCHIVE}"
		else
		    /usr/bin/gzcat "${LU_MINIROOT_PATH}/${LU_MINIROOT_ARCHIVE}" > "${TMP_FAILSAFE_ARCHIVE}"
		fi

		if [ "$?" -ne 0 ]; then
			${LUPRINTF} -Eelp2 "`gettext 'Cannot decompress media miniroot archive <%s>.'`" "${LU_MINIROOT_PATH}/${LU_MINIROOT_ARCHIVE}"
			exit_script 2
		fi

		# Locate compressed java archive. If not there, it is ok
		# because it is an earlier version of Solaris which doesn't
		# have this archive.
		#
		# Only uncompress the archive if lu.cpio.bz2 not available
		# since the contents are already included in lu.cpio.bz2.
		#
		if [ ! -f ${LU_MINIROOT_MNTPT}/${LU_MINIROOT_CPIO}.bz2 -a -s "${mmr_media_toolsdir}/Boot/${LU_WIZARD_ARCHIVE}" ]; then
			${LUPRINTF} -lp1 "`gettext 'Uncompressing miniroot archive (Part2)'`"
			TMP_WIZARD_ARCHIVE="/tmp/${LU_WIZARD_ARCHIVE}.$$"
			mkdir -p ${TMP_WIZARD_ARCHIVE}

			cd ${TMP_WIZARD_ARCHIVE}
			/usr/bin/bzcat "${mmr_media_toolsdir}/Boot/${LU_WIZARD_ARCHIVE}" | cpio -cidum
			if [ "$?" -ne 0 ]; then
				${LUPRINTF} -Eelp2 "`gettext 'Cannot decompress media miniroot archive <%s>.'`" "${mmr_media_toolsdir}/Boot/${LU_WIZARD_ARCHIVE}"
				exit_script 2
			fi
			LU_WIZARD_ARCHIVE_PRESENT=1
		fi

		#
		# Save failsafe multiboot/dboot. This will be installed in the 
		# ABE later when we unmount the miniroot
		#
		${LUPRINTF} -lp1 "`gettext 'Copying failsafe kernel from media.'`"
		TMP_FAILSAFE_KERNEL="/tmp/failsafe_kernel.$$"

		# Check for unix (dboot failsafe kernel) first, since 
		# multiboot exists on both multiboot and dboot systems
		if [ -f "${mmr_media}/${FAILSAFE_DBOOT_UNIX}" -a -s "${mmr_media}/${FAILSAFE_DBOOT_UNIX}" ]; then
			TMP_FAILSAFE_KERNEL_TYPE=unix
			/bin/cp -p "${mmr_media}/${FAILSAFE_DBOOT_UNIX}" "${TMP_FAILSAFE_KERNEL}" 
		elif [ -f "${mmr_media}/${FAILSAFE_MULTI_BOOT}" -a -s "${mmr_media}/${FAILSAFE_MULTI_BOOT}" ]; then
			TMP_FAILSAFE_KERNEL_TYPE=multiboot
			/bin/cp -p "${mmr_media}/${FAILSAFE_MULTI_BOOT}" "${TMP_FAILSAFE_KERNEL}" 
		else
			${LUPRINTF} -Eelp2 "`gettext 'The failsafe kernel does not exist on the media.'`"
			exit_script 2
		fi

		if [ "$?" -ne 0 ]; then
			${LUPRINTF} -Eelp2 "`gettext 'Save of failsafe kernel to <%s> failed.'`" "${TMP_FAILSAFE_KERNEL}"
			exit_script 2
		fi
	fi

	#
	# Check for the miniroot cpio archive and use it if it exists
	#
	if [ -f ${LU_MINIROOT_MNTPT}/${LU_MINIROOT_CPIO}.bz2 ]; then
		if [ -n "$mmr_lax" ]; then
			return
		fi

		#
		# Try to copy the needed utility directories from an old 
		# directory style miniroot.
		#
		TMP_MINIROOT_DIR="/tmp/miniroot.$$"
		LU_MINIROOT_DEVICE=${TMP_MINIROOT_DIR}
		/bin/mkdir -m 755 -p ${TMP_MINIROOT_DIR} > /dev/null 2>&1
		if [ $? -ne 0 ] ; then
			${LUPRINTF} -Eelp2 "`gettext 'Cannot create temporary miniroot directory <%s>.'`" "${TMP_MINIROOT_DIR}"
			exit_script 2
		fi
		mmr_curdir="`/bin/pwd`"
		cd ${LU_MINIROOT_MNTPT};

		/bin/cp ${LU_MINIROOT_CPIO}.bz2 ${TMP_MINIROOT_DIR}
		if [ "$?" -ne 0 ]; then
		   ${LUPRINTF} -Eelp2 "`gettext 'Cannot copy Live Upgrade cpio archives <%s> from media <%s>.'`" "${LU_MINIROOT_CPIO}.bz2" "${LU_MINIROOT_MNTPT}"
		   exit_script 2
		fi

		cd ${TMP_MINIROOT_DIR};

		/bin/bunzip2 ${LU_MINIROOT_CPIO}.bz2
		if [ "$?" -ne 0 ]; then
		   ${LUPRINTF} -Eelp2 "`gettext 'Cannot uncompress Live Upgrade cpio archives <%s> on media <%s>.'`" "${LU_MINIROOT_CPIO}.bz2" "${LU_MINIROOT_MNTPT}"
		   exit_script 2
		fi

		/bin/cat "${LU_MINIROOT_CPIO}" | /bin/cpio -icdmu
		if [ "$?" -ne 0 ] ; then
			${LUPRINTF} -Eelp2 "`gettext 'Cannot unarchive Live Upgrade miniroot from media <%s>.'`" "${LU_MINIROOT_MNTPT}"
			exit_script 2
		fi

		cd ${mmr_curdir}

		# The miniroot will be loopback mounted, set the filesystem 
		# type to lofs
		LU_MINIROOT_FSTYPE=lofs
	else

		${LUPRINTF} -lp1 "`gettext 'Creating miniroot device'`"
		LU_MINIROOT_DEVICE=`/usr/sbin/lofiadm -a ${TMP_FAILSAFE_ARCHIVE}`
		if [ "$?" -ne 0 ]; then
			${LUPRINTF} -Eelp2 "`gettext 'Cannot create miniroot device.'`"
			LU_MINIROOT_DEVICE=""
			exit_script 2
		fi

		#
		# The archive can (currently) be ufs or isofs. Determine the 
		# filesystem type
		#
		LU_MINIROOT_FSTYPE=`lulib_fstyp ${LU_MINIROOT_DEVICE}`
		if [ "$?" -ne 0 ]; then
			${LUPRINTF} -Eelp2 "`gettext 'Cannot determine miniroot archive filesystem type <%s>.'`" "${LU_MINIROOT_DEVICE}"
			exit_script 2
		fi
	fi
	${LUPRINTF} -lp1 "`gettext 'miniroot filesystem is <%s>'`" "${LU_MINIROOT_FSTYPE}"

	${LUPRINTF} -lp1 "`gettext 'Mounting miniroot at <%s>'`" "${LU_MINIROOT_MNTPT}"

	/usr/sbin/mount -F "${LU_MINIROOT_FSTYPE}" "${LU_MINIROOT_DEVICE}" "${LU_MINIROOT_MNTPT}" 
	if [ "$?" -ne 0 ]; then
		${LUPRINTF} -Eelp2 "`gettext 'Cannot mount miniroot at <%s>.'`" "${LU_MINIROOT_MNTPT}"
		LU_MINIROOT_MNTPT=""
		exit_script 2
	fi

	if [ ${LU_WIZARD_ARCHIVE_PRESENT} -eq 1 ] ; then
		LU_WIZARD_MNTPT="${LU_MINIROOT_MNTPT}/usr/lib/install/data/wizards"		

		${LUPRINTF} -lp1 "`gettext 'Mounting miniroot Part 2 at <%s>'`" "${LU_MINIROOT_MNTPT}"
		rm -f ${LU_WIZARD_MNTPT}
		mkdir -p ${LU_WIZARD_MNTPT}

		/usr/sbin/mount -F "lofs" "${TMP_WIZARD_ARCHIVE}/usr/lib/install/data/wizards" ${LU_WIZARD_MNTPT}

		if [ "$?" -ne 0 ]; then
			${LUPRINTF} -Eelp2 "`gettext 'Cannot mount miniroot Part2 at <%s>.'`" "${LU_WIZARD_MNTPT}"
			LU_WIZARD_MNTPT=""
			exit_script 2
		fi
	fi
}

#
# Note: this is called from exit_script() which in turn can
# be invoked from various points in this script. Hence the checks
#
umount_miniroot()
{


	if [ -n "${LU_WIZARD_MNTPT}" ]; then
		lulib_unmount_pathname ${LU_WIZARD_MNTPT} > /dev/null 2>&1
		if [ "$?" -ne 0 ]; then
			${LUPRINTF} -Eelp2 "`gettext 'Cannot unmount miniroot at <%s>.'`" "${LU_WIZARD_MNTPT}"
		fi
		LU_WIZARD_MNTPT=""
	fi

	if [ -n "${TMP_WIZARD_ARCHIVE}" ]; then
		/usr/bin/rm -rf ${TMP_WIZARD_ARCHIVE} > /dev/null 2>&1
	fi

	if [ -n "${LU_MINIROOT_MNTPT}" ]; then
		lulib_unmount_pathname "${LU_MINIROOT_MNTPT}" > /dev/null 2>&1
		if [ "$?" -ne 0 ]; then
			${LUPRINTF} -Eelp2 "`gettext 'Cannot unmount miniroot at <%s>.'`" "${LU_MINIROOT_MNTPT}"
		fi
		LU_MINIROOT_MNTPT=""
	fi

	if [ -n "${TMP_MINIROOT_DIR}" ] ; then
		if [ -d ${TMP_MINIROOT_DIR} ] ; then
			/bin/rm -rf "${TMP_MINIROOT_DIR}" >/dev/null 2>&1 
		fi
		LU_MINIROOT_DEVICE=""
	fi

	if [ -n "${LU_MINIROOT_DEVICE}" ]; then
		/usr/sbin/lofiadm -d "${LU_MINIROOT_DEVICE}"  >/dev/null 2>&1
		LU_MINIROOT_DEVICE=""
	fi

	if [ -n "$INSTALL_FAILSAFE_ON" ]; then
		# Install the configured failsafe archive.
		# And multiboot for x86 systems in the ABE.
		install_failsafe "$INSTALL_FAILSAFE_ON"
	fi

	if [ -n "$TMP_FAILSAFE_ARCHIVE" ] ; then
		/bin/rm -f "${TMP_FAILSAFE_ARCHIVE}"  >/dev/null 2>&1 
		/bin/rm -f "${TMP_FAILSAFE_ARCHIVE}.gz"  >/dev/null 2>&1 
	fi

	if [ -n "$TMP_FAILSAFE_KERNEL" ] ; then
		/bin/rm -f "${TMP_FAILSAFE_KERNEL}" >/dev/null 2>&1 
	fi
}

#
# Save the GRUB menu (if any) that exists on the ABE
# This function assumes that the ABE is mounted.
#
# Arguments:
#	$1 - The mountpoint of the ABE
#	$2 - The name of the ABE
# Returns:
#	0 on success
#	1 on failure
#
save_menu()
{
    /bin/rm -f "$TMP_MENU_LST"

    if [ "$LU_SYSTEM_ARCH" != i386 ]; then
       ${LUPRINTF} -Eelp2 "`gettext 'save_menu(): Cannot be invoked on a <%s> system.'`" "${LU_SYSTEM_ARCH}"
       return 1
    fi

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

    ABEmntpt="$1"
    ABEname="$2"

    #
    # Check if the ABE has a boot partition. If yes,
    # unmount it to get access to /boot on the ABE
    # root filesystem
    #
    dev=`/sbin/mount | /bin/nawk -v mntpt="${ABEmntpt}/boot" ' { if ($1 == mntpt) {printf("%s\n", $3); exit 8;}}'`
    if [ "$?" -eq 8 -a -n "$dev" ]; then
       lulib_unmount_pathname "${ABEmntpt}/boot"
       if [ "$?" -ne 0 ]; then
          ${LUPRINTF} -Eelp2 "`gettext 'save_menu(): Cannot unmount x86 boot partition <%s>.'`" "$dev"
	  return 1
       fi
    else
       dev=""
    fi

    ${LUPRINTF} -lp1 "`gettext 'Checking for GRUB menu on ABE <%s>.'`" "$ABEname"
    if [ -f "${ABEmntpt}/${BOOT_MENU}" -a -s "${ABEmntpt}/${BOOT_MENU}" ]; then
        ${LUPRINTF} -lp1 "`gettext 'Saving GRUB menu on ABE <%s>.'`" "$ABEname"
       /bin/cp -p "${ABEmntpt}/${BOOT_MENU}" "${TMP_MENU_LST}"
    fi

    #
    # If we unmounted the ABE boot partition above, mount it now
    #
    if [ -n "$dev" ]; then
       /sbin/mount -F pcfs "$dev" "${ABEmntpt}/boot"
       if [ "$?" -ne 0 ]; then
          ${LUPRINTF} -Eelp2 "`gettext 'save_menu(): Cannot remount x86 boot partition <%s>.'`" "$dev"
	  /bin/rm -f "${TMP_MENU_LST}"
	  return 1
       fi
    fi

    return 0
}

#
# Restore the GRUB menu (if any) that existed on the ABE prior to upgrade.
# This function assumes that the ABE is mounted.
# A (good) side effect of this function is that it deletes any blank menu
# that may have been created by upgrade.
# Note that we cannot assume the boot partition has been deleted at this point.
#
# Arguments:
#	$1 - The mountpoint of the ABE
#	$2 - The name of the ABE
# Returns:
#	0 on success
#	1 on failure
#
restore_menu()
{
    if [ "$LU_SYSTEM_ARCH" != i386 ]; then
       ${LUPRINTF} -Eelp2 "`gettext 'restore_menu(): Cannot be invoked on a <%s> system.'`" "${LU_SYSTEM_ARCH}"
       return 1
    fi

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

    ABEmntpt="$1"
    ABEname="$2"

    #
    # Check if the ABE has a boot partition. If yes,
    # unmount it to get access to /boot on the ABE
    # root filesystem
    #
    dev=`/sbin/mount | /bin/nawk -v mntpt="${ABEmntpt}/boot" ' { if ($1 == mntpt) {printf("%s\n", $3); exit 9;}}'`
    if [ "$?" -eq 9 -a -n "$dev" ]; then
       lulib_unmount_pathname "${ABEmntpt}/boot"
       if [ "$?" -ne 0 ]; then
          ${LUPRINTF} -Eelp2 "`gettext 'restore_menu(): Cannot unmount x86 boot partition <%s>.'`" "$dev"
	  return 1
       fi
    else
       dev=""
    fi

    #
    # If a GRUB menu previously existed on the ABE restore it. If not, delete any menu
    # found as this would be a blank menu generated by upgrade.
    # Remove the pathname from the ABE's software database to avoid pkgchk errors.
    #
    if [ -f "${TMP_MENU_LST}" -a -s "${TMP_MENU_LST}" ]; then
       ${LUPRINTF} -lp1 "`gettext 'Restoring GRUB menu on ABE <%s>.'`" "$ABEname"
       # The directory may not have been created yet.
       /bin/mkdir -p "${ABEmntpt}/${BOOT_MENU_DIR}"
       /bin/cp -p "${TMP_MENU_LST}" "${ABEmntpt}/${BOOT_MENU}"
    elif [ -f "${ABEmntpt}/${BOOT_MENU}" ]; then
       /bin/rm "${ABEmntpt}/${BOOT_MENU}"
       PKGNAME=`/bin/nawk -v BOOT_MENU="/$BOOT_MENU" 'index($1, BOOT_MENU) {print $NF}' "${ABEmntpt}/var/sadm/install/contents"`
       if [ -n "${PKGNAME}" ]; then
          /usr/sbin/removef -R "${ABEmntpt}" ${PKGNAME} "/${BOOT_MENU}" > /dev/null
          /usr/sbin/removef -f -R "${ABEmntpt}" ${PKGNAME}
       fi
       ${LUPRINTF} -lp1 "`gettext 'Deleted empty GRUB menu on ABE <%s>.'`" "$ABEname"
    fi

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

    #
    # If we unmounted the ABE boot partition above, mount it now
    #
    if [ -n "$dev" ]; then
       /sbin/mount -F pcfs "$dev" "${ABEmntpt}/boot"
       if [ "$?" -ne 0 ]; then
          ${LUPRINTF} -Eelp2 "`gettext 'restore_menu(): Cannot remount x86 boot partition <%s>.'`" "$dev"
	  return 1
       fi
    fi

    return 0
}

################################################################################
# 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.
#
# The main code is supposed to do minimal processing sufficient to parse and validate as much
# of the command line arguments and environment as possible for options and arguments that
# are common to all operations, and then to pass control to a specific "do_" function that 
# performs the specific operation requested.
################################################################################

# Make sure that all temporary files are initially deleted.

/bin/rm -f ${ALL_TEMP_FILES} 1>/dev/null 2>&1

# signal handling for cleanup.
# 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 "interruptHandler" 1 2 3 9 15

# 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_script 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_script 5
fi

. $LUBIN/lulib

# 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_script 2
fi

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

# Reset all command line parse flags to default values.
# These flags are MAJOR MODES, only one of which can be specified:
flag_c="" # -c - check media.			[** MAJOR MODE **]
flag_C="" # -C - check package.			[** MAJOR MODE **]
flag_f="" # -f - flash install.			[** MAJOR MODE **]
flag_i="" # -i - installer.			[** MAJOR MODE **]
flag_I="" # -I - information on package.	[** MAJOR MODE **]
flag_p="" # -p - add packages.			[** MAJOR MODE **]
flag_P="" # -r - remove packages.		[** MAJOR MODE **]
flag_t="" # -t - add patches.			[** MAJOR MODE **]
flag_T="" # -T - remove patches.		[** MAJOR MODE **]
flag_u="" # -u - update os.			[** MAJOR MODE **]

# These flags are PARAMETERS, which are dependent upon the major mode:
flag_a="" # -a - flash_archive for -f flash major mode / pkg_admin_file for -p package add major mode.
flag_d="" # -d - same as '-s' flag for -p package add major mode only.
flag_D="" # -D - dry run mode.
flag_F="" # -F - flash verify.
flag_J="" # -J "p" - jumpstart profile.
flag_j="" # -j p - jumpstart profile path.
flag_l="" # -l f - log file path.
flag_N="" # -N - no execute mode.
flag_n="" # -n "n" - be name.
flag_o="" # -o f - output file path.
flag_O="" # -O "o" - options passed to underlying installation tool(s).
flag_s="" # -s p - source path.
flag_x="" # -x n - set debug level (PRIVATE).

# Validate the command line arguments.

while [ $# -ne 0 ] ; do
  while getopts a:cCDd:fFiIJ:j:l:Nn:O:o:PpTts:ux:X c ; do

    case $c in
      a) # -a - flash_archive for -f flash major mode / pkg_admin_file for -p package add major mode.
	 flag_a="${flag_a} ${OPTARG}"
	 ;;
      c) # -c - check media .
	 flag_c="1"
	 ;;
      C) # -C - check package.
	 flag_C="1"
	 ;;
      d) # -d - same as '-s' flag for -p package add major mode only.
	 lulib_cannot_duplicate_option "${flag_d}" "${OPTARG}" "-d"
	 flag_d="${OPTARG}"
	 ;;
      D) # -D - dry run mode.
	 flag_D="1"
	 ;;
      f) # -f - flash install
	 flag_f="1"
	 ;;
      F) # -F - flash verify
	 flag_F="1"
	 ;;
      i) # -i - installer.
	 flag_i="1"
	 ;;
      I) # -I - information on package.
	 flag_I="1"
	 ;;
      J) # -J "p" - jumpstart profile.
	 lulib_cannot_duplicate_option "${flag_J}" "${OPTARG}" "-J"
	 flag_J="${OPTARG}"
	 ;;
      j) # -j p - jumpstart profile path.
	 lulib_cannot_duplicate_option "${flag_j}" "${OPTARG}" "-j"
	 flag_j="${OPTARG}"
	 ;;
      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
	   ${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
	   ${LUPRINTF} -Eelp2 "`gettext 'Argument <%s> to -l option may not be created or appended to.'`" "${OPTARG}"
	   exit_script 3
	 fi
	 flag_l="${OPTARG}"
	 lulib_set_error_log_file "${flag_l}"
	 ;;
      N) # -N - no execute mode.
	 flag_N="1"
	 ;;
      n) # -n "n" - be name.
	 lulib_cannot_duplicate_option "${flag_n}" "${OPTARG}" "-n"
	 flag_n="${OPTARG}"
	 ;;
      O) # -O "o" - options passed to underlying installation tool(s).
	 if [ -z "${flag_O}" ] ; then
	   flag_O="${OPTARG}"
	 else
	   flag_O="${flag_O} ${OPTARG}"
	 fi
	 ;;
      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
	   ${LUPRINTF} -Eelp2 '%s' "${ERRMSG}"
	   ${LUPRINTF} -Eelp2 "`gettext 'Argument <%s> to -o option may not be created or appended to.'`" "${OPTARG}"
	   exit_script 3
	 fi
	 flag_o="${OPTARG}"
	 lulib_set_session_log_file "${flag_o}"
	 ;;
      p) # -p - add packages.
	 flag_p="1"
	 ;;
      P) # -P - remove packages.
	 flag_P="1"
	 ;;
      s) # -s p - source path.
	 lulib_cannot_duplicate_option "${flag_s}" "${OPTARG}" "-s"
	 flag_s="${OPTARG}"
	 LU_MEDIA_PATH="$flag_s"; export LU_MEDIA_PATH
	 ;;
      T) # -T - remove patches.
	 flag_T="1"
	 ;;
      t) # -t - add patches.
	 flag_t="1"
	 ;;
      u) # -u - update os.
	 flag_u="1"
	 ;;
      X) # -X - set XML output mode.
	 lulib_set_output_format 'xml'
	 ;;
      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}"
	 ;;
      *) # 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 #############
  ######################################################################################

# Set command line arguments found (if any).
cmdNames="$*"

# Verify that at least one operation option was specified..
if [ -z "${flag_c}${flag_C}${flag_f}${flag_i}${flag_I}${flag_p}${flag_t}${flag_P}${flag_T}${flag_u}" ] ; then
  ${LUPRINTF} -Eelp2 "`gettext 'At least one option from <-c, -C, -f, -i, -I, -p, -P, -t, -T, -u> must be specified.'`"
  usage 3
fi

# Verify that only one operation option was specified.
if [ "${flag_c}${flag_C}${flag_f}${flag_i}${flag_I}${flag_p}${flag_t}${flag_P}${flag_T}${flag_u}" != "1" ] ; then
  ${LUPRINTF} -Eelp2 "`gettext 'Only one option from <-c, -C, -f, -i, -I, -p, -P, -t, -T, -u> may be specified.'`"
  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 BE.'`"
  exit_script 2
fi

# If an operation is requested that requires a target boot environment
# name, validate it here.
if [ -n "${flag_C}${flag_f}${flag_i}${flag_I}${flag_p}${flag_t}${flag_P}${flag_T}${flag_u}" ] ; then

  # A valid BE name must be provided.
  if [ -z "${flag_n}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'The required target BE name was not specified with the -n option.'`"
    usage 3
  fi
  BE_NAME="${flag_n}"
fi
  
# If an operation is requested that requires a target boot environment
# BE must have p7zip utility to install packages from S10u5 or later.
if [ -n "${flag_i}${flag_I}${flag_p}${flag_P}${flag_u}${flag_f}" ] ; then
  if [ ! -x  /usr/bin/p7zip ] ; then
    ${LUPRINTF} -Eelp2 "`gettext '/usr/bin/p7zip was not found.\nIf you do upgrade to or do other operations like pkgadd from Solaris 10 05/08 or later version, you will need to install the p7zip patch as well as other patches before running luupgrade. Please consult with the technical instruction (info doc) 206844 on the SunSolve(tm) web site.'`"
    exit_script 2
  fi
fi

# If an operation is requested that requires a target boot environment
# itself be valid ("complete"), validate it here.

if [ -n "${flag_C}${flag_i}${flag_I}${flag_p}${flag_t}${flag_P}${flag_T}${flag_u}${flag_f}" ] ; then

  lulib_validate_be "${BE_NAME}" "${CURR_BE}" "${flag_f}"
  if [ "$?" -ne "0" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to use the boot environment <%s>.'`" "${BE_NAME}"
    exit_script 2
  fi

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

# If an operation is requested that can not be done when a BE is busy, check for it now.
if [ -n "${flag_f}${flag_p}${flag_P}${flag_t}${flag_T}${flag_i}" ] ; then
  lulib_check_any_be_busy
  if [ $? -ne 0 ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'A BE is busy with another operation.'`"
    exit_script 2
  fi
fi

# If dry run mode, disable mailing of any log files
if [ -n "${flag_N}" ] ; then
  MAIL_DISABLE="yes"
fi

#
# Delete menu entries if BE content changes
#
if [ -z "${flag_N}" -a -z "$flag_c" -a -z "$flag_C" -a -z "$flag_I" ]; then
   if [ "$LU_SYSTEM_ARCH" = i386 ]; then
      lulib_ask_for_menu_propagate
      if [ "$?" -eq 1 ]; then
         exit_script 2
      fi
      lulib_delete_menu_entry "${BE_NAME}"
      if [ $? -ne 0 ] ; then
         ${LUPRINTF} -Eelp2 "`gettext 'Cannot delete GRUB menu entry for boot environment <%s>.'`" "${BE_NAME}"
         exit_script 2
      fi
   elif [ -x /sbin/zpool ]; then
      BE_ID=`${LUETCBIN}/ludo get_be_id "${BE_NAME}" 2>&1`
      if [ "$?" -ne "0" -o -z "${BE_ID}" ] ; then
         ${LUPRINTF} -Eelp2 '%s' "${BE_ID}"
         ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine BE ID for BE <%s>: %s.'`" "${BE_NAME}" "${ERR_STR}"
         exit_script 2
      fi
      lulib_delete_menu_entry "${BE_NAME}" "${BE_ID}"
      # sparc always succeeds...
   fi
fi

  ######################################################################################
  ############## Call specific function to handle the operation requested ##############
  ######################################################################################

#
# The [-l error_log] and [-o outfile] and [-n "BE_name"] options have already been processed.
#

commandStatus="0"

if [ -n "${flag_c}" ] ; then
  ###
  ### Check Media:     luupgrade -c -F -s media_path [-l error_log] [-o outfile]
  ###
  lulib_cannot_have_options "${flag_d}${flag_D}${flag_n}${flag_j}${flag_J}${flag_N}${flag_O}" "-c" "-d, -D, -n, -j, -J, -N, -O"
  lulib_must_have_option "${flag_s}" "-c" "-s"
  lulib_cannot_have_argument "${cmdNames}" "-c"
  if [ -n "${flag_F}" ] ; then
    mount_miniroot "$flag_s" ""
    do_checkMiniroot "${flag_s}"
    commandStatus="$?"
  else
    mount_miniroot "$flag_s" "lax"
    do_checkMedia "${flag_s}"
    commandStatus="$?"
  fi
elif [ -n "${flag_f}" ] ; then
  ###
  ### Flash Upgrade:   luupgrade -f -n "BE_name" [-l error_log] [-o outfile] [-N] (-s flash_path | -j profile_path | -J "profile")
  ###
  lulib_must_have_option "${flag_n}" "-f" "-n"
  lulib_must_have_option "${flag_s}" "-f" "-s"
  lulib_must_have_options "${flag_j}${flag_J}${flag_a}" "-f" "-j, -J, -a"
  lulib_cannot_have_conflicting_option "${flag_a}" "-f" "${flag_j}" "-j"
  lulib_cannot_have_conflicting_option "${flag_a}" "-f" "${flag_J}" "-J"
  lulib_cannot_have_conflicting_option "${flag_j}" "-f" "${flag_J}" "-J"
  lulib_cannot_have_argument "${cmdNames}" "-f"

  mount_miniroot "$flag_s" ""
  do_flashInstall "${CURR_BE}" "${BE_NAME}" "${flag_j}" "${flag_J}" "${flag_N}" "${flag_D}" "${flag_s}" "${flag_a}"
  commandStatus="$?"
elif [ -n "${flag_i}" ] ; then
  ###
  ### Run Installer:   luupgrade -i -n "BE_name" [-l error_log] [-o outfile] [-N] -s installer_source_path [-O "installer_options"] [installer]
  ###
  lulib_cannot_have_options "${flag_d}${flag_a}${flag_D}${flag_F}${flag_j}${flag_J}" "-i" "-d, -a, -D, -F, -j, -J"
  lulib_must_have_option "${flag_n}" "-i" "-n"
  lulib_must_have_option "${flag_s}" "-i" "-s"
  do_runInstaller "${BE_NAME}" "${flag_N}" "${flag_O}" "${flag_s}" "${cmdNames}"
  commandStatus="$?"
elif [ -n "${flag_p}" ] ; then
  ###
  ### Add Packages:    luupgrade -p -n "BE_name" [-l error_log] [-o outfile] [-N] ((-s|-d) packages_path) [-a pkg_admin_file] [-O "pkgadd_options"] [pkginst [pkginst...]]
  ###
  lulib_cannot_have_options "${flag_D}${flag_F}${flag_j}${flag_J}" "-p" "-D, -F, -j, -J"
  lulib_cannot_have_conflicting_option "${flag_s}" "-s" "${flag_d}" "-d"
  lulib_must_have_option "${flag_n}" "-p" "-n"
  lulib_must_have_option "${flag_s}${flag_d}" "-p" "-s, -d"
  # For the -a option, pretend that it was inside of a "-O" option
  if [ -n "${flag_a}" ] ; then
    if [ -z "${flag_O}" ] ; then
      flag_O="-a ${flag_a}"
    else
      flag_O="${flag_O} -a ${flag_a}"
    fi
  fi
  do_addPackages "${BE_NAME}" "${flag_N}" "${flag_O}" "${flag_s}${flag_d}" "${cmdNames}"
  commandStatus="$?"
elif [ -n "${flag_t}" ] ; then
  ###
  ### Add Patches:     luupgrade -t -n "BE_name" [-l error_log] [-o outfile] [-N] -s patches_path  [-O "patchadd_options"] [patchname [patchname...]]
  ###
  lulib_cannot_have_options "${flag_d}${flag_a}${flag_D}${flag_F}${flag_j}${flag_J}" "-t" "-d, -a, -D, -F, -j, -J"
  lulib_must_have_option "${flag_n}" "-t" "-n"
  lulib_must_have_option "${flag_s}" "-t" "-s"
  do_addPatches "${BE_NAME}" "${flag_N}" "${flag_O}" "${flag_s}" "${cmdNames}"
  commandStatus="$?"
elif [ -n "${flag_P}" ] ; then
  ###
  ### Remove Packages: luupgrade -P -n "BE_name" [-l error_log] [-o outfile] [-N] [-O "pkgadd_options"] pkginst [pkginst...]
  ###
  lulib_cannot_have_options "${flag_d}${flag_a}${flag_D}${flag_F}${flag_s}${flag_j}${flag_J}" "-P" "-d, -a, -D, -F, -s, -j, -J"
  lulib_must_have_option "${flag_n}" "-P" "-n"
  lulib_must_have_argument "${cmdNames}" "-P"
  do_removePackages "${BE_NAME}" "${flag_N}" "${flag_O}" "${cmdNames}"
  commandStatus="$?"
elif [ -n "${flag_T}" ] ; then
  ###
  ### Remove Patches:  luupgrade -T -n "BE_name" [-l error_log] [-o outfile] [-N] [-O "patchrm_options"] patchname [patchname...]
  ###
  lulib_cannot_have_options "${flag_d}${flag_a}${flag_D}${flag_F}${flag_s}${flag_j}${flag_J}" "-T" "-d, -a, -D, -F, -s, -j, -J"
  lulib_must_have_option "${flag_n}" "-T" "-n"
  lulib_must_have_argument "${cmdNames}" "-T"
  do_removePatches "${BE_NAME}" "${flag_N}" "${flag_O}" "${cmdNames}"
  commandStatus="$?"
elif [ -n "${flag_C}" ] ; then
  ###
  ### Check Packages:    luupgrade -C -n "BE_name" [-l error_log] [-o outfile] [-N] [-O "pkgadd_options"] [pkginst [pkginst...]]
  ###
  lulib_cannot_have_options "${flag_d}${flag_a}${flag_D}${flag_F}${flag_j}${flag_J}${flag_s}" "-p" "-d, -a, -D, -F, -j, -J, -s"
  lulib_must_have_option "${flag_n}" "-p" "-n"
  do_checkPackages "${BE_NAME}" "${flag_N}" "${flag_O}" "${cmdNames}"
  commandStatus="$?"
elif [ -n "${flag_I}" ] ; then
  ###
  ### Package Info:    luupgrade -I -n "BE_name" [-l error_log] [-o outfile] [-N] [-O "pkgadd_options"] [pkginst [pkginst...]]
  ###
  lulib_cannot_have_options "${flag_d}${flag_a}${flag_D}${flag_F}${flag_j}${flag_J}${flag_s}" "-p" "-d, -a, -D, -F, -j, -J, -s"
  lulib_must_have_option "${flag_n}" "-p" "-n"
  do_infoPackages "${BE_NAME}" "${flag_N}" "${flag_O}" "${cmdNames}"
  commandStatus="$?"
elif [ -n "${flag_u}" ] ; then
  ###
  ### OS Upgrade:      luupgrade -u -n "BE_name" [-l error_log] [-o outfile] [-N] -s os_image_path [-j profile_path]
  ###
  lulib_cannot_have_options "${flag_d}${flag_J}" "-u" "-d, -J"
  lulib_must_have_option "${flag_n}" "-u" "-n"
  lulib_must_have_option "${flag_s}" "-u" "-s"
  lulib_cannot_have_argument "${cmdNames}" "-u"
  ${LUPRINTF} +X -a "${MAIL_LOGFILE}" "`gettext 'Upgrade Operating System of BE <%s> from media <%s>.'`" "${BE_NAME}" "${flag_s}"

  #
  # With Newboot aka GRUB boot, the miniroot is a compressed file
  # Expand and mount the miniroot here.
  #
  mount_miniroot "$flag_s" ""
  do_upgradeOs "${BE_NAME}" "${flag_j}" "${flag_N}" "${flag_s}" "${CURR_BE}" "${flag_D}"
  commandStatus="$?"
  if [ "${commandStatus}" -ne "0" ] ; then
    ${LUPRINTF} +X -a "${MAIL_LOGFILE}" "`gettext 'Operating System upgrade FAILED.'`"
  else
    ${LUPRINTF} +X -a "${MAIL_LOGFILE}" "`gettext 'Operating System upgrade successful.'`"
  fi
else
  # ### NO OPERATION TO PERFORM?
  ${LUPRINTF} -Eelp2 "`gettext 'Internal logic error (dont know which operation to perform).'`"
  exit_script 2
fi

# Operation has completed

exit_script $commandStatus
