#!/sbin/sh

#################################################################################################
#
# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#
# ident	"@(#)lubootdevice.sh	1.1	08/06/25 SMI"
#
# This utility is not for public use; the interface is subject to change 
# without notice.
#
# USAGE:        lubootdevice [-m mntpt] [-C]
# FUNCTION:     Outputs the full device node name for the boot device to stdout.
#		This should handle SCSI slices, DAP Vdisks, VM Volumes, 
#		RAID slices, and ZFS root pools.
#		The distinction needs to be made between the the boot device and
#		the root specification.  The root specification can either be
#		a metadevice, Veritas logical volume, ZFS root pool, or 
#		physical device.  The boot device is the actual physical device
#		that gets booted.
# INPUT:	-m mntpt - optional mount point to determine boot device for
#			(this mount point MUST be a boot mount point, 
#			e.g. must contain /etc directory)
#		-C - confirm boot device selection from user IF 
#			devnm/vfstab returns a meta-device and boot 
#			device selected is chosen from the boot prom
# OUTPUT:	Full path of boot device
# DEV:          JKJ
#
# Note: performance testing has proven that "/sbin/sh" provides the best performance over
# /bin/sh and /bin/ksh.
#
#################################################################################################

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

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

usage()
{

  ${LUPRINTF} -p2 "`gettext 'Usage: %s [-l error_log] [-o outfile] [-a] [-m mntpt]'`" "${LU_PROG_NAME}"

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

#################################################################################################
# Name:		is_it_bootdev
# Description:	Determine if device specified is a valid block device for a Solaris root file system.
# Local Prefix:	iird_
# Arguments:	$1 = full path name of device to check.
#		$2 = mount point
# Example:	is_it_bootdev "/dev/dsk/c0t0d0s0" "/"
# Returns:	0 - $1 is a valid block device for a Solaris root file system.
#		1 - $1 is NOT a valid block device for a Solaris root file system.
#################################################################################################

is_it_bootdev()
{
  iird_device="$1"
  iird_mntpt="$2"

  # If on the intel platform, reject any physical disk slice - must be a solaris slice.
  if [ "${LU_SYSTEM_ARCH}" = "i386" ] ; then
    echo "${iird_device}" | grep '^/dev/dsk/.*p.$' > /dev/null 2>&1
    if [ "$?" -eq "0" ] ; then
      if [ -n "${LUPRINTF}" ] ; then
        ${LUPRINTF} -lp2D - "`gettext 'Candidate boot device <%s> is physical slice: ignored.'`" "${iird_device}"
      fi
      return 1
    fi
  fi

  # If a disk device return success.
  echo "${iird_device}" | grep "^/dev/dsk/" > /dev/null 2>&1
  if [ "$?" -eq "0" ] ; then
    if [ -b "${iird_device}" ] ; then
      if [ -n "${LUPRINTF}" ] ; then
	${LUPRINTF} -lp2D - "`gettext 'Candidate boot device <%s> is solaris slice: accepted.'`" "${iird_device}"
      fi
      return 0
    else
      if [ -n "${LUPRINTF}" ] ; then
	${LUPRINTF} -lp2D - "`gettext 'Candidate boot device <%s> is solaris slice but is not a block device: ignored.'`" "${iird_device}"
      fi
      return 1
    fi
  fi

  # Device not recognized.
  if [ -n "${LUPRINTF}" ] ; then
    ${LUPRINTF} -lp2D - "`gettext 'Candidate boot device <%s> not recognized: ignored.'`" "${iird_device}"
  fi
  return 1
}

#################################################################################################
# Name:		confirm_selection
# Description:	Confirm selection of device with user if enabled.
# Local Prefix:	csl_
# Arguments:	$1 = logical device being looked up.
#		$2 = physical block device found.
#		$3 = confirmation flag ("" to NOT confirm, otherwise confirm).
# Example:	confirm_selection "/dev/md/dsk/d10" "/dev/dsk/c0t0d0s0" "yes"
# Returns:	0 - Selection is confirmed.
#		1 - Selection is NOT confirmed.
#################################################################################################

confirm_selection()
{
  csl_logDev="$1"
  csl_physDev="$2"
  csl_confirmSelectionFlag="$3"

  # Only confirm with the user if enabled to do so.
  if [ -n "${csl_confirmSelectionFlag}" ] ; then
    # Only confirm with user if standard input is not from a file or pipe.
    /bin/tty -s
    if [ "$?" -eq "0" ] ; then
      yesAnswer="`gettext \"yes\"`"
      noAnswer="`gettext \"no\"`"
      theAnswer=""
      while [ "X${theAnswer}" != "X${yesAnswer}" -a "X${theAnswer}" != "X${noAnswer}" ] ; do
	if [ "${LU_SYSTEM_ARCH}" = "sparc" ] ; then
	  ${LUPRINTF} -lpn2 "`gettext 'Is the physical device <%s> the boot device for the logical device <%s>? (%s or %s) '`" "${csl_physDev}" "${csl_logDev}" "$yesAnswer" "$noAnswer"
	else
	  ${LUPRINTF} -lpn2 "`gettext 'Is the disk slice <%s> the Solaris boot device for the logical device <%s>? (%s or %s) '`" "${csl_physDev}" "${csl_logDev}" "$yesAnswer" "$noAnswer"
	fi
	read theAnswer
	if [ "X${theAnswer}" != "X${yesAnswer}" -a "X${theAnswer}" != "X${noAnswer}" ] ; then
	  ${LUPRINTF} -Eelp2 "`gettext 'Invalid Choice - valid choices are: <%s> or <%s>.'`" "${yesAnswer}" "${noAnswer}"
	fi
      done

      if [ "X${theAnswer}" != "X${yesAnswer}" ] ; then
	return 1
      fi
    fi
  fi
  return 0
}

#################################################################################################
# Name:		do_oos_mode
# Description:	Perform operation in single user maintenence mode.
# Local Prefix:	dom_
# Arguments:	$1 = optional mount point to return boot device of ("" implies current BE)
# Example:      exit_script "0"
# Returns:	<none>
#################################################################################################

do_oos_mode()
{
  dom_mntpt="${1:-/}"

  LU_BE_CONFIG_FILE="/etc/lu/.BE_CONFIG"

  # Attempt to determine the root specification using devnm; if that fails,
  # attempt to find the root spec from the vfstab file.

  ROOT_SPEC="`/usr/sbin/devnm ${dom_mntpt} 2>/dev/null | awk ' { print $1 } '`"

  #
  # if the mountpoint is zfs then get the boot device direct from zfs
  #

  # get the file system type from df
  dfnout="`/usr/sbin/df -n ${mntpt} 2>&1`"
  if [ "$?" -eq 0 ] ; then
    mntfstyp="`echo ${dfnout} | /bin/sed 's/.*:[ ]*//'`"
    if [ "$mntfstyp" = "zfs" ] ; then
	poolnm=`echo "${ROOT_SPEC}" | /bin/nawk -F/ '{ print $1 }'`
	ZFS_ROOT_SPEC=`lulib_get_zfs_root_boot_device $poolnm`
	${LUPRINTF} -lp2D -  \
	    "`gettext 'Boot device for mount point <%s> is <%s>.'`" \
	    "${mntpt}" "${ZFS_ROOT_SPEC}"
	echo "${ZFS_ROOT_SPEC}"
	exit 0
    fi
  fi

  if [ -z "${ROOT_SPEC}" -a -r "${dom_mntpt}/etc/vfstab" ] ; then
    ROOT_SPEC=`/bin/sed -e '/^[	 ]*$/d' -e '/#.*/d' < "${dom_mntpt}/etc/vfstab" | awk ' { if ( $3 == "/" ) { print $1; exit 0 } } '`
  fi

  if [ -n "${ROOT_SPEC}" ] ; then
    is_it_bootdev "${ROOT_SPEC}" "${dom_mntpt}"
    if [ "$?" -eq "0" ] ; then
      echo "${ROOT_SPEC}"
      return 0
    fi
  fi

  # See if the boot device can be obtained from the lutab file.

  BE_BOOT_DEV=`${LUETCBIN}/ludo get_boot_device_from_mntpt "${dom_mntpt}" 2>/dev/null`
  if [ "$?" -eq 0 -a -n "${BE_BOOT_DEV}" -a  -b "${BE_BOOT_DEV}" ] ; then
    is_it_bootdev "${BE_BOOT_DEV}" "${dom_mntpt}"
    if [ "$?" -eq "0" ] ; then
      echo "${BE_BOOT_DEV}"
      return 0
    fi
  fi

  # see if the target BE contains a BE configuration file
  # and if so look for the BOOT_DEVICE entry.

  if [ -f "${dom_mntpt}/${LU_BE_CONFIG_FILE}" ] ; then
    BE_BOOT_DEVICE=`grep "^LUBECF_BE_BOOT_DEVICE=" "${dom_mntpt}/${LU_BE_CONFIG_FILE}" | cut -d'=' -f2`
    if [ "$?" -eq "0" -a -n "${BE_BOOT_DEVICE}" -a -b "${BE_BOOT_DEVICE}" ] ; then
      is_it_bootdev "${BE_BOOT_DEVICE}" "${dom_mntpt}"
      if [ "$?" -eq "0" ] ; then
	echo "${BE_BOOT_DEVICE}"
	return 0
      fi
    fi
  fi

  echo "`gettext 'Unable to determine boot environment name for mount point: '`""<${dom_mntpt}>" >&2
  return 1
}

#################################################################################################
# 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.
#################################################################################################

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

initRunLevel="`LANG=C LC_ALL=C /bin/who -r | /bin/awk '{print $3; exit 0}'`"
if [ -z "${initRunLevel}" ] ; then
  initRunlevel="`LANG=C LC_ALL=C /bin/who -a | /bin/awk '{if ($2 == \"run-level\") {print $3; exit 0}}'`"
fi
if [ "${initRunLevel}" = "S" -o "${initRunLevel}" = "s" -o "${initRunLevel}" = "1" ] ; then
  # We are in maintenance mode: do minimal operations.
  # Reset all command line parse flags to default values.
  flag_m="" # -m n - alternative BE mount point to look up boot device of (assumes '/')

  while getopts m: c
  do
    case $c in
      m) # -m n - BE mount point to find current BE name from.
	 # If the argument is a null string, then ignore the flag - makes scripting easier (e.g. -m "" instead of testing for "" in calling script)
	 if [ -n "${OPTARG}" ] ; then
	   flag_m="$OPTARG"
	 fi
	 ;;
      \?) # unknown - option: ignore.
	  ;;
    esac
  done

  LU_OUTPUT_FORMAT_OVERRIDE='text'
  export LU_OUTPUT_FORMAT_OVERRIDE
  LU_OUTPUT_FORMAT='text'
  export LU_OUTPUT_FORMAT

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

  LUPRINTF='echo'

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

  # Invoke single user mode functionality.

  do_oos_mode "${flag_m}"
  exit "$?"
fi

# Dot the defaults file.

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

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

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

# Dot the Live Upgrade library functions.

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

. $LUBIN/lulib

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

# Reset all command line parse flags to default values.
flag_C="" # -C - confirm boot device selection if chosen from boot prom.
flag_l="" # -l f - log file path.
flag_m="" # -m n - alternative BE mount point to look up boot device of (assumes '/')
flag_o="" # -o f - output file path.
flag_x="" # -x n - set debug level to n (PRIVATE).

while [ $# -ne 0 ] ; do
  while getopts Cl:m:o:x:X c
  do
    case $c in
      C) # -C - confirm boot device selection if chosen from boot prom.
	 flag_C="yes"
	 ;;
      l) # -l f - error log file path.
	 # This overrides the LU_ERROR_LOG_FILE setting read from /etc/default/lu
	 lulib_cannot_duplicate_option "${flag_l}" "${OPTARG}" "-l"
	 ${LUPRINTF} -lp2D - "`gettext 'Verifying that the error log file <%s> specified can be created and appended to.'`" "${OPTARG}"
	 ERRMSG="`${LUPRINTF} -c \"${OPTARG}\" 2>&1`"
	 if [ $? -ne 0 ] ; then
	   [ -n "${ERRMSG}" ] && ${LUPRINTF} -elp2 '%s' "${ERRMSG}"
	   ${LUPRINTF} -Eelp2 "`gettext 'Argument <%s> to -l option may not be created or appended to.'`" "${OPTARG}"
	   exit 3
	 fi
	 flag_l="${OPTARG}"
	 lulib_set_error_log_file "${flag_l}"
	 ;;
      o) # -o f - output file path.
	 # This overrides the LU_SESSION_LOG_FILE setting read from /etc/default/lu
	 lulib_cannot_duplicate_option "${flag_o}" "${OPTARG}" "-o"
	 ${LUPRINTF} -lp2D - "`gettext 'Verifying that the session log file <%s> can be created and appended to.'`" "${OPTARG}"
	 ERRMSG="`${LUPRINTF} -c \"${OPTARG}\" 2>&1`"
	 if [ $? -ne 0 ] ; then
	   [ -n "${ERRMSG}" ] && ${LUPRINTF} -elp2 '%s' "${ERRMSG}"
	   ${LUPRINTF} -Eelp2 "`gettext 'Argument <%s> to -o option may not be created or appended to.'`" "${OPTARG}"
	   exit 3
	 fi
	 flag_o="${OPTARG}"
	 lulib_set_session_log_file "${flag_o}"
	 ;;
      m) # -m n - alternative BE mount point to look up boot device of (assumes '/')
	 # If the argument is a null string, then ignore the flag - makes scripting easier (e.g. -m "" instead of testing for "" in calling script)
	 if [ -n "${OPTARG}" ] ; then
	   lulib_cannot_duplicate_option "${flag_m}" "${OPTARG}" "-m"
	   if [ ! -r "${OPTARG}" ] ; then
	     ${LUPRINTF} -Eelp2 "`gettext 'The mount point <%s> provided by the <-m> option is not valid (not mounted, not readable).'`" "${OPTARG}"
	     usage 3
	   fi
	   lulib_validate_bemntpt "${OPTARG}"
	   if [ "$?" -ne "0" ] ; then
	     ${LUPRINTF} -Eelp2 "`gettext 'The mount point <%s> provided by the <-m> option is not a valid ABE mount point.'`" "${OPTARG}"
	     usage 3
	   fi
	   flag_m="$OPTARG"
	 fi
	 ;;
      x) # -x n - set debug level to n (PRIVATE).
	 # This overrides the default setting read from /etc/default/lu
	 lulib_cannot_duplicate_option "${flag_x}" "${OPTARG}" "-x"
	 /bin/test "${OPTARG}" -ge 0 2>/dev/null
	 if [ $? -gt 1 ] ; then
	   ${LUPRINTF} -Eelp2 "`gettext 'Argument <%s> to -x option is not a number.'`" "${OPTARG}"
	   usage 3
	 fi
	 flag_x="${OPTARG}"
	 lulib_set_debug "${flag_x}"
	 ;;
      X) # -X - set XML output mode.
	  lulib_set_output_format 'xml'
	  ;;
      \?) # unknown - option.
	  usage 3
    esac
  done

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

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

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

# If any command line arguments provided, exit with error.
if [ "$#" -ne "0" ] ; then
  ${LUPRINTF} -Eelp2 "`gettext 'Command line arguments <%s> not allowed.'`" "$*"
  usage 3
fi

# Determine the status of SDS

lulib_discover_sds_installation
SDS_DEVROOT=${SDS_DEVROOT:="/dev/md"}

# Default mount point to "/" if not specified via -m option
mntpt="${flag_m:=/}"

# Attempt to determine the root specification using devnm; if that fails,
# attempt to find the root spec from the vfstab file.

ROOT_SPEC="`/usr/sbin/devnm ${mntpt} 2>/dev/null | awk ' { print $1 } '`"
[ -n "${ROOT_SPEC}" ] && ${LUPRINTF} -lp2D - "`gettext 'Candidate boot device \
for mount point <%s> is <%s> [from <%s>].'`" "${mntpt}" "${ROOT_SPEC}" \
"/usr/sbin/devnm ${mntpt}"

#
# if the mountpoint is zfs then get the boot device direct from zfs
#

# get the file system type from df
dfnout="`/usr/sbin/df -n ${mntpt} 2>&1`"
if [ "$?" -eq 0 ] ; then
    mntfstyp="`echo ${dfnout} | /bin/sed 's/.*:[ ]*//'`"
    if [ "$mntfstyp" = "zfs" ] ; then
	poolnm=`echo "${ROOT_SPEC}" | /bin/nawk -F/ '{ print $1 }'`
	ZFS_ROOT_SPEC=`lulib_get_zfs_root_boot_device $poolnm`
	${LUPRINTF} -lp2D -  \
	    "`gettext 'Boot device for mount point <%s> is <%s>.'`" \
	    "${mntpt}" "${ZFS_ROOT_SPEC}"
	echo "${ZFS_ROOT_SPEC}"
	exit 0
    fi
fi

if [ -z "${ROOT_SPEC}" -a -r "${mntpt}/etc/vfstab" ] ; then
  ROOT_SPEC=`$LUBIN/lucomm_del "${mntpt}/etc/vfstab" | awk ' { if ( $3 == "/" ) { print $1; exit 0 } } '`
  [ -n "${ROOT_SPEC}" ] && ${LUPRINTF} -lp2D - "`gettext 'Candidate boot device \
for mount point <%s> is <%s> [from <%s>].'`" "${mntpt}" "${ROOT_SPEC}" "${mntpt}/etc/vfstab"
fi

if [ -n "${ROOT_SPEC}" ] ; then
  is_it_bootdev "${ROOT_SPEC}" "${mntpt}"
  if [ "$?" -eq "0" ] ; then
    ${LUPRINTF} -lp2D - "`gettext 'Boot device for mount point <%s> is <%s>.'`" \
"${mntpt}" "${ROOT_SPEC}"
    echo "${ROOT_SPEC}"
    exit 0
  fi
fi

# See if the boot device can be obtained from the lutab file.
BE_BOOT_DEV=`${LUETCBIN}/ludo get_boot_device_from_mntpt "${mntpt}" 2>/dev/null`
if [ "$?" -eq 0 -a -n "${BE_BOOT_DEV}" ] ; then
  ${LUPRINTF} -lp2D - "`gettext 'Candidate boot device for mount point <%s> is \
<%s> [from <%s>].'`" "${mntpt}" "${BE_BOOT_DEV}" \
"${LUETCBIN}/ludo get_boot_device_from_mntpt ${mntpt}"
  [ -z "${ROOT_SPEC}" ] && ROOT_SPEC="${BE_BOOT_DEV}"
  if [ -b "${BE_BOOT_DEV}" ] ; then
    is_it_bootdev "${BE_BOOT_DEV}" "${mntpt}"
    if [ "$?" -eq "0" ] ; then
      ${LUPRINTF} -lp2D - "`gettext 'Boot device for mount point <%s> is <%s>.'`" \
"${mntpt}" "${BE_BOOT_DEV}"
	echo "${BE_BOOT_DEV}"
	exit 0
    else
      ${LUPRINTF} -Wlp2D - "`gettext 'Boot device <%s> for mount point <%s> from \
<%s> is not a valid boot device.'`" "${BE_BOOT_DEV}" "${mntpt}" \
"${LUETCBIN}/ludo get_boot_device_from_mntpt ${mntpt}"
    fi
  else
    ${LUPRINTF} -Wlp2D - "`gettext 'Boot device <%s> for mount point <%s> from \
<%s> is not a block device.'`" "${BE_BOOT_DEV}" "${mntpt}" \
"${LUETCBIN}/ludo get_boot_device_from_mntpt ${mntpt}"
  fi
else
  ${LUPRINTF} -Wlp2D - "`gettext 'Boot device for mount point <%s> not found \
from <%s>.'`" "${mntpt}" "${LUETCBIN}/ludo get_boot_device_from_mntpt ${mntpt}"
fi

# see if the target BE contains a BE configuration file and if so look
# for the ROOT_SLICE entry.

if [ -f "${mntpt}/${LU_BE_CONFIG_FILE}" ] ; then
  BE_BOOT_DEV=`/bin/grep "^LUBECF_BE_BOOT_DEVICE=" "${mntpt}/${LU_BE_CONFIG_FILE}" | /bin/cut -d'=' -f2`
  if [ -n "${BE_BOOT_DEV}" ] ; then
    ${LUPRINTF} -lp2D - "`gettext 'Candidate boot device for mount point <%s> \
is <%s> [from <%s>].'`" "${mntpt}" "${BE_BOOT_DEV}" "${mntpt}/${LU_BE_CONFIG_FILE}"
      [ -z "${ROOT_SPEC}" ] && ROOT_SPEC="${BE_BOOT_DEV}"
      if [ -b "${BE_BOOT_DEV}" ] ; then
	is_it_bootdev "${BE_BOOT_DEV}" "${mntpt}"
	if [ "$?" -eq "0" ] ; then
	  ${LUPRINTF} -lp2D - "`gettext 'Boot device for mount point <%s> is <%s>.'`" \
"${mntpt}" "${BE_BOOT_DEV}"
	    echo "${BE_BOOT_DEV}"
	    exit 0
	else
	  ${LUPRINTF} -Wlp2D - "`gettext 'Boot device <%s> for mount point <%s> from \
<%s> is not a valid boot device.'`" "${BE_BOOT_DEV}" "${mntpt}" "${mntpt}/${LU_BE_CONFIG_FILE}"
	fi
      else
	${LUPRINTF} -Wlp2D - "`gettext 'Boot device <%s> for mount point <%s> from <%s> \
is not a block device.'`" "${BE_BOOT_DEV}" "${mntpt}" "${mntpt}/${LU_BE_CONFIG_FILE}"
      fi
      ${LUPRINTF} -Wlp2D - "`gettext 'Boot device for mount point <%s> not found \
in BE configuration file <%s>.'`" "${mntpt}" "${mntpt}/${LU_BE_CONFIG_FILE}"
  fi
else
  ${LUPRINTF} -lp2D - "`gettext 'BE configuration file <%s> not found.'`" \
"${mntpt}/${LU_BE_CONFIG_FILE}"
fi

# Any root specification discovered so far is not a device node and the boot
# device for the specified mount point could not be found "the easy
# way". If it is an encapsulated root spec (for example, either a
# SVM metadevice or a Veritas Logical Volume), then
# attempt to obtain the current system boot device and see if that is
# the physical device for the currently running system root file
# system.

if [ -n "${ROOT_SPEC}" ] ; then
  echo "${ROOT_SPEC}" | egrep "^${SDS_DEVROOT}/dsk/|^/dev/vx/dsk/" > /dev/null 2>&1
  if [ "$?" -eq "0" -a "${mntpt}" = "/" ] ; then
    ${LUPRINTF} -lp2D - "`gettext 'Boot device <%s> for mount point <%s> is \
logical device: attempting to obtain real boot device from boot prom.'`" \
"${ROOT_SPEC}" "${mntpt}"

    # First attempt to get the device from lubootdev.

    ROOT_SPEC1="`/etc/lib/lu/lubootdev -b 2>&1`"
    if [ "$?" -eq "0" -a -n "${ROOT_SPEC1}" ] ; then
      is_it_bootdev "${ROOT_SPEC1}" "${mntpt}"
      if [ "$?" -eq "0" ] ; then
	# Got the name from the prom...
	${LUPRINTF} -lp2D - "`gettext 'Boot device for mount point <%s> is <%s>.'`" \
"${mntpt}" "${ROOT_SPEC1}"
	${LUPRINTF} -Wlp2 "`gettext 'The device <%s> for the root file system \
mount point <%s> is not a physical device.'`" "${ROOT_SPEC}" "${mntpt}"
	${LUPRINTF} -Wlp2 "`gettext 'The system boot prom identifies the physical \
device <%s> as the system boot device.'`" "${ROOT_SPEC1}"
	confirm_selection "${ROOT_SPEC}" "${ROOT_SPEC1}" "${flag_C}"
	if [ "$?" -eq "0" ] ; then
	  ${LUPRINTF} -Ilp2 "`gettext 'Assuming the boot device <%s> obtained from \
the system boot prom is the physical boot device for logical device <%s>.'`" \
"${ROOT_SPEC1}" "${ROOT_SPEC}"
	  echo "${ROOT_SPEC1}"
	  exit 0
	fi
      else
	${LUPRINTF} -Wlp2 "`gettext 'Unable to determine boot device directly \
from boot prom; attempting to access boot device settings directly.'`"
      fi
    else
      ${LUPRINTF} -Wlp2 '%s' "${ROOT_SPEC1}"
      ${LUPRINTF} -Wlp2 "`gettext 'Unable to obtain boot device directly from \
boot prom; attempting to access boot device settings directly.'`"
    fi

    # Next, attempt to use eeprom setting to determine real boot device.

    ROOT_SPEC1="`/usr/sbin/eeprom bootpath | cut -c10- | awk ' { print $1 } '`"
    # Some systems (like sparcs, may have boot-device and not bootpath
    if [ ! -b "${mntpt}/devices/${ROOT_SPEC1}" ] ; then
      ROOT_SPEC1="`/usr/sbin/eeprom boot-device | cut -c13- | awk ' { print $1 } '`"
      # In maint mode (OOS fallback), eeprom on x86 fails
      # so bootpath must be taken directly from the bootenv.rc file.
      if [ ! -b "${mntpt}/devices/${ROOT_SPEC1}" ] ; then
	bootenv="${mntpt}/platform/`uname -i`/boot/solaris/bootenv.rc"
	if [ -f "${bootenv}" ] ; then
	  ROOT_SPEC1=`grep "^setprop bootpath" ${bootenv} 2>/dev/null | awk ' { print $3 } '`
	fi
      fi
    fi

    # If a device was discovered from the eeprom, validate it.

    if [ -n "${ROOT_SPEC1}" ] ; then
      ${LUPRINTF} -lp2D - "`gettext 'Boot device <%s> for mount point <%s> is boot device <%s>.'`" "${ROOT_SPEC}" "${mntpt}" "${ROOT_SPEC1}"
      ROOT_SPEC2="${ROOT_SPEC}"
      ROOT_SPEC=`ls -l ${mntpt}/dev/dsk | grep "${ROOT_SPEC1}\$" 2>/dev/null | cut -c55- | awk ' { print $1 ; exit 0 } '`
      if [ -n "${ROOT_SPEC}" ] ; then
	${LUPRINTF} -lp2D - "`gettext 'Boot device <%s> is device node <%s>.'`" "${ROOT_SPEC1}" "${ROOT_SPEC}"
	ROOT_SPEC="/dev/dsk/${ROOT_SPEC}"
	is_it_bootdev "${ROOT_SPEC}" "${mntpt}"
	if [ "$?" -eq "0" ] ; then
	  confirm_selection "${ROOT_SPEC2}" "${ROOT_SPEC}" "${flag_C}"
	  if [ "$?" -eq "0" ] ; then
	    ${LUPRINTF} -lp2D - "`gettext 'Boot device for mount point <%s> is <%s>.'`" "${mntpt}" "${ROOT_SPEC}"
	    echo "${ROOT_SPEC}"
	    exit 0
	  fi
	fi
      else
	${LUPRINTF} -Wlp2 "`gettext 'Unable to determine boot device by accessing boot device settings directly.'`"
      fi
    else
      ${LUPRINTF} -Wlp2 "`gettext 'Unable to obtain boot device by accessing boot device settings directly.'`"
    fi
  fi
fi

# Unable to discover the boot device directly, "the easy way", from
# interrogating the boot prom, or by directly accessing the boot prom
# settings. If a root specification was discovered, attempt to find the real
# physical device by looking up the major/minor device number in the
# devices tree.

if [ -n "${ROOT_SPEC}" ] ; then
  # Get a device node with the same major and minor numbers that is in the correct
  # format.
  
  MAJOR=`find ${ROOT_SPEC} -follow -ls 2>/dev/null | awk -F, '{print $1; exit 0}' | awk '{print $7; exit 0}'`
  MINOR=`find ${ROOT_SPEC} -follow -ls 2>/dev/null | awk -F, '{print $2; exit 0}' | awk '{print $1; exit 0}'`
  if [ -z "${MAJOR}" -o -z "${MINOR}" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine major and minor device numbers for boot device <%s>.'`" "${ROOT_SPEC}"
    exit 1
  fi
  ${LUPRINTF} -lp2D - "`gettext 'Attempting to find device node for boot device <%s> major <%s> minor <%s>.'`" "${ROOT_SPEC}" "${MAJOR}" "${MINOR}"
  
  ROOT_SPEC=`find /dev/dsk -follow -name "[cv]*" -ls | \
      grep "[ 	]*$MAJOR,[ 	]*$MINOR " 2>/dev/null | head -1 | \
      awk -F/ '{
  		for (i=2; i<=NF; i++) printf("/%s",$i);
  	     }
  	     END { printf("\n"); }' `
fi

# If the boot device has not been found, issue error message and exit
# with failure return code.

if [ -z "${ROOT_SPEC}" -o ! -b "${ROOT_SPEC}" ] ; then
  if [ "${mntpt}" = "/" ] ; then
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine boot device for current BE.'`"
  else
    ${LUPRINTF} -Eelp2 "`gettext 'Unable to determine boot device for BE mounted at <%s>.'`" "${mntpt}"
  fi
  exit 1
fi

${LUPRINTF} -lp2D - "`gettext 'Boot device for mount point <%s> is <%s>.'`" "${mntpt}" "${ROOT_SPEC}"
echo "${ROOT_SPEC}"
exit 0
