#!/bin/ksh
#
# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#
#pragma ident	"@(#)install-finish.sh	1.5	06/06/13 SMI"
#
# This script is run by libspmisvc at the completion of
# install/upgrade. It replaces the original inst9.sh which
# applied driver updates to the target OS. The syntax is
#
#	install-finish <rootdir> <install_type>
#
# With multiboot, we do additional work to create boot
# archive and copy failsafe archive and a few odds and ends.
#

BASEDIR=$1
INSTALL_TYPE=$2
BOOTENVRC=${BASEDIR}/boot/solaris/bootenv.rc
GRUBMENU=${BASEDIR}/boot/grub/menu.lst
ALTGRUBMENU=${BASEDIR}/stubboot/boot/grub/menu.lst

set_boot_active()
{
	RAW_SLICE="$1"

	TMP1=/tmp/.set_active.1.$$
	TMP2=/tmp/.set_active.2.$$

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

	/sbin/fdisk -W "$TMP1" "$P0"
	/bin/grep -v \* "$TMP1" | /bin/grep -v '^[	 ]*$' > "$TMP2"
	/bin/rm -f "$TMP1"

	# make sure there is a Solaris partition before doing anything
	#
	/bin/awk '{
		if ( $1 == "130" ) exit 10
		else if ( $1 == "191" ) exit 10
	    } ' "$TMP2"
	if [ $? != 10 ] ; then
		/bin/rm -f "$TMP2"
		return 0
	fi

	# if there is a Solaris2 partition, set it active, otherwise
	# set the Solaris (130 aka Linux swap active)
	#
	/bin/awk '{ print $1 }' "$TMP2" | /bin/grep 191 > /dev/null
	if [ $? = 0 ] ; then
		/bin/awk '{
			if ( $1 == "191" )
				printf "%s 128 %s %s %s %s %s %s %s %s\n", $1, \
				    $3, $4, $5, $6, $7, $8, $9, $10
				else printf "%s 0 %s %s %s %s %s %s %s %s\n", \
				    $1, $3, $4, $5, $6, $7, $8, $9, $10
		    }' "$TMP2" > "$TMP1"
	else
		/bin/awk '{
			if ( $1 == "130" )
				printf "%s 128 %s %s %s %s %s %s %s %s\n", $1, \
				    $3, $4, $5, $6, $7, $8, $9, $10
				else printf "%s 0 %s %s %s %s %s %s %s %s\n", \
				    $1, $3, $4, $5, $6, $7, $8, $9, $10
		    }' "$TMP2" > "$TMP1"
	fi

	/sbin/fdisk -F "$TMP1" "$P0"

	/bin/rm -f "$TMP1"
	/bin/rm -f "$TMP2"
}

add_failsafe_menu()
{
	RDSK="$1"
	bootadm update-menu -R ${BASEDIR} -o $RDSK

	# Check and update menu.lst in /stubboot
	#
	if [ -n "$ENT" ]; then
		bootadm update-menu -R ${BASEDIR}/stubboot -o $RDSK,${BASEDIR}
	fi
}

# fix the failsafe menu to redirect console to tty.
fix_failsafe_menu()
{
	MENUFILE="$1"

	# if console already set, don't touch it
	/bin/grep "/boot/multiboot kernel/unix -s -B console=" ${MENUFILE} \
		> /dev/null 2>&1
	if [ "$?" -eq 0 ]; then
		return
	fi

	case "$osconsole" in
	tty[ab])
		sed "s#/boot/multiboot kernel/unix -s#/boot/multiboot kernel/unix -s -B console=${osconsole}#" \
		    ${MENUFILE} > ${MENUFILE}.new
		cat ${MENUFILE}.new > ${MENUFILE}
		rm ${MENUFILE}.new
		;;
	esac
}

# bootpath may not be present in bootenv.rc after installing S10 FCS.
# Fix it here so system boots correctly following an upgrade
fix_bootpath()
{
	grep "^setprop[	 ]\{1,\}bootpath" $BOOTENVRC > /dev/null
	if [ $? = 0 ]; then
		return
	fi

	rootdev=`grep -v "^#" $BASEDIR/etc/vfstab | \
	    grep "[ 	]/[ 	]" | nawk '{print $1}'`
	bootpath=`/bin/ls -l $BASEDIR/$rootdev | nawk '{ print $11 }' |\
	    sed -e 's#[./]*/devices/#/#'`
	echo "setprop bootpath $bootpath" >> $BOOTENVRC
}

# since the root device might be a metadevice, all the components need to
# be located so each can be operated upon individually
#
get_rootdev_list()
{
	metadev=`grep -v "^#" $BASEDIR/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
	for rootdev in $rootdevlist ; do
		echo /dev/rdsk/$rootdev
	done
}


# apply driver updates
/sbin/install-du ${BASEDIR}

# If not multiboot based, bail now. We can be applying an
# old flasharchive.
[ -f ${BASEDIR}/platform/i86pc/multiboot ] || exit 0

# Compensate for missing gzip until SUNWgzip is moved to
# the core metacluster
if [ ! -f ${BASEDIR}/usr/bin/gzip ] ; then
	cp /usr/bin/gzip ${BASEDIR}/usr/bin
fi

# if keyboard type was set to something other than US-English,
# propagate it to the installed system
kbdtype=`eeprom kbd-type | cut -f 2 -d =`
if [ "$kbdtype" != "US-English" ] ; then
	grep -v "setprop kbd-type" ${BASEDIR}/boot/solaris/bootenv.rc > \
	    /tmp/bootenv$$
	echo "setprop kbd-type '$kbdtype'" >> /tmp/bootenv$$
	mv /tmp/bootenv$$ ${BASEDIR}/boot/solaris/bootenv.rc
fi

# delete input-device/output-device/console from bootenv.rc for flash install
if [ "$INSTALL_TYPE" = "flash_install" ] ; then
	grep -v "^setprop input-device" ${BASEDIR}/boot/solaris/bootenv.rc | \
		grep -v "^setprop output-device" | \
		grep -v "^setprop console" > /tmp/bootenv.rc.$$
	cp /tmp/bootenv.rc.$$ ${BASEDIR}/boot/solaris/bootenv.rc
	rm /tmp/bootenv.rc.$$
fi


# add console device if not already there
osconsole=`awk '/^setprop output-device/ {print $3}' ${BOOTENVRC} | \
    tr -d "'\""`
if [ -z "${osconsole}" ]; then
	osconsole=`awk '/^setprop console/ {print $3}' ${BOOTENVRC} | \
	    tr -d "'\""`
fi

# If osconsole is not set (fresh install), we set it here based on
# what the current console device is.
if [ -z "${osconsole}" ]; then

	# this following line is different from the ones above in 
	# that is parses prtconf output and not bootenv.rc the
	# trailing massage should not match the above lines
	osconsole=`prtconf -v /devices | sed -n '/console/{n;p;}' | \
	    cut -f 2 -d \'`
	if [ -z "${osconsole}" ]; then
		osconsole=`prtconf -v /devices | \
		    sed -n '/output-device/{n;p;}' | cut -f 2 -d \'`
		[ "$osconsole" = "screen" ] && osconsole=text
	fi
	# default console to text
	: ${osconsole:=text}
	# put it in bootenv.rc
	echo "setprop console '$osconsole'" >> $BOOTENVRC
fi

# Now, turn on splashimage if osconsole is "text" or "screen"
case "$osconsole" in
text|screen)
	sed "s/^#[ 	]*splashimage/splashimage/" ${GRUBMENU} \
	    > ${GRUBMENU}.new
	cat ${GRUBMENU}.new > ${GRUBMENU}
	rm ${GRUBMENU}.new
	;;
esac

# check for an x86 stub boot partition and if it exists, move it 
# to /stubboot taking care to copy the stuff we still need to /boot
ENT=`grep ":boot[	 ]\{1,\}${BASEDIR}/boot[	 ]" /etc/mnttab`
if [ ! -z "$ENT" ] ; then
	DEV=`echo $ENT | awk '{print $1}'`
	umount ${BASEDIR}/boot
	mkdir ${BASEDIR}/stubboot
	mount -F pcfs $DEV ${BASEDIR}/stubboot

	# Use tar so symlinks, if any, are copied as symlinks.
	(
	    cd ${BASEDIR}/stubboot
	    tar cf - acpi grub solaris.xpm solaris
	) | (cd ${BASEDIR}/boot; tar xpf -)

	sed 's#[	 ]/boot[	 ]#	/stubboot	#' \
	    ${BASEDIR}/etc/vfstab > ${BASEDIR}/etc/vfstab.new
	mv ${BASEDIR}/etc/vfstab.new ${BASEDIR}/etc/vfstab
fi

# copy miniroot archive to the system
cp /cdrom/boot/x86.miniroot ${BASEDIR}/boot/x86.miniroot-safe
cp /cdrom/boot/multiboot ${BASEDIR}/boot

# set the Solaris partition on the just installed drive to active
#
get_rootdev_list | while read rootdev ; do
	set_boot_active $rootdev
	add_failsafe_menu $rootdev
done

# add bootpath to bootenv.rc if not already present
fix_bootpath

fix_failsafe_menu ${GRUBMENU}
if [ -n "$ENT" ]; then
	fix_failsafe_menu ${ALTGRUBMENU}
fi

# add entries for other installed OS's to the grub menu
mkmenu ${GRUBMENU}

# create boot archive and remove filestat to skip archive check
/sbin/bootadm update-archive -R ${BASEDIR}
rm -f ${BASEDIR}/boot/solaris/filestat.ramdisk
