#!/bin/sh

##############################################################################
#
# All the documentation for this script is spread throughout the script at
# various places to help explain the logic.  The general documentation and
# update log and anything else that may be helpful is in a section of the
# script that can be found by searching for the word DOCUMENTATION (all caps).
#                                                      - James Baack
##############################################################################

######## The code below this comment was taken from a Veritas Volume Manager
######## script.  Location is /etc/vx/bin/vxeeprom..

# check if this is an SSA device path and if so fix it to be a bootable path
ssa_boot_path()
{
	devices_path=$1
	ssa_devices_path=
	
	# if this an SSA interface controller type device 
	if echo $devices_path | grep "\/SUNW,pln@" > /dev/null 2>&1
	then
		# check the path is already correct	
		ssa_addr=`basename $devices_path`
		if echo $ssa_addr | grep "SUNW,ssd@" > /dev/null 2>&1
		then
			return 1
		else # the path is not correct for bootability 
			# incert "SUNW," 
			ssd_addr=`basename $devices_path`
			devices_dir=`dirname $devices_path`
			ssa_devices_path=$devices_dir/"SUNW,"$ssd_addr
		fi
	else  # not an SSA interface controller type device
		return 1
	fi		
			
	ssa_bootdev=$ssa_devices_path
	return 0		
}

# check if this is an ide device path and if so fix it to be a bootable path
ide_boot_path()
{
	devices_path=$1
	ide_devices_path=

	# pci device path looks like:
	#	/devices/pci@1f,0/pci@1,1/ide@3/dad@0,0

	dev_path=`dirname $devices_path`
	ide_path=`basename $dev_path`
	# if this an ide interface controller type device 
	if echo $ide_path | grep "ide@" > /dev/null 2>&1
	then
		# check the path is already correct	
		ide_device=`basename $devices_path`
		if echo $ide_device | grep "disk@" > /dev/null 2>&1
		then
			return 1
		else # the path is not correct for bootability 
			# substitute "dad" of "dad@0,0" with "disk" 
			ide_addr=`echo $ide_device | cut -d@ -f2`
			devices_dir=`dirname $devices_path`
			ide_devices_path=$devices_dir/"disk"@"$ide_addr"
		fi
	else  # not an ide interface controller type device
		return 1
	fi		
			
	ide_bootdev=$ide_devices_path
	return 0		
}

# check if this is an pci device path and if so fix it to be a bootable path
pci_boot_path()
{
	devices_path=$1
	pci_devices_path=

	# pci device path looks like:
	#	/devices/pci@1f,4000/scsi@3/sd@0,0:a

	dev_path=`dirname $devices_path`
	pci_path=`basename $dev_path`
	# if this an pci interface controller type device 
	if echo $pci_path | egrep "scsi@|fp@" > /dev/null 2>&1
	then
		# check the path is already correct	
		pci_device=`basename $devices_path`
		if echo $pci_device | grep "disk@" > /dev/null 2>&1
		then
			return 1
		else # the path is not correct for bootability 
			# substitute "sd/ssd" of "sd@0,0" with "disk" 
			pci_addr=`echo $pci_device | cut -d@ -f2`
			devices_dir=`dirname $devices_path`
			pci_devices_path=$devices_dir/"disk"@"$pci_addr"
		fi
	else  # not an pci interface controller type device
		return 1
	fi		
			
	pci_bootdev=$pci_devices_path
	return 0		
}

######## The code above this comment was taken from a Veritas Volume Manager
######## script.  Location is /etc/vx/bin/vxeeprom..

### An error message that is used alot.
ErrorMsg1()
{
echo "*ERROR* This script is going to exit, and is not deleting the project"
echo "*ERROR* from the project directory.  Project name: $PROJECT_NAME"
}  ########## End of ErrorMsg1

### A warning message that is used alot.
WarningMsg1()
{
WARNING_SWITCH=1
echo "*WARNING* The following command has already been executed (good? or bad?),"
echo "*WARNING* won't execute it again (manual intervention may be required):"
echo "*WARNING* $COMMAND"
}  ########## End of WarningMsg1

### Make sure the filesystem passed to this routine has plexs (mirrors) on 
### both the active and back-off disk
PlexCount()
{
if [ "$1" != "." ]
 then
   if [ `grep "^$1" $PROJECT_DIR/vol_plex_sd_associations | awk '{ print $5 }' | sort -u | wc -l` -ne 2 ]
    then
      echo "\n*ERROR* There needs to be one plex (mirror) for volume $1 on"
      echo "*ERROR* each of the following disks: $ACTIVE_DISK and $BACKOFF_DISK"
      ErrorMsg1
      exit 1
   fi
fi
}  ########## End of PlexCount

### Remove the incomplete project directory.
RemoveProjectDir()
{
echo "\n*MSG* Project directory $PROJECT_DIR is being deleted now"
COMMAND="rm -r $PROJECT_DIR"
echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
if [ $RC -ne 0 ]
 then
   echo "*ERROR* rm exited with a return code of $RC"
   exit 1
fi
}  ########## End of RemoveProjectDir

### Build the needed records for /etc/vfstab that will allow the server to be
### booted without Volume Manager.
BuildVFSTABRecords()
{
if [ $2 -eq 999 ]
 then
   return 0
fi
DEVICE_TO_MOUNT="`echo \"$3\" | awk '{ print $1 }'`"
DEVICE_TO_FSCK="`echo \"$3\" | awk '{ print $2 }'`"
if [ "$DEVICE_TO_FSCK" = "-" ]
 then
   echo "$3" | sed -e "s!$DEVICE_TO_MOUNT!/dev/dsk/${1}s${2}!g" >> $PROJECT_DIR/etc_vfstab_$X.change
   RC=$?
 else
   echo "$3" | sed -e "s!$DEVICE_TO_MOUNT!/dev/dsk/${1}s${2}!g" -e "s!$DEVICE_TO_FSCK!/dev/rdsk/${1}s${2}!g" >> $PROJECT_DIR/etc_vfstab_$X.change
   RC=$?
fi
if [ $RC -ne 0 ]
 then
   echo "\n*ERROR* sed (2) was not successful - ended with a return code of $RC."
   ErrorMsg1
   exit 1
fi
}  ########## End of BuildVFSTABRecords

### This routine adds to the files to be used as input to a format command
### to change how the disk is partitioned.  
### Input parameters for this routine are defined below:
### Parm 1 is the physical disk
### Parm 2 is the VM volume name
### Parm 3 is the Tag for a format
### Parm 4 is the Flag for a format
### Parm 5 the name of the temporary file which has a reformatted prtvtoc output
### Rounding will happen, if needed, when figuring the starting cyl for each
### partition.  This is done, just in case, VM put a bootstrap of 1 sector
### on the disk (subdisk ending with a -B0).
BuildPartitionRecords()
{
if [ "$2" = "." ]
 then
   return 999
fi
FigureNextPartitionNumber
PART_NUM_TO_USE=$?
if [ $PART_NUM_TO_USE -eq 999 ]
 then
   return 999
fi

### The data needed for these output files to feed into a format command is 
### defined below.  Each value is a seperate line of the file.
### Partition Number
### Partition Tag
### Partition Flag
### Partition Start in cylinders           
### Partition Size in blocks

### Do the records for the VTOC before it was changed.  Only need to do the
### partitons that are going to be used for changing the VTOC.  Partion 2 and   
### the VM public and private partions don't need to be in this file since
### they aren't changing.
echo "$PART_NUM_TO_USE" >> $FORMATFILEBEFORE
TVALUES="`grep \"^$PART_NUM_TO_USE \" $5`"
RC=$?
if [ $RC -ge 2 ]
 then
   echo "\n*ERROR* Could not determine existing partition information from"
   echo "*ERROR* the temporary work file named: $5"
   ErrorMsg1
   exit 1
fi 
if [ $RC -eq 0 ]
 then
   TTAG="`echo \"$TVALUES\" | awk '{ print $2 }'`"
   TFLAGS="`echo \"$TVALUES\" | awk '{ print $3 }'`"
   TFIRSTSECTOR="`echo \"$TVALUES\" | awk '{ print $4 }'`"
   TSECTORCOUNT="`echo \"$TVALUES\" | awk '{ print $5 }'`"
 else
   TTAG="T0T"
   TFLAGS="00"
   TFIRSTSECTOR="0"
   TSECTORCOUNT="0"
fi
case $TTAG in
   T0T) echo "unassigned" >> $FORMATFILEBEFORE   
      ;;
   T1T) echo "boot" >> $FORMATFILEBEFORE
      ;;
   T2T) echo "root" >> $FORMATFILEBEFORE
      ;;
   T3T) echo "swap" >> $FORMATFILEBEFORE
      ;;
   T4T) echo "usr" >> $FORMATFILEBEFORE
      ;;
   T5T) echo "backup" >> $FORMATFILEBEFORE
      ;;
   T6T) echo "stand" >> $FORMATFILEBEFORE
      ;;
   T7T) echo "var" >> $FORMATFILEBEFORE
      ;;
   T8T) echo "home" >> $FORMATFILEBEFORE
      ;;
   T9T) echo "alternates" >> $FORMATFILEBEFORE
      ;;
   *)
      echo "\n*ERROR* Encountered a tag ($TTAG) not defined in the case statement"
      ErrorMsg1
      exit 1
      ;;
esac
case $TFLAGS in
   '00') echo "wm" >> $FORMATFILEBEFORE
      ;;
   '01') echo "wu" >> $FORMATFILEBEFORE
      ;;
   '10') echo "rm" >> $FORMATFILEBEFORE
      ;;
   '11') echo "ru" >> $FORMATFILEBEFORE
      ;;
   *)
      echo "\n*ERROR* Encountered a flags ($TFLAGS) not defined in the case statement"
      ErrorMsg1
      exit 1
      ;;
esac
echo "$TFIRSTSECTOR $SECTORS_PER_CYL" | awk '{ print ( $1 / $2 ) }' >> $FORMATFILEBEFORE
echo "${TSECTORCOUNT}b" >> $FORMATFILEBEFORE

### Do the records for changing the VTOC to use for making disk bootable outside
### of VM
echo "$PART_NUM_TO_USE" >> $FORMATFILECHANGE
echo "$3" >> $FORMATFILECHANGE
echo "$4" >> $FORMATFILECHANGE
TVALUES="`grep \" $1 \" $PROJECT_DIR/vol_plex_sd_associations | grep \"^$2 \" | grep -v '\-B0 ' | awk '{ print $6, $7 }'`"
VMDISKOFFS=`echo $TVALUES | awk '{ print $1 }'`
VMLENGTH=`echo $TVALUES | awk '{ print $2 }'`
echo "$VMDISKOFFS $VM_PUBLIC_START $SECTORS_PER_CYL" | awk '{
  data_start = $1 + $2
  if ( data_start % $3 > 0 ) {
     print ( int( data_start / $3 ) + 1)  
     }
   else {
     print ( data_start / $3 )
     }
   }' >> $FORMATFILECHANGE
grep " $1 " $PROJECT_DIR/vol_plex_sd_associations | grep "^$2 " | grep '\-B0 ' > /dev/null 2>&1
if [ $? -eq 0 ]
 then
   VMLENGTH="`echo \"$VMLENGTH\" | awk '{ print ( $1 + 1 ) }'`"
fi
echo "${VMLENGTH}b" >> $FORMATFILECHANGE

### return the partition number to use for the filsystem
return $PART_NUM_TO_USE
}  ########## End of BuildPartitionRecords

### Figure the next partition number that can be used and also set the 
### LAST_USED_PARTITION to the new used value.
### Return the partition to use if one is found.  If none are available or left
### to use, return a 999 value
FigureNextPartitionNumber()
{
while [ true ]
do
   PN=`echo $LAST_USED_PARTITION | awk '{ print $1 + 1 }'`
   if [ $PN -ge 8 ]
    then
      return 999
   fi
   LAST_USED_PARTITION=$PN
   for UNAV in $UNAVAILABLE_PARTITIONS
   do
      if [ $UNAV -eq $PN ]
       then
         continue 2
      fi
   done
   return $PN
done
}  ########## End of FigureNextPartitionNumber

### Determine is the current value of the COMMAND variable exists in the
### current progression file ($PROGRESS_FILE).  If it exists, return a 1,
### if it does not exist, return a 0.
PriorExecutionCheck()
{
grep "^$COMMAND" $PROGRESS_FILE > /dev/null 2>&1
if [ $? -eq 1 ]
 then 
   return 0
fi
### return a found return code (1), even if grep gets an error return code of 2
return 1
}  ########## End of PriorExecutionCheck

### Check the see if the use-nvramrc? is set to true, if it is, set the switch.
### If it is not, set it to true.
DoUseNvramrc()
{
eeprom use-nvramrc? | grep 'use-nvramrc?=true' > /dev/null 2>&1
if [ $? -eq 0 ]
 then
   USE_NVRAMRC_SET_SWITCH=1
 else
   if [ $EEPROM_USABLE_SWITCH -eq 1 ]
    then
      echo "\n*MSG* Setting the eeprom parameter use-nvramrc? to true"
      COMMAND="eeprom use-nvramrc?=true"
      if [ "$DEBUG" = "yes" ]
       then
         echo "*DEBUG COMMAND* $COMMAND"
       else
         echo "$COMMAND" >> $PROGRESS_FILE
         echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
         if [ $RC -ne 0 ]
          then
            echo "*ERROR* eeprom exited with a return code of $RC"
            exit 1
         fi
         USE_NVRAMRC_SET_SWITCH=1
      fi
   fi
fi
}  ########## End of DoUseNvramrc


Function1() 
{
### Determine all the physical disks in rootdg that have a mirror of the
### root volume on them
vxprint -Gts -g rootdg | egrep `vxprint -F "%aslist" -g rootdg rootvol | sed -e "s/,/|/g"` | awk '{ print $8 }' | sort -u > $TEMP1
if [ `cat $TEMP1 | wc -l` -ne 2 ]
 then
   echo "\n*ERROR* There must be two and only two mirrors defined for root mirroring."
   echo "*ERROR* If you have more than two, remove all but two of the mirrors manually."
   echo "*ERROR* -OR- If the root disk is not mirrored, this back-off automation script"
   echo "*ERROR* will not work."
   RemoveProjectDir
   exit 1
fi

### Now we know the two physical disks, ask the user which one is to be saved
### as the back-off disk
awk 'BEGIN { count = 0 } { printf("\t%d\t%s\n", ++count, $1) }' $TEMP1 > $TEMP2
echo "\n\tq\tquit\n" >> $TEMP2
      
while [ true ]
do
   echo "\n\n\nBelow are the two physical disks that make up the mirrors for the root"
   echo "filesystem."
   echo "Please select the disk to use for back-off purposes.. (the back-off disk)\n"
   cat $TEMP2
   echo "Select the disk by the number in the left column: \c"
   read CHOICE
   BACKOFF_DISK=`grep "	$CHOICE	" $TEMP2 | awk '{ print $2 }'` ## tabs are used here
   if [ -n "$BACKOFF_DISK" ]
    then
      if [ "$BACKOFF_DISK" = "quit" ]
       then
         RemoveProjectDir
         echo "\nLeaving the back-off automation script!"
         exit 0
      fi
      while [ true ]
      do
         echo "\n\nDisk selected is: $BACKOFF_DISK"
         echo "\nIs this correct? (y/n): \c"
         read ANSWER
         if [ "$ANSWER" = "y" ]
          then
            break 2
         fi
         if [ "$ANSWER" = "n" ]
          then
            continue 2
         fi
         echo "\n Selection not recognized, try again by pressing Return/Enter!"
         read JUNK
      done
   fi
   echo "\n Selection not recognized, try again by pressing Return/Enter!"
   read JUNK
done

echo "\n*MSG* The disk to be used for back-off is: $BACKOFF_DISK"
ACTIVE_DISK=`grep -v "$BACKOFF_DISK" $TEMP2 | head -1 | awk '{ print $2 }'`
echo "*MSG* The disk to be used for patching, upgrading, etc is: $ACTIVE_DISK"

### Put the disk names into the appropriate files for storing
echo "$BACKOFF_DISK" > $PROJECT_DIR/physical_disk.backoff
grep "^${BACKOFF_DISK}" $PROJECT_DIR/physical_disk.backoff > /dev/null 2>&1
if [ $? -ne 0 ]
 then
   echo "\n*ERROR* The back-off disk did not get stored into a file."
   ErrorMsg1
   exit 1
fi

echo "$ACTIVE_DISK" > $PROJECT_DIR/physical_disk.active
grep "^${ACTIVE_DISK}" $PROJECT_DIR/physical_disk.active > /dev/null 2>&1
if [ $? -ne 0 ]
 then
   echo "\n*ERROR* The active disk did not get stored into a file."
   ErrorMsg1
   exit 1
fi

### Make a backup copy of /etc/system
echo "\n*MSG* Making a copy of the current /etc/system file"
COMMAND="cp -p /etc/system $PROJECT_DIR/etc_system.before"
echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
if [ $RC -ne 0 ]
 then
   echo "*ERROR* cp (1) exited with a return code of $RC"
   ErrorMsg1
   exit 1
fi

### Make a modified version of /etc/system to disable VM
sed -e "/rootdev:\/pseudo\/vxio@0:0/d" -e "/set vxio:vol_rootdev_is_volume=1/d" /etc/system > $PROJECT_DIR/etc_system.change
RC=$?
if [ $RC -ne 0 ]
 then
   echo "\n*ERROR* sed (3) was not successful - ended with a return code of $RC."
   ErrorMsg1
   exit 1
fi
echo "\n*MSG* Created a modified version of /etc/system to disable VM at boot time."
echo "*MSG* The file is $PROJECT_DIR/etc_system.change"

### Make a backup copy of /etc/vfstab
echo "\n*MSG* Making a copy of the current /etc/vfstab file"
COMMAND="cp -p /etc/vfstab $PROJECT_DIR/etc_vfstab.before"
echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
if [ $RC -ne 0 ]
 then
   echo "*ERROR* cp (2) exited with a return code of $RC"
   ErrorMsg1
   exit 1
fi

### Do a couple of vxprints - just for grins
echo "\n*MSG* Executing vxprint with a couple of different options for each diskgroup"
for X in `vxdg -q list | awk '{ print $1 }'`
do
   COMMAND="vxprint -ht -g $X"
   echo "*COMMAND* $COMMAND > $PROJECT_DIR/vxprint_ht_$X.before" ; $COMMAND > $PROJECT_DIR/vxprint_ht_$X.before ; RC=$?
   if [ $RC -ne 0 ]
    then
      echo "*ERROR* vxprint exited with a return code of $RC"
      ErrorMsg1
      exit 1
   fi
   AGE_OF_VER=`echo $VXVM_VERSION | awk '{ 
      if ( $1 >= 3 ) print ("3.x or newer")
      if ( $1 < 3 ) print ("older than 3.x")
      }'`
   if [ "$AGE_OF_VER" != "older than 3.x" ]
    then
      COMMAND="vxprint -mhvrps -g $X"
      echo "*COMMAND* $COMMAND > $PROJECT_DIR/vxprint_mhvrps_$X.before" ; $COMMAND > $PROJECT_DIR/vxprint_mhvrps_$X.before ; RC=$?
      if [ $RC -ne 0 -a $RC -ne 11 ]
       then
         echo "*ERROR* vxprint exited with a return code of $RC"
         ErrorMsg1
         exit 1
      fi
    else
      COMMAND="vxprint -mhvps -g $X"
      echo "*COMMAND* $COMMAND > $PROJECT_DIR/vxprint_mhvps_$X.before" ; $COMMAND > $PROJECT_DIR/vxprint_mhvps_$X.before ; RC=$?
      if [ $RC -ne 0 -a $RC -ne 11 ]
       then
         echo "*ERROR* vxprint exited with a return code of $RC"
         ErrorMsg1
         exit 1
      fi
   fi
done

### Do a couple of vxdisks - just for grins
echo "\n*MSG* Executing vxdisk with a couple of different options to get a list and details"
COMMAND="vxdisk list"
echo "*COMMAND* $COMMAND > $PROJECT_DIR/vxdisk_list.before" ; $COMMAND > $PROJECT_DIR/vxdisk_list.before ; RC=$?
if [ $RC -ne 0 ]
 then
   echo "*ERROR* vxdisk exited with a return code of $RC"
   ErrorMsg1
   exit 1
fi
cat /dev/null > vxdisk_list_detail.before
for X in `vxdisk -q list | awk '{ print $1 }'`
do
   COMMAND="vxdisk list $X"
   echo "*COMMAND* $COMMAND >> $PROJECT_DIR/vxdisk_list_detail.before" ; $COMMAND >> $PROJECT_DIR/vxdisk_list_detail.before ; RC=$?
   if [ $RC -ne 0 ]
    then
      echo "*ERROR* vxdisk exited with a return code of $RC"
      ErrorMsg1
      exit 1
   fi
   echo " " >> $PROJECT_DIR/vxdisk_list_detail.before
done

### Make a copy of volboot just for grins
echo "\n*MSG* Making a copy of the current /etc/vx/volboot file"
COMMAND="cp -p /etc/vx/volboot $PROJECT_DIR/etc_vx_volboot.before"
echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
if [ $RC -ne 0 ]
 then
   echo "*ERROR* cp (3) exited with a return code of $RC"
   ErrorMsg1
   exit 1
fi

### Determine the volume names of \ (root), swap, usr, var, and opt
grep -v "^#" /etc/vfstab | awk '{ print $1,$3,$4,$5,":SPLIT:" $0 }' > $TEMP1
#VXVM_ROOT_VOL=`grep " / " $TEMP1 | awk '{ print $1 }'`     # V1.1 commented
#VXVM_ROOT_VOL="`basename $VXVM_ROOT_VOL`"                  # V1.1 commented
VXVM_ROOT_VOL="rootvol"                                     # V1.1
VFSTAB_ROOT_LINE="`grep \" / \" $TEMP1 | awk -F\":SPLIT:\" '{ print $3 }'`"
echo "root $VXVM_ROOT_VOL" > $PROJECT_DIR/volume_names
#VXVM_SWAP_VOL=`grep " swap " $TEMP1 | awk '{ print $1 }'`  # V1.1 commented
#VXVM_SWAP_VOL="`basename $VXVM_SWAP_VOL`"                  # V1.1 commented
VXVM_SWAP_VOL="`vxprint -g rootdg -vt | grep \"^v\" | awk '{ print $1,$2,$3,$4,$5,$6,$7,$8,$9,\" \" }' | grep \" swap \" | awk '{ print $2 }'`"   # V1.1
#VFSTAB_SWAP_LINE="`grep \" swap \" $TEMP1 | awk -F\":SPLIT:\" '{ print $3 }'`"                                                             # V1.1 commented
VFSTAB_SWAP_LINE="`grep \" swap \" $TEMP1 | grep \"/$VXVM_SWAP_VOL \" | awk -F\":SPLIT:\" '{ print $3 }'`"                                  # V1.1
echo "swap $VXVM_SWAP_VOL" >> $PROJECT_DIR/volume_names
VXVM_USR_VOL=`grep " /usr " $TEMP1 | awk '{ print $1 }'`
VXVM_USR_VOL="`basename $VXVM_USR_VOL`"
VFSTAB_USR_LINE="`grep \" /usr \" $TEMP1 | awk -F\":SPLIT:\" '{ print $3 }'`"
echo "usr $VXVM_USR_VOL" >> $PROJECT_DIR/volume_names
VXVM_VAR_VOL=`grep " /var " $TEMP1 | awk '{ print $1 }'`
VXVM_VAR_VOL="`basename $VXVM_VAR_VOL`"
VFSTAB_VAR_LINE="`grep \" /var \" $TEMP1 | awk -F\":SPLIT:\" '{ print $3 }'`"
echo "var $VXVM_VAR_VOL" >> $PROJECT_DIR/volume_names
VXVM_OPT_VOL=`grep " /opt " $TEMP1 | awk '{ print $1 }'`
VXVM_OPT_VOL="`basename $VXVM_OPT_VOL`"
VFSTAB_OPT_LINE="`grep \" /opt \" $TEMP1 | awk -F\":SPLIT:\" '{ print $3 }'`"
echo "opt $VXVM_OPT_VOL" >> $PROJECT_DIR/volume_names

### Build a record with the association between volumes, plexes and sub-disks.
### There will be a record for each sub-disk in rootdg that is associated with
### one of the five volumes.
vxprint -ts -g rootdg | grep "^sd" > $TEMP1
exec 3<&0 < $TEMP1
while read VMTYPE VMNAME VMPLEX VMDISK VMDISKOFFS VMLENGTH VMCOLOFF VMDEVICE VMMODE
do
   echo "`vxprint -F "%vname" -g rootdg $VMNAME` $VMPLEX $VMNAME $VMDISK $VMDEVICE $VMDISKOFFS $VMLENGTH" >> $TEMP2
done
for X in $VXVM_ROOT_VOL $VXVM_SWAP_VOL $VXVM_OPT_VOL $VXVM_USR_VOL $VXVM_VAR_VOL
do
   if [ "$X" != "." ]
    then
      EGREP_SEARCH="${EGREP_SEARCH}^${X} |"
   fi
done
exec 0<&3 3<&-
egrep "$EGREP_SEARCH" $TEMP2 | egrep " $BACKOFF_DISK | $ACTIVE_DISK " > $PROJECT_DIR/vol_plex_sd_associations

### Make sure all the root filesystems that this script handles have plexes
### (mirrors) on both the active and back-off disk
PlexCount "$VXVM_ROOT_VOL"
PlexCount "$VXVM_SWAP_VOL"
PlexCount "$VXVM_USR_VOL"
PlexCount "$VXVM_VAR_VOL"
PlexCount "$VXVM_OPT_VOL"

### Save a prtvtoc of the active and backoff disks
echo "\n*MSG* Saving a prtvtoc of the active disk ($ACTIVE_DISK)"
COMMAND="prtvtoc /dev/rdsk/${ACTIVE_DISK}s2"
echo "*COMMAND* $COMMAND > $PROJECT_DIR/prtvtoc_${ACTIVE_DISK}.before" ; $COMMAND > $PROJECT_DIR/prtvtoc_${ACTIVE_DISK}.before ; RC=$?
if [ $RC -ne 0 ]
 then
   echo "*ERROR* prtvtoc exited with a return code of $RC"
   ErrorMsg1
   exit 1
fi

echo "\n*MSG* Saving a prtvtoc of the backoff disk ($BACKOFF_DISK)"
COMMAND="prtvtoc /dev/rdsk/${BACKOFF_DISK}s2"
echo "*COMMAND* $COMMAND > $PROJECT_DIR/prtvtoc_${BACKOFF_DISK}.before" ; $COMMAND > $PROJECT_DIR/prtvtoc_${BACKOFF_DISK}.before ; RC=$?
if [ $RC -ne 0 ]
 then
   echo "*ERROR* prtvtoc exited with a return code of $RC"
   ErrorMsg1
   exit 1
fi

### Figure out how the disks VTOC should be formatted to make them bootable
### without Volume Manager.
### Also, build the vfstab file to use for booting without VM and determine the
### bootpath for the device.
for X in $BACKOFF_DISK $ACTIVE_DISK
do
   ### Determine the number of sectors per cylinder
   SECTORS_PER_CYL=`grep "sectors/cylinder" $PROJECT_DIR/prtvtoc_$X.before | awk '{ print $2 }'`
   if [ -z "$SECTORS_PER_CYL" ]
    then
      echo "\n*ERROR* Could not determine the sectors per cylinder for disk $X"
      ErrorMsg1
      exit 1
   fi

   ### Determine which disk partitions are not available for use
   ### Partition 2 is always not available
   ### The partition with a Tag of 15 (VM private area) is always not available
   ### The partition with a Tag of 14 (VM public area) is always not available
   grep -v "^*" $PROJECT_DIR/prtvtoc_$X.before | awk '{ printf("%d T%dT %s %d %d %d\n", $1, $2, $3, $4, $5, $6) }' > $TEMP1
   UNAVAILABLE_PARTITIONS="2 "
   UNAVAILABLE_PARTITIONS="$UNAVAILABLE_PARTITIONS `egrep ' T14T | T15T ' $TEMP1 | awk '{ print $1 }'`"

   ### Get start of Volume Manager public area to be used to figure actual
   ### disk offsets for the physical disk.
   VM_PUBLIC_START=`grep ' T14T ' $TEMP1 | awk '{ print $4 }'`

   ### Rounding will happen, if needed, when figuring the starting cyl for each
   ### partition.  This is done, just in case, VM put a bootstrap of 1 sector
   ### on the disk (subdisk ending with a -B0).
   ### Call routine to figure partition format information for each filesystem
   LAST_USED_PARTITION=-1
   FORMATFILEBEFORE=$PROJECT_DIR/format_command_$X.before
   FORMATFILECHANGE=$PROJECT_DIR/format_command_$X.change
   echo "partition" > $FORMATFILEBEFORE
   echo "partition" > $FORMATFILECHANGE
   ### Parm 3 is the Tag for a format
   ### Parm 4 is the Flag for a format
   BuildPartitionRecords "$X" "$VXVM_ROOT_VOL" "root" "wm" "$TEMP1"
   ROOT_PARTITION=$?
   BuildPartitionRecords "$X" "$VXVM_SWAP_VOL" "swap" "wu" "$TEMP1"
   SWAP_PARTITION=$?
   BuildPartitionRecords "$X" "$VXVM_USR_VOL" "usr" "wm" "$TEMP1"
   USR_PARTITION=$?
   BuildPartitionRecords "$X" "$VXVM_VAR_VOL" "var" "wm" "$TEMP1"
   VAR_PARTITION=$?
   BuildPartitionRecords "$X" "$VXVM_OPT_VOL" "unassigned" "wm" "$TEMP1"
   OPT_PARTITION=$?

   if [ "`tail -1 $FORMATFILEBEFORE`" != "partition" ]
    then
      echo "label" >> $FORMATFILEBEFORE
   fi
   echo "q" >> $FORMATFILEBEFORE
   echo "q" >> $FORMATFILEBEFORE
   if [ "`tail -1 $FORMATFILECHANGE`" != "partition" ]
    then
      echo "label" >> $FORMATFILECHANGE
   fi
   echo "q" >> $FORMATFILECHANGE
   echo "q" >> $FORMATFILECHANGE

   echo "\n*MSG* The input for a format to restore partitions for $X has been created"
   echo "*MSG* in file $FORMATFILEBEFORE."
   echo "\n*MSG* The input for a format to change partitions for $X has been created"
   echo "*MSG* in file $FORMATFILECHANGE."

   ### Create a change vfstab file with all lines beginning with /dev commented
   ### out.  The needed lines to make the disk bootable outside of VM will be 
   ### added at the end of the file
   sed -e "s!^/dev!#/dev!g" $PROJECT_DIR/etc_vfstab.before > $PROJECT_DIR/etc_vfstab_$X.change
   RC=$?
   if [ $RC -ne 0 ]
    then
      echo "\n*ERROR* sed (1) was not successful - ended with a return code of $RC."
      ErrorMsg1
      exit 1
   fi
   BuildVFSTABRecords "$X" "$ROOT_PARTITION" "$VFSTAB_ROOT_LINE"
   BuildVFSTABRecords "$X" "$SWAP_PARTITION" "$VFSTAB_SWAP_LINE"
   BuildVFSTABRecords "$X" "$USR_PARTITION" "$VFSTAB_USR_LINE"
   BuildVFSTABRecords "$X" "$VAR_PARTITION" "$VFSTAB_VAR_LINE"
   BuildVFSTABRecords "$X" "$OPT_PARTITION" "$VFSTAB_OPT_LINE"
   echo "\n*MSG* The modified vfstab file for $X has been created in file "
   echo "*MSG* $PROJECT_DIR/etc_vfstab_$X.change."

   ### Build a file of filesystems and associated partitions for the changed
   ### VTOC.
   PARTITIONFILECHANGE="$PROJECT_DIR/partitions_$X.change"
   if [ $ROOT_PARTITION -eq 999 ]
    then
      echo "root ." >> $PARTITIONFILECHANGE
    else
      echo "root $ROOT_PARTITION" >> $PARTITIONFILECHANGE
   fi
   if [ $SWAP_PARTITION -eq 999 ]
    then
      echo "swap ." >> $PARTITIONFILECHANGE
    else
      echo "swap $SWAP_PARTITION" >> $PARTITIONFILECHANGE
   fi
   if [ $USR_PARTITION -eq 999 ]
    then
      echo "usr ." >> $PARTITIONFILECHANGE
    else
      echo "usr $USR_PARTITION" >> $PARTITIONFILECHANGE
   fi
   if [ $VAR_PARTITION -eq 999 ]
    then
      echo "var ." >> $PARTITIONFILECHANGE
    else
      echo "var $VAR_PARTITION" >> $PARTITIONFILECHANGE
   fi
   if [ $OPT_PARTITION -eq 999 ]
    then
      echo "opt ." >> $PARTITIONFILECHANGE
    else
      echo "opt $OPT_PARTITION" >> $PARTITIONFILECHANGE
   fi
   echo "\n*MSG* A file of filesystem to partition associations for device $X has been"
   echo "*MSG* create in $PARTITIONFILECHANGE"

   ### Time to figure the bootpath for the device
   TLINK="`ls -l "/dev/dsk/\${X}s${ROOT_PARTITION}" 2> /dev/null`"
   TDEVICE="`expr "\$TLINK" : '.* -> \.\./\.\./devices\(/.*\)'`"
   ssa_boot_path $TDEVICE
   if [ $? -eq 0 ]
    then
      TDEVICE=$ssa_bootdev
   fi
   ide_boot_path $TDEVICE
   if [ $? -eq 0 ]
    then
      TDEVICE=$ide_bootdev
   fi
   pci_boot_path $TDEVICE
   if [ $? -eq 0 ]
    then
      TDEVICE=$pci_bootdev
   fi
   if [ -n "$TDEVICE" ]
    then
      echo "\n*MSG* Boot path for ${X}s${ROOT_PARTITION} is $TDEVICE"
      echo "$TDEVICE" > $PROJECT_DIR/bootpath_$X
      echo "*MSG* This path has been placed into file $PROJECT_DIR/bootpath_$X"
    else
      echo "\n*ERROR* The bootpath for ${X}s${ROOT_PARTITION} could not be determined!"
      ErrorMsg1
      exit 1
   fi

done

### Check to make sure the bootblock file exists (contains the bootblock code)
if [ -f $BOOTBLOCKFILENAME ]
 then
   echo "$BOOTBLOCKFILENAME ok" > $PROJECT_DIR/bootblk_file
 else
   echo "$BOOTBLOCKFILENAME notfound" > $PROJECT_DIR/bootblk_file
   echo "\n*ERROR* The bootblock code file was not found.  It should be located"
   echo "*ERROR* at $BOOTBLOCKFILENAME."
   echo "*ERROR* The preparation is still considered good, but you will need to"
   echo "*ERROR* manaully create the necessary bootblock at a later time - this"
   echo "*ERROR* script will remind you to do this manual effort."
fi

### Put the okay file in the directory to let the other functions know it is
### good.
ls -l $PROJECT_DIR > $PROJECT_DIR/.Preparation_okay

echo "\n*MSG* The Preparation Function has finished good!"
echo "*MSG* The name of this project:  $PROJECT_NAME"

}  ########## End of Function1

Function2() 
{
### Set the name of the function progression file
### This file is used to log commands just before they get executed.  This file
### gets used to determine if a command that may cause potential problems if
### executed twice has already been executed once. 
PROGRESS_FILE=$PROJECT_DIR/.Break_Root_Mirroring_progress
touch $PROGRESS_FILE

echo "\n*MSG* The device being used for the backoff of this project is: $PHYSICAL_BACKOFF_DISK"

### Sync the filesystems
echo "\n*MSG* Sync'ing the filesystems now"
COMMAND="sync"
if [ "$DEBUG" = "yes" ]
 then
   echo "*DEBUG COMMAND* $COMMAND"
 else
   echo "$COMMAND" >> $PROGRESS_FILE
   echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
   if [ $RC -ne 0 ]
    then
      echo "*ERROR* sync exited with a return code of $RC"
      exit 1
   fi
fi

### Dissociate the plexes on the backoff device for the root filesystems
for FS in root swap usr var opt
do
   case $FS in
      root)
         TMP_VOL_NAME=$ROOT_VOL_NAME
         TMP_BACKOFF_PLEX=$ROOT_BACKOFF_PLEX
         ;;
      swap)
         TMP_VOL_NAME=$SWAP_VOL_NAME
         TMP_BACKOFF_PLEX=$SWAP_BACKOFF_PLEX
         ;;
      usr)
         TMP_VOL_NAME=$USR_VOL_NAME
         TMP_BACKOFF_PLEX=$USR_BACKOFF_PLEX
         ;;
      var)
         TMP_VOL_NAME=$VAR_VOL_NAME
         TMP_BACKOFF_PLEX=$VAR_BACKOFF_PLEX
         ;;
      opt)
         TMP_VOL_NAME=$OPT_VOL_NAME
         TMP_BACKOFF_PLEX=$OPT_BACKOFF_PLEX
         ;;
      *)
         echo " Should never ever get here - someone has messed with the script (3)"
         exit 1
         ;;
   esac

   if [ "$TMP_VOL_NAME" != '.' ]
    then

      echo "\n*MSG* Dissociating plex: $TMP_BACKOFF_PLEX from volume: $TMP_VOL_NAME"
      COMMAND="vxplex -g rootdg -v $TMP_VOL_NAME dis $TMP_BACKOFF_PLEX"

      if [ "$DEBUG" = "yes" ]
       then
         echo "*DEBUG COMMAND* $COMMAND"
       else
         ### Check to see if this command has already been executed (good or bad)
         PriorExecutionCheck
         if [ $? -eq 0 ]
          then
            ### The command has not been executed before this time
            echo "$COMMAND" >> $PROGRESS_FILE
            echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
            if [ $RC -ne 0 ]
             then
               echo "*ERROR* vxplex (1) exited with a return code of $RC"
               exit 1
            fi
          else
            ### The command has been executed before, so don't do it again
            WarningMsg1
         fi
      fi
   fi
done

### Modify the VTOC of the backoff device
echo "\n*MSG* Modifying the VTOC of device $PHYSICAL_BACKOFF_DISK"
COMMAND="format -s -f $PROJECT_DIR/format_command_${PHYSICAL_BACKOFF_DISK}.change $PHYSICAL_BACKOFF_DISK"

if [ "$DEBUG" = "yes" ]
 then
   echo "*DEBUG COMMAND* $COMMAND"
 else
   ### Check to see if this command has already been executed (good or bad)
   PriorExecutionCheck
   if [ $? -eq 0 ]
    then
      ### The command has not been executed before this time
      echo "$COMMAND" >> $PROGRESS_FILE
      echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
      if [ $RC -ne 0 ]
       then
         echo "*ERROR* format (1) exited with a return code of $RC"
         exit 1
      fi
    else
      ### The command has been executed before, so don't do it again
      WarningMsg1
   fi
fi

### fsck the partitions of the dissociated plexes
for FS in root usr var opt
do
   case $FS in
      root)
         TMP_VOL_NAME=$ROOT_VOL_NAME
         TMP_BACKOFF_PARTITION=$ROOT_BACKOFF_PARTITION
         ;;
      usr)
         TMP_VOL_NAME=$USR_VOL_NAME
         TMP_BACKOFF_PARTITION=$USR_BACKOFF_PARTITION
         ;;
      var)
         TMP_VOL_NAME=$VAR_VOL_NAME
         TMP_BACKOFF_PARTITION=$VAR_BACKOFF_PARTITION
         ;;
      opt)
         TMP_VOL_NAME=$OPT_VOL_NAME
         TMP_BACKOFF_PARTITION=$OPT_BACKOFF_PARTITION
         ;;
      *)
         echo " Should never ever get here - someone has messed with the script (4)"
         exit 1
         ;;
   esac

   if [ "$TMP_VOL_NAME" != '.' ]
    then
      echo "\n*MSG* fsck'ing partition /dev/rdsk/${PHYSICAL_BACKOFF_DISK}s${TMP_BACKOFF_PARTITION}"
      COMMAND="fsck -y /dev/rdsk/${PHYSICAL_BACKOFF_DISK}s${TMP_BACKOFF_PARTITION}"
      if [ "$DEBUG" = "yes" ]
       then
         echo "*DEBUG COMMAND* $COMMAND"
       else
         ### Check to see if this command has already been executed (good or bad)
         PriorExecutionCheck
         if [ $? -eq 0 ]
          then
            ### The command has not been executed before this time
            echo "$COMMAND" >> $PROGRESS_FILE
            echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
            if [ $RC -ne 0 ]
             then
               echo "*ERROR* fsck exited with a return code of $RC"
               exit 1
            fi
          else
            ### The command has been executed before, so don't do it again
            WarningMsg1
         fi
      fi
   fi
done

### Build the bootblock on the root partition of the backoff device
if [ "`cat $PROJECT_DIR/bootblk_file | awk '{ print $2 }'`" = "ok" ]
 then
   echo "\n*MSG* Building the bootblock on /dev/rdsk/${PHYSICAL_BACKOFF_DISK}s${ROOT_BACKOFF_PARTITION}"
   COMMAND="/usr/sbin/installboot `cat $PROJECT_DIR/bootblk_file | awk '{ print $1 }` /dev/rdsk/${PHYSICAL_BACKOFF_DISK}s${ROOT_BACKOFF_PARTITION}"
   if [ "$DEBUG" = "yes" ]
    then
      echo "*DEBUG COMMAND* $COMMAND"
    else
      ### Check to see if this command has already been executed (good or bad)
      PriorExecutionCheck
      if [ $? -eq 0 ]
       then
         ### The command has not been executed before this time
         echo "$COMMAND" >> $PROGRESS_FILE
         echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
         if [ $RC -ne 0 ]
          then
            echo "*ERROR* installboot exited with a return code of $RC"
            exit 1
         fi
         BOOTBLOCK_BUILT_SWITCH=1
       else
         ### The command has been executed before, so don't do it again
         WarningMsg1
      fi
   fi
 else
   WARNING_SWITCH=1
   echo "\n*WARNING* The bootblock code file was not found.  It should be located"
   echo "*WARNING* at $BOOTBLOCKFILENAME."
   echo "*WARNING* When this function completes you will need to manually create the"
   echo "*WARNING* bootblock on the backoff device in the root partition."
fi

### Check on the devalias situation and do what can be done
### First check to see if a devalias is already set that will work
TMP_DEVALIAS_NAME="`prtconf -vp | grep -v 'bootpath:' | grep "\'$BACKOFF_BOOTPATH\'" | head -1 | awk -F\":\" '{ print $1 }' | awk '{ print $1}'`"
if [ -n "$TMP_DEVALIAS_NAME" ]
 then
   ### There is a devalias set for the bootpath we need.  Now check to see if
   ### it is coming from nvramrc.  If it is comming from nvramrc than make sure
   ### that use-nvramrc? is true.  All eeprom change stuff can only be done if
   ### the EEPROM_USABLE_SWITCH has previously been set to a 1.
   DEVALIAS_SET_SWITCH=1
   DEVALIAS_NAME="$TMP_DEVALIAS_NAME"
   eeprom nvramrc | grep "devalias $TMP_DEVALIAS_NAME $BACKOFF_BOOTPATH" > /dev/null 2>&1
   if [ $? -eq 0 ]
    then
      NVRAMRC_SET_SWITCH=1
      DoUseNvramrc
   fi
 else
   ### No devalias set for the bootpath we need.  Create one in the nvramrc and
   ### make sure the use-nvramrc? is true.  All eeprom change stuff can only be 
   ### done if the EEPROM_USABLE_SWITCH has previously been set to a 1.
   if [ $EEPROM_USABLE_SWITCH -eq 1 ]
    then
      echo "\n*MSG* Updating the eeprom parameter nvramrc with the following:"
      echo "*MSG* devalias $DEVALIAS_NAME $BACKOFF_BOOTPATH"
      echo "#!/bin/sh" > $TEMP1
      echo "eeprom nvramrc 2>/dev/null | grep -v \"devalias $DEVALIAS_NAME\" |" >> $TEMP1
      echo "   (" >> $TEMP1
      echo "      sed -e \"1s/nvramrc=//\" -e 1p -e 1d" >> $TEMP1
      echo "      echo \"devalias $DEVALIAS_NAME $BACKOFF_BOOTPATH\"" >> $TEMP1
      echo "   ) | eeprom nvramrc=\"\`cat\`\"" >> $TEMP1
      echo "exit $?" >> $TEMP1
      chmod 744 $TEMP1
      if [ "$DEBUG" = "yes" ]
       then
         echo "*DEBUG COMMAND* ---v"
         cat $TEMP1 | head -6 | tail -5
       else
         cat $TEMP1 | head -6 | tail -5 >> $PROGRESS_FILE
         echo "*COMMAND* ---v"
         cat $TEMP1 | head -6 | tail -5
         $TEMP1 ; RC=$?
         if [ $RC -ne 0 ]
          then
            echo "*ERROR* eeprom exited with a return code of $RC"
            exit 1
         fi
         DEVALIAS_SET_SWITCH=1
         NVRAMRC_SET_SWITCH=1
      fi
      DoUseNvramrc
   fi
fi

### Do what is needed to mount up the root partition on the backoff device
### Make sure a directory is defined for the mount point
if [ ! -d $USAGE_MNT_POINT ]
 then
   echo "\n*MSG* Building the directory $USAGE_MNT_POINT for the mount point"
   COMMAND="mkdir $USAGE_MNT_POINT"
   if [ "$DEBUG" = "yes" ]
    then
      echo "*DEBUG COMMAND* $COMMAND"
    else
      echo "$COMMAND" >> $PROGRESS_FILE
      echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
      if [ $RC -ne 0 ]
       then
         echo "*ERROR* mkdir exited with a return code of $RC"
         exit 1
      fi
   fi
fi
### See if the mount point we use is already mounted, if it is, umount it.
df | grep "^$USAGE_MNT_POINT" > /dev/null 2>&1
if [ $? -eq 0 ] 
 then
   echo "\n*MSG* Umounting $USAGE_MNT_POINT for script usage"
   COMMAND="umount $USAGE_MNT_POINT"
   if [ "$DEBUG" = "yes" ]
    then
      echo "*DEBUG COMMAND* $COMMAND"
    else
      echo "$COMMAND" >> $PROGRESS_FILE
      echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
      if [ $RC -ne 0 ]
       then
         echo "*ERROR* umount (1) exited with a return code of $RC"
         exit 1
      fi
   fi
fi 
### Now we know we are ready to mount the root partition of the backoff device
echo "\n*MSG* Mounting /dev/dsk/${PHYSICAL_BACKOFF_DISK}s${ROOT_BACKOFF_PARTITION} as $USAGE_MNT_POINT for script usage"
COMMAND="mount -F ufs /dev/dsk/${PHYSICAL_BACKOFF_DISK}s${ROOT_BACKOFF_PARTITION} $USAGE_MNT_POINT"
if [ "$DEBUG" = "yes" ]
 then
   echo "*DEBUG COMMAND* $COMMAND"
 else
   echo "$COMMAND" >> $PROGRESS_FILE
   echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
   if [ $RC -ne 0 ]
    then
      echo "*ERROR* mount exited with a return code of $RC"
      exit 1
   fi
fi

### Now copy the modified files from the Preparation Function
echo "\n*MSG* Overlay ${USAGE_MNT_POINT}/etc/vfstab with a modified version without VxVM devices"
COMMAND="cp ${USAGE_MNT_POINT}${PROJECT_DIR}/etc_vfstab_${PHYSICAL_BACKOFF_DISK}.change ${USAGE_MNT_POINT}/etc/vfstab"
if [ "$DEBUG" = "yes" ]
 then
   echo "*DEBUG COMMAND* $COMMAND"
 else
   echo "$COMMAND" >> $PROGRESS_FILE
   echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
   if [ $RC -ne 0 ]
    then
      echo "*ERROR* cp (4) exited with a return code of $RC"
      exit 1
   fi
fi
echo "\n*MSG* Overlay ${USAGE_MNT_POINT}/etc/system with a modified version without VxVM"
COMMAND="cp ${USAGE_MNT_POINT}${PROJECT_DIR}/etc_system.change ${USAGE_MNT_POINT}/etc/system"
if [ "$DEBUG" = "yes" ]
 then
   echo "*DEBUG COMMAND* $COMMAND"
 else
   echo "$COMMAND" >> $PROGRESS_FILE
   echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
   if [ $RC -ne 0 ]
    then
      echo "*ERROR* cp (5) exited with a return code of $RC"
      exit 1
   fi
fi

### Touch a VM file so that VM will not startup at boot time
echo "\n*MSG* Touching a file to prevent VxVM from starting at boot time"
COMMAND="touch ${USAGE_MNT_POINT}/etc/vx/reconfig.d/state.d/install-db"
if [ "$DEBUG" = "yes" ]
 then
   echo "*DEBUG COMMAND* $COMMAND"
 else
   echo "$COMMAND" >> $PROGRESS_FILE
   echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
   if [ $RC -ne 0 ]
    then
      echo "*ERROR* touch exited with a return code of $RC"
      exit 1
   fi
fi

### Copy the .Break_Root_Mirroring_progress file to the backoff root partition
### This contains all the commands executed for the Break Root Mirroring 
### Function with the exception of the last umount which follows this.
echo "\n*MSG* Copying the command progress file over to the backoff root partition"
COMMAND="cp $PROJECT_DIR/.Break_Root_Mirroring_progress ${USAGE_MNT_POINT}${PROJECT_DIR}/.Break_Root_Mirroring_progress"
if [ "$DEBUG" = "yes" ]
 then
   echo "*DEBUG COMMAND* $COMMAND"
 else
   echo "$COMMAND" >> $PROGRESS_FILE
   echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
   if [ $RC -ne 0 ]
    then
      echo "*ERROR* cp (6) exited with a return code of $RC"
      exit 1
   fi
fi

### Umount the backoff root partiton
echo "\n*MSG* Umounting $USAGE_MNT_POINT, all work is done"
COMMAND="umount $USAGE_MNT_POINT"
if [ "$DEBUG" = "yes" ]
 then
   echo "*DEBUG COMMAND* $COMMAND"
 else
   echo "$COMMAND" >> $PROGRESS_FILE
   echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
   if [ $RC -ne 0 ]
    then
      echo "*ERROR* umount (2) exited with a return code of $RC"
      exit 1
   fi
fi

### The work is done, prepare to end with any necessary messages
if [ "$DEBUG" = "yes" ]
 then
   echo "\n*MSG* The Break Root Mirroring Function has finished good!  (DEBUG Mode)"
 else
   ### bootblock instructions
   if [ $BOOTBLOCK_BUILT_SWITCH -eq 0 ]
    then
      echo "\n*INSTRUCTIONS* --> Create a bootblock on the root partition (s${ROOT_BACKOFF_PARTITION}) of the"
      echo "*INSTRUCTIONS*     backoff device ($PHYSICAL_BACKOFF_DISK).  Do a man on installboot for" 
      echo "*INSTRUCTIONS*     more information." 
   fi
   
   ### devalias instructions
   case "${DEVALIAS_SET_SWITCH}${NVRAMRC_SET_SWITCH}${USE_NVRAMRC_SET_SWITCH}" in
      '111'|'100')
         ### Everything is set, no manual instructions needed
         ;;
      *)
         ### This includes '000' and '110' and anything not programmed for
         echo "\n*INSTRUCTIONS* --> OpenBoot parameters for the devalias of the bootpath"
         echo "*INSTRUCTIONS*     need to be verified.  If the following parameters don't"
         echo "*INSTRUCTIONS*     have the associated values, they need to be manually"
         echo "*INSTRUCTIONS*     set at the OpenBoot prompt."
         echo "*INSTRUCTIONS*     At the OpenBoot prompt enter the following command:"
         echo "*INSTRUCTIONS*        printenv use-nvramrc?"
         echo "*INSTRUCTIONS*     The returned result must be:"
         echo "*INSTRUCTIONS*        true"
         echo "*INSTRUCTIONS*     If not, then it must be set with the following command:"
         echo "*INSTRUCTIONS*        setenv use-nvramrc? true"
         echo "*INSTRUCTIONS*     Enter the following command:"
         echo "*INSTRUCTIONS*        printenv nvramrc"
         echo "*INSTRUCTIONS*     A returned result must be:"
         echo "*INSTRUCTIONS*        devalias $DEVALIAS_NAME $BACKOFF_BOOTPATH"
         echo "*INSTRUCTIONS*     If not, then it must be set with the following commands:"
         echo "*INSTRUCTIONS*        nvalias $DEVALIAS_NAME $BACKOFF_BOOTPATH"
         echo "*INSTRUCTIONS*        nvstore"
         ;;
   esac

   ### Final and constant instructions
   echo "\n*INSTRUCTIONS* --> When all previous instructions, if any, have been"
   echo "*INSTRUCTIONS*     followed, it is highly recommended to boot the server"
   echo "*INSTRUCTIONS*     from the backoff device to ensure it is bootable and"
   echo "*INSTRUCTIONS*     works. To do this, shutdown the server cleanly and then"
   echo "*INSTRUCTIONS*     from the OpenBoot prompt enter the following command:"
   echo "*INSTRUCTIONS*        boot $DEVALIAS_NAME"
   
   if [ $WARNING_SWITCH -eq 1 ]
    then
      echo "\n*MSG* The Break Root Mirroring Function has finished with warnings!"
      echo "*MSG* Read the previous warnings and instructions and take any appropriate"
      echo "*MSG* actions if needed."
    else
      echo "\n*MSG* The Break Root Mirroring Function has finished good!"
      echo "*MSG* Read the previous instructions and take any appropriate actions."
   fi
fi

}  ########## End of Function2

Function3() 
{
### Validate to make sure the user wants to do this function
while [ true ]
do
   echo "\nYou have chosen to remirror the root partitions using $PHYSICAL_BACKOFF_DISK as the source."
   echo "This is Step 1 of a two step process of using the back-off device."
   echo "\nIs this correct? (y/n): \c"
   read ANSWER
   if [ "$ANSWER" = "y" ]
    then
      break
   fi
   if [ "$ANSWER" = "n" ]
    then
      echo "\nLeaving the back-off automation script - try again!"
      exit 0
   fi
   echo "\n Selection not recognized, try again by pressing Return/Enter!"
   read JUNK
done

### Set the name of the function progression file
### This file is used to log commands just before they get executed.  This file
### gets used to determine if a command that may cause potential problems if
### executed twice has already been executed once. 
PROGRESS_FILE=$PROJECT_DIR/.Use_Backoff_to_Recover_Root_Partitions_Step1_progress
touch $PROGRESS_FILE

### Ensure the server is booted from the backoff device and not the active!
if [ "$THE_LIVE_ACTUAL_BOOTPATH" != "$BACKOFF_BOOTPATH" ]
 then
   if [ "$DEBUG" = "yes" ]
    then
      echo "\n*DEBUG MSG* For this Function, the server must be booted from device $PHYSICAL_BACKOFF_DISK"
      echo "*DEBUG MSG* which has a bootpath of ${BACKOFF_BOOTPATH}"
    else
      echo "\n*ERROR* For this Function, the server must be booted from device $PHYSICAL_BACKOFF_DISK"
      echo "*ERROR* which has a bootpath of ${BACKOFF_BOOTPATH}"
      exit 1
   fi
fi

### Ensure VM is not running!
if [ "`vxdctl mode`" != 'mode: not-running' ]
 then
   if [ "$DEBUG" = "yes" ]
    then
      echo "\n*DEBUG MSG* For this Function, Volume Manager must not be running!"
    else
      echo "\n*ERROR* For this Function, Volume Manager must not be running!"
      echo "*ERROR* Must be booted on the backoff device with unecapsulated filesystems!"
      exit 1
   fi
fi

### Issue a few commands to get VM up and all the volumes in a disabled state
### Start some worker threads, then start vxconfigd in disabled mode and then  
### enable vxconfigd.
echo "\n*MSG* Starting the VxVM worker threads"
COMMAND="vxiod set 10"
if [ "$DEBUG" = "yes" ]
 then
   echo "*DEBUG COMMAND* $COMMAND"
 else
   ### Check to see if this command has already been executed (good or bad)
   PriorExecutionCheck
   if [ $? -eq 0 ]
    then
      ### The command has not been executed before this time
      echo "$COMMAND" >> $PROGRESS_FILE
      echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
      if [ $RC -ne 0 ]
       then
         echo "*ERROR* vxiod exited with a return code of $RC"
         exit 1
      fi
    else
      ### The command has been executed before, so don't do it again
      WarningMsg1
   fi
fi

echo "\n*MSG* Starting vxconfigd in disabled mode"
COMMAND="vxconfigd -d"
if [ "$DEBUG" = "yes" ]
 then
   echo "*DEBUG COMMAND* $COMMAND"
 else
   ### Check to see if this command has already been executed (good or bad)
   PriorExecutionCheck
   if [ $? -eq 0 ]
    then
      ### The command has not been executed before this time
      echo "$COMMAND" >> $PROGRESS_FILE
      echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
      if [ $RC -ne 0 ]
       then
         echo "*ERROR* vxconfigd exited with a return code of $RC"
         exit 1
      fi
    else
      ### The command has been executed before, so don't do it again
      WarningMsg1
   fi
fi

echo "\n*MSG* Enabling vxconfigd"
COMMAND="vxdctl enable"
if [ "$DEBUG" = "yes" ]
 then
   echo "*DEBUG COMMAND* $COMMAND"
 else
   ### Check to see if this command has already been executed (good or bad)
   PriorExecutionCheck
   if [ $? -eq 0 ]
    then
      ### The command has not been executed before this time
      echo "$COMMAND" >> $PROGRESS_FILE
      echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
      if [ $RC -ne 0 ]
       then
         echo "*ERROR* vxdctl exited with a return code of $RC"
         exit 1
      fi
    else
      ### The command has been executed before, so don't do it again
      WarningMsg1
   fi
fi

### Attach the plexes of the backoff device to the active volumes then
### set the states of the backoff plexes to CLEAN.  Then offline the associated
### plexes from the active device.
for FS in root swap usr var opt
do
   case $FS in
      root)
         TMP_VOL_NAME=$ROOT_VOL_NAME
         TMP_BACKOFF_PLEX=$ROOT_BACKOFF_PLEX
         TMP_ACTIVE_PLEX=$ROOT_ACTIVE_PLEX
         ;;
      swap)
         TMP_VOL_NAME=$SWAP_VOL_NAME
         TMP_BACKOFF_PLEX=$SWAP_BACKOFF_PLEX
         TMP_ACTIVE_PLEX=$SWAP_ACTIVE_PLEX
         ;;
      usr)
         TMP_VOL_NAME=$USR_VOL_NAME
         TMP_BACKOFF_PLEX=$USR_BACKOFF_PLEX
         TMP_ACTIVE_PLEX=$USR_ACTIVE_PLEX
         ;;
      var)
         TMP_VOL_NAME=$VAR_VOL_NAME
         TMP_BACKOFF_PLEX=$VAR_BACKOFF_PLEX
         TMP_ACTIVE_PLEX=$VAR_ACTIVE_PLEX
         ;;
      opt)
         TMP_VOL_NAME=$OPT_VOL_NAME
         TMP_BACKOFF_PLEX=$OPT_BACKOFF_PLEX
         TMP_ACTIVE_PLEX=$OPT_ACTIVE_PLEX
         ;;
      *)
         echo " Should never ever get here - someone has messed with the script (6)"
         exit 1
         ;;
   esac

   if [ "$TMP_VOL_NAME" != '.' ]
    then

      echo "\n*MSG* Attaching plex: $TMP_BACKOFF_PLEX to volume: $TMP_VOL_NAME"
      COMMAND="vxplex -g rootdg att $TMP_VOL_NAME $TMP_BACKOFF_PLEX"
      if [ "$DEBUG" = "yes" ]
       then
         echo "*DEBUG COMMAND* $COMMAND"
       else
         ### Check to see if this command has already been executed (good or bad)
         PriorExecutionCheck
         if [ $? -eq 0 ]
          then
            ### The command has not been executed before this time
            echo "$COMMAND" >> $PROGRESS_FILE
            echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
            if [ $RC -ne 0 ]
             then
               echo "*ERROR* vxplex (3) exited with a return code of $RC"
               exit 1
            fi
          else
            ### The command has been executed before, so don't do it again
            WarningMsg1
         fi
      fi

      echo "\n*MSG* Setting state of plex $TMP_BACKOFF_PLEX to CLEAN"
      COMMAND="vxmend -g rootdg fix clean $TMP_BACKOFF_PLEX"
      if [ "$DEBUG" = "yes" ]
       then
         echo "*DEBUG COMMAND* $COMMAND"
       else
         ### Check to see if this command has already been executed (good or bad)
         PriorExecutionCheck
         if [ $? -eq 0 ]
          then
            ### The command has not been executed before this time
            echo "$COMMAND" >> $PROGRESS_FILE
            echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
            if [ $RC -ne 0 ]
             then
               echo "*ERROR* vxmend (1) exited with a return code of $RC"
               exit 1
            fi
          else
            ### The command has been executed before, so don't do it again
            WarningMsg1
         fi
      fi

      echo "\n*MSG* Setting state of plex $TMP_ACTIVE_PLEX to OFFLINE"
      COMMAND="vxmend -g rootdg off $TMP_ACTIVE_PLEX"
      if [ "$DEBUG" = "yes" ]
       then
         echo "*DEBUG COMMAND* $COMMAND"
       else
         ### Check to see if this command has already been executed (good or bad)
         PriorExecutionCheck
         if [ $? -eq 0 ]
          then
            ### The command has not been executed before this time
            echo "$COMMAND" >> $PROGRESS_FILE
            echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
            if [ $RC -ne 0 ]
             then
               echo "*ERROR* vxmend (2) exited with a return code of $RC"
               exit 1
            fi
          else
            ### The command has been executed before, so don't do it again
            WarningMsg1
         fi
      fi
   fi
done

### Issue a few commands to get all volumes started and start any recovery
### operations if needed.
echo "\n*MSG* Starting all the volumes"
COMMAND="vxrecover -ns"
if [ "$DEBUG" = "yes" ]
 then
   echo "*DEBUG COMMAND* $COMMAND"
 else
   ### Check to see if this command has already been executed (good or bad)
   PriorExecutionCheck
   if [ $? -eq 0 ]
    then
      ### The command has not been executed before this time
      echo "$COMMAND" >> $PROGRESS_FILE
      echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
      if [ $RC -ne 0 ]
       then
         echo "*ERROR* vxrecover (1) exited with a return code of $RC"
         exit 1
      fi
    else
      ### The command has been executed before, so don't do it again
      WarningMsg1
   fi
fi

echo "\n*MSG* Starting recovery operations on volumes if needed"
COMMAND="vxrecover -vs"
if [ "$DEBUG" = "yes" ]
 then
   echo "*DEBUG COMMAND* $COMMAND"
 else
   ### Check to see if this command has already been executed (good or bad)
   PriorExecutionCheck
   if [ $? -eq 0 ]
    then
      ### The command has not been executed before this time
      echo "*MSG* This command may run for some time - be patient!"
      echo "$COMMAND" >> $PROGRESS_FILE
      echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
      if [ $RC -ne 0 ]
       then
         echo "*ERROR* vxrecover (2) exited with a return code of $RC"
         exit 1
      fi
    else
      ### The command has been executed before, so don't do it again
      WarningMsg1
   fi
fi

### Now restore the system files: /etc/vfstab and /etc/system to their original
### state 
echo "\n*MSG* Restore /etc/vfstab to original state"
COMMAND="cp ${PROJECT_DIR}/etc_vfstab.before /etc/vfstab"
if [ "$DEBUG" = "yes" ]
 then
   echo "*DEBUG COMMAND* $COMMAND"
 else
   echo "$COMMAND" >> $PROGRESS_FILE
   echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
   if [ $RC -ne 0 ]
    then
      echo "*ERROR* cp (7) exited with a return code of $RC"
      exit 1
   fi
fi
echo "\n*MSG* Restore /etc/system to original state"
COMMAND="cp ${PROJECT_DIR}/etc_system.before /etc/system"
if [ "$DEBUG" = "yes" ]
 then
   echo "*DEBUG COMMAND* $COMMAND"
 else
   echo "$COMMAND" >> $PROGRESS_FILE
   echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
   if [ $RC -ne 0 ]
    then
      echo "*ERROR* cp (8) exited with a return code of $RC"
      exit 1
   fi
fi

### Remove the VM file that keeps VM from starting at boot time
echo "\n*MSG* Removing file /etc/vx/reconfig.d/state.d/install-db"
COMMAND="rm /etc/vx/reconfig.d/state.d/install-db"
if [ "$DEBUG" = "yes" ]
 then
   echo "*DEBUG COMMAND* $COMMAND"
 else
   echo "$COMMAND" >> $PROGRESS_FILE
   echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
   if [ $RC -ne 0 ]
    then
      echo "*ERROR* rm exited with a return code of $RC"
      exit 1
   fi
fi

### The work is done, prepare to end with any necessary messages and maybe 
### touch a done file
if [ "$DEBUG" = "yes" ]
 then
   echo "\n*MSG* The Use Back-off to Recover Root Partitions (Step 1) Function has finished"
   echo "*MSG* good!  (DEBUG Mode)"
 else
   ### Touch a file to show that this step is done..
   touch $PROJECT_DIR/.Use_Backoff_to_Recover_Root_Partitions_Step1_done
   
   ### Final and constant instructions
   echo "\n*INSTRUCTIONS* --> The server must now be rebooted before continuing with"
   echo "*INSTRUCTIONS*     Function 4 (Step 2).  Cleanly shutdown the server and then"
   echo "*INSTRUCTIONS*     boot from the backoff device ($PHYSICAL_BACKOFF_DISK)."
   echo "*INSTRUCTIONS*     When the server is back up after the reboot, you must"
   echo "*INSTRUCTIONS*     execute Function 4 (Step 2) to finish the recovery process."
   if [ $WARNING_SWITCH -eq 1 ]
    then
      echo "\n*MSG* The Use Back-off to Recover Root Partitions (Step 1) Function has finished"
      echo "*MSG* with warnings!  Read the previous warnings and instructions and take"
      echo "*MSG* any appropriate actions if needed."
    else
      echo "\n*MSG* The Use Back-off to Recover Root Partitions (Step 1) Function has"
      echo "*MSG* finished good!"
      echo "*MSG* Read the previous instructions and take any appropriate actions."
   fi
fi
}  ########## End of Function3

Function4() 
{
### Validate to make sure the user wants to do this function
while [ true ]
do
   echo "\nYou have chosen to remirror the root partitions using $PHYSICAL_BACKOFF_DISK as the source."
   echo "This is Step 2 of a two step process of using the back-off device."
   echo "\nIs this correct? (y/n): \c"
   read ANSWER
   if [ "$ANSWER" = "y" ]
    then
      break
   fi
   if [ "$ANSWER" = "n" ]
    then
      echo "\nLeaving the back-off automation script - try again!"
      exit 0
   fi
   echo "\n Selection not recognized, try again by pressing Return/Enter!"
   read JUNK
done

### Set the name of the function progression file
### This file is used to log commands just before they get executed.  This file
### gets used to determine if a command that may cause potential problems if
### executed twice has already been executed once. 
PROGRESS_FILE=$PROJECT_DIR/.Use_Backoff_to_Recover_Root_Partitions_Step2_progress
touch $PROGRESS_FILE

### Ensure the server is booted from the backoff device and not the active!
if [ "$THE_LIVE_ACTUAL_BOOTPATH" != "$BACKOFF_BOOTPATH" ]
 then
   if [ "$DEBUG" = "yes" ]
    then
      echo "\n*DEBUG MSG* For this Function, the server must be booted from device $PHYSICAL_BACKOFF_DISK"
      echo "*DEBUG MSG* which has a bootpath of ${BACKOFF_BOOTPATH}"
    else
      echo "\n*ERROR* For this Function, the server must be booted from device $PHYSICAL_BACKOFF_DISK"
      echo "*ERROR* which has a bootpath of ${BACKOFF_BOOTPATH}"
      exit 1
   fi
fi

### Ensure that the Use Back-off to Recover Root Partitions (Step 1) Function
### was already ran
if [ ! -f $PROJECT_DIR/.Use_Backoff_to_Recover_Root_Partitions_Step1_done ]
 then
   if [ "$DEBUG" = "yes" ]
    then
      echo "\n*DEBUG MSG* For this Function to properly work, the Use Back-off to Recover"
      echo "*DEBUG MSG* Root Partitions (Step 1) Function must be executed in its"
      echo "*DEBUG MSG* entirety first!"
    else
      echo "\n*ERROR* For this Function to properly work, the Use Back-off to Recover"
      echo "ERROR* Root Partitions (Step 1) Function must be executed in its"
      echo "*ERROR* entirety first!"
      exit 1
   fi
fi

### Modify the VTOC of the backoff device back to its original configuration
echo "\n*MSG* Modifying the VTOC of device $PHYSICAL_BACKOFF_DISK back to original configuration"
COMMAND="format -s -f $PROJECT_DIR/format_command_${PHYSICAL_BACKOFF_DISK}.before $PHYSICAL_BACKOFF_DISK"

if [ "$DEBUG" = "yes" ]
 then
   echo "*DEBUG COMMAND* $COMMAND"
 else
   ### Check to see if this command has already been executed (good or bad)
   PriorExecutionCheck
   if [ $? -eq 0 ]
    then
      ### The command has not been executed before this time
      echo "$COMMAND" >> $PROGRESS_FILE
      echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
      if [ $RC -ne 0 ]
       then
         echo "*ERROR* format (3) exited with a return code of $RC"
         exit 1
      fi
    else
      ### The command has been executed before, so don't do it again
      WarningMsg1
   fi
fi

### Take the plexes of the active device out of the offline state.
for FS in root swap usr var opt
do
   case $FS in
      root)
         TMP_VOL_NAME=$ROOT_VOL_NAME
         TMP_ACTIVE_PLEX=$ROOT_ACTIVE_PLEX
         ;;
      swap)
         TMP_VOL_NAME=$SWAP_VOL_NAME
         TMP_ACTIVE_PLEX=$SWAP_ACTIVE_PLEX
         ;;
      usr)
         TMP_VOL_NAME=$USR_VOL_NAME
         TMP_ACTIVE_PLEX=$USR_ACTIVE_PLEX
         ;;
      var)
         TMP_VOL_NAME=$VAR_VOL_NAME
         TMP_ACTIVE_PLEX=$VAR_ACTIVE_PLEX
         ;;
      opt)
         TMP_VOL_NAME=$OPT_VOL_NAME
         TMP_ACTIVE_PLEX=$OPT_ACTIVE_PLEX
         ;;
      *)
         echo " Should never ever get here - someone has messed with the script (7)"
         exit 1
         ;;
   esac

   if [ "$TMP_VOL_NAME" != '.' ]
    then

      echo "\n*MSG* Taking plex $TMP_ACTIVE_PLEX out of the offline state"
      COMMAND="vxmend -g rootdg on $TMP_ACTIVE_PLEX"
      if [ "$DEBUG" = "yes" ]
       then
         echo "*DEBUG COMMAND* $COMMAND"
       else
         ### Check to see if this command has already been executed (good or bad)
         PriorExecutionCheck
         if [ $? -eq 0 ]
          then
            ### The command has not been executed before this time
            echo "$COMMAND" >> $PROGRESS_FILE
            echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
            if [ $RC -ne 0 ]
             then
               echo "*ERROR* vxmend (3) exited with a return code of $RC"
               exit 1
            fi
          else
            ### The command has been executed before, so don't do it again
            WarningMsg1
         fi
      fi
   fi
done

### Do the recovery operations to sync the mirrors 
echo "\n*MSG* Starting recovery operations on volumes to sync the mirrors"
COMMAND="vxrecover -vs"
if [ "$DEBUG" = "yes" ]
 then
   echo "*DEBUG COMMAND* $COMMAND"
 else
   ### Check to see if this command has already been executed (good or bad)
   PriorExecutionCheck
   if [ $? -eq 0 ]
    then
      ### The command has not been executed before this time
      echo "*MSG* This command will run for some time - be patient!"
      echo "$COMMAND" >> $PROGRESS_FILE
      echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
      if [ $RC -ne 0 ]
       then
         echo "*ERROR* vxrecover (3) exited with a return code of $RC"
         exit 1
      fi
    else
      ### The command has been executed before, so don't do it again
      WarningMsg1
   fi
fi

### The work is done, prepare to end with any necessary messages
if [ "$DEBUG" = "yes" ]
 then
   echo "\n*MSG* The Use Back-off to Recover Root Partitions (Step 2) Function has finished"
   echo "*MSG* good!  (DEBUG Mode)"
 else
   ### Final and constant instructions
   echo "\n*INSTRUCTIONS* --> The server should now be back to the state it was in"
   echo "*INSTRUCTIONS*     before any changes were started.  Validate the Volume"
   echo "*INSTRUCTIONS*     Manager states of all volumes and plexes by using the"
   echo "*INSTRUCTIONS*     'vxprint -ht' command."
   if [ $WARNING_SWITCH -eq 1 ]
    then
      echo "\n*MSG* The Use Back-off to Recover Root Partitions (Step 2) Function has"
      echo "*MSG* finished with warnings!  Read the previous warnings and instructions"
      echo "*MSG* and take any appropriate actions if needed."
    else
      echo "\n*MSG* The Use Back-off to Recover Root Partitions (Step 2) Function has"
      echo "*MSG* finished good!"
      echo "*MSG* Read the previous instructions and take any appropriate actions."
   fi
fi
}  ########## End of Function4

Function5() 
{
### Validate to make sure the user wants to do this function
while [ true ]
do
   echo "\nYou have chosen to remirror the root partitions using $PHYSICAL_ACTIVE_DISK as the source."
   echo "\nIs this correct? (y/n): \c"
   read ANSWER
   if [ "$ANSWER" = "y" ]
    then
      break
   fi
   if [ "$ANSWER" = "n" ]
    then
      echo "\nLeaving the back-off automation script - try again!"
      exit 0
   fi
   echo "\n Selection not recognized, try again by pressing Return/Enter!"
   read JUNK
done

### Set the name of the function progression file
### This file is used to log commands just before they get executed.  This file
### gets used to determine if a command that may cause potential problems if
### executed twice has already been executed once. 
PROGRESS_FILE=$PROJECT_DIR/.Remirror_Root_Partitions_Backoff_not_needed_progress
touch $PROGRESS_FILE

### Ensure the server is booted from the active device and not the backoff!
if [ "$THE_LIVE_ACTUAL_BOOTPATH" != "$ACTIVE_BOOTPATH" ]
 then
   if [ "$DEBUG" = "yes" ]
    then
      echo "\n*DEBUG MSG* For this Function, the server must be booted from device $PHYSICAL_ACTIVE_DISK"
      echo "*DEBUG MSG* which has a bootpath of ${ACTIVE_BOOTPATH}"
    else
      echo "\n*ERROR* For this Function, the server must be booted from device $PHYSICAL_ACTIVE_DISK"
      echo "*ERROR* which has a bootpath of ${ACTIVE_BOOTPATH}"
      exit 1
   fi
fi

### Modify the VTOC of the backoff device back to its original configuration
echo "\n*MSG* Modifying the VTOC of device $PHYSICAL_BACKOFF_DISK back to original configuration"
COMMAND="format -s -f $PROJECT_DIR/format_command_${PHYSICAL_BACKOFF_DISK}.before $PHYSICAL_BACKOFF_DISK"

if [ "$DEBUG" = "yes" ]
 then
   echo "*DEBUG COMMAND* $COMMAND"
 else
   ### Check to see if this command has already been executed (good or bad)
   PriorExecutionCheck
   if [ $? -eq 0 ]
    then
      ### The command has not been executed before this time
      echo "$COMMAND" >> $PROGRESS_FILE
      echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
      if [ $RC -ne 0 ]
       then
         echo "*ERROR* format (2) exited with a return code of $RC"
         exit 1
      fi
    else
      ### The command has been executed before, so don't do it again
      WarningMsg1
   fi
fi

### Attach the plexes of the backoff device to the active volumes
for FS in root swap usr var opt
do
   case $FS in
      root)
         TMP_VOL_NAME=$ROOT_VOL_NAME
         TMP_BACKOFF_PLEX=$ROOT_BACKOFF_PLEX
         ;;
      swap)
         TMP_VOL_NAME=$SWAP_VOL_NAME
         TMP_BACKOFF_PLEX=$SWAP_BACKOFF_PLEX
         ;;
      usr)
         TMP_VOL_NAME=$USR_VOL_NAME
         TMP_BACKOFF_PLEX=$USR_BACKOFF_PLEX
         ;;
      var)
         TMP_VOL_NAME=$VAR_VOL_NAME
         TMP_BACKOFF_PLEX=$VAR_BACKOFF_PLEX
         ;;
      opt)
         TMP_VOL_NAME=$OPT_VOL_NAME
         TMP_BACKOFF_PLEX=$OPT_BACKOFF_PLEX
         ;;
      *)
         echo " Should never ever get here - someone has messed with the script (5)"
         exit 1
         ;;
   esac

   if [ "$TMP_VOL_NAME" != '.' ]
    then

      echo "\n*MSG* Attaching plex: $TMP_BACKOFF_PLEX to volume: $TMP_VOL_NAME (mirroring)"
      COMMAND="vxplex -g rootdg att $TMP_VOL_NAME $TMP_BACKOFF_PLEX"
      if [ "$DEBUG" = "yes" ]
       then
         echo "*DEBUG COMMAND* $COMMAND"
       else
         ### Check to see if this command has already been executed (good or bad)
         PriorExecutionCheck
         if [ $? -eq 0 ]
          then
            ### The command has not been executed before this time
            echo "*MSG* This command will run for some time - be patient!"
            echo "$COMMAND" >> $PROGRESS_FILE
            echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
            if [ $RC -ne 0 ]
             then
               echo "*ERROR* vxplex (2) exited with a return code of $RC"
               exit 1
            fi
          else
            ### The command has been executed before, so don't do it again
            WarningMsg1
         fi
      fi
   fi
done

### The work is done, prepare to end with any necessary messages
if [ "$DEBUG" = "yes" ]
 then
   echo "\n*MSG* The Remirror Root Partitions - Back-off not needed Function has finished"
   echo "*MSG* good!  (DEBUG Mode)"
 else
   if [ $WARNING_SWITCH -eq 1 ]
    then
      echo "\n*MSG* The Remirror Root Partitions - Back-off not needed Function has finished"
      echo "*MSG* with warnings!  Read the previous warnings and take any appropriate"
      echo "*MSG* actions if needed."
    else
      echo "\n*MSG* The Remirror Root Partitions - Back-off not needed Function has"
      echo "*MSG* finished good!"
   fi
fi
}  ########## End of Function5

### Variable Definitions
ROOT_DIR=/back-off
PROJECT_ROOT_DIR=$ROOT_DIR/project
TEMP1=$ROOT_DIR/temp1
TEMP2=$ROOT_DIR/temp2
DISK_PARTITIONS="0 1 2 3 4 5 6 7"
BOOTBLOCKFILENAME="/usr/platform/`uname -i`/lib/fs/ufs/bootblk"
DEVALIAS_NAME="back-off"
USAGE_MNT_POINT=/bofmnt

SCRIPT_NAME="`basename $0`"
VERSION=1.3

### Start of main logic

### Has debug mode been requested
### Set the DEBUG variable to 'yes' if you only want to see what the commands
### would look like for function 2, 3, 4 or 5.  The commands will NOT be
### executed if set to 'yes'.
DEBUG=""
if [ $# -ne 0 ]
 then
   if [ "$1" = "debug" ]
    then
      DEBUG="yes"
   fi
fi

### Determine the type of Volume Manager package installed and its version.
echo "\nPkginfo data is being gathered, please be patient..."
echo "On older/slower servers it may take a few seconds before the menu is"
echo "displayed..."
VXVM_PKG=`pkginfo | grep '^system' | grep -i 'vxvm ' | awk '{ print $2 }'`
if [ "X$VXVM_PKG" = "X" ]
 then
   echo "\nCould not determine the package name for Volume Manager!"
   echo "Leaving the back-off automation script!"
   exit 1
fi
VXVM_VERSION=`pkginfo -l $VXVM_PKG | grep 'VERSION:' | awk '{ print $2 }' | cut -d',' -f1`
if [ "X$VXVM_VERSION" = "X" ]
 then
   echo "\nCould not determine the version for Volume Manager!"
   echo "Leaving the back-off automation script!"
   exit 1
fi

### Find out what function the user wants to do
while [ true ]
do
   clear
   echo "\nWelcome to the back-off automation script (V${VERSION}) main menu!"
   echo "Please select the function you want to perform..\n"
   echo " 1	Preparation"
   echo " 2	Break Root Mirroring"
   echo " 3	Use Back-off to Recover Root Partitions (Step 1)" 
   echo " 4	Use Back-off to Recover Root Partitions (Step 2)"
   echo " 5	Remirror Root Partitions - Back-off not needed"
   echo "\n"
   echo " ?	Display more detail about the script and each function"
   echo " q	quit"
   echo ""
   echo " 	Volume Manager Package = $VXVM_PKG    Version = $VXVM_VERSION"
   echo ""
   echo "Select the function to perform: \c"

   read FUNCTION
   case $FUNCTION in
      1|2|3|4|5)
         break
         ;;
      q)
         echo "\nLeaving the back-off automation script!"
         exit 0
         ;;
      '?')
         clear
         ### Overall DOCUMENTATION for the script is below.  Put any new
         ### documentation after the following line (the cat), and before the
         ### line containing only the word THEEND (all caps).  When changes
         ### are made to this script be sure to update the VERSION variable
         ### to keep track of what is being used out in the field.
         cat << THEEND | more
Back-off Automation Script - Version ${VERSION}

This script automates processes associated with VxVM (Veritas Volume Manager).
Use this script when making major changes to a system and you need a back-off
process in case the changes go bad.  This script will do the following:
-> Dissociate mirrors of root filesystem volumes.  Making a back-off disk.
-> Make a disk device bootable without VxVM (unencapsulated).  The back-off 
   disk can be booted directly without a CD.
-> Resync the mirrors if the changes went well and you want the root 
   filesystems to be mirrored again.
-> Switch out plexes of a volume.  If the changes went bad, this script can
   take the back-off device and make its root filesystems the active ones
   in Volume Manager.  This will place the system back to the state it was
   in before any changes were attempted.

There are a few general assumptions which were used when designing this script.
Adhering to these will hopefully ensure the script will work properly for 
you.  The assumptions are:
-> The root filesystems have 2 and only two mirrors for each filesystem.
-> VxVM public and private partitions each have their own disk sclice.  This
   is the way a standard VxVM implementation is.  Generally speaking, the 
   standard VxVM root disk encapsulation and mirroring process should be
   followed.
-> This script will only manage, unencapsualte, the following root filesystems
   on a disk, all other filesystems will be left alone:
      / (root)
      swap (not a filesystem, but still managed)
      /usr
      /var
      /opt
-> If /usr, /var or /opt are individual filesystems, they must reside on the
   same disk as the / (root) partition.  Swap must also reside on the same
   disk.  The mirrors of these must all reside on another disk.
-> No manual changes will be made to /etc/vfstab and /etc/system during the
   time period this script is being used.  If changes are made, they will be 
   overlayed to what they were when Function 1 of this script was ran for the
   project being used.  Same holds true for the VTOC configurations of the 
   active and back-off device.  Depending upon the situation, this script
   may restore them to what they were when the project was created.
-> For E10K's, E15K's or SunFires, eeprom commands are not effective for 
   carrying boot parameter changes through a system reboot.  Changes for
   these types of systems must be done at the OBP prompt to make them stick.
   This script should detect these class of servers and issue some manual
   instructions to follow for setting up a devalias if needed.


TERMINOLOGY
-> Active Device = The device the user will use to add patches, make changes
    on, actively use during the maintenance process.
-> Back-off Device = The device being set aside for back-off purposes only.
    This script will make the device bootable, with unecapsulated partitions,
    outside of Volume Manager control.  No CD will be required to restore
    the system to the state it was in before any changes were attempted.  Once
    this device has been setup as a back-off, the user must not manually make
    any changes on it, unless instructed by this script.


DESCRIPTIONS OF THE FUNCTIONS
-> Function 1 - Preparation
    Gathers the current configuration, asks the user a few questions and
    stores the configurations for later use.  The data is stored in a directory
    and is referred to as a project.  A project must be created before any
    of the other functions can be executed.  The project must be complete and
    not manually modified to be valid for use by the other functions.
-> Function 2 - Break Root Mirroring
    Dissociates a mirror set of the managed filesystems.  Makes the back-off
    device bootable outside of Volume Manager.  The partitions on the back-off
    device are fsck'ed to ensure their integrity.  Function 1 must be 
    successfully executed and a project built for this Function to operate.
-> Function 3 - Use Back-off to Recover Root Partitions (Step 1)
    The changes to the active disk did not go as planned and now they must
    be backed off - the system must be restored to a state before the changes
    were attempted.  This Function is step 1 of a two step process that will
    switch the active plexes for the managed filesystems (volumes).  When
    complete this Function will have Volume Manager set to use the plexes on
    the back-off device as the source plexes of the volumes.  Data in the
    managed filesystems on the active device will be overlayed.  Function 1
    and 2 must be successfully executed for this Function to properly work.
    When this Function completes, the server must be rebooted using the
    back-off device as the boot device.
-> Function 4 - Use Back-off to Recover Root Partitions (Step 2)
    This is step 2 of a two step process (continuation of Function 3 after
    the server was rebooted using the back-off device as the boot device).
    This Function will instruct Volume Manager to resync the mirrors, with
    the back-off device being the source mirrors.  The reboot after Function
    3 actually came up using the plexes on the back-off device as the
    live and enabled plexes for the volumes.  Data in the managed filesystems
    on the the active device will be overlayed.  Function 1, 2 and 3 must
    be successfully executed for this Function to properly work.
-> Function 5 - Remirror Root Partitions - Back-off not needed
    The changes to the active device went well and now the back-off device
    needs to be resynced to the active device.  This Function will instruct 
    Volume Manager to resync the mirrors, with the active device being the
    source mirrors.  Data in the managed filesystems on the back-off device
    will be overlayed.  Function 1 and 2 must be successfully executed for
    this Function to properly work.
    

INPUT PARAMETERS (positional)
-> parm1 = 'debug'
       Puts the script into debug mode and will show the values of
       variables and will show the commands to be executed, BUT will not
       execute them.  This is an optional parameter.


RETURN CODES
-> 0 = Good
-> 1 = An error has occurred and the script can not continue


TEST/COMPATIBLE ENVIRONMENTS
-> Version 1.0 of this script:
     Tested on:
       Solaris 2.6
       Solaris 8 
       VxVM 3.2,REV=08.15.2001.23.27 
             PSTAMP: VERITAS-3.2t-GA:14-August-2001)
       VxVM 3.0.4,REV=04.18.2000.10.00
             PSTAMP: VERITAS-3.0.4e_p5.1:29-March-2001
       Sun Enterprise VM 2.5 
             PSTAMP: veritas-2.5i:10-sept-1997)
     Compatibility Facts: 
       It works on Solaris 2.6
       It works on Solaris 8
       It works with Sun Enterprise VM 2.5
       It works with Veritas VxVM 3.0.4
       It works with Veritas VxVM 3.2
     Compatibility Assumptions: 
       It should work on Solaris 7
       It should work on any version of VxVM between 2.5 and 3.2


MODIFICATIONS LOG
 -----------------------------------------------------------------------------
 | Version |   Date   |     Coder     | Description                          |
 |=========|==========|===============|======================================|
 | 1.0     | 20020411 | James Baack   | New                                  |
 |---------|----------|---------------|--------------------------------------|
 | 1.1     | 20020420 | James Baack   | Hardcoded the volume name for root as|
 |         |          |               | rootvol.                             |
 |         |          |               | Added different logic to determine   |
 |         |          |               | the volume name for swap.  This is   |
 |         |          |               | needed due to the potential of more  |
 |         |          |               | than 1 swap defined in vfstab.       |
 |         |          |               | Improved the line of code to extract |
 |         |          |               | the needed vfstab information for the|
 |         |          |               | swap entry.  Again, this is needed   |
 |         |          |               | due to the potential of more than 1  |
 |         |          |               | swap defined in vfstab.              |
 |         |          |               | Added some data to the help detail.  |
 |---------|----------|---------------|--------------------------------------|
 | 1.2     | 20031124 | James Baack   | Changed the parameters used by       |
 |         |          |               | vxprint when gathering information   |
 |         |          |               | during Function 1.  Also added a     |
 |         |          |               | couple of vxdisk commands to gather  |
 |         |          |               | other valuable information during    |
 |         |          |               | Function 1.  The vxprint parameters  |
 |         |          |               | were changed due to situations where |
 |         |          |               | no volumes, plexs or sub-disks exist |
 |         |          |               | in a disk group, only the disk       |
 |         |          |               | device (dm).  The return code check  |
 |         |          |               | for the vxprint was modified to      |
 |         |          |               | deal with RCs of 11.                 |
 |---------|----------|---------------|--------------------------------------|
 |1.3      | 20031212 | James Baack   | It was found that an option added    |
 |         |          |               | for version 1.2 of this script did   |
 |         |          |               | not work for a pre 2.5.1 version of  |
 |         |          |               | Sun Cluster Volume Manager.  The     |
 |         |          |               | option is the '-r'.  Added logic to  |
 |         |          |               | determine the vxvm package and then  |
 |         |          |               | the version.  Using the version, the |
 |         |          |               | logic will determine if it should or |
 |         |          |               | should not use the '-r' option.      |
 |---------|----------|---------------|--------------------------------------|
 |         |          |               |                                      |
 -----------------------------------------------------------------------------

THEEND
         echo " "
         echo "Press Return/Enter to go back to the main menu"

         read JUNK
         ;;
      *)
         echo "\n Selection not recognized, try again by pressing Return/Enter!"
   
         read JUNK
         ;;
   esac
done

### Clear the screen
clear

case $FUNCTION in
   1)
      ### Make sure the base directories are in place
      if [ ! -d $ROOT_DIR ]
       then
         echo "\n*MSG* Directory $ROOT_DIR does not exist - creating it now"
         COMMAND="mkdir $ROOT_DIR"
         echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
         if [ $RC -ne 0 ]
          then
            echo "*ERROR* mkdir exited with a return code of $RC"
            exit 1
         fi
      fi
      if [ ! -d $PROJECT_ROOT_DIR ]
       then
         echo "\n*MSG* Directory $PROJECT_ROOT_DIR does not exist - creating it now"
         COMMAND="mkdir $PROJECT_ROOT_DIR"
         echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
         if [ $RC -ne 0 ]
          then
            echo "*ERROR* mkdir exited with a return code of $RC"
            exit 1
         fi
      fi

      ### Find a name for this project
      while [ true ]
      do
         PROJECT_NAME=`date +%Y%m%d%H%M%S`
         if [ ! -d $PROJECT_ROOT_DIR/$PROJECT_NAME ]
          then
            break
         fi
      done

      echo "\n*MSG* This project is named: $PROJECT_NAME (format-\>yyyymmddhhmmss)"
 
      PROJECT_DIR=$PROJECT_ROOT_DIR/$PROJECT_NAME

      ### Build the project directory
      echo "\n*MSG* Project directory $PROJECT_DIR is being created now"
      COMMAND="mkdir $PROJECT_DIR"
      echo "*COMMAND* $COMMAND" ; $COMMAND ; RC=$?
      if [ $RC -ne 0 ]
       then
         echo "*ERROR* mkdir exited with a return code of $RC"
         exit 1
      fi
      ;;

   2|3|4|5)
      ### Make sure the base directories are in place
      if [ ! -d $ROOT_DIR ]
       then
         echo "\n*ERROR* Directory $ROOT_DIR does not exist.  Function 1 (Preparation) must be ran first."
         exit 1
      fi
      if [ ! -d $PROJECT_ROOT_DIR ]
       then
         echo "\n*ERROR* Directory $PROJECT_ROOT_DIR does not exist.  Function 1 (Preparation) must be ran first."
         exit 1
      fi
      
      ### Determine what projects are out there and ask the user which one they
      ### want to use, also make sure the projects have successfully gone 
      ### through Preparation (.Preparation_okay file in directory).
      ls -1 $PROJECT_ROOT_DIR > $TEMP2
      cat /dev/null > $TEMP1
      exec 3<&0 < $TEMP2
      while read CANDIDATE
      do
         if [ -f $PROJECT_ROOT_DIR/$CANDIDATE/.Preparation_okay ]
          then
            ls -l $PROJECT_ROOT_DIR/$CANDIDATE | diff - $PROJECT_ROOT_DIR/$CANDIDATE/.Preparation_okay > /dev/null 2>&1
            if [ $? -eq 0 ]
             then
               ### At this point, the diff above found no differences which
               ### means the files in the project are the same as when they
               ### were created.  Unless, some joker modifed the 
               ### .Preparation_okay file to reflect the modifications.
               echo "$CANDIDATE" >> $TEMP1
             fi
         fi
      done
      exec 0<&3 3<&-
      awk 'BEGIN { count = 0 } { printf("\t%d\t%s\n", ++count, $1) }' $TEMP1 > $TEMP2
      echo "\n\tq\tquit\n" >> $TEMP2
      
      while [ true ]
      do
         echo "\n\nBelow is a list of projects successfully created through Function 1"
         echo "(Preparation) and have not been modified since that time."
         echo "\nPlease select the project you want to use..\n"
         cat $TEMP2
         echo "Select the project by the number in the left column: \c"
         read CHOICE
         PROJECT_NAME=`grep "	$CHOICE	" $TEMP2 | awk '{ print $2 }'` ## tabs are used here
         if [ -n "$PROJECT_NAME" ]
          then
            if [ "$PROJECT_NAME" = "quit" ]
             then
               echo "\nLeaving the back-off automation script!"
               exit 0
            fi
            while [ true ]
            do
               if [ "$DEBUG" = "yes" ]
                then
                  echo "\n\nProject selected is: $PROJECT_NAME  (DEBUG Mode)"
                else
                  echo "\n\nProject selected is: $PROJECT_NAME"
               fi
               echo "\nIs this correct? (y/n): \c"
               read ANSWER
               if [ "$ANSWER" = "y" ]
                then
                  break 2
               fi
               if [ "$ANSWER" = "n" ]
                then
                  continue 2
               fi
               echo "\n Selection not recognized, try again by pressing Return/Enter!"
               read JUNK
            done
         fi
         echo "\n Selection not recognized, try again by pressing Return/Enter!"
         read JUNK
      done

      if [ "$DEBUG" = "yes" ]
       then
         echo "\n*MSG* The project to be used is: $PROJECT_NAME  (DEBUG Mode)"
       else
         echo "\n*MSG* The project to be used is: $PROJECT_NAME"
      fi
 
      PROJECT_DIR=$PROJECT_ROOT_DIR/$PROJECT_NAME

      ### Set a bunch of variables to be used by the various functions
      ### These variables get set from various files in the project directory.

      ROOT_VOL_NAME="`grep '^root ' $PROJECT_DIR/volume_names | awk '{ print $2 }'`"
      SWAP_VOL_NAME="`grep '^swap ' $PROJECT_DIR/volume_names | awk '{ print $2 }'`"
      USR_VOL_NAME="`grep '^usr ' $PROJECT_DIR/volume_names | awk '{ print $2 }'`"
      VAR_VOL_NAME="`grep '^var ' $PROJECT_DIR/volume_names | awk '{ print $2 }'`"
      OPT_VOL_NAME="`grep '^opt ' $PROJECT_DIR/volume_names | awk '{ print $2 }'`"

      PHYSICAL_ACTIVE_DISK="`cat $PROJECT_DIR/physical_disk.active`"
      PHYSICAL_BACKOFF_DISK="`cat $PROJECT_DIR/physical_disk.backoff`"
      THE_LIVE_ACTUAL_BOOTPATH=`prtconf -vp | grep 'bootpath:' | awk '{ print $2 }' | awk -F"'" '{ print $2 }'`
      ACTIVE_BOOTPATH=`cat $PROJECT_DIR/bootpath_${PHYSICAL_ACTIVE_DISK}`
      BACKOFF_BOOTPATH=`cat $PROJECT_DIR/bootpath_${PHYSICAL_BACKOFF_DISK}`

      ROOT_ACTIVE_PLEX="`grep \"^$ROOT_VOL_NAME \" $PROJECT_DIR/vol_plex_sd_associations | grep \" $PHYSICAL_ACTIVE_DISK \" | awk '{ print $2 }' | head -1`"
      ROOT_BACKOFF_PLEX="`grep \"^$ROOT_VOL_NAME \" $PROJECT_DIR/vol_plex_sd_associations | grep \" $PHYSICAL_BACKOFF_DISK \" | awk '{ print $2 }' | head -1`"
      ROOT_BACKOFF_PARTITION="`grep \"^root \" $PROJECT_DIR/partitions_${PHYSICAL_BACKOFF_DISK}.change | awk '{ print $2 }'"
      ROOT_ACTIVE_PARTITION="`grep \"^root \" $PROJECT_DIR/partitions_${PHYSICAL_ACTIVE_DISK}.change | awk '{ print $2 }'"
      if [ "$SWAP_VOL_NAME" != '.' ]
       then
         SWAP_ACTIVE_PLEX="`grep \"^$SWAP_VOL_NAME \" $PROJECT_DIR/vol_plex_sd_associations | grep \" $PHYSICAL_ACTIVE_DISK \" | awk '{ print $2 }' | head -1`"
         SWAP_BACKOFF_PLEX="`grep \"^$SWAP_VOL_NAME \" $PROJECT_DIR/vol_plex_sd_associations | grep \" $PHYSICAL_BACKOFF_DISK \" | awk '{ print $2 }' | head -1`"
         SWAP_BACKOFF_PARTITION="`grep \"^swap \" $PROJECT_DIR/partitions_${PHYSICAL_BACKOFF_DISK}.change | awk '{ print $2 }'"
         SWAP_ACTIVE_PARTITION="`grep \"^swap \" $PROJECT_DIR/partitions_${PHYSICAL_ACTIVE_DISK}.change | awk '{ print $2 }'"
      fi
      if [ "$USR_VOL_NAME" != '.' ]
       then
         USR_ACTIVE_PLEX="`grep \"^$USR_VOL_NAME \" $PROJECT_DIR/vol_plex_sd_associations | grep \" $PHYSICAL_ACTIVE_DISK \" | awk '{ print $2 }' | head -1`"
         USR_BACKOFF_PLEX="`grep \"^$USR_VOL_NAME \" $PROJECT_DIR/vol_plex_sd_associations | grep \" $PHYSICAL_BACKOFF_DISK \" | awk '{ print $2 }' | head -1`"
         USR_BACKOFF_PARTITION="`grep \"^usr \" $PROJECT_DIR/partitions_${PHYSICAL_BACKOFF_DISK}.change | awk '{ print $2 }'"
         USR_ACTIVE_PARTITION="`grep \"^usr \" $PROJECT_DIR/partitions_${PHYSICAL_ACTIVE_DISK}.change | awk '{ print $2 }'"
      fi
      if [ "$VAR_VOL_NAME" != '.' ]
       then
         VAR_ACTIVE_PLEX="`grep \"^$VAR_VOL_NAME \" $PROJECT_DIR/vol_plex_sd_associations | grep \" $PHYSICAL_ACTIVE_DISK \" | awk '{ print $2 }' | head -1`"
         VAR_BACKOFF_PLEX="`grep \"^$VAR_VOL_NAME \" $PROJECT_DIR/vol_plex_sd_associations | grep \" $PHYSICAL_BACKOFF_DISK \" | awk '{ print $2 }' | head -1`"
         VAR_BACKOFF_PARTITION="`grep \"^var \" $PROJECT_DIR/partitions_${PHYSICAL_BACKOFF_DISK}.change | awk '{ print $2 }'"
         VAR_ACTIVE_PARTITION="`grep \"^var \" $PROJECT_DIR/partitions_${PHYSICAL_ACTIVE_DISK}.change | awk '{ print $2 }'"
      fi
      if [ "$OPT_VOL_NAME" != '.' ]
       then
         OPT_ACTIVE_PLEX="`grep \"^$OPT_VOL_NAME \" $PROJECT_DIR/vol_plex_sd_associations | grep \" $PHYSICAL_ACTIVE_DISK \" | awk '{ print $2 }' | head -1`"
         OPT_BACKOFF_PLEX="`grep \"^$OPT_VOL_NAME \" $PROJECT_DIR/vol_plex_sd_associations | grep \" $PHYSICAL_BACKOFF_DISK \" | awk '{ print $2 }' | head -1`"
         OPT_BACKOFF_PARTITION="`grep \"^opt \" $PROJECT_DIR/partitions_${PHYSICAL_BACKOFF_DISK}.change | awk '{ print $2 }'"
         OPT_ACTIVE_PARTITION="`grep \"^opt \" $PROJECT_DIR/partitions_${PHYSICAL_ACTIVE_DISK}.change | awk '{ print $2 }'"
      fi

      if [ "$DEBUG" = "yes" ]
       then
         echo "\n*MSG* ROOT_VOL_NAME=$ROOT_VOL_NAME"
         echo "*MSG* ROOT_BACKOFF_PARTITION=$ROOT_BACKOFF_PARTITION"
         echo "*MSG* ROOT_ACTIVE_PARTITION=$ROOT_ACTIVE_PARTITION"
         echo "*MSG* SWAP_VOL_NAME=$SWAP_VOL_NAME"
         echo "*MSG* SWAP_BACKOFF_PARTITION=$SWAP_BACKOFF_PARTITION"
         echo "*MSG* SWAP_ACTIVE_PARTITION=$SWAP_ACTIVE_PARTITION"
         echo "*MSG* USR_VOL_NAME=$USR_VOL_NAME"
         echo "*MSG* USR_BACKOFF_PARTITION=$USR_BACKOFF_PARTITION"
         echo "*MSG* USR_ACTIVE_PARTITION=$USR_ACTIVE_PARTITION"
         echo "*MSG* VAR_VOL_NAME=$VAR_VOL_NAME"
         echo "*MSG* VAR_BACKOFF_PARTITION=$VAR_BACKOFF_PARTITION"
         echo "*MSG* VAR_ACTIVE_PARTITION=$VAR_ACTIVE_PARTITION"
         echo "*MSG* OPT_VOL_NAME=$OPT_VOL_NAME"
         echo "*MSG* OPT_BACKOFF_PARTITION=$OPT_BACKOFF_PARTITION"
         echo "*MSG* OPT_ACTIVE_PARTITION=$OPT_ACTIVE_PARTITION"
         echo "*MSG* PHYSICAL_ACTIVE_DISK=$PHYSICAL_ACTIVE_DISK"
         echo "*MSG* PHYSICAL_BACKOFF_DISK=$PHYSICAL_BACKOFF_DISK"
         echo "*MSG* ACTIVE_BOOTPATH=$ACTIVE_BOOTPATH"
         echo "*MSG* BACKOFF_BOOTPATH=$BACKOFF_BOOTPATH"
         echo "*MSG* THE_LIVE_ACTUAL_BOOTPATH=$THE_LIVE_ACTUAL_BOOTPATH"
         echo "*MSG* ROOT_ACTIVE_PLEX=$ROOT_ACTIVE_PLEX"
         echo "*MSG* ROOT_BACKOFF_PLEX=$ROOT_BACKOFF_PLEX"
         echo "*MSG* SWAP_ACTIVE_PLEX=$SWAP_ACTIVE_PLEX"
         echo "*MSG* SWAP_BACKOFF_PLEX=$SWAP_BACKOFF_PLEX"
         echo "*MSG* USR_ACTIVE_PLEX=$USR_ACTIVE_PLEX"
         echo "*MSG* USR_BACKOFF_PLEX=$USR_BACKOFF_PLEX"
         echo "*MSG* VAR_ACTIVE_PLEX=$VAR_ACTIVE_PLEX"
         echo "*MSG* VAR_BACKOFF_PLEX=$VAR_BACKOFF_PLEX"
         echo "*MSG* OPT_ACTIVE_PLEX=$OPT_ACTIVE_PLEX"
         echo "*MSG* OPT_BACKOFF_PLEX=$OPT_BACKOFF_PLEX"
      fi

      ### Initialize some switches to know what to report at the end of the 
      ### function.
      WARNING_SWITCH=0
      PLATFORM="`uname -i`"
      case $PLATFORM in
         'SUNW,Ultra-Enterprise-15000'| \
         'SUNW,Ultra-Enterprise-10000'| \
         'SUNW,Sun-Fire')
            EEPROM_USABLE_SWITCH=0
            ;;
         *)
            EEPROM_USABLE_SWITCH=1
            ;;
      esac
      DEVALIAS_SET_SWITCH=0
      NVRAMRC_SET_SWITCH=0
      USE_NVRAMRC_SET_SWITCH=0
      BOOTBLOCK_BUILT_SWITCH=0

      ;;
   *) 
      echo " Should never ever get here - someone has messed with the script (1)"
      exit 1
      ;;
esac

case $FUNCTION in
   1)
      Function1
      ;;
   2)
      Function2
      ;;
   3)
      Function3
      ;;
   4)
      Function4
      ;;
   5)
      Function5
      ;;
   *) 
      echo " Should never ever get here - someone has messed with the script (2)"
      exit 1
      ;;
esac

exit 0
