#!/bin/ksh

# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.

# Definitions for override safety mechanism
PATCH_OVERRIDE_LIB="${ROOTDIR}/usr/lib/patch/patch_override_lib"


# script in a fucntion so that it can be overridden if needed.
postpatch()
{
PATH="/usr/bin:/usr/sbin:${PATH}"; export PATH
PKGCOND=/usr/bin/pkgcond
ARCH=`uname -p`

is_pcfs_boot=yes
is_zfs_boot=no

check_pcfs_boot()
{
	bootdev=`grep -v "^#" "${ROOTDIR}/etc/vfstab" | grep pcfs \
		| grep "[ 	]/stubboot[ 	]" | nawk '{print $1}'`
	if [ X"$bootdev" = "X" ]; then
		is_pcfs_boot=no
	fi
}

check_zfs_boot()
{
	if [ -f "${ROOTDIR}/etc/lu/GRUB_slice" ]; then
		dev=`grep '^PHYS_SLICE=' "${ROOTDIR}/etc/lu/GRUB_slice" | \
			cut -d= -f2`
		if [ "`fstyp $dev`" = "zfs" ]; then
			is_zfs_boot=yes
		fi
	else
		rootfstype=`df -n ${ROOTDIR:-/} | awk '{print $3}'`
		if [ "$rootfstype" = "zfs" ]; then
			is_zfs_boot=yes
		fi
			
	fi
}

#
# Detect SVM root and return the list of raw devices under the mirror
#
get_rootdev_list()
{
	if [ -f "${ROOTDIR}/etc/lu/GRUB_slice" ]; then
		dev=`grep '^PHYS_SLICE' "${ROOTDIR}/etc/lu/GRUB_slice" | \
			cut -d= -f2`
		if [ "$is_zfs_boot" = "yes" ]; then
			fstyp -a "$dev" | grep 'path: ' | grep -v phys_path: | \
				cut -d"'" -f2 | sed 's+/dsk/+/rdsk/+'
		else
			echo "$dev"
		fi
		return
	elif [ "$is_zfs_boot" = "yes" ]; then
		rootpool=`df -k ${ROOTDIR:-/} | tail +2 | cut -d/ -f1`
		rootdevlist=`zpool iostat -v "$rootpool" | tail +5 | \
			grep -v mirror | sed -n -e '/--/q' -e p | awk '{print $1}'`
	else
		metadev=`grep -v "^#" "${ROOTDIR}/etc/vfstab" | \
			grep "[	 ]/[ 	]" | nawk '{print $2}'`
		if [[ $metadev = /dev/rdsk/* ]]; then
			rootdevlist=`echo "$metadev" | sed -e "s#/dev/rdsk/##"`
		elif [[ $metadev = /dev/md/rdsk/* ]]; then
			metavol=`echo "$metadev" | sed -e "s#/dev/md/rdsk/##"`
			rootdevlist=`metastat -p $metavol | \
				grep -v "^$metavol[	 ]" | nawk '{print $4}'`
		fi
	fi
	for rootdev in $rootdevlist
	do
		echo /dev/rdsk/$rootdev
	done
}

#
# multiboot: install grub on the boot slice
#
install_grub()
{
	# Stage 2 blocks must remain untouched
	STAGE1="${ROOTDIR}/boot/grub/stage1"
	STAGE2="${ROOTDIR}/boot/grub/stage2"

	if [ $is_pcfs_boot = yes ]; then
		#
		# Note: /stubboot/boot/grub/stage2 must stay untouched.
		#
		mkdir -p "${ROOTDIR}/stubboot/boot/grub"
		cp "${ROOTDIR}/boot/grub/menu.lst" "${ROOTDIR}/stubboot/boot/grub"
		bootdev=`grep -v "^#" "${ROOTDIR}/etc/vfstab" | grep pcfs | \
			grep "[	 ]/stubboot[ 	]" | nawk '{print $1}'`
		rpcfsdev=`echo "$bootdev" | sed -e "s/dev\/dsk/dev\/rdsk/"`
		if [ X"$rpcfsdev" != X ]; then
			print "Installing grub on $rpcfsdev"
			"${ROOTDIR}/sbin/installgrub" $STAGE1 $STAGE2 $rpcfsdev
		fi
	fi

	grubdevlist=`get_rootdev_list`
	zfsarg=""
	if [ "$is_zfs_boot" = "yes" ]; then
		zfsarg="-Z"
	fi

	for rootdev in $grubdevlist
	do
		if [ X"$rpcfsdev" != X ]; then
			echo "Creating GRUB menu in ${MENUDIR}/stubboot"
			"${ROOTDIR}/sbin/bootadm" update-menu $zfsarg \
				-R "${MENUDIR}/stubboot" \
				-o "$rootdev,${MENUDIR}" 2>/dev/null
		else
			echo "Creating GRUB menu in ${MENUDIR:-/}"
			"${ROOTDIR}/sbin/bootadm" update-menu -R "${MENUDIR:-/}" \
				$zfsarg -o $rootdev 2>/dev/null
		fi
		print "Installing grub on $rootdev"
		"${ROOTDIR}/sbin/installgrub" $STAGE1 $STAGE2 $rootdev
	done
}

update_failsafe()
{
	cp -f $patchdir/failsafe_archive "${ROOTDIR}/boot/x86.miniroot-safe"
}

ExecuteALLCmds()
{
if [ "$SAFEMODE_INSTALL" = "true" ] ; then
	PATCH_COMMON_LIB="/usr/lib/patch/patch_common_lib"
	. $PATCH_COMMON_LIB
	InitSafemode
	cp $patchdir/bootadm $SAFEMODE_OVERLAY_DIR/sbin/bootadm
	MENUDIR="/"
else
	MENUDIR="${ROOTDIR}"
fi

if [ -f "${MENUDIR}/platform/i86pc/multiboot" -a "$ARCH" = i386 ] ; then
	check_pcfs_boot
	check_zfs_boot
	install_grub
fi
update_failsafe

return 0
}

determine_pkgcond () {

  if $PKGCOND  is_whole_root_nonglobal_zone > /dev/null 2>&1 ; then
      # Execute non-global whole root zone commands.
      return 0
  fi

  if $PKGCOND  is_nonglobal_zone > /dev/null 2>&1 ; then
      # Execute non-global zone commands. Should be no action here
      return 0
  fi

  if $PKGCOND is_netinstall_image > /dev/null 2>&1 ; then
      # Execute commands applicable to patching the mini-root.
      # There are usually no actions to take here since your patching
      # the mini-root on an install server.
      return 0
  fi

  if $PKGCOND is_mounted_miniroot > /dev/null 2>&1 ; then
      # Execute commands specific to the mini-root
      return 0
  fi

  if $PKGCOND is_diskless_client > /dev/null 2>&1 ; then
      # Execute commands specific to diskless client
      return 0
  fi
  if $PKGCOND is_alternative_root > /dev/null 2>&1 ; then
      # Execute commands specific to an alternate root
      ExecuteALLCmds
      return 0
  fi

  if $PKGCOND is_global_zone > /dev/null 2>&1 ; then
      # In a global zone and system is mounted on /.
      # Execute all commands.
      ExecuteALLCmds
      return 0
  fi
     return 1

}

#as we already require patches that require 119254-51 we already have pkgcond
determine_pkgcond || exit 1
}

# load the override lib if it exists
[ -f "${PATCH_OVERRIDE_LIB}" ] && . "${PATCH_OVERRIDE_LIB}"

# execute the script function
postpatch "$@"


exit 0
