#!/bin/ksh # # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #pragma ident "@(#)install-finish.sh 1.10 08/09/24 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 # # 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 LOCGRUBMENU=/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" if [ "$rootfstype" = "zfs" ] ; then bootadm update-menu -R $BASEDIR -Z -o $RDSK else bootadm update-menu -R ${BASEDIR} -o $RDSK fi # 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() { if [[ "$rootfstype" = "zfs" ]] ; then cat > /tmp/pooldev.$$ << EOF BEGIN {poolstart = 0} \$1 == poolname {poolstart = 1} /^ / {if (poolstart == 1 && \$1 != "mirror") print "/dev/rdsk/" \$1} EOF zpool iostat -v $rootpool | \ nawk -f /tmp/pooldev.$$ -v poolname=$rootpool rm -f /tmp/pooldev.$$ return fi metadev=$(nawk -v b="$BASEDIR" '$2 == b {print $1}' /etc/mnttab) if [[ $metadev = /dev/dsk/* ]] ; then rootdevlist=`echo "$metadev" | sed -e "s#/dev/dsk/##"` elif [[ $metadev = /dev/md/dsk/* ]] ; then metavol=`echo "$metadev" | sed -e "s#/dev/md/dsk/##"` 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 -t ${BASEDIR} # If not multiboot/newboot based, bail now. We can be applying an # old flasharchive. Mach=`uname -m` Platform=`uname -p` [ -f $BASEDIR/platform/i86pc/multiboot -o \ "$Platform" = "sparc" -a -d $BASEDIR/boot/solaris ] || exit 0 rootfstype=`grep "^[^ ]* $BASEDIR " /etc/mnttab | \ nawk '{print $3}'` if [ "$rootfstype" = "zfs" ] ; then rootpool=`grep "^[^ ]* $BASEDIR " /etc/mnttab | \ nawk '{print $1}' | sed 's,/.*,,'` GRUBMENU=$BASEDIR/${rootpool}/${LOCGRUBMENU} else GRUBMENU=$BASEDIR/${LOCGRUBMENU} fi if [ "$Mach" = "i86pc" ] ; then # Propagate the keyboard layout info to the installed system. kbdlayout=`eeprom keyboard-layout | cut -f 2 -d =` if [ -n "$kbdlayout" ] ; then grep -v "setprop keyboard-layout" $BOOTENVRC > $BOOTENVRC.new echo "setprop keyboard-layout '$kbdlayout'" >> $BOOTENVRC.new cat $BOOTENVRC.new > $BOOTENVRC rm $BOOTENVRC.new 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 ( cd ${BASEDIR}/stubboot find acpi grub solaris solaris.xpm | \ cpio -pdum $BASEDIR/boot ) # Since /stubboot (the old /boot) is a PCFS, permissions of # files/directories might not be correct. Also since PCFS # doesn't support symlinks, symlinks such # /boot/solaris/bin/root_archive might not have been installed # on the old /boot. So we'll use pkgchk -f to fix all these # on the new /boot. Note, the -P option arguments all end # with a / to fix everything under those directories, but not # the directories themselves. We use the -p option to fix # specific directories and files. pkgchk -R $BASEDIR -fqn -P \ /boot/acpi/,/boot/grub/,/boot/solaris/ pkgchk -R $BASEDIR -fqn -p \ /boot,/boot/acpi,/boot/grub,/boot/solaris,/boot/solaris.xpm # Rename /boot in /etc/vfstab to /stubboot. Use cp to # keep vfstab's permissions and ownership. sed 's#[ ]/boot[ ]# /stubboot #' \ ${BASEDIR}/etc/vfstab > /tmp/vfstab cp /tmp/vfstab $BASEDIR/etc/vfstab rm -f /tmp/vfstab fi # copy miniroot archive to the system cp /cdrom/boot/x86.miniroot ${BASEDIR}/boot/x86.miniroot-safe mkdir -p $BASEDIR/boot/platform/i86pc/kernel > /dev/null 2>&1 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 if [ "$rootfstype" != "zfs" ] ; then fix_bootpath fi 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} else cp /cdrom/boot/sparc.miniroot $BASEDIR/platform/sun4u/failsafe ln -f $BASEDIR/platform/sun4u/failsafe $BASEDIR/platform/sun4v/failsafe ln -f $BASEDIR/platform/sun4u/failsafe $BASEDIR/platform/sun4us/failsafe fi # Remove old .devlink_db for new one to be created after upgrade rm -f $BASEDIR/dev/.devlink_db # create boot archive and remove filestat to skip archive check /sbin/bootadm update-archive -R ${BASEDIR} rm -f ${BASEDIR}/boot/solaris/filestat.ramdisk # copy files to the root dataset of the root pool if [ "$rootfstype" = "zfs" -a "$Mach" = "i86pc" ] ; then cp ${BASEDIR}/boot/grub/splash.xpm.gz \ ${BASEDIR}/${rootpool}/boot/grub/splash.xpm.gz fi