#!/sbin/sh -
#
# @(#)vxbootcheck.sh	1.5	99/05/12 SMI
#
# Copyright (c) 1998, by Sun Microsystems, Inc.
# All rights reserved.
#
# Purpose:      To maintain list of boot disks in motherboard eeproms.
#               To set the dump device as required.
#

#
# Home dirs of split & cms.
# Calculate based on pkginfo as they are relocatable
#
 
CMS_ROOT=/usr/platform/SUNW,Ultra-4FT
CMSHOME=${CMSHOME:-$CMS_ROOT/SUNWcms}
 
#
# Make sure that the utilities needed can be found
#
 
LD_LIBRARY_PATH="$CMSHOME/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"

PATH=$PATH:$CMSHOME/lib:/usr/lib/vxvm/bin:/sbin
 
. ${VOLADM_LIB:-/usr/lib/vxvm/voladm.d/lib}/vxadm_lib.sh
 
set_OS_variables

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

vxdumplist=${TMPDIR:-/tmp}/vxdumplist
vxbootlist=${TMPDIR:-/tmp}/vxbootlist
vxbootdisks=${TMPDIR:-/tmp}/vxbootdisks

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

# get events from vxconfigd, waiting for 1 second of quiescence
# before checking volume manager database
 
vxnotify -g rootdg -w 1 | while read code more
do
#
# First collate lists of bootable disks i.e. those containing rootvol
#
    # get a list of all subdisks associated with active rootvol plexes
        root_subdisk_list=`vxprint -F '%aslist' \
                       -e '((pl_state="ACTIVE") && (assoc="rootvol"))' \
                       | sed -e "s/,/ /"`

    # get a list of vm disks containing these subdisks
        root_vmdisk_list=`vxprint -F '%dmname' $root_subdisk_list | sort -u`

    # get device name associated with these vm disks
        root_device_list=`vxprint -F '%assoc' $root_vmdisk_list`

#
# Now look for suitable swap partitions to assign as dump device
#

    # look for volumes that contain swap
    firstswap=
    dumpvol=
    cat /etc/vfstab | while read dev rdev mpoint fstype more
    do
            isdumpdev=
            case $fstype in
            swap )        [ -z "$firstswap" ] && isdumpdev=yes
                    firstswap=yes
                    ;;
            *)        continue;;
            esac
    
            case $dev in
            /dev/vx/dsk/rootdg/*)
                    vol="`expr "\$dev" : '/dev/vx/dsk/rootdg/\(.*\)'`"
                    ;;
            /dev/vx/dsk/*/*)
                    vol="`expr "\$dev" : '/dev/vx/dsk/[^/]*/\(.*\)'`"
                    ;;
            /dev/vx/dsk/*)
                    vol="`expr "\$dev" : '/dev/vx/dsk/\(.*\)'`"
                    ;;
            *)        continue
            esac
            [ -n "$isdumpdev" ] && dumpvol=$vol
    
    # For Solaris, if the first swap device is a volume, then it will
    # be used as the dump device.  Since VxVM does not currently support
    # volumes as dump devices, make an underlying partition device into
    # the dump device.
    
            rm $vxdumplist > /dev/null 2>&1
            vxprint -se \
                    "sd_pl_offset=0 && sd_device!=\"\" &&
                     assoc.assoc=\"$dumpvol\" && len >= assoc.assoc.len" \
                    -F "%path %dev_offset %len" |
            {
                while read path devoffset sdlen
                do
                    # get the disk offset of the subdisk
                    dogi_path_to_slice $path base_slice
                    [ -n "$base_slice" ] || continue
                    dogi_slice_rawpath $base_slice base_rawpath
                    STAT_PSTARTSEC=
                    STAT_DISK_TYPE=
                    eval "`vxparms -s $base_rawpath 2> /dev/null`"
                    [ -n "$STAT_PSTARTSEC" ] || continue
                    [ "X$STAT_DISK_TYPE" = Xdisk ] || continue
                    diskoffset=`expr $devoffset + $STAT_PSTARTSEC`
    
                    # locate a partition that matches the beginning of that
                    # subdisk, and that is not longer than the subdisk
                    dogi_slice_to_device $base_slice base_device
                    for slice_num in 1 0 2 3 4 5 6 7
                    do
                        dogi_device_slice $base_device $slice_num try_slice 
                        dogi_slice_rawpath $try_slice try_rawpath
                        STAT_PSTARTSEC=
                        STAT_PNUMSEC=
                        eval "`vxparms -s $try_rawpath`"
                        [ -n "$STAT_PSTARTSEC" -a -n "$STAT_PNUMSEC" ] ||
                                    continue
                        [ $STAT_PSTARTSEC -eq $diskoffset ] || continue
                        [ $STAT_PNUMSEC -le $sdlen ] || continue
                        [ -n "$base_device" ] || continue
    
                        # set dumpdev for possible the dump device
                        dogi_slice_blkpath $try_slice dumpdev

                        # if this corresponds to a device containing rootvol
                        # add it to our list of possible dump devices
                        full_base_device=$base_device"s2"
                        for testdev in $root_device_list
                        do
                            if [ "$testdev" = "$full_base_device" ] 
                            then
                                echo "$dumpdev" >> $vxdumplist
                            fi
                        done
                    done
                done
                }
    done

#
# Now work through dump list until we successfully allocate a partition
# as the dump device. Make this the first entry in the list of
# boot disks stored in the motherboard eeproms.
#

    rm $vxbootlist > /dev/null 2>&1
    cat $vxdumplist | while read device
    do
        rdevice="`echo $device | sed -e "s/dsk/rdsk/"`"
        if (`$CMSHOME/lib/scsictl SETDUMP $rdevice $device`) then

            # put this as the first disk in the boot list
            echo $device > $vxbootlist
            break
        fi
    done

#
# Now tag onto the boot disks list, the other disks that appear
# to be bootable i.e. contain active rootvol plexes
#

        vxprint -F '%assoc' $root_vmdisk_list  | awk '$1!="-" {
                fullname = "/dev/dsk/" $1
                print fullname
                } ' | sort -u >> $vxbootlist

#
# Then convert the boot list from device path format, to prom alias format
#

    rm $vxbootdisks > /dev/null 2>&1
    cat $vxbootlist | while read disk
    do
        ls -l $disk \
                | sed -e "s/^.*devices//" \
                      -e "s/^.*4,2000.*sd@/b-dsk/" \
                      -e "s/^.*6,2000.*sd@/a-dsk/" \
                      -e "s/,.*$//" \
                | nawk '{ printf "%s ", $1 }' >> $vxbootdisks
    done

#
# Finally, update the motherboard eeproms with the new list of boot disks
#

	$CMSHOME/sbin/cmsrootdisks -l A-MBD -r "`cat $vxbootdisks`" \
                                                  >/dev/null 2>&1
	$CMSHOME/sbin/cmsrootdisks -l B-MBD -r "`cat $vxbootdisks`" \
                                                  >/dev/null 2>&1

done
