#!/bin/ksh
#
# [Start of PROLOG]
#
# Tivoli Storage Manager for System Backup and Recovery
#
# Licensed Materials - Property of IBM
#
#  5698-SYS
#
# (C) COPYRIGHT International Business Machines Corp. 1992,2003
# All Rights Reserved
#
# US Government Users Restricted Rights - Use, duplication or
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
#
## [End of PROLOG]
#                                                    
# sysinstall - mAin system install program for use with Sysback
#
#

# Load library of installation functions
. /usr/lpp/sysback/inst/sysinst.lib

# Set debug mode
# Note that error messages will not appear on the screen
if [[ -n "$SBDEBUG" ]]; then
	if [[ -f $NFSMOUNTDIRINFO ]]; then
		cat $NFSMOUNTDIRINFO | while read a b
		do
			if [[ "$a" = "DEBUG_DIR" ]]; then
				export DEBUG_DIR=$b
			fi
			if [[ "$a" = "NFS_DIR" ]]; then
				export NFS_DIR=$b
			fi
		done
		DEBUGOUT=${DEBUG_DIR}/${DEBUGFILE}
		export DEBUGOUT
	fi
	touch $DEBUGOUT 2>/dev/null
	if [[ $? -eq 0 ]]; then
		exec 2>>$DEBUGOUT
		export XSET="set -x"
	else
		print "Writing to temporary default file /tmp/debug.out" \
			>> /tmp/debug.out
		print "Could not write to debug file $DEBUGOUT" >> /tmp/debug.out
		exec 2>>/tmp/debug.out
		export XSET="set -x"
	fi
	if [ ! -z "$REMAKEVG" ]; then
		print - "------------ [sysinstall $*: $(date)] --------------" >&2
	else 
		print - "------------ [sysinstall $*: $(cat /tmp/date)] --------------" >&2
	fi
else 
	set +x
fi

$XSET

integer numpvs
rm -f $INSTERR
MAXPPS=1016     # LVM limitation on #PPS per PV
KSH=/bin/ksh

sync;sync

############################################################
# Local Subroutines
############################################################
# The following are local subroutines that typically will
# only need to be called from within this sysinstall script.
#
# Any function which may be called within sysinstall may also
# be called from an outside program by using the "callfunct"
# routine. If, however, the routine sets any global variables,
# those variables will not be accessible to an outside program.
#
# For any routine which sets global variables, it is best to
# put the routine in the "sysinst.lib" library and load the
# library into the calling script. This way, any global
# variables set within the functions will be accessible to
# other parts of the program.

# As updates are applied which affect the fields in the volume group
# information file, the VER and SBVER variables, read here from the
# file, will determine the contents of the VGFIELDS and LVFIELDS.

# Save device description for sysmenus
setdevdesc()
{


	$XSET

	butype=$1

	if [[ -s $LVMDEVLIST ]] && [[ "$butype" = "lvmonly" ]]; then
		DEVLIST=$(cat $LVMDEVLIST)
	else
		DEVLIST=$(cat $INSTDEVLIST)
	fi

	sync;sync

	case $DEVLIST in
		/dev/rmt*) 
			devdesc="Tape Drive"
			numdevs=$(print $DEVLIST | wc -w | sed "s/ //g")
			[ $numdevs -gt 1 ] && pl=s
			[ "$LOADER" = y ] && { devdesc="Tape Loader"; pl=; }

			print "${devdesc}$pl [$(print $DEVLIST | sed "s?/dev/??g")]" \
				> $INSTDEVDESC
		;;
		/dev/tok*|/dev/ent*|/dev/fddi*) 
			print "Network [$(basename $DEVLIST)]" > $INSTDEVDESC
		;;
		/dev/cd*) 
			print "CDROM [$(basename $DEVLIST)]" > $INSTDEVDESC
		;;
		tsmdev)
			print "TSMVIRDEV [tsmdev]" > $INSTDEVDESC
		;;
		tsmbadev)
			print "TSMBADEV [tsmbadev]" > $INSTDEVDESC
		;;
	esac

	sync;sync
}


#
# Update $INSTDEVINFO file
#
update_instdevinfo_file() {
	
	$XSET
	
	VAL=$1

	sync;sync

	grep -v "^tsmdev" $INSTDEVINFO > /tmp/$$file
	lsdev -Cl$VAL | read x x loc x
	desc="TSM Virtual Device ($VAL)"
	printf "%-13.13s %-35.35s  %s\n" "tsmdev" "$desc" "$loc" >> /tmp/$$file
	cp /tmp/$$file $INSTDEVINFO
	rm -f /tmp/$$file

	sync;sync
}



#
#
#
MountFilesystems()
{

	$XSET

	fslist=$1

	if [[ -z "$fslist" ]]; then
		return
	fi

	if [[ ! -f "$fslist" ]]; then
		return
	fi

	exec 4<$fslist
	while read -u4 lvnum
	do
		dir=$(/usr/sbin/sblvminfo query -Tl -tm -f$VGINFO -n$lvnum)
		lv=$(/usr/sbin/sblvminfo query -Tl -tl -f$VGINFO -n$lvnum)
		make_dirs ${MROOT}$dir 2>/dev/null
		if [[ -n "$RECOVERY" ]];then
			fsck -y /dev/$lv >/dev/null 2>&1a
		fi
		mount /dev/$lv ${MROOT}$dir
		retcode=$?
		if [[ $? -ne 0 ]]; then
			syserror "Error mounting logical volume $lv on ${MROOT}$dir" 2
		fi
	done
}


UnMountFilesystems() {

	$XSET

	>/tmp/$$tmpfile

	if [[ "$DEVTYPE" = "TSMBA" ]]; then
		sblvminfo check -Tf -tv -urootvg -f $VGINFO | while read lvnum
		do
			mntpt=$(sblvminfo query -Tl -tm -f $VGINFO -n$lvnum)
			if [[ -n "$mntpt" ]]; then
				print "$mntpt" >>/tmp/$$tmpfile
			fi
		done
		sort -r /tmp/$$tmpfile > /tmp/$$newfile
		
		wc /tmp/$$newfile | read total x
		i=1
		while [[ $i -le $total ]]; do
			mntpt=$(sbparse_command parse_1 -n$i -f /tmp/$$newfile)
			if [[ "$mntpt" = "/" ]]; then
				(( i = $i + 1 ))
				continue
			fi
			mount | grep -w ${MROOT}${mntpt} >/dev/null && \
				unmountfs ${MROOT}${mntpt}
			(( i = $i + 1 ))
		done

	else
		# Unmount /usr, /tmp and /var filesystems
		# Unmount /usr, /tmp and /var filesystems
		unmountfs $MROOT/usr
		mount | grep -w $MROOT/tmp >/dev/null && unmountfs $MROOT/tmp
		mount | grep -w $MROOT/var >/dev/null && unmountfs $MROOT/var
	fi

}
	
			

#
# Changes LV copies for the complete VG
#
change_lv_copies() {

	$XSET

	VG=$1
	COPIES=$2

	sync;sync

	/usr/sbin/sblvminfo check -Tl -tv -f $VGINFO -u $VG | while read lvnum
	do
		set_lv $lvnum ""
		[ $VGNAME != $VG ] && continue
		[ $COPIES -eq $copies ] && continue

		numpvs=$(print $LVpvlist | wc -w)
		if [ $COPIES -gt $numpvs -a $numpvs -gt 0 ]; then
			LVpvlist=""
			U_LVpvlist=1
		fi

		if [ $COPIES -gt $upper ]; then
			upper=$COPIES
			U_UPPER=1
		fi                             
		
		# Update the LV record
		U_COPIES=1
		copies=$COPIES
		updatelvmfields $lvnum $lvname
	done

	sync;sync
}



#
# Updates values in the tsmclientinfo file
#
update_tsm() {

	$XSET

	type=$1
	file=$2
	val=$3

	sync;sync

	if [[ -z "$type" ]] || [[ -z "$file" ]]; then
		return
	fi

	grep -v "$type" $file > /tmp/$$tmp
	print "$type $val" >> /tmp/$$tmp
	cp /tmp/$$tmp $file
	rm -f /tmp/$$tmp

	sync;sync
}

	
#
# Change the kern type
#
change_kern64() {

    $XSET

    val=$1

	sync;sync

    grep -v "^CHRP64 " $VGINFO > $VGINFO.tmp
	print "CHRP64 $1 " > /tmp/$$file
	cat /tmp/$$file $VGINFO.tmp > $VGINFO
    rm -f $VGINFO.tmp /tmp/$$file

	sync;sync

}



#
# Read the kern type from the vginfo file
#
read_kern64() {

	$XSET

	sync;sync

	unset value
	grep "^CHRP64 " $VGINFO | read x value

	if [ ! -z "$value" ]; then
		export CHRP64=$value
	fi

	sync;sync
}


#
# Set the non sparse value
#
change_nonsparse() {

    $XSET

    val=$1

	sync;sync

    grep -v "^NONSPARSE " $VGINFO > $VGINFO.tmp
	print "NONSPARSE $1 " > /tmp/$$file
	cat /tmp/$$file $VGINFO.tmp > $VGINFO
    rm -f $VGINFO.tmp /tmp/$$file

	sync;sync

}


#
# Global change of the vg copies
#
check_vg_copies() {

	$XSET

	COPIES=$1
	VG=$2

	sync;sync

	X=0

	/usr/sbin/sblvminfo check -Tl -tv -f$VGINFO -u $VG | while read lvnum
	do
		set_lv $lvnum ""
		if [ "$VG" = "$VGNAME" ]; then
			numpvs=$(print $LVpvlist | wc -w)
			if [ $COPIES -gt $numpvs -a $numpvs -gt 0 ]; then
				LVpvlist=""
				U_LVpvlist=1
				X=1
			fi
			if [ $COPIES -gt $upper ]; then
				upper=$COPIES
				U_UPPER=1
				X=1
			fi
			if [ $COPIES -ne $copies ]; then
				copies=$COPIES
				U_COPIES=1
				X=1
			fi
			if [ $X -eq 1 ]; then
			# Update the LV record
			updatelvmfields $lvnum $lv
			fi
		fi
	done

	sync;sync

}


#
# Can't have JFS2 filesystems in rootvg on a non-chrp system
#
check_fs2_jfs2() {

	$XSET
	
	lv=$1

	sync;sync

	case "$lv" in
		hd4|hd2|hd9var|hd3);;
		*) return;;
	esac

	if [ "$platform" != "chrp" -a "$jfs2" != "n" ]; then
		jfs2="n"
		lverr "Non chrp hardware does not support jfs2 for system filesystem.\nChanging to jfs."
		change_value=1
		[ $RC -eq 0 ] && RC=2
	fi

	sync;sync
}


#
# Can't have system filesystems on a nonchrp system
#
check_lv_jfs2 () {

	$XSET

	lv=$1

	sync;sync

	case "$lv" in
		hd4|hd2|hd9var|hd3|hd8);;
		*) return;;
	esac

	if [ "$lv" = "hd8" -a "$platform" != "chrp" -a "$type" != "jfslog" ]; then
		type="jfslog"
		U_TYPE=1
		lverr "Non chrp hardware does not support jfs2 for system filesystem.\nChanging to jfs."
		[ $RC -eq 0 ] && RC=2
		return
	fi

	[ "$lv" = "hd8" ] && return

	if [ "$platform" != "chrp" -a "$type" = "jfs2" ]; then
		type="jfs"
		U_TYPE=1
		lverr "Non chrp hardware does not support jfs2 for system filesystem.\nChanging to jfs."
		[ $RC -eq 0 ] && RC=2
		return
	fi

	sync;sync

}


#
# Global change of the jfs type of a filesystem
#
change_jfstype() {

	$XSET

	j2=$1
	VG=$2

	sync;sync

	
	case "$j2" in
		Y|2) j2=y;;
		N|1) j2=n;;
	esac

	/usr/sbin/sblvminfo check -Tl -tv -f$VGINFO -u$VG | while read lvnum
	do
		set_lv $lvnum ""
		if [ "$platform" != "chrp" -a "$VGNAME" = "rootvg" -a "$j2" != "n" -a -z "$EDITONLY" ]; then
			continue
		fi
		
		if [ -z "$VG" -o "$VG" = "$VGNAME" ]; then
			if [[ "$mountpt" = "-" ]] && [[ ( "$type" = "jfslog" ) || \
				( "$type" = "jfs2log" ) ]]; then
				 [[ "$j2" = "y" ]] && type="jfs2log" || type="jfslog"
				U_TYPE=1
				updatelvmfields $lvnum $lvname
			fi
			if [[ "$mountpt" != "-" ]]; then
				[[ "$j2" = "y" ]] && type="jfs2" || type="jfs"
				U_TYPE=1
				updatelvmfields $lvnum $lvname
			fi
		fi
	done

	/usr/sbin/sblvminfo query -TF -a -f$VGINFO > /tmp/...$$buffer
	cat /tmp/...$$buffer | while read lvnum
	do
		set_fs2 $lvnum $lvname
		if [ "$platform" != "chrp" -a "$VGNAME" = "rootvg" -a "$j2" != "n" ]; then
			continue
		fi
		if [ -z "$VG" -o "$VG" = "$VGNAME" ]; then
			[  "$j2" = "y" -o "$j2" = "Y" -o "$j2" = "2" ] && jfs2="y"
			[  "$j2" = "n" -o "$j2" = "N" -o "$j2" = "1" ] && jfs2="n"
			U_JFS2=1
			updatefs2fields $lvnum $lvname
		fi
	done

	sync;sync

	return 0

}

	
#
# Convert PV location or PVID (depending on version of Sysback)
# to a current hdisk name
#
pv_to_hdisk() {
$XSET
	PV=$1

	sync;sync

	grep -w $PV $PVINFO | read hdisk x
	if [[ -n $hdisk ]]; then
		# Return the hdisk name
		print $hdisk
		return 0
	else # PVID not found, now try the old location code
		return 1 #Disk did not match
	fi

	sync;sync
	return 1   #Disk did not match
}



#################################################################
changepv_hotspare() 
#################################################################
{
	$XSET

	PVNAME=$1
	HOTSPARE=$2

	sync;sync

	active=" "
	rm -f $PVHOTSPARELIST.tmp >/dev/null 2>&1
	print "" > $PVHOTSPARELIST.tmp
	> $PVHOTSPARELIST.tmp

	exec 4<$PVHOTSPARELIST
	while read -u4 pvname pvaddr vgname hotspare desc
    do
		if [ "$PVNAME" = "$pvname" ]; then
			printf "%s%-14.14s%-16.16s%-13.13s%-7.7s%.30s\n" "$active" $pvname $pvaddr "$vgname" "$HOTSPARE" "$desc" >> $PVHOTSPARELIST.tmp
		else
			printf "%s%-14.14s%-16.16s%-13.13s%-7.7s%.30s\n" "$active" $pvname $pvaddr "$vgname" "$hotspare" "$desc" >> $PVHOTSPARELIST.tmp
		fi
	done

	mv $PVHOTSPARELIST.tmp $PVHOTSPARELIST

	sync;sync

	exit 0
}

	
#
# Check the total amount of disk space available
#
checkpvspace() {
$XSET

	sync;sync

	# Get total disk space available on target disks

	tot_disk_avail=0
	largest_pvsize=0
	[ -z "$1" ] && return 0 # no disks selected

	for pvname in $*
	do
		size=$(bootinfo -s $pvname)
		size=${size:=0}

		# Reduce by 1 MB for VGDA
		((size = size - 1))
		[ $size -lt 0 ] && size=0

		# Keep track of the largest PV size in the VG
		if [ $size -gt $largest_pvsize ]
		   then largest_pvsize=$size
		fi

		((tot_disk_avail = tot_disk_avail + size))
	done

	sync;sync
}


#
# Get the amount of space required to create the volume group & LVs
#
checkvgspace() {
$XSET

	sync;sync

	get_version
	unset VGACTIVE
	vgname=$1

	# See if vg is currently active
	if [[ -n "$RECOVERY" ]]; then
		VGACTIVE=1
   else 
		if [[ -z "$EDITONLY" ]]; then
			getlvminfo -V $vgname >/dev/null 2>&1 && VGACTIVE=1
		fi
	fi

	# Get total PV space available
	if [[ -n "$VGACTIVE" ]]; then
		# VG is active, get current PV list
		PVlist="$(getlvminfo -V $vgname -pN1)"
		ppsize=$(getlvminfo -V $vgname -S)
	else # Get PV list from VGINFO
		set_vg 0 $vgname
	fi
	checkpvspace $PVlist

	tot_lv_size=0
	rc=0

	# Compute total size of all logical volumes to be created.
	if [ ! -z "$VGACTIVE" ]
	then # Get current LV sizes
		for lvname in $(getlvminfo -V $vgname -l1 2>/dev/null)
		do
			if [[ -n "$RECOVERY" ]]; then
				# Dont include current / and /usr filesystem sizes
				# in totals since we're going to delete them anyway.
				[ $lvname = $ROOTLV -o $lvname = $USRLV ] && continue
			fi
			getlvminfo -L $lvname -nc1 | read lps copies
			((megsize = lps * copies * ppsize))
			((tot_lv_size = tot_lv_size + megsize))
		done
	fi

	# Get LV sizes from vginfo file
	/usr/sbin/sblvminfo check -Tl -tv -f$VGINFO -u $vgname | while read lvnum
	do
		VGNAME=$(/usr/sbin/sblvminfo query -Tl -tv -f$VGINFO -n$lvnum)
		createopt=$(/usr/sbin/sblvminfo query -Tl -tc -f$VGINFO -n$lvnum)
		lps=$(/usr/sbin/sblvminfo query -Tl -tL -f$VGINFO -n$lvnum)
		copies=$(/usr/sbin/sblvminfo query -Tl -tC -f$VGINFO -n$lvnum)
		lvname=$(/usr/sbin/sblvminfo query -Tl -tl -f$VGINFO -n$lvnum)

		[ $VGNAME != $vgname ] && continue
		[ $createopt = n ] && continue

		if [[ -n "$RECOVERY" ]]; then
			# Get only sizes of / and /usr filesystems since these
			# are the only ones we'll be creating. Get sizes from
			# vginfo file even though they currently exist since
			# we'll be removing the current ones.
			[ $lvname != $ROOTLV -a $lvname != $USRLV ] && continue

		   else # If LV already exists, we got the real size already
				if [ -z "$EDITONLY" ]
				   then getlvminfo -L $lvname 2>/dev/null && continue
				fi
		fi

		# Use size info from vginfo file
		((megsize = lps * copies * ppsize))
		megsize=${megsize:=0}
		((tot_lv_size = tot_lv_size + megsize))
	done

	# Get number of free PPs
	((diskpps = tot_disk_avail / ppsize))
	((lvpps = tot_lv_size / ppsize))
	((freemb = tot_disk_avail - tot_lv_size))
	((freepps = freemb / ppsize))

	# Write to a file for the menus
	[ ! -z "$SPACEFILE" ] && \
		print $tot_disk_avail $diskpps $tot_lv_size $lvpps $freemb $freepps \
			> $SPACEFILE

	sync;sync
}


#
# Update #LPs for all LVs if PP size changed
#
update_lvpps()
{
$XSET
	vgname=$1
	oldppsize=$2
	ppsize=$3

	sync;sync

	/usr/sbin/sblvminfo check -Tl -tv -f$VGINFO -u $vgname | while read lvnum
	do
		set_lv $lvnum ""

		# Note that we use origmb to base calculation
		# of new lps value. This may allow the lps value
		# to increase by 1 if lps increased, then decreased
		((lps = origmb / ppsize))
		((minmb = oldppsize * minlps))
		((minlps =  minmb / ppsize))
		U_LPS=1
		U_MINLPS=1

		# If minlps not even, add 1 more
		[ $(( minmb % ppsize)) != 0 ] && ((minlps = minlps + 1))

		if [ $minlps != 0 ]
		   then # Make sure LPs not less than minLPs
				[ $lps -lt $minlps ] && ((lps = lps + 1))
		   else # Can't use minLPs - if LPs not even, add 1
				[ $((origmb % ppsize)) != 0 ] && ((lps = lps + 1))
		fi

		# Max LPs must be at least LPs
		if [ $maxlps -lt $lps ];then
			maxlps=$lps
			U_MAXLPS=1
		fi
			
		# Can't use map if PP size changed
		if [ $ppmap = y ];then
				ppmap = n
				U_PPMAP=1
				case "$type" in
					boot) 		priority=03;;
					jfslog) 	priority=04;;
					paging) 	priority=10;;
					sysdump) 	priority=90;;
					*) 			priority=20;;
				esac
				U_PRIORITY=1
		fi

		# Update vginfo file
		updatelvmfields $lvnum $lvname
	done

	sync;sync

	return 0
}

#
# Check the physical partition map for the specified logical volume
#
checkppmap() {
$XSET

	# PP Map must meet the following criteria:
	# 1. A PV must exist on the system with the same PVID or Location code
	# 2. The PV must be assigned to the logical volume
	# 3. The LV PP#s must not be higher than the largest PP on the disk
	# 4. Number of PP Map entries must match #PPs in LV
	# Usage: checkppmap lvname pvname1 pvname2 ...
	# Return code: 0 = Map is OK, saved as /tmp/$lvname.ppmap
	#              1 = Map cannot be used to create the LV, error message
	#                  sent to stdout.

	caller=$1
	[ $caller = 1 ] && shift
	lvname=$1; shift
	vgname=$1; shift
	numpps=$1; shift
	LVpvlist="$*"

	sync;sync

	# Get map data from vginfo file
	/usr/sbin/sblvminfo query -Tp -f$VGINFO -d$lvname > /tmp/$lvname.ppmap
	LV=$lvname
#	LV=$(/usr/sbin/sblvminfo query -Tl -f$VGINFO -tl -n$lvnum)
	if [ ! -s /tmp/$lvname.ppmap ]
	   then if [ $caller = 1 ]
				then print "No map data available for logical volume $LV." >>$INSTERR
				else lverr "No map data available for logical volume $LV."	
			fi
			return 1
	fi

	# Get ppsize from VG record
	ppsize=$(/usr/sbin/sblvminfo query -Tv -tp -f$VGINFO -d $vgname)

	# Check that ppmap is same size as LV
	mapsize=$(cat /tmp/$lvname.ppmap | wc -l)
	mapsize=$(print $mapsize)
	if [ $mapsize != $numpps ]
	   then if [ $caller = 1 ]
			   then print "The partition map requires $mapsize partitions, which does not equal the current logical volume size ($numpps PPs)." >>$INSTERR
			   else lverr "The partition map requires $mapsize partitions, which does not\n\tequal the current logical volume size ($numpps PPs)."
			fi

			return 1
	fi

	# Check that PVs are available and get highest PP number
	cat /tmp/$lvname.ppmap | sed "s/:/ /" >/tmp/..buffer5
	exec 5</tmp/..buffer5
	while read -u5 hdiskname pp
	do
		if [ "$hdiskname" = missing ]
		   then if [ $caller = 1 ]
				   then print "Cannot use physical partition map because the original physical volumes do not exist or have been changed." >>$INSTERR
				   else lverr "Cannot use physical partition map because the original physical\n\tvolumes do not exist or have been changed."
				fi
				return 1
		fi

		# Get the highest PP number on the disk
		hdnum=${hdiskname#hdisk}
		[ "${pvsize[${hdnum}]}" -lt $pp ] && \
			pvsize[${hdnum}]=$pp
	done

   	# Make sure LV is on the hdisks in map 
   	for hdiskname in $(cat /tmp/$lvname.ppmap |cut -d: -f1 | sort | uniq)
   	do
		print $LVpvlist | grep -w $hdiskname >/dev/null 2>&1
		if test $? -ne 0
		   then # Not in LV PVlist. If LV PVlist is not set and PV is
				# found in the VG PVlist, we're OK.
				if [ "$LVpvlist" = "" ]
				   then # Get vg pv list
						vgpvs=$(/usr/sbin/sblvminfo query -Tv -tP -f$VGINFO -d $vgname)
						echo $vgpvs | grep -w $hdiskname >/dev/null 2>&1
						if test $? -eq 0
						   then continue # Found in VG
						fi
				fi
				if [ $caller = 1 ]
				   then print "Cannot use the PP Map because either physical volume $hdiskname is not assigned to this LV and/or is not in the $vgname volume group." >>$INSTERR
				   else lverr "Cannot use PP Map because physical volume $hdiskname is not\n\tassigned to this LV or is not in the $vgname volume group." >>$INSTERR
				fi
				return 1
		fi
   	done
	
	# Make sure PPs in LV are not higher than PV sizes
	for hdiskname in $LVpvlist
	do
		checkpvspace $hdiskname
		diskpps=$((tot_disk_avail / ppsize))

		hdnum=${hdiskname#hdisk}
		if [ ${pvsize[${hdnum}]} -gt $diskpps ]
		   then if [ $caller = 1 ]
				   then print "Cannot use the PP Map because it requires partition number ${pvsize[${hdnum}]}, which is greater than the size of $hdiskname ($diskpps PPs)."
				   else lverr "Cannot use PP Map because it requires partition number ${pvsize[${hdnum}]},\n\twhich is greater than the size of $hdiskname ($diskpps PPs)."
				fi
				return 1
		fi
	done

	sync;sync
	
	return 0
}


#
# See if volume group exists
#
isvg() {

	vgname=$1

	sync;sync
	getlvminfo -V $vgname 2>/dev/null
	if test $? -ne 0
	   then print "Volume group $vgname does not exist" >> $INSTERR
			return 1
	fi

	sync;sync

	return 0
}


#
# See if logical volume exists
#
islv() {

	lvname=$1

	sync;sync

	getlvminfo -L $lvname 2>/dev/null
	if test $? -ne 0
	   then return 0
	fi
	print "Logical Volume $lvname already exists!" >> $INSTERR
	return 1

	sync;sync
}


#
# Display volume group errors from checkvginfo
#
vgerr() {
	vmsg="$@"
	if [ "$VGERR" = 0 ]
	   then print "\nThe following errors were found in the volume group records:" >&2
			print - "-----------------------------------------------------------" >&2
		VGERR=1
	fi
	if [ ! -z "$vmsg" ]
	   then print - "> $vmsg" >&2
	fi
}

NFSMountUnmount() {
	$XSET

	opt=$1
	sysnfsout_1=$2
	sysnfsout_2=$3

	#
	# Unmouting NFS filesystem
	# We must stop debugging and move the output to the console
	# or we will get a device busy error message
	#
	if [[ "$opt" = "u" ]] || [[ "$opt" = "U" ]];then

		#
		# Turn debugging off and set debugout to the console
		#
		if [[ -n $SBDEBUG ]]; then
			set +x
			sync;sync;sync
			TTY=$(/usr/bin/tty)
			exec 2> ${TTY}
		fi
		sysnfs -uS$sysnfsout_1 -s$sysnfsout_2
		rc=$?

		#
		# Turn debugging back on and move the output back to debugout
		#
		if [[ -n $SBDEBUG ]]; then
			$XSET
			exec 2>>$DEBUGOUT
		fi
		return $rc
	fi

	

	if [[ "$opt" = "m" ]] || [[ "$opt" = "M" ]];then
		bootdev=$(bootinfo -b)
		sysnfs -s$sysnfsout_2 -S$sysnfsout_1 -b $bootdev \
			-f $DEBUGNFSINFO -F $NETINFO
		return $?
	fi

}


#
# Display logical volume errors from checkvginfo
#
lverr() {

	if [ $LVERR = 0 ]
	   then print - "\nThe following errors were found in the logical volume records:" >&2
			print - "-------------------------------------------------------------" >&2
		LVERR=1
	fi
	print - "> $lvname: $@" >&2
}

# Rebuild all boot logical volumes in the rootvg volume group.
# Since there may be multiple bootlvs, we must find the 
# physical location of each, run bosboot for each bootlv, then
# reset the bootlist to include all bootable disks.
rebuild_bootlvs()
{
$XSET

	sync;sync

	# Get the disks containing a boot lv			
	BOOTLV=
	>/tmp/..bootlv
	getlvminfo -V rootvg -l >/tmp/..buffer4
	wc /tmp/..buffer4 | read total_opts x
	i=1 
	while [ $i -le $total_opts ]
	do
		lvname=$(sbparse_command parse_1 -n$i -f/tmp/..buffer4)
		(( i = $i + 1 ))
		[ "$(getlvminfo -L $lvname -t)" != boot ] && continue
		print $lvname >> /tmp/..bootlv
	done
	if [ ! -s /tmp/..bootlv ] 
	   then print "\n\07No logical volumes with type \"boot\" were found!"
			return 1
	fi

	rm -f /dev/ipldevice $BOOTDISKS
	wc /tmp/..bootlv | read total_opts x
	i=1 
	while [ $i -le $total_opts ]
	do
		lvname=$(sbparse_command parse_1 -n$i -f/tmp/..bootlv)
		(( i = $i + 1 ))
		# Get disk for the bootlv
		getlvminfo -L $lvname -pN1 | read diskname x

		# Link ipl device to first boot disk
		[ ! -c /dev/ipldevice ] && \
			ln /dev/$diskname /dev/ipldevice 2>/dev/null
		print "Initializing boot logical volume $lvname on $diskname .."
		bosboot -a -d /dev/$diskname -l /dev/$lvname
		if [ $? -ne 0 ]; then
			print "\n\07Error creating boot logical volume!"
		else 
			print getlvminfo -L $lvname -pN1 >> $BOOTDISKS
		fi

		# The following will add the AIX level to the boot LV, which is
		# required for use by the AIX migration install process
		/usr/lpp/bosinst/blvset -d /dev/$diskname -p menu </dev/null 2>/dev/null
	done


	wc /tmp/..bootlv | read total_opts x

	i=1 
	unset HD5DISK BOOTLIST

	while [ $i -le $total_opts ]
	do
		lvname=$(sbparse_command parse_1 -n$i -f/tmp/..bootlv)
		(( i = $i + 1 ))
		# Set bootlist to all disks containing a bootlv
		if [[ -n $(getlvminfo -L $lvname -pN1) ]]; then
			set -- $(getlvminfo -L $lvname -pN1)
			if [ "$lvname" = "hd5" ]; then
				HD5DISK="$*"
			else
				BOOTLIST="$BOOTLIST $*"
			fi
		else
			syserror "No boot logical volumes were initialized successfully" 2
			return 0
		fi
	done
	BOOTLIST="$HD5DISK $BOOTLIST"


	if [ -z "$BOOTLIST" ]; then
		syserror "No boot logical volumes were initialized successfully" 2
		return 0
	fi

	print "Setting boot device list to: $BOOTLIST"
	bootlist -m normal $BOOTLIST
	if [[ $? -ne 0 ]]; then
		syserror "Failed to set bootlist for device(s) $BOOTLIST." 2
	fi
	rm -f $BOOTDISKS

	sync;sync

	return 0
}


# This routine is used to merge the RAM filesystem data with the
# rootvg data on disk. This is used either after restoring / and /usr
# during a recovery install or when using the import option from the
# utilities menu.
merge_diskroot() 
{
$XSET

	sync;sync

	export PATH=/usr/sbin:/etc:/usr/bin
	export LIBPATH=$MROOT/usr/ccs/lib:$MROOT/usr/lib:/usr/lib:/lib
	export ODMDIR=/etc/objrepos

	case $FIRSTDEV in
		/dev/cd*) 
				if [[ -n "$REMOTE" ]]; then
					OIFS="$IFS"
					IFS="="
					sbclient instserver "env" | grep "CLIENT_HOST=" | read x thostname
					IFS="$OIFS"
					sbclient instserver "sb_cdmnt -u 11 -h $thostname"
				else
					umount_cd $FIRSTDEV $CDMOUNTPT
				fi
				;;
	esac

	# Put mount/umount in /etc so we can mount/umount /usr filesystem
	cp /usr/sbin/mount /etc
	ln -f /etc/mount /etc/umount 2>/dev/null

	# Link shared libraries to /lib. For network boot, this will 
	# point to the mounted /usr filesystem from the server
	rm -fr /lib 2>/dev/null
	mkdir /lib
	ln /usr/lib/lib* /lib >/dev/null 2>&1
	sync;sync;sync

 	# Mount the root filesystem first
	print "Merging RAM filesystem with rootvg data .."
	mount -f /dev/$ROOTLV $MROOT || \
		syserror "Unable to mount root filesystem!" 2

	# create symlinks for jfs compression
	ln -s $MROOT/sbin/comp* /sbin >/dev/null 2>&1

	# If not network boot, mount /usr also to access commands
	if [ "$BOOTTYPE" != $NET ]
	   then /etc/mount /dev/$USRLV /$MROOT/usr || \
			syserror "Unable to mount /usr filesystem!" 2
	fi

	OPATH=$PATH
	PATH=$PATH:$MROOT/usr/sbin:$MROOT/usr/bin

	# Save VGDA data
	find /etc/vg -print | cpio -updmv $MROOT >/dev/null 2>&1

	# Save normal boot devices. The rc.boot script will 
	# recover the original /dev during the next normal (disk) boot.
	rm -fr $MROOT/dev.org >/dev/null 2>&1
	mkdir -p $MROOT/dev $MROOT/dev.org
	mkdir -p $MROOT/dev

	# Copy RAM devices to regular file system
	/usr/lib/boot/mergedev >/dev/null 2>&1

	# Let bosboot command know that we did not boot from disk
	print "Sysback booted from $BOOTDEV" > /BOOTFS_COOKIE

	# Copy real /etc/filesystem to RAM for next mount
	cp $MROOT/etc/filesystems /etc

	print "Mounting boot filesystems .."
	unset LIBPATH
	export LIBPATH=/lib
	sync; sync
	[ $BOOTTYPE != "$NET" ] && {
		/etc/umount /dev/$USRLV || \
			syserror "Unable to unmount /usr filesystem" 2
	}
	umount /dev/$ROOTLV || \
		syserror "Unable to unmount root ($MROOT) filesystem" 2

	# Make sure to access ksh from RAM root in case of failure
	# If network boot, this means going to the server
    KSH=/../usr/bin/ksh

	# Mount all filesystms with type=bootfs
	mount -f -t bootfs || \
		syserror "Unable to mount /, /usr or /var filesystem!" 2

	# In case user changed fstype of /var, try to mount again
	mount /var >/dev/null 2>&1
	sync; sync; sync

	case $FIRSTDEV in
		/dev/cd*)
			if [[ -n "$REMOTE" ]]; then
				export CDMOUNTPT_1=/.sbcd_11
				export SB_DATA_1=$CDMOUNTPT_1/usr/sys/sysback_images 
				OIFS="$IFS"
				IFS="="
				sbclient instserver "env" | grep "CLIENT_HOST=" | read x thostname
				IFS="$OIFS"
				vfs=$(sbclient instserver "sb_cdmnt -td $FIRSTDEV")
				if [[ -z "$vfs" ]]; then
					vfs="cdrfs"
				fi
				sbclient instserver "sb_cdmnt -v$vfs -m 11 -d $FIRSTDEV -h $thostname"

			else
				export CDMOUNTPT=/mnt$$
				export SB_DATA=$CDMOUNTPT/usr/sys/sysback_images 
				mkdir $CDMOUNTPT >/dev/null 2>&1
				mount_cd $FIRSTDEV $CDMOUNTPT
			fi
			;;
	esac

	# Now, mount the rest of the filesystems - make sure
	# to do so in correct order so as not to mount over parents
	getlvminfo -V rootvg -l >/tmp/..buffer4
	wc /tmp/..buffer4 | read total_opts x
	i=1
	while [ $i -le $total_opts ]
	do
		lvname=$(sbparse_command parse_1 -f/tmp/..buffer4 -n$i)
		(( i = $i + 1 ))
		[ $lvname = $ROOTLV -o $lvname = $USRLV \
			-o $lvname = $VARLV ] && continue
		dir=$(lsjfs | grep ":/dev/$lvname:" 2>/dev/null | tail +1 | \
			cut -d: -f1)
		[ ! -z "$dir" ] && print $lvname $dir
	done > /tmp/..buffer5

	#
	# We need to copies files in the ramfs /tmp into
	# the real /tmp, then mount /tmp first before any of
	# the other filesystems are mounted
	#
	mkdir -p $MROOT/tmp
	mount /dev/hd3 $MROOT/tmp
	cd /tmp
	# Saving RAMFS /tmp data
	find . -print | cpio -updmv $MROOT/tmp >/dev/null 2>&1
	cd /
	sync;sync;sync
	umount /dev/hd3
	mount /dev/hd3 /tmp
	

	wc /tmp/..buffer5 | read total_opts x
	i=1
	while [ $i -le $total_opts ]
	do
		lvname=$(sbparse_command parse_2 -F1 -f/tmp/..buffer5 -n$i)
		mountpt=$(sbparse_command parse_2 -F2 -f/tmp/..buffer5 -n$i)
		(( i = $i + 1 ))
		if [ "$lvname" = "hd3" -o "$mountpt" = "/tmp" ]; then
			continue
		fi
		print "Checking and mounting $mountpt filesystem .."
		fsck -fp /dev/$lvname 2>/dev/null
		mount $mountpt || \
			print "\07Mount of $mountpt (/dev/${lvname}) failed!\n"
	done
	sync; sync; sync

	# Now use ksh in /usr filesystem
	KSH=/usr/bin/ksh

	print "\nAll filesystems in rootvg have been mounted."

	sync;sync

	return 0
}



# Unmount the specified filesystem. If it fails, retry every 20
# seconds for up to 2 minutes before halting. This is becasue
# some processes take a while to terminate or may be using a
# shared library in the specified filesystem.
unmountfs() {
$XSET

	fsdir=$1
	OK=1
	sync;sync;sync
	while true
	do
		umount $fsdir 2>/dev/null
		if test $? -ne 0
		   then if [ $OK -gt 6 ]
				   then syserror "Unable to unmount the $fsdir filesystem. You must select \"perform maintenance\" and unmount the $fsdir filesystem before continuing!" 2
					break
				fi
				[ $OK -eq 1 ] && \
				print "Waiting to unmount $fsdir filesystem .." >&2
				sleep 20
				((OK = OK + 1))
		   else break
		fi
	done
}


#
# See is there is a config method for the specified
# device. This ensures that device support for a
# network device is installed
#
iscfg() {
$XSET
	device=$1

	sync;sync

#	LANG=C odmget CuDv | grep -p $device | grep PdDvLn | read x x uniquetype
	odmget CuDv | grep -p $device | grep PdDvLn | read x x uniquetype
	[ -z "$uniquetype" ] && return 1

	uniquetype=$(print $uniquetype | sed "s/\"//g")
#	LANG=C odmget PdDv | grep -p $uniquetype | \
	odmget PdDv | grep -p $uniquetype | \
		grep "[	 ]*Configure" | read x x cfgfile
	[ -z "$cfgfile" ] && return 1
	cfgfile=$(print $cfgfile | sed "s/\"//g")
	[ ! -f $cfgfile ] && return 1

	sync;sync

	return 0
}



# Perform a sync command every 30 seconds while data is restored.
# This function is run in the background
syncdaemon() {
	while :
	do
		sync
		sleep 15
	done 2>/dev/null
}

# This function operates the same as the 'chdev' command but is
# used instead since chdev does not exist.
change_dev() {
$XSET

	devname=$1
	attribute=$2
	value=$3

	sync;sync

	devname=$(basename $devname)
	rc=0

	# Get config methods
	UCFG=$(lsdev -Cl$devname -r Unconfigure)
	[ -z "$UCFG" -o ! -x "$UCFG" ] && UCFG=/etc/methods/ucfgdevice
	CHANGE=$(lsdev -Cl$devname -r Change)
	[ -z "$CHANGE" -o ! -x "$CHANGE" ] && CHANGE=/etc/methods/chggen
	CFG=$(lsdev -Cl$devname -r Configure)
	[ -z "$CFG" -o ! -x "$CFG" ] && CFG=/etc/methods/cfgsctape

	# Rewind
	sbdevice -qr $devname

	# Set block size to specified value
	$UCFG -l $devname
	if test $? -ne 0
	   then print "Cannot unconfigure device $devname" > $INSTERR
		return 1
	fi
	$CHANGE -l $devname -a ${attribute}=$value
	if test $? -ne 0
	   then print "Cannot change $attribute on device $devname" > $INSTERR
		rc=1
	fi
	$CFG -l $devname
	if test $? -ne 0
	   then print "Cannot configure device $devname" > $INSTERR
		return 1
	fi
	[ $rc -eq 1 ] && return 1

	# Rewind (waits until device ready)
	sbdevice -qr $devname

	sync;sync
}



# Check to see if this is a boot tape, and if so, set block
# size as needed and skip boot images
skip_boot() {
$XSET

	dev=$(basename $1)

	sync;sync

    # Position tape to beginning of master image
	sbdevice -r $dev #rewind

	# See if tape is bootable by looking for IPL magic number
	DUMMY=$(dd if=/dev/$dev bs=1b count=1 2>/dev/null)
	rc=$?
	if [[ $rc -eq 0 ]]; then
		TEST1=$(echo $DUMMY | dd bs=1 count=4 conv=ascii 2>/dev/null) || rc=$?
	fi
	if [[ $rc -eq 0 ]]; then
		TEST2=$(echo $DUMMY | dd bs=1 skip=1 count=3 2>/dev/null) || rc=$?
	fi
	if [ $rc -ne 0 -o \( "$TEST1" != "IBMA" -a "$TEST2" != "ELF" \) ]
	   then # Either not bootable or volume 1 is not inserted
			sbdevice -r $dev # rewind
			print 'There are no boot images on this tape.' >$INSTERR
			return 1
	fi
	
	# Forward to Sysback programs image
	sbdevice -r $dev # rewind
	sbdevice -f3 $dev # fwd to image 4
	if [[ $? -ne 0 ]]; then
		print "The boot images on this tape are incomplete." >$INSTERR
		return 1
	fi

	# Get block size of rootvg backup from image #4
	#
	# Make temporary work space
	mkdir /tmp/setbs || return 1
	cd /tmp/setbs

	# Read only first 10K in case this is a mksysb backup
	dd if=/dev/$dev.1 count=20 2>/dev/null | \
		restbyname -xqf- ./tmp/...blksz >/dev/null 2>&1
	if [[ $? != 0 ]] || [[ ! -f ./tmp/...blksz ]]; then
		print "This bootable tape was not created by Sysback or TSM for System Backup and Recovery." >$INSTERR
			return 1
	fi

	# Set block size as specified in install image
	mv -f ./tmp/...blksz /tmp/...blksz
	cd /
	rm -fr /tmp/setbs
	ROOTBS=$(cat /tmp/...blksz)

	# See if block size of backup is same as boot image
	if [[ "$ROOTBS" != 512 ]]; then
		# Change BS to backup image and reposition
		sbdevice -r $dev
		change_dev $dev block_size $ROOTBS >/dev/null || return 1
		CURBS=$ROOTBS

		# Rewind
		sbdevice -r $dev

		# Forward
		sbdevice -f4 $dev
		if [[ $? -ne 0 ]]; then
			print "Cannot forward tape past boot record" >$INSTERR
			return 1
		fi
	fi

	sync;sync
}



# Get name of first available paging logical volume and swap on
swapon_paging()
{
$XSET

	sync;sync

	getlvminfo -V rootvg -l >/tmp/..buffer5
	wc /tmp/..buffer5 | read total_opts x
	i=1
	while [ $i -le $total_opts ]
	do
		lvname=$(sbparse_command parse_1 -n$i -f/tmp/..buffer5)
		(( i = $i + 1 ))
		if [ "$(getlvminfo -L $lvname -t)" = paging ]
		   then print $lvname > /tmp/..pagelv
	   			swapon /dev/$lvname && break
		fi
	done
	rc=0
	[ ! -s /tmp/..pagelv ] && rc=1
	rm -f /tmp/..pagelv
	sync;sync
	return $rc
}


#######################################################
#######################################################
# Perform task based on command line option specified #
#######################################################
#######################################################

case "$1" in 

################################################################
getaixver)      # Write AIX version and release to a file 
################################################################
	print "$(uname -v) $(uname -r)" > /tmp/aixver
	exit 0
	;;
	
################################################################
isactive)       # See if VG or LV currently exists
################################################################
	shift
	type=$1
	name=$2
	
	if [ "$type" = V -o "$type" = L ]
	   then 
			getlvminfo -$type $name 2>/dev/null
			if test $? -ne 0
			   then exit 0
			   else exit 1 # VG or LV is active
			fi
	fi
	print "Invalid arguments to isactive: $*" >$INSTERR
	exit 2
	;;

################################################################
setupfiles)     # Create files used by sysmain and other routines
################################################################

	$XSET

	sync;sync

	# If NORMAL is set, we are running in normal mode
	# If REMAKEVG set, we're running remakevg, otherwise, we're running sysmain
	cd /
	if [[ -z "$NORMAL" ]]; then
		# Move devices catalog (for use by lsdev commands)
			if [[ ! -f /usr/lib/methods/devices.cat ]] && \
				[[ $BOOTTYPE != $NET ]] && [[ -z "$NORMAL" ]]; then
					mkdir /usr/lib/methods 2>/dev/null
					mv /usr/lpp/sysback/inst/devmin.cat \
							/usr/lib/methods/devices.cat
					mv /usr/lpp/sysback/inst/scdisk.cat \
							/usr/lib/methods 2>/dev/null
			fi
			#
			# We must move files from the CD/DVD SPOT to the ramfs
			#
			if [[ $BOOTTYPE = $CD ]] && [[ ! -f /tmp/cd.extract ]]; then
				# Does the CD need to be mounted
				unset LINE
				LINE=$(mount | grep -e "cdrfs" -e "udfs")
				if [[ -z "$LINE" ]]; then
					mount_cd /dev/`bootinfo -b` $CDMOUNTPT
				fi

				#
				# Removing files in /etc/objrepos not needed for the system
				# install to make more space
				#
				cd /etc/objrepos
				$CDMOUNTPT/usr/bin/rm -f MenuGoal TMInput DAVars FRUB FRUs 2>/dev/null
				#
				# Removing and rebuilding /etc
				#
				showled 0x42 "Copying /etc"
				cd $CDMOUNTPT/etc
				ls > /tmp/filelist
				cat /tmp/filelist | while read file
				do
					$CDMOUNTPT/usr/bin/rm -f /etc/$file 2>/dev/null
					$CDMOUNTPT/usr/bin/cp -h $file /etc 2>/dev/null
				done

				#
				# Removing and rebuilding /root/etc
				#
				cd $CDMOUNTPT/root/etc
				ls > /tmp/filelist
				cat /tmp/filelist | while read file
				do
					$CDMOUNTPT/usr/bin/rm -f /root/etc/$file 2>/dev/null
					$CDMOUNTPT/usr/bin/cp -h $file /etc 2>/dev/null
				done

				#
				# Removing and rebuilding /root/sbin
				#
				showled 0x42 "Copying /sbin"
				mkdir -p /sbin 
				cd $CDMOUNTPT/root/sbin
				ls > /tmp/filelist
				cat /tmp/filelist | while read file
				do
					$CDMOUNTPT/usr/bin/rm -f /root/sbin/$file 2>/dev/null
					$CDMOUNTPT/usr/bin/cp -h $file /sbin 2>/dev/null
				done

				#
				# Removing and rebuilding /root/sbin/helpers
				#
				showled 0x42 "cp /sbin/helpers"
				mkdir -p /sbin/helpers
				cd $CDMOUNTPT/root/sbin/helpers
				ls > /tmp/filelist
				cat /tmp/filelist | while read file
				do
					$CDMOUNTPT/usr/bin/rm -f /sbin/helpers/$file 2>/dev/null
					$CDMOUNTPT/usr/bin/cp -h $file /sbin/helpers 2>/dev/null
				done
				cd $CDMOUNTPT/sbin/helpers
				ls > /tmp/filelist
				cat /tmp/filelist | while read file
				do
					$CDMOUNTPT/usr/bin/rm -f /sbin/helpers/$file 2>/dev/null
					$CDMOUNTPT/usr/bin/cp -h $file /sbin/helpers 2>/dev/null
				done

				#
				# Removing and rebuilding:
				# /usr/lpp/bos/inst_root/sbin/helpers/jfs2
				#
				if [[ $(uname -v) -ge 5 ]]; then
					showled 0x42 "cp helpers/jfs2"
					mkdir -p /sbin/helpers/jfs2
					cd $CDMOUNTPT/usr/lpp/bos/inst_root/sbin/helpers/jfs2
					ls > /tmp/filelist
					cat /tmp/filelist | while read file
					do
						$CDMOUNTPT/usr/bin/rm -f /usr/lpp/bos/inst_root/sbin/helpers/jfs2/$file 2>/dev/null
						$CDMOUNTPT/usr/bin/cp -h $file /sbin/helpers/jfs2 2>/dev/null
					done
				fi

				#
				# Removing files in /usr/lib/objrepos not needed for the system
				# install to make more space
				#
				showled 0x42 "cp lib/objrepos"
				cd /usr/lib/objrepos
				$CDMOUNTPT/usr/bin/rm -f CC CC.vc FONT FONT.vc KEYBOARD KEYBOARD.vc MESSAGES MESSAGES.vc 2>/dev/null

				#
				# Removing files in /usr/lib/drivers/pci not needed for the 
				# system install to make more space
				#
				cd /usr/lib/drivers/pci
				$CDMOUNTPT/usr/bin/rm -fr * 2>/dev/null

				#
				# Removing files in /usr/lib/drivers/isa not needed for the 
				# system install to make more space
				#
				cd /usr/lib/drivers/isa
				$CDMOUNTPT/usr/bin/rm -fr * 2>/dev/null

				#
				# Removing files in /usr/lib/drivers/pse not needed for the 
				# system install to make more space
				#
				cd /usr/lib/drivers/pse
				$CDMOUNTPT/usr/bin/rm -fr * 2>/dev/null

				#
				# Removing files in /usr/lib/microcode not needed for the 
				# system install to make more space
				#
				cd /usr/lib/microcode
				$CDMOUNTPT/usr/bin/rm -fr * 2>/dev/null


				#
				# Removing files in /usr/lpp/bosinst not needed for the 
				# system install to make more space
				#
				cd /usr/lpp/bosinst
				$CDMOUNTPT/usr/bin/rm -f * 2>/dev/null

				#
				# Removing files in /usr/lpp/bos not needed for the 
				# system install to make more space
				#
				cd /usr/lpp/bos
				$CDMOUNTPT/usr/bin/rm -fr * 2>/dev/null

				#
				# Removing files in /usr/lpp/diagnostics not needed for the 
				# system install to make more space
				#
				cd /usr/lpp/diagnostics
				$CDMOUNTPT/usr/bin/rm -fr * 2>/dev/null
	
				#
				# Removing alog, cpio, uncompress not required for the
				# system install to make more space
				#	
				cd /usr/bin
				rm -f alog cpio uncompress 2>/dev/null	
			    cd $CDMOUNTPT/usr/bin
                $CDMOUNTPT/usr/bin/cp alog cpio uncompress /usr/bin	

				#Removing and rebuilding /usr/bin
				showled 0x42 "cp /usr/bin"
				cd $CDMOUNTPT/usr/bin
				ls | grep -vE "^ksh|^sh|^tee|^cat|^alog|^cpio|^uncompress" > /tmp/filelist
				cat /tmp/filelist | while read file
				do
					$CDMOUNTPT/usr/bin/rm -f /usr/bin/$file 2>/dev/null
					$CDMOUNTPT/usr/bin/cp -h $file /usr/bin 2>/dev/null
				done

				#Removing and rebuilding /usr/sbin
				showled 0x42 "cp /usr/sbin"
				cd $CDMOUNTPT/usr/sbin
				ls | grep -vE "^umount|^mount|^bootinfo|^lsdev" > /tmp/filelist
				cat /tmp/filelist | while read file
				do
					$CDMOUNTPT/usr/bin/rm -f /usr/sbin/$file 2>/dev/null
					$CDMOUNTPT/usr/bin/cp -h $file /usr/sbin 2>/dev/null
				done
				
				#Removing and rebuilding /usr/share
				showled 0x42 "cp /usr/share"
				if [[ -d "$CDMOUNTPT/usr/share" ]]; then
					cd $CDMOUNTPT/usr/share
					$CDMOUNTPT/usr/bin/rm -fr /usr/share 2>/dev/null
					$CDMOUNTPT/usr/bin/mkdir /usr/share  2>/dev/null
					$CDMOUNTPT/usr/bin/cp -r * /usr/share 2>/dev/null
				fi
				
				#Removing and rebuilding /usr/lib/nls
				showled 0x42 "cp /usr/lib/nls"
				if [[ -d "$CDMOUNTPT/usr/lib/nls" ]]; then
					cd $CDMOUNTPT/usr/lib/nls
					$CDMOUNTPT/usr/bin/rm -fr /usr/lib/nls 2>/dev/null
					$CDMOUNTPT/usr/bin/mkdir /usr/lib/nls 2>/dev/null
					$CDMOUNTPT/usr/bin/cp -r * /usr/lib/nls 2>/dev/null
				fi
				
				#Removing and rebuilding /usr/lib/methods
				showled 0x42 "cp lib/methods"
				cd $CDMOUNTPT/usr/lib/methods
				ls | grep -vE "^devices.cat" > /tmp/filelist
				cat /tmp/filelist | while read file
				do
					$CDMOUNTPT/usr/bin/rm -f /usr/lib/methods/$file 2>/dev/null
					$CDMOUNTPT/usr/bin/cp -h $file /usr/lib/methods 2>/dev/null
				done
				
				#Removing and rebuilding /usr/lib/drivers
				showled 0x42 "cp lib/drivers"
				cd $CDMOUNTPT/usr/lib/drivers
				ls | grep -vE "^pci|^isa|^pse" > /tmp/filelist
				cat /tmp/filelist | while read file
				do
					$CDMOUNTPT/usr/bin/rm -f /usr/lib/drivers/$file 2>/dev/null
					$CDMOUNTPT/usr/bin/cp -hr $file /usr/lib/drivers 2>/dev/null
				done

				#Removing and rebuilding /usr/lpp/bos/inst_root/sbin/helpers
				# to /sbin/helpers
				showled 0x42 "cp /sbin"
				cd /$CDMOUNTPT/usr/lpp/bos/inst_root/sbin
				ls > /tmp/filelist
				cat /tmp/filelist | while read file
				do
					$CDMOUNTPT/usr/bin/rm -f /sbin/$file 2>/dev/null
					$CDMOUNTPT/usr/bin/cp -hr $file /sbin 2>/dev/null
				done

				if [[ -d ${CDMOUNTPT}${TSMDIR} ]]; then

					if [[ -d ${CDMOUNTPT}${TSMCLIENTDIR}/lang ]]; then
						showled 0x42 "cp client/lang"
						cd ${CDMOUNTPT}${TSMCLIENTDIR}/lang
						mkdir -p ${TSMCLIENTDIR}/lang
						cp -hr * ${TSMCLIENTDIR}/lang
					fi

					if [[ -d ${CDMOUNTPT}${TSMAPIDIR} ]]; then
						showled 0x42 "cp client/api"
						cd ${CDMOUNTPT}${TSMAPIDIR}
						mkdir -p $TSMAPIDIR
						cp -hr * $TSMAPIDIR
						CreateTSMNetFile

						if [[ ! -e /usr/sbin/sbtsm ]]; then
							ln -s /usr/lpp/sysback/sbtsm /usr/sbin/sbtsm
						fi

						if [[ ! -e ${TSMAPIDIR}/bin/en_US ]]; then 
							ln -s ${TSMCLIENTDIR}/lang/en_US \
								${TSMAPIDIR}/bin/en_US

							ln -s ${TSMCLIENTDIR}/lang/en_US \
								/tmp/en_US
						fi

						if [[ ! -e ${TSMAPIDIR}/bin/EN_US ]]; then 

							ln -s ${TSMCLIENTDIR}/lang/EN_US \
								${TSMAPIDIR}/bin/EN_US

							ln -s ${TSMCLIENTDIR}/lang/EN_US \
								/tmp/EN_US
						fi


						if [[ ! -e /usr/lib/libApiDS.a ]]; then
							ln -s ${TSMAPIDIR}/bin/libApiDS.a /usr/lib/libApiDS.a
						fi
					fi

					if [[ -d ${CDMOUNTPT}${TSMICC32DIR} ]]; then
						showled 0x42 "cp client/icc32"
						cd ${CDMOUNTPT}${TSMICC32DIR}
						mkdir -p $TSMICC32DIR
						cp -hr * $TSMICC32DIR
					fi

					if [[ -d ${CDMOUNTPT}${TSMICC64DIR} ]]; then
						showled 0x42 "cp client/icc64"
						cd ${CDMOUNTPT}${TSMICC64DIR}
						mkdir -p $TSMICC64DIR
						cp -hr * $TSMICC64DIR
					fi

					if [[ ! -e /usr/lib/libpthread.a ]]; then
						ln -s /usr/lib/libpthreads.a /usr/lib/libpthread.a
					fi

					if [[ -d ${CDMOUNTPT}${TSMBADIR} ]]; then
						cd ${CDMOUNTPT}${TSMBADIR}
						showled 0x42 "cp client/ba"
						mkdir -p $TSMBADIR
						cp -hr * $TSMBADIR
						CreateTSMNetFile
					
						if [[ ! -e ${TSMBADIR}/bin/en_US ]]; then 
							ln -s ${TSMCLIENTDIR}/lang/en_US \
								${TSMBADIR}/bin/en_US
						fi
					fi
				fi

				sync;sync
				showled 0xfff
				echo "Extract" >  /tmp/cd.extract
				umount_cd /dev/`bootinfo -b` $CDMOUNTPT

				#
				# We need to nfs mount here since all of the needed files
				# are now loaded
				#
				if [[ -n "$DEBUG_NETDEV" ]] && [[ -n "$CLIENT_IPADDR" ]] && \
					[[ -n "$DEBUG_SRV" ]] && [[ -n "$DEBUG_SUBMASK" ]] && \
					[[ -n "$DEBUG_DIR" ]] && [[ -n "$DEBUGFILE" ]]; then
					/usr/sbin/sysnfs -b $BOOTTYPE -F /tmp/netinfo \
						-f $DEBUGNFSINFO

					if [[ -n "$SBDEBUG" ]]; then
						if [[ -f $NFSMOUNTDIRINFO ]]; then
							cat $NFSMOUNTDIRINFO | while read a b
							do
								if [[ "$a" = "DEBUG_DIR" ]]; then
									export DEBUG_DIR=$b
								fi
								if [[ "$a" = "NFS_DIR" ]]; then
									export NFS_DIR=$b
								fi
							done

							#
							# Has debug been turned on pior to nfs mount
							# if so, do we have a debug file which needs to
							# be copied over
							#
							if [[ -n "$DEBUGOUT" ]]; then
								DEBUGOUT_BOOTTIME=/tmp/debug.out
							else
								unset DEBUGOUT_BOOTTIME
							fi

							DEBUGOUT=${DEBUG_DIR}/${DEBUGFILE}
							export DEBUGOUT
						fi
						touch $DEBUGOUT 2>/dev/null
						if [[ $? -eq 0 ]]; then
							exec 2>>$DEBUGOUT
							export XSET="set -x"
							if [[ -n "$DEBUGOUT_BOOTTIME" ]] && \
								[[ -s "$DEBUGOUT_BOOTTIME" ]]; then
								cp $DEBUGOUT_BOOTTIME \
									${DEBUG_DIR}/${DEBUGFILE}_boottime
							fi
							sync;sync
						else
							print "Could not write to debug file $DEBUGOUT" \
								>> /tmp/debug.out
							print "Writing to temporary default file /tmp/debug.out" >> /tmp/debug.out
							exec 2>>/tmp/debug.out
							export XSET="set -x"
						fi
				fi
			fi
			sync;sync

		fi

		#
		# Does the umount and unmount command exist, if not then create the
		# hard link
		#
		if [[ ! -f /usr/sbin/umount ]]; then
			ln /usr/sbin/mount /usr/sbin/umount
		fi

		if [[ ! -f /usr/sbin/unmount ]]; then
			ln /usr/sbin/mount /usr/sbin/unmount
		fi
		
		sync;sync

	fi


	if [[ -n "$EDITONLY" ]]; then
	   # If editing only, get PV list from VGINFO file
			VGname="(free)"
			grep '^PV ' $VGINFO | while read x PVid Location Hdiskname
			do
				desc=$(lsdev -Cl $Hdiskname -F description)
				print "$Hdiskname $VGname $PVid $Location $desc"
			done > $PVINFO
			
	   else # Get list of PVs on the system
			for Hdiskname in $(getlvminfo -PN)
			do
				# Get vgname its assigned to (always free if maint mode)
				VGname=""
				for vg in $(getlvminfo -VN)
				do
					getlvminfo -V $vg -pN1 | grep -w $Hdiskname >/dev/null
					if [[ $? -eq 0 ]]; then
						VGname=$vg
						break
					fi
				done
				if [[ -z "$VGname" ]]; then
					VGname="(free)"
				fi
				PVid=$(getlvminfo -P $Hdiskname -iI)
				Location=$(getlvminfo -P $Hdiskname -iX)
				if [[ -z "$Location" ]]; then
					Location="XX-XX-XX"
				fi
				desc=$(lsdev -Cl $Hdiskname -F description)
				print "$Hdiskname $VGname $PVid $Location $desc"
			done > $PVINFO
	fi


	[[ -n "$REMAKEVG" ]] && exit 0


	# Set default install device. NETDEV variable is the default
	# if set (noprompt install). Otherwise, set to boot device.
	if [[ ! -f $INSTDEVLIST ]]; then
		if [[ -n "$NETDEV" ]]; then
			print /dev/$NETDEV > $INSTDEVLIST
		else
			if [[ -n "$NORMAL" ]]; then
				>$INSTDEVLIST
			else 
				print /dev/$BOOTDEV > $INSTDEVLIST
			fi
		fi

		if [[ -s $LVMDEVLIST ]] && [[ -n "$LVMONLY" ]]; then
			INSTDEV=$(cat $LVMDEVLIST)
			setdevdesc "lvmonly"
		else
			INSTDEV=$(cat $INSTDEVLIST)
			setdevdesc
		fi
	fi

	touch $LVMDEVLIST

	# For network installs, append port number to services file
	grep "^sbnet" /etc/services >/dev/null 2>&1
	if [[ $? -ne 0 ]]; then
		print "sbnet\t\t1239/tcp\t\t\t# Sysback Remote Backup/Install" \
			>> /etc/services
	fi

        grep "^icmp" /etc/protocols >/dev/null 2>&1
        if [[ $? -ne 0 ]]; then
                print "icmp\t\t1\t\tICMP\t\t#Internet Control Message"\
                       >> /etc/protocols
        fi  

	# Get list of available install devices
	{ LANG=C lsdev -Cctape -S Available | grep rmt # Tape Devices
	  LANG=C lsdev -Cccdrom -S Available | grep ^cd # CDROM/DVD devices
	  LANG=C lsdev -Ccadapter | grep ^tok          # Token-ring
	  LANG=C lsdev -Ccadapter | grep ^ent          # Ethernet
	  LANG=C lsdev -Ccadapter | grep ^fdd          # FDDI
	} >/tmp/..buffer4
	exec 4</tmp/..buffer4
	while read -u4 dev status loc desc
	do
		iscfg $dev && \
			printf "/dev/%-8.8s %-35.35s  %s\n" $dev "$desc" $loc 
	done > $INSTDEVINFO


	#
	# Setting up TSM api device and net information
	#
	if [[ -f ${TSMAPIDIR}/bin/libApiDS.a ]]; then 

		if [[ -z "$TSM_NETDEV" ]]; then
			TSM_NETDEV=$BOOTDEV
			lsdev -Cl$TSM_NETDEV | read x x loc x
		fi
		grep -q tsmdev $INSTDEVINFO
		if [[ $? -ne 0 ]];then
			desc="TSM Virtual Device ($TSM_NETDEV)"
			printf "%-13.13s %-35.35s  %s\n" "tsmdev" "$desc" "$loc" >> $INSTDEVINFO
		fi

		{
			LANG=C lsdev -Ccadapter | grep ^tok          # Token-ring
			LANG=C lsdev -Ccadapter | grep ^ent          # Ethernet
			LANG=C lsdev -Ccadapter | grep ^fdd          # FDDI	
		} > /tmp/..buffer4
		exec 4</tmp/..buffer4
		while read -u4 dev status loc desc
		do
			iscfg $dev && \
			printf "/dev/%-8.8s %-35.35s  %s\n" $dev "$desc" $loc
		done > $TSMNETDEVS

		if [[ ! -f ${DSMI_DIR}/libApiDS.a ]]; then
			mkdir -p ${DSMI_DIR}/en_US
			cp -hr ${TSMAPIDIR}/bin/en_US $DSMI_DIR
			cp ${TSMAPIDIR}/bin/libApiDS.a  $DSMI_DIR
                        mkdir -p ${DSMI_DIR}/EN_US
                        cp -hr ${TSMAPIDIR}/bin/EN_US $DSMI_DIR
                        cp ${TSMAPIDIR}/bin/libApiDS.a  $DSMI_DIR
		fi
	fi

	#
	# Setting up TSM BA and net information
	#
	if [[ -f ${TSMBADIR}/bin/dsmc ]]; then 
		
		if [[ ! -d ${DSM_DIR}/en_US ]]; then
			mkdir -p ${DSM_DIR}/en_US
			cp -hr ${TSMBADIR}/bin/en_US $DSM_DIR
		fi

		if [[ -z "$TSMBA_NETDEV" ]]; then
			TSMBA_NETDEV=$BOOTDEV
			lsdev -Cl$TSMBA_NETDEV | read x x loc x
		fi
		grep -q tsmbadev $INSTDEVINFO
		if [[ $? -ne 0 ]];then
			desc="TSM BA Device ($TSMBA_NETDEV)"
			printf "%-13.13s %-35.35s  %s\n" "tsmbadev" "$desc" "$loc" >> $INSTDEVINFO
		fi

		if [[ ! -s $TSMNETDEVS ]]; then
			{
				LANG=C lsdev -Ccadapter | grep ^tok          # Token-ring
				LANG=C lsdev -Ccadapter | grep ^ent          # Ethernet
				LANG=C lsdev -Ccadapter | grep ^fdd          # FDDI	
			} > /tmp/..buffer4
			exec 4</tmp/..buffer4
			while read -u4 dev status loc desc
			do
				iscfg $dev && \
				printf "/dev/%-8.8s %-35.35s  %s\n" $dev "$desc" $loc
			done > $TSMNETDEVS
		fi
	fi


	#
	# Building the DEBUGNETDEVS for remote NFS debug
	#
	{
		LANG=C lsdev -Ccadapter | grep ^tok          # Token-ring
		LANG=C lsdev -Ccadapter | grep ^ent          # Ethernet
		LANG=C lsdev -Ccadapter | grep ^fdd          # FDDI	
	} > /tmp/..buffer4
	exec 4</tmp/..buffer4
	while read -u4 dev status loc desc
	do
		iscfg $dev && \
		printf "/dev/%-8.8s %-35.35s  %s\n" $dev "$desc" $loc
	done > $DEBUGNETDEVS

	[ -s $INSTDEVINFO ] || rm -f $INSTDEVINFO
 
	# Get list of available install devices
	# Used for the post install of additional device support

	{ LANG=C lsdev -Cctape -S Available | grep rmt   # Tape Devices
	LANG=C lsdev -Cccdrom -S Available | grep ^cd  # CDROM
	} >/tmp/..buffer4
	exec 4</tmp/..buffer4
	while read -u4 dev status loc desc
	do
		iscfg $dev && \
		printf "/dev/%-8.8s %-35.35s  %s\n" $dev "$desc" $loc
		done > $NFSDEVFILE

	if [[ -n "$NIMLPPSOURCE" ]]; then
		echo "$NIMLPPSOURCE      LPP Source Directory" >> $NFSDEVFILE
	fi

	if [[ ! -s "$NFSDEVFILE" ]]; then
		rm -f $NFSDEVFILE
	fi
	
	# Get network settings from prior install if we didnt boot from network
	if [[ "$BOOTTYPE" != "$NET" ]] && \
		[[ -f /usr/lpp/sysback/inst/netinfo ]]; then
		mv /usr/lpp/sysback/inst/netinfo $NETINFO
	fi

	# Create a default netinfo file if not already there
	if [[ ! -f $NETINFO ]]; then
		# Get network interface
		netdev=$(basename $INSTDEV)
		case $netdev in
			ent*) lnetdev=en$(expr "$netdev" : "ent\(.*\)");;
			tok*) lnetdev=tr$(expr "$netdev" : "tok\(.*\)");;
			fddi*) lnetdev=fi$(expr "$netdev" : "fddi\(.*\)");;
			*) netdev=ent0; lnetdev=en0;;
		esac
		print "$netdev undefined undefined undefined undefined 16 $lnetdev bnc" > $NETINFO
	fi
	cp $NETINFO $NFSINFO
	if [[ ! -f "$DEBUGNFSINFO" ]];then
		cp $NETINFO $DEBUGNFSINFO
	fi

	sync;sync

	exit 0
	;;


################################################################
getdumpdevs) # Get a list of tape/diskette devices for dump output
################################################################
	# First, see if there is a dump to be dumped
	rm -f $INSTERR

	sync;sync

	# Format the output for the screen
	LANG=C lsdev -Ccdiskette -SAvailable | sed "s/^fd/rfd/" >/tmp/..buffer4
	LANG=C lsdev -Cctape -SAvailable >>/tmp/..buffer4
	exec 4</tmp/..buffer4
	while read -u4 dev status loc desc
	do
		printf "/dev/%-8.8s %-35.35s  %s\n" $dev "$desc" $loc
	done > $TEMPFILE
	if [[ ! -s "$TEMPFILE" ]]; then
		print "There are no tape or diskette devices available for dump output." > $INSTERR
		exit 1
	fi

	sync;sync

	exit 0
	;;


################################################################
copy_dump) # Copy dump to the specified device
################################################################
	# Note that this routine is dependent on the "copydump" 
	# command, which is undocumented and included in the
	# bos.rte.sysbr fileset! We use copydump to ensure that
	# we always create the dump in the format expected by
	# IBM product support. The arguments to this command and the
	# resulting error messages are taken from the source code
	# from the command since the command itself is completely
	# no-verbose!
	shift
	dumplv=$1
	dumpsize=$2
	pvloc=$3
	outputdev=$4
	bosinstflag=1 # tells copydump to varyon rootvg and mount filesystems
	tapeflag=0
	[[ $outputdev = /dev/rmt* ]] && { tapeflag=1; tapemsg="and kernel "; }

	print "\nPlease wait - copying system dump to $outputdev .."
	copydump $dumplv $dumpsize $pvloc $outputdev $tapeflag $bosinstflag 
	rc=$?

	# The following error codes come from the copydump.h file.
	[ $rc -ne 0 ] && print "\07"
	case $rc in
		 0) print "System Dump ${tapemsg}has been copied to $outputdev."
			print "After reboot, use the tar command to extract the dump.";;
		 1) print "Usage error from copydump command!";;
		 2) print "Unable to intialize ODM.";;
		 3) print "Unable to get the physical volume for the dump device.";;
		 4) print "Unable to import the physical volume for the dump device.";;
		 5) print "Unable to vary on the rootvg volume group to access the dump device.";;
		 6) print "Unable to open the dump device to read.";;
		 7) print "Unable to move the file pointer for the dump device.";;
		 8) print "Unable to read from the dump device.";;
		 9) print "No valid dump in the dump device.";;
		10) print "Unable to get the device information for output device $outputdev";;
		11) print "Unable to configure output device $outputdev";;
		14) print "Unable to copy the kernel (/unix) to the dump device. However, the system\ndump has been copied successfully."
			print "After reboot, use the tar command to extract the dump.";;
		 *) print "Failed to copy the system dump to the output device $outputdev"
			print "Return code is $rc.";;
	esac

	# Start a permanent shell
	print "\nYou are now in a maintenance shell. You may not exit this shell.\nUse normal process for rebooting the system when desired.\n"
	loopshell

	exit 1 # should never get here
	;;


################################################################
getvgpvlist) # Get a list of PVs for the selected VG on active system
################################################################
	# Return 0 if VG active, 1 if not.

	sync;sync

	rm -f $INSTERR
	shift
	vgname=$1
	PVlist="$(getlvminfo -V $vgname -pN1 2>/dev/null)"
	rc=$?
	print "$PVlist" > $VGPVLIST

	sync;sync

	exit $rc
	;;

	
################################################################
gettsmdev)  # Get list of installation images and devices from server
################################################################
    # Existence of vginfo error file indicates an error
	
	sync;sync

	rm -f $INSTERR $NETINSTOPTS

	# If install device is network, contact the server,
	# and just get the list of installation images.
	if [[ -z "$NORMAL" ]]; then
		grep -w $(basename $INSTDEV) $NETSTAT >/dev/null 2>&1              
            if [[ $? -ne 0 ]]; then
				# Network has not yet been configured
				tsm_sysnet -c || exit $?
			fi
		fi

    # Get device or file(s) to install from
	tsm_sysnet -i rootvg
	if [[ $? -ne 0 ]]; then
		rm -f $NETINSTOPTS
		exit 1
	fi

	sync;sync

	exit 0
;;

################################################################
getudfbid) #Get all backup IDs on UDF DVDs
################################################################

	cddev=$2
	rhost=$3

	sync;sync

	rm -f $UDF_BID_FILE
	> $UDF_BID_FILE

	vfs="cdrfs"

	#
	# Local check
	#
	if [[ -z $rhost ]]; then
		if [[ -z $VERSION ]]; then
			VERSION=$(uname -v)
		fi
		if [[ -z $RELEASE ]]; then
			RELEASE=$(uname -r)
		fi
		
		if [[ ${VERSION}${RELEASE} -ge 52 ]]; then
			vfs=$(bootinfo -f $cddev)
		else
			vfs="cdrfs"
		fi
	else #Remote check
		vfs=$(sbclient $rhost "setbs -C $cddev")
		if [[ -z "$vfs" ]]; then
			vfs="cdrfs"
		fi
	fi

	#
	# Only one backup on all cdrfs
	#
	if [[ "$vfs" = "cdrfs" ]]; then
		exit 1
	fi

	if [[ "$vfs" = "udfs" ]];then
		if [[ -z $rhost ]]; then
			mount_cd $cddev $CDMOUNTPT
			ls $SB_DATA/SB.*.CDTOC  > /tmp/$$tmpfile 2>/dev/null
			umount_cd $cddev $CDMOUNTPT
		else
			OIFS="$IFS"
            IFS="="
            sbclient $rhost "env" | grep "CLIENT_HOST=" | read x thostname
            IFS="$OIFS"
			vfs=$(sbclient instserver "sb_cdmnt -td $cddev")
			if [[ -z "$vfs" ]]; then
				vfs="cdrfs"
			fi
            sbclient $rhost "sb_cdmnt -v$vfs -m 11 -d $cddev -h $thostname"	
			sbclient $rhost "ls $SB_DATA_1/SB.*.CDTOC" > /tmp/$$tmpfile 2>/dev/null
			sbclient $rhost "sb_cdmnt -u 11 -d $cddev -h $thostname"
		fi
	fi

	if [[ ! -s /tmp/$$tmpfile ]]; then
		rm -f /tmp/$$tmpfile
		exit 1
	fi

	wc /tmp/$$tmpfile | read num_opts x
	i=1

	while [ $i -le $num_opts ]   
	do
		file=$(/usr/sbin/sbparse_command parse_1 -f/tmp/$$tmpfile -n$i)
		file=$(basename $(echo $file | sed "s/\.CDTOC//"))
		(( i = $i + 1 ))
		printf "\t%-25s\n" $file >> $UDF_BID_FILE
	done
	rm -f /tmp/$$tmpfile

	sync;sync

	exit 0
;;


################################################################
getnetdev)  # Get list of installation images and devices from server
################################################################
	# Existence of vginfo error file indicates an error
	rm -f $INSTERR $NETINSTOPTS

	sync;sync

	# If install device is network, contact the server,
	# and just get the list of installation images.
	if [[ -z "$NORMAL" ]]; then
		grep -w $(basename $INSTDEV) $NETSTAT >/dev/null 2>&1
		if [[ $? -ne 0 ]]; then
			# Network has not yet been configured
			sysnet -c || exit $?
		fi
	fi

	# Get device or file(s) to install from
	sysnet -i rootvg
	if [[ $? -ne 0 ]]; then
		rm -f $NETINSTOPTS
		exit 1
	fi

	sync;sync

	exit 0
	;;

################################################################
get_headerfiles)      # Get header information from backup media
################################################################
	# This routine is normally called only once, but may be called again
	# if the install device is changed after the first call to this
	# routine. If we had previously forwarded to a backup sequence number
	# other than the first, subsequent calls may cause us to do this
	# again without first rewinding, which will likely fail.
	rc=0
	cd /
	
	arg_2=$2
	arg_3=$3

	sync;sync

	# LED to indicate we're reading data files
	if [[ "$INSTMODE" = noprompt ]]; then
		showled 0xA40 "read data files"
	fi

	# Set device variables
	set_device_vars "$arg_2"

	if [[ $DEVTYPE != FILE ]] && [[ $DEVTYPE != CD ]] && \
		[[ $DEVTYPE != TSM ]]; then
		# Do what is necessary to skip the boot images on the tape
		# if we did not boot from the tape. If we booted from the
		# tape, we would already be positioned correctly, but may
		# need to change the blocksize to read the backup data, which
		# requires us to rewind and forward past the boot images again.
		if [[ -z "$REMOTE" ]];then
			# Local tape
			############
			if [[ $FIRSTDEV = /dev/$BOOTDEV ]] && \
				[[ ! -f /tmp/..skipped ]]; then
				# We booted from install device
				# Check & change block size if needed
				ROOTBS=$(cat /tmp/...blksz)
				if [[ "$ROOTBS" != 512 ]]; then
					change_dev $FIRSTDEV block_size $ROOTBS \
						>/dev/null 2>&1 || {
						print "Cannot change block size of device $FIRSTDEV" > $INSTERR
						exit 1
					}
					# Forward past boot images
					sbdevice -qf4 $FIRSTDEV 2>$INSTERR || {
					print "Cannot forward past boot images on device $FIRSTDEV" >$INSTERR
					exit 1
					}
				fi
				sbread -H $FIRSTDEV >/dev/null 2>&1
				if [[ $? -ne 0 ]]; then
					# User may have changed tapes in the drive
					skip_boot $FIRSTDEV >/dev/null || exit 1
				fi
				
		   else # User changed install device or we had previously
				# skipped to a latter backup sequence so we must
				# rewind and start over.
				skip_boot $FIRSTDEV >/dev/null || exit 1
		fi
		
					# Set all additional devices to same block size
					ROOTBS=$(cat /tmp/...blksz)
					numdevs=$(print $DEVLIST | wc -w)
					if test $numdevs -gt 1
					   then for dev in $DEVLIST
							do
								case $dev in
									$FIRSTDEV) 
										# Dont change first device
										;;
									*)	change_dev $dev block_size $ROOTBS \
											>/dev/null 2>&1 || {
											print "Unable to set blocksize to $ROOTBS on device $dev." >$INSTERR
											exit 1
										}
										;;
								esac
							done
					fi

			   else # Remote tape
					#############
					# Set the block size and forward the remote tape
					# to the first backup image, if not already done
					# Run the getvginfo script remotely, which sets the tape
					# blocksize and forwards past the boot images.
					# Note that this call returns the contents of the LVM info
					# on the backup image, which we ignore. We keep this code
					# around in case the server is running an older level
					# of sysback that requires it.
					sbclient instserver "getvginfo $FIRSTDEV >/dev/null" \
						2>$INSTERR
					if test $? -ne 0
		  				then print "Unable to skip boot images on remote device $FIRSTDEV." >> $INSTERR
							exit 1
					fi
			fi
	fi

	# Get current backup header, toc & vginfo files
	# This will also set the read options needed for forwarding tapes
	read_header_files $arg_3

	# If not a tape device (local or remote), return now since
	# the backup sequence number does not apply to files
	if [[ "$DEVTYPE" = "FILE" ]] || [[ "$DEVTYPE" = "CD" ]]; then 
		if [[ "$INSTMODE" = noprompt ]]; then
			showled 0xA46
		fi

		BUSEQ=1	
	fi

	# If not set otherwise, assume a backup sequence number of 1
	if [[ -z "$BUSEQ" ]]; then
		BUSEQ=1
	fi

	# Forward to the selected backup sequence number if greater than 1
	i=1
	while [ $i -lt $BUSEQ ]
	do
		# Get number of images in current backup.
		# Note that the backup TYPE must begin with "TOC" for this to
		# be a multi-image backup. If not, this is a single image (file/
		# directory backup) with no TOC and only a single image.
		MULTI=
		grep "^Type" $HEADER | read x TYPE
		[[ $TYPE = TOC* ]] && MULTI=y
		if [ ! -z "$MULTI" ]
		   then n=1
				cat $TOCFILE | while read imagenum x
				do
					if [ $imagenum != $n ]
				   	then print "Table of contents file is invalid!" >$INSTERR
							rm -f $TOCFILE
							exit 1
					fi
					((n=n+1))
				done
				NUMIMAGES=$((n - 1))

		   else # This is a single-image backup with no TOC info
				NUMIMAGES=1
		fi
		
		# Skip images
		if [ -z "$REMOTE" ]
		   then # Local
				sbfwd $POLICY -s $NUMIMAGES $DEVLIST 2>/dev/null
		   else # Remote
				sbclient instserver "sbfwd -s $NUMIMAGES $DEVLIST 2>/dev/null"
		fi
		if test $? -ne 0
		   then # Rewind all devices to start over
				if [ -z "$REMOTE" ]
				   then sbdevice -r $DEVLIST 2>/dev/null
				   else sbclient instserver "sbdevice -r $DEVLIST" 2>/dev/null
				fi
				print "Unable to forward to the selected backup sequence number." >$INSTERR
				rm -f $TOCFILE $HEADER
				exit 1
		fi
		((i = i + 1))

		# This flag indicates that we've skipped images in case the
		# install device changes and we must rewind.
		> /tmp/..skipped

		# Get header info & toc for next backup
		read_header_files $arg_3
	done

	# We're now positioned at the start of the rootvg backup for the
	# selected backup sequence number

	# Mark that we have already extracted the files
	basename $INSTDEV > $EXTRACT

	#
	# If we restored a vginfo file from dskt, copy over the restored file
	#
	if [[ -f /tmp/...vginfo ]]; then
		cp /tmp/...vginfo $VGINFO
		cp $VGINFO $VGINFO_ORG
		print "dskt" > $EXTRACT
	fi

	# If the LVMINFO variable is set, grab the selected file
	# from the server and overwrite restored LVM info
	if [[ -n "$LVMINFO" ]] && [[ -n "$REMOTE" ]]; then
		sbclient instserver "cat $LVMINFO 2>/dev/null" > /tmp/.temp
		if [[ $? -eq 0 ]]; then
			mv /tmp/.temp $VGINFO
			cp $VGINFO $VGINFO_ORG
			print "dskt" > $EXTRACT
	   else # Ignore error - use the LVM info from the media
			rm -f /tmp/.temp
		fi
	fi

	# Get backup type
	grep "^TYPE " $VGINFO | cut -d' ' -f2 >$BUTYPE

	# LED for normal install processing
	[ "$INSTMODE" = noprompt ] && showled 0xA46

	sync;sync

	exit 0
	;;

################################################################
check_log)	# LV has moved to a new VG, so make sure there is a
			# jfslog in the new VG
################################################################
	shift
	vgname=$1

	sync;sync


	if [ ! -z "$REMAKEVG" ]
	   then # If VG does not exist - get jfslog from VGINFO file
			getlvminfo -V $vgname 2>/dev/null || REMAKEVG=""
	fi

	if [ -z "$REMAKEVG" ]; then
			# First, get a valid log lv from the vginfo file
			/usr/sbin/sblvminfo check -Tl -tv -f $VGINFO -u $vgname | \
			while read lvnum
			do
				set_lv $lvnum
				[ $VGNAME != $vgname ] && continue
				[ $type != jfslog ] && continue
				logname=$lvname
				break
			done
	   else # Normal mode
			getlvminfo -V $vgname -l 2>/dev/null | while read lvname
			do
				[ $(getlvminfo -L $lvname -t) != jfslog ] && continue
				logname=$lvname
				break
			done
	fi
	if [ -z "$logname" ]
	   then print "You cannot place a filesystem in the $vgname volume group because there is no jfslog logical volume." >>$INSTERR
			exit 1
	fi

	sync;sync

	exit 0
	;;

################################################################
callfunct)      # Call a function in the library
################################################################
	shift
	function=$1
	shift
	args="$@"

	$function $args
	exit $?
	;;

##################################################################
reboot)         # Reboot the system. If rootvg active, unmount everything first.
##################################################################
	if [ -f /etc/shutdown ]
	   then # unmount and sync everything possible
			killall
			sync
			umount all 2>/dev/null
			sync
			sleep 5
	fi
	reboot -ql
	;;

##################################################################
checklvpvs) # Make sure PVlist in LV records match those for the VG
##################################################################
	shift
	vg=$1

	sync;sync


	# Get PV list for the VG
	PVlist=$(/usr/sbin/sblvminfo query -Tv -tP -f $VGINFO -d $vg)

	# Get the LVlist for the VG
	>$lvfile
	/usr/sbin/sblvminfo check -Tl -tv -f $VGINFO -u $vg > $lvfile

	# For each LV, make sure hdisks are assigned to the VG
	cat $lvfile | while read lvnum x
	do
		LVpvlist=$(/usr/sbin/sblvminfo query -Tl -tP -f $VGINFO -n $lvnum)

		newpvlist=
		for hdiskname in $LVpvlist
		do
			print "$PVlist" | grep -w $hdiskname >/dev/null 2>&1
			[ $? -ne 0 ] && continue
			newpvlist="${newpvlist}$hdiskname "
		done
		LVpvlist=$newpvlist

		# Update the LV record
		/usr/sbin/sblvminfo update -Tl -tP -f $VGINFO -u "$LVpvlist" -n $lvnum
	done

	sync;sync

	exit 0
	;;


##################################################################
checkvginfo) # Pre-install checks
##################################################################
	# Note that standard output should only contain main titles. Standard
	# error should contain status messages, and any errors prior to failure
	# exit should be written to $INSTERR (up to 2 lines). 
	# Args:
	#   $1    = check type: 
	#				VG = volume group(s)
	#				LV = logical volume(s)
	#   $2 .. = volume group file name
	#   $3 .. = logical volume file name
	
	# If RECOVERY environment variable set, this is a recovery install,
    # so igmore all parameters and check only the / and /usr filesystems.

	# Things are a little strange on the variables due to the
    # way the fuction is called from.

	vgfile=$3
	lvfile=$4

	sync;sync


	if [[ -z $VERSION ]]; then
		VERSION=$(uname -v)
	fi
	if [[ -z $RELEASE ]]; then
		RELEASE=$(uname -r)
	fi


	if [[ -n "$RECOVERY" ]]; then
		# Recovery install. Global variables defined in sysmain
		lvnum=$(/usr/sbin/sblvminfo query -f $VGINFO -Tl -tN -d hd4)
		echo "$lvnum hd4" > $lvfile
		lvnum=$(/usr/sbin/sblvminfo query -f $VGINFO -Tl -tN -d hd2)
		echo "$lvnum hd2" >> $lvfile
		checktype=LV

	   else # Check according to arguments
			shift
			checktype=$1
			shift
			VGERR=0
	fi


	if [ -f $vgfile ]; then
		unset VGLIST
		cat $vgfile | while read vg
		do
			if [ "$vg" = "ALL" ]; then
				VGLIST=ALL
			fi
		done
	fi
	if [ -f $lvfile ]; then
		unset LVLIST
		cat $lvfile | while read lv
		do
			if [ "$lv" = "ALL" ]; then
				LVLIST=ALL
			fi
		done
	fi
		
	if [ "${VGLIST}$LVLIST" = ALL ]
	   then # Get the VG or LV list from the vginfo file
			case $checktype in
				VG) 
					unset VGLIST
					>$vgfile
					/usr/sbin/sblvminfo query -a -Tv -f $VGINFO >$vgfile
					;;
				LV) 
					unset LVLIST
					>$lvfile
					/usr/sbin/sblvminfo query -a -Tl -f $VGINFO >$lvfile
					;;
			esac
	fi

	RC=0
	get_version

	if [ -z "$REMAKEVG" ]
	then 
		# Make sure we booted from same version/release as we are installing
		if [ "${VER}$REL" != "${VERSION}$RELEASE" ]
		   then print "You are attempting to restore an AIX version $VER.$REL backup after booting from AIX version $VERSION.$RELEASE boot media! This process is not supported!" >> $INSTERR
				rm -f $VGINFO $HEADER $TOCFILE $EXTRACT
				exit 9
		fi
	
		# This process only supports sysback backups at Sysback 4.1 or higher
		if [ "$SBVER" -lt 40100 ]
		   then CURVER=$((SBVER / 10000))
				CURREL=$(((SBVER - (SBVER / 10000 * 10000)) / 100))
				print "You are attempting to install a backup created with Sysback version $CURVER.$CURREL. This process requires Sysback 4.1 or higher." >>$INSTERR
				exit 9
		fi
	
		# Make sure this is a valid VGINFO file
		print "Validating LVM information"
		junk=$(grep "^TOC " $VGINFO 2>/dev/null)
		if [ "$junk" = "" ]
		   then print "The table of contents is missing from the LVM info file." >>$INSTERR
				exit 9
		fi
	fi

	#
	# We must convert the vglist file to a usable format
	#
	if [ ! -z "$REMAKEVG" -a "$checktype" = "VG" ]; then
		rm -f /tmp/$$tmpfile
		> /tmp/$$tmpfile
		wc $vgfile | read num_opts x
		i=1
		while [ $i -le $num_opts ] 
		do
			vg=$(sbparse_command parse_1 -f$vgfile -n$i)
			(( i = $i + 1 ))
			value=$(sblvminfo query -Tv -tN -d $vg -f $VGINFO)
			print "$value" >> /tmp/$$tmpfile
		done
		cp /tmp/$$tmpfile $vgfile
	fi
			
	#
	# We must convert the lvlist file to a usable format
	#
	if [ ! -z "$REMAKEVG" -a "$checktype" = "LV" ]; then
		rm -f /tmp/$$tmpfile
		> /tmp/$$tmpfile
		wc $lvfile | read num_opts x
		i=1
		while [ $i -le $num_opts ] 
		do
			lv=$(sbparse_command parse_1 -f$lvfile -n$i)
			(( i = $i + 1 ))
			value=$(sblvminfo query -Tl -tN -d $lv -f $VGINFO)
			print "$value" >> /tmp/$$tmpfile
		done
		cp /tmp/$$tmpfile $lvfile
	fi
			
	# If checktype is VG, create LVLIST for the specified VG(s)
	if [ $checktype = VG ]
	   then 
			>$lvfile
		# See if this LV is to be created in a VG in the VGLIST
			cat $vgfile | while read vgnum x
			do
				/usr/sbin/sblvminfo check -Tl -tv -U$vgnum -f $VGINFO >>$lvfile
			done
	fi

	# If first time through, convert all PP map data from PVIDs to hdisks.
	# If an old PV is not available, set the hdisk name to "missing".
	if [ -z "$(grep ^UPDATED $VGINFO)" ]
	   then print "Updating physical volume info .."
			for PV in $(grep ^PV $VGINFO | cut -d' ' -f2)
			do
				# Convert pvid to hdisk
				hdiskname=$(pv_to_hdisk $PV)
				if [ $? -ne 0 -o -z "$hdiskname" ]
				   then hdiskname=missing
				fi

				# Change the PV names in the PP maps
				mv $VGINFO $VGINFO.old
				sed "s/^$PV:/$hdiskname:/" $VGINFO.old > $VGINFO
				rm -f $VGINFO.old
			done

			# Update PV names in the VG records
			/usr/sbin/sblvminfo query -a -Tv -f $VGINFO > /tmp/..buffer4	
			exec 4</tmp/..buffer4
			while read -u4 vgnum x
			do
				PVlist=$(/usr/sbin/sblvminfo query -Tv -tP -f $VGINFO -n$vgnum)
				unset newpvlist
				for pv in $PVlist
				do
					# convert PV to new hdisk name
					hdiskname=$(pv_to_hdisk $pv)
					if [[ ! -z $hdiskname ]]
					   then # Got the new hdisk name - add to list
							if [ -z "$newpvlist" ]; then
								newpvlist="$hdiskname"
							else
								newpvlist="$newpvlist $hdiskname"
							fi
					   else # Either duplicates or not found
							# Get the prior hdisk name and location
							grep "^PV $pv " $VGINFO | read x x location hdisk
							vgerr "Physical Volume ID $pv (previously $hdisk at\n  location $location) does not exist on this system."
							RC=1
					fi
				done
	
			    # Add hdisk names to record and write to file
				PVlist="$newpvlist"
		/usr/sbin/sblvminfo update -f $VGINFO -Tv -tP -n $vgnum -u "$newpvlist"
			done

			# Update PV names in the LV records
			# Do this only for LVs selected since this takes time
			cat $lvfile | while read lvnum lv
			do
				# Convert PVIDs for all logical volumes. Do this for 
				# all LVs even if VG or LV is not created in case user 
				# changes create option
				LVpvlist=$(/usr/sbin/sblvminfo query -Tl -tP -f $VGINFO -n $lvnum)
					# Convert PVs to hdisk names
					newpvlist=
					for pv in $LVpvlist
					do
						# convert PV to new hdisk name
						hdiskname=$(pv_to_hdisk $pv)
						if [[ -z $hdiskname ]]
						   then continue # PV no longer exists - we already
										# should have displayed error message
										# for the VG record
						fi
						newpvlist="${newpvlist} $hdiskname"
					done
					LVpvlist="$newpvlist"

					# Write the new pv list and go on to next LV
					/usr/sbin/sblvminfo update -Tl -tP -f $VGINFO -n $lvnum -u "$LVpvlist"
			done
	fi

	#
	# Check the volume groups
	#
	if [ $checktype = VG ]
	   then 
			unset vgnum vgname
			cat $vgfile | while read vgnum vgname
			do
				set_vg $vgnum $vgname 
				if [ "${VERSION}$RELEASE" -ge 43 ] 
					then
					set_vgext $vgnum $vgname
					if [ -z "$factor" ]; then
						factor=1
					fi
					if [ -z "$bigvg" ]; then
						bigvg='n'
					fi
				else  # AIX is not at 4.3, set to default values
					factor=1
					bigvg='n'
				fi
	
	
				# If ignoring this VG, skip the rest 
				[ $vgopt = D ] && continue

				print "Checking volume group $vgname .."

				if [ $vgopt = I ]
				   then # VG is to be imported - make sure at least 1 selected
						if [ -z "$PVlist" ]
						   then vgerr "Volume group $vgname changed from IMPORT to IGNORE since there\n  are no remaining physical volumes assigned to this volume group.\n  If you wish to create or import this volume group, you must\n  select at least one physical volume."
								vgopt=D
								/usr/sbin/sblvminfo update -Tv -tV -f $VGINFO -n $vgnum -u "$vgopt"
								[ $RC -eq 0 ] && RC=2
						fi
						# In any case, dont bother checking space for VG or LVs
						# since we are only importing.
						continue
				fi

				# If running remakevg, remove any PVs from the PVlist that
				# are already assigned to active VGs
				if [ ! -z "$REMAKEVG" ]
				   then NEWPVlist=
						for pv in $PVlist
						do
							remove=0
							for vg in $(getlvminfo -VN)
							do
								[ $vg = $vgname ] && continue
								getlvminfo -V $vg -pN1 2>/dev/null | \
									grep -w $pv > /dev/null
								if test $? -eq 0
								   then vgerr "Physical volume $pv has been removed from the PV list for volume group\n  $vgname because it is already assigned to the $vg volume group."
										
										remove=1
										[ $RC -eq 0 ] && RC=2
										break
								fi
							done
							if [ $remove != 1 ]
							   then # PV not in use, add to new pvlist
									NEWPVlist="$NEWPVlist $pv"
							fi
						done
						# Remove 1st space and assign new PVlist
						PVlist=$(print "$NEWPVlist" | cut -c2-999)
						/usr/sbin/sblvminfo update -Tv -tP -f $VGINFO -n $vgnum -u "$PVlist"

						# Can't mix and match vpaths and hdisks in the
						# same volume group
						unset SB_VPATH SB_HDISK
						for pv in $PVlist
						do
							case $pv in
								hdisk*) SB_HDISK=1;;
								vpath*) SB_VPATH=1;;
							esac
						if [ ! -z "$SB_HDISK" -a ! -z "$SB_VPATH" ]; then
							vgerr "A volume group cannot have both vpath disks and hdisks in the same\nvolume group.  If you wish to create or import this volume group,\nyou must deselect either the vpath or hdisk from this physical volume list."
							RC=1
						fi
					done
				fi

				# VG is to be created - there must be disks selected.
				if [ "$PVlist" = "" ]
				   then if [ $vgname != rootvg -a -z "$REMAKEVG" ] 
						   then vgerr "Volume group $vgname changed from CREATE to IGNORE since there\n  are no remaining physical volumes assigned to this volume group.\n  If you wish to create or import this volume group, you must\n  select at least one physical volume."
								vgopt=D
								/usr/sbin/sblvminfo update -Tv -tV -f $VGINFO -n $vgnum -u "$vgopt"
								RC=1
						   else vgerr "There are no physical volumes remaining for the $vgname volume\n  group. You must assign at least one physical volume to $vgname before\n  continuing."
								RC=1
						fi
						continue
				fi

				#
				# Verify enough remaining space selected for this VG
				#
				checkvgspace $vgname 
				if [ "$tot_disk_avail" -lt "$tot_lv_size" ]
				   then vgerr "The $vgname volume group requires $tot_lv_size MB ($lvpps PPs) of disk\n  space. The physical volumes currently assigned to this VG contain\n  only $tot_disk_avail MB ($diskpps PPs). You will be required to either select\n  additional disk space for this volume group or change the\n  logical volume attributes to require less disk space before\n  continuing the install."
						RC=1
				fi
	
				#
				# Make sure the Physical partition size is large enough for the 
				# selected disks (cannot have more than MAXPPS on a single disk
				#
				oldppsize=$ppsize

				#If the factor size is set, then change the MAXPPS
				if [ ! -z "$factor" -a "$factor" -gt 1 ] 
					then (( MAXPPS = $MAXPPS * $factor ))
				fi

				while [ "$largest_pvsize" != 0 -a \
					$((largest_pvsize / ppsize)) -gt $MAXPPS ]
				do
					((ppsize = ppsize * 2))
				done
				if [ $oldppsize != $ppsize ]
				   then # Change PPsize in the Vg record
						/usr/sbin/sblvminfo update -Tv -ts -f $VGINFO -n$vgnum -u "$ppsize"
		
						# Update all of the LV records for the VG
						update_lvpps $vgname $oldppsize $ppsize
	
						vgerr "The volume group contains a $largest_pvsize MB disk, which requires the\n  physical partition size to be at least $ppsize MB. The previous PPsize\n  was only $oldppsize, so it has been automatically changed and all\n  logical volume records have been updated to reflect the new value."
						[ $RC -eq 0 ] && RC=2
				fi
	
			done # Next VG
	fi

	#
	# Check the logical volume records
	#
	LVERR=0
	cat $lvfile | while read lvnum lv
	do
		set_lv $lvnum $lv
		lv=$lvname
		vgname=$VGNAME
		unset U_LVpvlist U_STRPSZ U_STRPWID U_COPIES U_UPPER U_PPMAP
		unset U_PRIORITY U_TYPE

		# Setting this option to make sure this value gets updated
		U_LVpvlist=1

		# Skip checks if LV is not to be created
		[ "$createopt" = n ] && continue

		print "Checking logical volume $lvname .."

		# Get PP size and PVlist for the VG
		if [ -z "$REMAKEVG" -a -z "$RECOVERY" ]
		   then 
			set_vg 0 $vgname
		   else if [ -z "$(getlvminfo -V $vgname 2>/dev/null)" ]
				   then 
					set_vg 0 $vgname
				   else getlvminfo -V $vgname -SpN1 | read ppsize PVlist
				fi
		fi

		# Make sure hdisks are still in the VG
		newpvlist=
		for hdiskname in $LVpvlist
		do
			print "$PVlist" | grep -w $hdiskname >/dev/null 2>&1
			[ $? -ne 0 ] && continue
			newpvlist="${newpvlist}$hdiskname "
		done
		LVpvlist=$newpvlist

		# Get number of PVs selected for this LV.
		numpvs=$(print $LVpvlist | wc -w)
		if test $numpvs -eq 0
		   then # If no PVs are selected for the LV, multiple copies
				# may be created as long as they do not exceed the
				# maximum PVs in the VG.
				numpvs=$(print $PVlist | wc -w)
		fi

		# Check striping stuff
		if [ $VER != 3 -a "$strpsz" != 0 ]
		   then # PVs must be specifically selected for the LV
				Lnumpvs=$(print $LVpvlist | wc -w)
				(( Lnumpvs = Lnumpvs / $copies ))
				if [ $Lnumpvs -le 1 ]
				   then lverr "Not enough PVs specified in the LV record - striping turned off"
						[ $RC -eq 0 ] && RC=2
						strpsz=0
						strpwid=0
						U_STRPSZ=1  
						U_STRPWID=1
				   else if [ $((lps % Lnumpvs)) -ne 0 ]
						   then lverr "#LPs not divisible by #PVs - striping turned off"
								[ $RC -eq 0 ] && RC=2
								strpsz=0
								strpwid=0
								U_STRPSZ=1  
								U_STRPWID=1
						fi
				fi
				# You can only strip and mirror at AIX 4.3.2
				if [ $copies -gt 1 -a ${VERSION}$RELEASE -lt 43 ]
				   then lverr "Cannot mirror a striped LV - #copies changed to 1"
						[ $RC -eq 0 ] && RC=2
						copies=1
						U_COPIES=1
				fi
		fi

		# Make sure copies do not exceed number of PVs for the LV
		if [ $numpvs -ne 0 -a $copies -gt $numpvs -a $strict = y ]
		   then # Too many copies - display error
				lverr "#Copies exceed selected PVs - copies changed to $numpvs."
				[ $RC -eq 0 ] && RC=2

				# Change line in vginfo file
				copies=$numpvs
				U_COPIES=1
		fi

		check_lv_jfs2 $lvname

		# Make sure number of PVs do not exceed upperbound
		if [ $upper -lt $numpvs -a "$strict" != "s" ]
		   then lverr "Upperbound limit less than #PVs - changed to $numpvs."
				upper=$numpvs
				U_UPPER=1
				[ $RC -eq 0 ] && RC=2
		fi
		if [ "$strict" = "s" ]; then
			if [ $upper -gt $(( $numpvs / $copies )) ]; then
				lverr "Upperbound limit is larger than the allowed value of $(($numpvs / $copies)) - changed to $(($numpvs / $copies))."
				upper=$(($numpvs / $copies))
				[ $RC -eq 0 ] && RC=2
			fi
		fi

		# Make sure lps is at least minlps
		if [ $minlps -ne 0 -a $lps -lt $minlps ]
		   then lverr "WARNING: Logical volume $lv is smaller than the minimum size.\n\tFailing to increase the size could cause the restore to fail."
				[ $RC -eq 0 ] && RC=2
		fi

		# See if LV is created using maps
		while [ $ppmap = y ]
		do      
			# Create logical volume using partition map
			print "Checking partition map for logical volume $lv"

			# Not on striped LVs
			if [ $VER = 4 -a "$strpsz" != 0 ]
			   then lverr "Partition maps are not supported on striped logical volumes."
					ppmap=n
					priority=2
					U_PPMAP=1
					U_PRIORITY=1
					break
			fi

			# Make sure copies and lps have not changed
			mapsize=$(grep -p "^PP $lv$" $VGINFO 2>/dev/null | \
				grep ':' | wc -l)
			mapsize=$(print $mapsize)
			[ $mapsize -eq 0 ] && \
			   lverr "No map data available for logical volume $lv."
			if [ $((lps * copies)) != $mapsize ]
			   then lverr "The partition map requires exactly $mapsize physical partitions,\n\twhich does not equal the current logical volume size."
					ppmap=n
					priority=5
					U_PPMAP=1
					U_PRIORITY=1
					break
			fi

			# Get/check partition map and translate PVIDs to hdisks
			errmsg=$(checkppmap $lv $vgname $((lps * copies)) $LVpvlist)
			if test $? -ne 0
			   then lverr "$errmsg"
					[ $RC -eq 0 ] && RC=2
					ppmap=n
					priority=5
					U_PPMAP=1
					U_PRIORITY=1
			fi
			break
		done

		# Update the LV record
		updatelvmfields $lvnum $lv	

	done # Next LV record

	cat $lvfile | while read lvnum lv
	do
		unset change_value OLDLINE
		/usr/sbin/sblvminfo query -Tf -tm -f $VGINFO -n $lvnum >/dev/null 2>&1
		if [ $? -ne 0 ]; then
			continue
		fi

		set_fs2 $lvnum $lv 

		vgname=$VGNAME
		check_fs2_jfs2 $LVNAME
		if [ ! -z "$change_value" ]; then
			updatefs2fields $lvnum $lv
		fi
	done

	# Mark VGINFO file so we dont convert PVIDs again
	if [ -z "$(grep ^UPDATED $VGINFO)" ]
	   then print >> $VGINFO
			print "UPDATED" >> $VGINFO
	fi

	# Remove temp files
	rm -f /tmp/$$*

	# If this is a recovery install, then the rootvg is mounted
	# Check to ensure the VG has enough space to recreate the
	# / and /usr logical volumes at the size defined in the
	# VGINFO file.
	if [[ -n "$RECOVERY" ]]; then
		checkvgspace rootvg
		if [ "$tot_disk_avail" -lt "$tot_lv_size" ]; then
			vgerr "To recreate the / and /usr filesystems at the defined sizes, the\n  rootvg volume group requires $tot_lv_size MB ($lvpps PPs) of disk\n  space. The physical volumes currently assigned to this VG contain\n  only $tot_disk_avail MB ($diskpps PPs). You must reduce the sizes\n  of the / and /usr filesystems before continuing the install."
			RC=1
		fi
	fi

	# If not a full system install, exit now
	if [[ -n "$REMAKEVG" ]] || [[ -n "$RECOVERY" ]]; then 
		exit $RC
	fi

	# Verify there is paging space in rootvg
	/usr/sbin/sblvminfo check -Tl -tv -f $VGINFO -u rootvg | while read lvnum
	do
		set_lv $lvnum
		if [ "$type" != "paging" ]; then
			continue
		fi
		[ $createopt = n ] && continue
		pagefound=y
		break
	done
	if [ "$pagefound" != y ]
	   then lverr "There is no paging space selected in the root volume group.\n\tYou must select to create at least one paging space."
			RC=1
	fi

	# Exit with return code
	# RC=0  No errors or warnings, installation may continue
	# RC=1  Cannot continue without changes
	# RC=2  Warnings provided, installation may continue
	print COMPLETE

	sync;sync

	exit $RC
	;;


################################################################
CheckFilespaceFile) #checks the filespacefile
###############################################################

	sync;sync
	
	shift

	dev=$1
	type_value=$2
	
	>$INSTERR

	if [[ -z "$dev" ]]; then
		print "No device was specified." >> $INSTERR 
		return 4
	fi

	if [[ "$dev" != "tsmbadev" ]];  then
		print "You must have the tsmbadev selected." >> $INSTERR
		return 4
	fi

	if [[ ! -f $DSMC_FILESPACE_FILE ]]; then
		SetTSMBAInfo "1"
	
		# If install device is network, contact the server,
		# and just get the list of installation images.
		if [[ -z "$NORMAL" ]]; then
			grep -w $(basename $INSTDEV) $NETSTAT >/dev/null 2>&1              
   	         if [[ $? -ne 0 ]]; then
					# Network has not yet been configured
					tsm_sysnet -c -b || exit $?
				fi
		fi
		sbdsmc -al -o $DSMC_FILESPACE_FILE $SBDSMC_OPTIONS
	fi

	grep -q "^/$" $DSMC_FILESPACE_FILE
	if [[ $? -ne 0 ]]; then
		print "The root (/) filespace is missing from the tivoli backup.  This filesystem is required for a complete system install." >> $INSTERR
		return 5
	fi

	grep -q "^/usr$" $DSMC_FILESPACE_FILE
	if [[ $? -ne 0 ]]; then
		print "The /usr filespace is missing from the tivoli backup.  This filesystem is required for a complete system install." >> $INSTERR
		return 5
	fi

	if [[ -n "$RECOVERY" ]] || [[ "$type_value" = "r" ]]; then
		return 0
	fi

	grep -q "^/var$" $DSMC_FILESPACE_FILE
	if [[ $? -ne 0 ]]; then
		print "The /var filespace is missing from the tivoli backup.  This filesystem is required for a complete system install." >> $INSTERR
		return 5
	fi

	sblvminfo check -Tl -tv -u"rootvg" -f $VGINFO | while read lvnum
	do
		mountpt=$(sblvminfo query -Tl -tm -f$VGINFO -n$lvnum)
		
		if [[ "$mountpt" = "-" ]]; then
			continue
		fi

		FS="/usr/tivoli"
		if [[ "$mountpt" = "$FS" ]]; then
			grep -q "^${FS}$" $DSMC_FILESPACE_FILE
			if [[ $? -ne 0 ]]; then
				print "Filesystem $FS exist in rootvg and must also be included in TSM client backup." >> $INSTERR
				return 6
			fi
		fi

		FS="/usr/tivoli/tsm"
		if [[ "$mountpt" = "$FS" ]]; then
			grep -q "^${FS}$" $DSMC_FILESPACE_FILE
			if [[ $? -ne 0 ]]; then
				print "Filesystem $FS exist in rootvg and must also be included in TSM client backup." >> $INSTERR
				return 6
			fi
		fi

		FS="/usr/tivoli/tsm/client"
		if [[ "$mountpt" = "$FS" ]]; then
			grep -q "^${FS}$" $DSMC_FILESPACE_FILE
			if [[ $? -ne 0 ]]; then
				print "Filesystem $FS exist in rootvg and must also be included in TSM client backup." >> $INSTERR
				return 6
			fi
		fi

		FS="/usr/tivoli/tsm/client/ba"
		if [[ "$mountpt" = "$FS" ]]; then
			grep -q "^${FS}$" $DSMC_FILESPACE_FILE
			if [[ $? -ne 0 ]]; then
				print "Filesystem $FS exist in rootvg and must also be included in TSM client backup." >> $INSTERR
				return 6
			fi
		fi
	done

	return 0
;;



#################################################################
getpv_vgs) # Get list of PVs and VGs they are assigned to
#################################################################

	sync;sync

	exec 4<$PVINFO
	while read -u4 pvname vgname pvid pvaddr desc
    do
		active=" "
		if [ ! -z "$REMAKEVG" -a -z "$EDITONLY" ]
		   then # normal mode - see if assigned to active volume group
				if [ "$vgname" = "(free)" ]
				   then # PV not assigned. See if assigned in VGINFO file.
						/usr/sbin/sblvminfo query -Tv -a -f$VGINFO | while read vgnum
						do
						pvlist=$(/usr/sbin/sblvminfo query -f$VGINFO -Tv -tP -n$vgnum)
						echo "$pvlist" | egrep -q "$pvname |$pvname$"
						if [ $? -eq 0 ]; then
							set_vg $vgnum $vgname
							if [ "$vgopt" = D ] 
							   then vgname="(free)"
							   else break
							fi
						fi
						done
				   else # Indicate to the menu program that PV is active
						active="*"
				fi

		   else # maint mode - get from VGINFO file which may have changed
				/usr/sbin/sblvminfo query -Tv -a -f$VGINFO | while read vgnum
				do
				pvlist=$(/usr/sbin/sblvminfo query -f$VGINFO -Tv -tP -n$vgnum)
				echo "$pvlist" | egrep -q "$pvname |$pvname$"
				if [ $? -eq 0 ]; then
					set_vg $vgnum $vgname
					if [ "$vgopt" = D ] 
					   then vgname=""
					   else break
					fi
				fi
				done
		fi
		[ -z "$vgname" ] && vgname="(free)"
		printf "%s%-14.14s%-14.14s%-16.16s%.32s\n" "$active" $pvname $pvaddr "$vgname" "$desc"  
	done > $PVVGLIST

	sync;sync

	exit 0
	;;

#################################################################
getpv_hotspare) # Get list of PVs and VGs they are assigned to
#################################################################

	sync;sync

	active=" "
	if [ -f $PVHOTSPARELIST ];then
		rm -f $PVHOTSPARELIST.tmp
		> $PVHOTSPARELIST.tmp
		exec 4<$PVHOTSPARELIST
		while read -u4 pvname pvaddr VGNAME hotspare desc
		do
			unset ACTIVE_VG NOTACTIVE_VG
			echo "$pvname" | grep "*" >/dev/null 
			PVNAME=$( echo $pvname | sed "s/*//" )
			/usr/sbin/sblvminfo query -Tv -a -f$VGINFO | while read vgnum
			do
				vgname=$(sblvminfo query -Tv -tv -f$VGINFO -n$vgnum)
				pvlist=$(getlvminfo -V $vgname -Np 2>/dev/null)
				rc=$?
				if [ $rc -eq 0 ]; then
					ACTIVE_VG=1
				fi
				if [ $rc -ne 0 ]; then
					pvlist=$(/usr/sbin/sblvminfo query -f$VGINFO -Tv -tP -n$vgnum)
					NOTACTIVE_VG=1
				fi
				echo "$pvlist" | egrep -q "$pvname |$pvname$"
				if [ $? -eq 0 ]; then
					if [ ! -z "$NOTACTIVE_VG" ]; then
						set_vg $vgnum
						if [ -z "$vgname" ]; then
							grep "$PVNAME " $PVINFO | read name vname x x x 
							if [ ! -z "$vname" ]; then
								vgname=$vname
							else
								continue
							fi
						else
							break
						fi
					fi
					if [ ! -z "$ACTIVE_VG" ]; then
						break; # Breaking out of the second loop
					fi
				fi # pvlist match against pvname
			done #loop through vglist

			if [ -z "$vgname" ]; then
				vgname="(free)"
			fi
			printf "%s%-14.14s%-16.16s%-13.13s%-7.7s%.30s\n" "$active" $PVNAME $pvaddr "$vgname" "$hotspare" "$desc" >> $PVHOTSPARELIST.tmp
		done # Loop through hotspare list
		mv $PVHOTSPARELIST.tmp $PVHOTSPARELIST
		exit 0
	fi

	print "" > $PVHOTSPARELIST
	> $PVHOTSPARELIST

	exec 4<$PVINFO
	while read -u4 pvname vgname pvid pvaddr desc
    do
		active=" "
		if [ ! -z "$REMAKEVG" -a -z "$EDITONLY" ]
		   then # normal mode - see if assigned to active volume group
				if [ "$vgname" = "(free)" ]
				   then # PV not assigned. See if assigned in VGINFO file.
						/usr/sbin/sblvminfo query -Tv -a -f$VGINFO | while read vgnum vgname
						do
							pvlist=$(/usr/sbin/sblvminfo query -f$VGINFO -Tv -tP -n$vgnum)
							echo "$pvlist" | egrep -q "$pvname |$pvname$"
							if [ $? -eq 0 ]; then
								set_vg $vgnum $vgname
								if [ "$vgopt" = D ];then
									vgname="(free)"
								else 
									break
								fi
							fi
						done
				   else # Indicate to the menu program that PV is active
						active=" "
				fi

		   else # maint mode - get from VGINFO file which may have changed
						/usr/sbin/sblvminfo query -Tv -a -f$VGINFO | while read vgnum vgname
						do
							pvlist=$(/usr/sbin/sblvminfo query -f$VGINFO -Tv -tP -n$vgnum)
							echo "$pvlist" | egrep -q "$pvname |$pvname$"
							if [ $? -eq 0 ]; then
								set_vg $vgnum $vgname
								if [ "$vgopt" = D ];then
									vgname=""
							   else 
									break
								fi
							fi
				done
		fi
		[ -z "$vgname" ] && vgname="(free)"
		unset found
		grep "^PVEXT " $VGINFO | while read line
		do
			 print $line | read x id addr x hotspare
			if [ "$id" = "$pvid" -o "$addr" = "$pvaddr" ];then
				[ "$hotspare" = "y" -o "$hotspare" = "Y" ] && hotspare="yes" || hotspare="no"
				printf "%s%-14.14s%-16.16s%-13.13s%-7.7s%.30s\n" "$active" $pvname $pvaddr "$vgname" "$hotspare" "$desc" >> $PVHOTSPARELIST
			found=1
			break;
			fi
		done
		if [ -z "$found" ]; then
			printf "%s%-14.14s%-16.16s%-13.13s%-7.7s%.30s\n" "$active" $pvname $pvaddr "$vgname" "no" "$desc" >> $PVHOTSPARELIST  
		fi
		unset found
	done 

	sync;sync

	exit 0
	;;


##################################################################
checkspace) # Verify space requirements for all volume groups
##################################################################
	# Note that standard output should only contain main titles. Standard
	# error should contain status messages, and any errors prior to failure
	# exit should be written to $INSTERR (up to 2 lines). 

	sync;sync

	integer count
	rm -f $INSTERR

	# Make sure rootvg is not already mounted
	if [ -z "$NORMAL" -a -c /dev/rootvg ]
	   then print "\07The root volume group is currently active! You must reboot before\nperforming the installation."
			sleep 3
		exit 1
	fi

	#
	# Compute minimum disk space required for each volume group
	#
	print Verifying space requirements ..
	print "VG Name        Available MB       Used MB            Free MB" >&2
	print - "----------     -------------      -------------      ------------" >&2
	notenough=0
	grep "^VG " $VGINFO >/tmp/..buffer4
	wc /tmp/..buffer4 | read total_opts x
	i=1
	while [ $i -le $total_opts ]
	do
		set_vg $i ""
		(( i = $i + 1 ))
		[ $vgopt = I ] && \
			printf "%-15.15sThis volume group will be imported\n" $vgname >&2
		[ $vgopt != C ] && continue

		# Get total disk space available for this VG
		checkpvspace $PVlist

		# Get total disk space required for this VG
		checkvgspace $vgname $VGINFO
	
		total="$(printf "%d (%-d PPs)" $tot_disk_avail $diskpps)"
		used="$(printf "%d (%-d PPs)" $tot_lv_size $lvpps)"
		avail="$(printf "%d (%-d PPs)" $freemb $freepps)"
		printf "%-15.15s%-19.19s%-19.19s%-19.19s" $vgname "$total" \
			"$used" "$avail" >&2

		if [ $tot_lv_size -gt $tot_disk_avail ]
		   then print " **" >&2
				notenough=1
		   else print >&2
		fi
	done

	[ $notenough = 1 ] && exit 1

	sync;sync

	exit 0
	;;


##################################################################
#
# Performs a getrootfs on the rootvg
#
##################################################################
importrootvg)

	if [[ -x /usr/lib/boot/chramfs ]]; then
		chramfs=/usr/lib/boot/chramfs
	fi
	if [[ -x /etc/chramfs ]]; then
		chramfs=/etc/chramfs
	fi
		
	if [[ ! -x /usr/lib/boot/chramfs ]] && [[ ! -x /etc/chramfs ]]; then
		cp /usr/lib/boot/chramfs /etc/chramfs
		chmod +x /etc/chramfs
		chramfs=/etc/chramfs
	fi

	if [[ $BOOTTYPE -eq 5 ]]; then
		unlink /SPOT
		mkdir /SPOT
		ln -s /usr /SPOT
		${chramfs} +81920
	fi

	set +x                      
	if [[ -n "$SBDEBUG" ]]; then
		TTY=$(/usr/bin/tty)     
		exec 2>${TTY}           
	fi

	export PS1="ksh> "

	if [[ -x /usr/lib/boot/getrootfs ]]; then
		getrootfs=/usr/lib/boot/getrootfs
	fi
	if [[ -x /etc/getrootfs ]]; then
		getrootfs=/etc/getrootfs
	fi
		
	if [[ ! -x /usr/lib/boot/getrootfs ]] && [[ ! -x /etc/getrootfs ]]; then
		cp /usr/lib/boot/getrootfs /etc
		chmod +x /etc/getrootfs
		getrootfs=/etc/getrootfs
	fi

	${getrootfs}
;;


		
##################################################################
runshell)       # Start a shell
##################################################################

	set +x
	if [[ -n "$SBDEBUG" ]]; then
		TTY=$(/usr/bin/tty)
		exec 2>${TTY}
	fi

	print "You have entered a maintenance shell. When finished, type \"exit\" to\nreturn to the Main Menu ..
"
	startshell nomsg
	
	# Re-exec sysmain since we exited to here
	print "\nPlease wait .."
	trap 2
	if [[ "$BOOTTYPE" = "$NET" ]]; then
		exec /etc/sysmain
	else
		exec /usr/lpp/sysback/inst/sysmain
	fi

	;;

##################################################################
runcopydump)
##################################################################
	set +x
	if [[ -n "$SBDEBUG" ]]; then
		TTY=$(/usr/bin/tty)
		exec 2> ${TTY}
	fi
	/usr/bin/copydumpmenu
	rc=$?
	(( rc1 = $rc >> 8 ))
	if [ $rc1 -gt 0 -a $rc1 -lt 5 ]; then
	case $rc1 in
		1)
			print "Unable to get the dump information for copying the dump\n\07" 
			print "Hit any key to return to main menu"
			read a
		;;
		2) 
			print "No previous dump exists.\n\07"
			print "Hit any key to return to main menu"
			read a
		;;
		3)
			print "Dump is not in a logical volume.  No dump copy is allowed\n\07"
			print "Hit any key to return to main menu"
			read a
		;;
		4)
			print "Unable to initialize ODM.  No dump copy is allowed\n\07"
			print "Hit any key to return to main menu"
			read a
		;;
		*)
			print "Unknown error has occurred.  No dump copy is allowed\n\07"
			print "Hit any key to return to main menu"
			print $rc1
			read a
		;;
	esac
	fi

	print "\nPlease wait .."
	[ $BOOTTYPE = $NET ] && exec /etc/sysmain
	exec /usr/lpp/sysback/inst/sysmain
	;;


##################################################################
reboot)     # Reboot the system
##################################################################
	# No return from this routine.
	ttymsg -l50 -i13 -cbs"REBOOT THE SYSTEM"
	if [ $PLATFORM != rspc ]
	   then print "\n\n\tTo boot in NORMAL mode, turn the key to the NORMAL position\n\n\tTo reboot in SERVICE mode, leave the key in SERVICE position\n\n\n\n\t\tThe system will reboot in 10 seconds ..."
	   else print "\n\n\tThe system will now reboot in NORMAL mode. If you wish to reboot\n\tin SERVICE mode, be prepared to press F1 (graphics) or F4 (ascii)\n\twhen the system icons appear.\n\n\n\n\tThe system will reboot in 10 seconds ..."
	fi

	sleep 10
	# If shutdown exists, user has already imported rootvg

	if [ -f /etc/shutdown ]
	   then # unmount and sync everything possible
			killall
			sync
			umount all 2>/dev/null
			sync
	fi
	reboot -ql
	;;


##################################################################
get_vgimports)	# Get a list of the volume groups on defined disks
##################################################################
	# Checks VGDA of each available disk on the system and
	# accumulates a list of VGs and associated PVs and LVs for use
	# in selection of VG to import from Utilities menu.
	# Note the list of PVs and LVs for each VG is shown only up to a 
	# certain number of characters to keep all entries on one line.

	shift
	# If $1=rootonly, then we have extracted the VGINFO from the 
	# media already and should list only rootvgs with a / filesystem
	# matching the lvname in the VGINFO file
	if [ "$1" = rootonly ]
	   then ROOTONLY=1
			grep '^FS / ' $VGINFO | read x x x rootlv x
	fi

	pvlist="$(getlvminfo -PN)"
	> $TEMPFILE
	for pvname in $pvlist
	do
		vgid=$(getlvminfo -G $pvname -i 2>/dev/null)
		[ -z "$vgid" ] && continue
		lvlist=
		curvgline="$(grep -w $vgid $TEMPFILE)"
		if [ -z "$curvgline" ]
	   	   then # Get list of LVs
				lvlist=$(getlvminfo -G $pvname -l1)

				# If we know the name of the root filesystem LV name,
				# list only VGs containing the name
				if [ ! -z "$ROOTONLY" ]
					then [ -z "$(print $lvlist | grep -w $rootlv)" ] && \
							continue
				fi
	
				# Get list of PVs in the VG
				pvlist=$(getlvminfo -G $pvname -pN1)
				[ "$(print $pvlist | cut -c29)" != "" ] && \
					pvlist="$(print $pvlist | cut -c1-26).."
				[ "$(print $lvlist | cut -c29)" != "" ] && \
					lvlist="$(print $lvlist | cut -c1-26).."
				printf "%-16.16s  %-28.28s  %-28.28s\n" $vgid "$pvlist" \
					"$lvlist" >> $TEMPFILE
		fi
	done

	if [ ! -s $TEMPFILE ]
	   then if [ -z "$ROOTONLY" ]
			   then print "No volume groups are defined on any available physical volumes. Cannot import a rootvg volume group." > $INSTERR
			   else print "Unable to find a root volume group containing a / ($rootlv) filesystem." > $INSTERR
			fi
			exit 2
	fi
	exit 0;;

 
##################################################################
import_rootvg)		# Import rootvg volume group and optionally
                    # check and mount filesystems
##################################################################	
	# arg1 = PVname (no /dev prefix)
	# arg2 = recovery install? (1=yes/0=no)
	# arg3 = mount filesystems? (1=yes/0=no)

	shift
	pvname=$1
	[ ! -b /dev/$pvname ] && \
		errshell "Invalid PV Name \"$pvname\" specified for import!"

	[ ! -z "$NORMAL" ] && exit 0

	shift
	[ "$1" = 1 ] && RECOVERY=1

	shift
	[ "$1" = 1 ] && MOUNTOPT=1

	# Import rootvg from specified PV 
	if [[ -z "$RECOVERY" ]]; then
		importvg -f -y rootvg $pvname >/dev/null
		print "Importing rootvg from $pvname .." || \
		   errshell "Could not import rootvg from $pvname" 2
	else 
		importvg -f -y rootvg $pvname > /tmp/tmperr 2>&1
		if [[ $? -ne 0 ]]; then
			print "Could not import rootvg from $pvname.                                        " > $INSTERR
			cat /tmp/tmperr | read line 
			print - "$line .." | cut -c1-76 >> $INSTERR
			rm -f /tmp/tmperr
			return 1
		fi
		rm -f /tmp/tmperr
	fi

	# Swap on the first available paging space
	swapon_paging
	if [[ $? -eq 1 ]] && [[ -z "$RECOVERY" ]]; then
	  print "\07NOTE: No paging space was found. Memory may be insufficient.\n"
	fi

	# If recovery install, we dont need to check or mount anything now.
	# Exit back to the menus
	if [[ -n "$RECOVERY" ]]; then 
		exit 0
	fi

	# Get the filesystem logical volume names for /, /usr, /var, /tmp
	# First try the VGINFO file if the user has restore one
	if [ -f $VGINFO ]
	   then # Get the LV names from the VGINFO file
			grep '^FS / ' $VGINFO | read x x x ROOTLV x
			grep '^FS /usr ' $VGINFO | read x x x USRLV x
			grep '^FS /var ' $VGINFO | read x x x VARLV x
	fi
	# else, get from the ODM database in RAM (comes from boot image)
	[ -z "$ROOTLV" ] && \
		ROOTLV=`odmget -q "attribute=label and value=/" CuAt 2>/dev/null |
		grep name |cut -f2 -d \"`
	[ -z "$ROOTLV" ] && errshell "Cannot find mount point for root filesystem!"
	[ -z "$USRLV" ] && \
		USRLV=`odmget -q "attribute=label and value=/usr" CuAt 2>/dev/null |
		grep name |cut -f2 -d \"`
	[ -z "$USRLV" ] && errshell "Cannot find mount point for /usr filesystem!"
	[ -z "$VARLV" ] && \
		VARLV=`odmget -q "attribute=label and value=/var" CuAt 2>/dev/null |
		grep name |cut -f2 -d \"`

	# Check and fix filesystems as needed
	print "Checking / filesystem .."
	fsck -fp /dev/$ROOTLV
	print "Checking /usr filesystem .."
	fsck -fp /dev/$USRLV
	if [ ! -z "$VARLV" ]
	   then print "Checking /var filesystem .."
			fsck -fp /dev/$VARLV
	fi
	print "\nThe volume group has been successfully imported.\n"

	# Mount filesystems only if user chose to do so
	# with option to rebuild boot logical volumes
	if [ ! -z "$MOUNTOPT" ]
	   then 
			merge_diskroot

			# See if user wants to rebuild the bootlv
			print -n "\nDo you wish to rebuild the boot logical volume now? (y/n) "
			read do_bosboot
			case "$do_bosboot" in
				y*|Y*) print "Rebuilding boot logical volume(s) .."
					rebuild_bootlvs
					;;
			esac
	fi

	# Start a permanent shell
	print "\nYou are now in a maintenance shell. You may not exit this shell.\nUse normal process for rebooting the system when desired.\n"
	loopshell

	exit 1 # should never get here
	;;


##################################################################
update_rootfs)        # Update the VGINFO file with current lv sizes
                      # of / and /usr filesystems
##################################################################

	sync;sync

	if [[ -z "$RECOVERY" ]] || [[ -z "$ROOTLV" ]] || [[ -z "$USRLV" ]]; then
		print "Not a recovery install - cannot update filesystem sizes!" \
			> $INSTERR
		exit 1
	fi

	# Get sizes and update
	for lvname in $ROOTLV $USRLV
	do
		# Get size of imported filesystem
		curlps=$(getlvminfo -L $lvname -n)

		# Update filesystem data
		set_lv 0 $lvname
		lps=$curlps
		U_LPS=1
		updatelvmfields 0 $lvname
	done

	sync;sync

	exit 0
	;;
	

##################################################################
install)        # Install the system!
##################################################################

	# Fall through to end of case statements
	# See "Begin Operating System Installation" below
	;;


#################################################################
*)             # Default - Anything else is an error
#################################################################
	print "Invalid option \"$1\" provided to sysinstall!" >$INSTERR
	exit 2
	;;
esac


##############################################
#                                            #
#        MAIN INSTALL SECTION                #
#                                            #
##############################################
# Begin Operating System Installation #
#######################################
# Note that the following is NOT run in under CURSES, so standard input and
# error apply.

# LED for normal install processing
[ "$INSTMODE" = noprompt ] && showled 0xA46 "install starting"

ttymsg -i13 -bcs "SYSTEM INSTALLATION"
ttymsg -v'|' -h '-' -l70 -i3 -s"The system installation process has begun. Interrupting the process at this point will render the system inoperable. If the system has a key switch, you may turn it to the NORMAL position at any time to allow the installation to complete with no further prompting."

# Set install type (POWER or regular SYSTEM)
grep ^TYPE $VGINFO | read x TYPE
[ -z "$TYPE" ] && TYPE=SYSTEM

# Set device variables
set_device_vars

sync;sync

# Set all variables required for reading the backup
set_read_vars

sync;sync

# If running in NORMAL (test), stop here.
if [ ! -z "$NORMAL" ]
   then print "\07\nRunning in NORMAL MODE - Stopping now before I screw up the system." 
		exit 1
fi

# Make more space in RAM Filesystem by clearing set functions
unset setdevdesc updatevginfo pv_to_hdisk checkpvspace \
	checkvgspace update_lvpps checkppmap isvg islv change_dev skip_boot \
	iscfg vgerr lverr pv_to_hdisk isvg islv read_header_files 

# Move vginfo file so we dont restore over it
mv $VGINFO /tmp/vginfo$$
VGINFO=/tmp/vginfo$$
mv $VGINFO_ORG /tmp/vginfo$$_org
VGINFO_ORG=/tmp/vginfo$$_org

# If the LV_SEDFILE exists, user changed some LV names or mount points, 
# so we need to update the TOC file for use by sysrestvg 
if [[ -s "$LV_SEDFILE" ]]; then
	cp $TOCFILE ${TOCFILE}.org
	mv $TOCFILE ${TOCFILE}.old
	sed -f $LV_SEDFILE ${TOCFILE}.old > $TOCFILE
	rm -f ${TOCFILE}.old
else
	cp $TOCFILE ${TOCFILE}.org
fi

# Complete install - make sure a VGDA exists on all disks we're
# going to make a VG onto
if [[ -z "$RECOVERY" ]];then
	grep "^VG " $VGINFO >/tmp/..buffer4
	exec 4</tmp/..buffer4
	while read -u4 $VGFIELDS
	do
		[ $vgopt != C ] && continue
		for disk in $PVlist
		do
			chgdisk -l $disk -a pv=yes
			if [[ $? -ne 0 ]]; then
				syserror "Unable to make $disk a physical volume" 2
			fi
		done
	done

else # Recovery install - remove current / and /usr filesystems. 
	rmlv -f $ROOTLV >/dev/null 2>&1 # Always expect errors but should
	rmlv -f $USRLV >/dev/null 2>&1  # complete successfully

	# Clear the jfs log logical volume(s)
	sblvminfo query -a -Tl -f$VGINFO | while read lvnum
	do
		set_lv $lvnum
		if [[ "$VGNAME" = "rootvg" ]] && [[ "$type" = "jfslog" ]]; then
			print y | logform /dev/$lvname >/dev/null 2>&1 
			if [[ $? -ne 0 ]]; then
				syserror "Failed formatting $lvname jfs log." 2
			fi
		fi
		if [[ "$VGNAME" = "rootvg" ]] && [[ "$type" = "jfs2log" ]]; then
			print y | logform -V jfs2 /dev/$lvname >/dev/null 2>&1 
			if [[ $? -ne 0 ]]; then
				syserror "Failed formatting $lvname jfs log." 2
			fi
		fi
	done
fi

sync;sync

# Remove programs and device driver files no longer needed
if [[ "$BOOTTYPE" != "$NET" ]]; then
	rm -rf /usr/sbin/logredo /usr/sbin/getrootfs /usr/sbin/importvg \
			 /usr/share/lib/terminfo/*
		cp /usr/lib/methods/showled /usr/bin # Save showled program elsewhere
		cd /usr/lib

		if [ -z "$SCRIPTS" ]; then
			rm -rf libcurses.a methods/* drivers/* microcode/*
		else
			rm -rf libcurses.a 
		fi

		cd /
		if [[ "$TYPE" != "POWER" ]] && [[ -z "$RECOVERY" ]]; then 
			rm /usr/sbin/fsck
		fi
fi

rm -f /etc/logredo /etc/sysinit /etc/importvg

# Create rootvg, start paging and create LVs and filesystems.
# Note that for RECOVERY install this will create only / and /usr filesystems.
if [[ "$INSTMODE" = noprompt ]]; then
	showled 0xA50 "create rootvg"
fi

sysmakevg rootvg

if [[ "$INSTMODE" = noprompt ]]; then
	showled 0xA46 "restore rootvg"
fi

#
# If the DEVTYPE is TSMBA (tsm ba client) then mount all filesystems
# in rootvg and restore all filesystems in rootvg.  All of the other DEVTYPES
# CD, TAPE, TSMAPI, FILE will use the following (see below)
# Mount /, /usr, /tmp and /var filesystems under $MROOT.
# These are only ones required for base OS and bootlv processing

if [[ "$DEVTYPE" = "TSMBA" ]]; then
	sblvminfo check -Tf -tv -urootvg -f $VGINFO > /tmp/..corefs
else
#### Original ####
#	SLIST="hd4 hd2 hd3 hd9var"
#	CheckTivoliFS "$SLIST" "rootvg"
#	>/tmp/..corefs
#	for lv in $SLIST
#	do
#		lvnum=$(/usr/sbin/sblvminfo query -Tl -tN -f$VGINFO -d$lv)
#		print "$lvnum" >> /tmp/..corefs
#	done
#### End of Original ####

#### Modified by Tany ####
	SLIST="hd4 bos_hd4 hd2 bos_hd2 hd3 bos_hd3 hd9var bos_hd9var"
	CheckTivoliFS "$SLIST" "rootvg"
	>/tmp/..corefs
	for lv in $SLIST
	do
		lvnum=$(/usr/sbin/sblvminfo query -Tl -tN -f$VGINFO -d$lv)
		[[ -n "$lvnum" ]] && print "$lvnum" >> /tmp/..corefs
	done
#### End of Tany Addendum ####
fi

# If not a power install, mount the filesystems
if [[ "$TYPE" != "POWER" ]]; then
	MountFilesystems /tmp/..corefs

fi

# File /var/efs/efsenabled should exists otherwise mount of EFS
# enabled filesystem fails
if [[ "$VERSION" = 6 ]]; then
   mkdir ${MROOT}/var/efs
   touch ${MROOT}/var/efs/efsenabled
   export EFSADDED=yes
fi


sync;sync

# Restore only / and /usr data at this point. Note that this will provide
# the means to create a bootable system although absense of /var data
# would result in errors on boot.
exec 4</tmp/..corefs
while read -u4 lvnum
do
	dir=$(/usr/sbin/sblvminfo query -Tl -tm -f$VGINFO -n$lvnum)
	lv=$(/usr/sbin/sblvminfo query -Tl -tl -f$VGINFO -n$lvnum)
	[ $dir != /tmp -a $dir != /var ] && rootlvlist="$rootlvlist $lv"
done
ttymsg -l60 -i8 -c -s "Restoring Base Operating System Data"
rm -f $restfile

#### Original ####
#val=$(/usr/sbin/sblvminfo query -Tl -tN -d hd4 -f$VGINFO)
#print "$val" > $lvfile
#val=$(/usr/sbin/sblvminfo query -Tl -tN -d hd2 -f$VGINFO)
#print "$val" >> $lvfile
#### End of Original ####

#### Modified by Tany ####
val=$(/usr/sbin/sblvminfo query -Tl -tN -d hd4 -f$VGINFO)
[[ -z "$val" ]] || val=$(/usr/sbin/sblvminfo query -Tl -tN -d bos_hd4 -f$VGINFO)
print "$val" > $lvfile
val=$(/usr/sbin/sblvminfo query -Tl -tN -d hd2 -f$VGINFO)
[[ -z "$val" ]] || val=$(/usr/sbin/sblvminfo query -Tl -tN -d bos_hd2 -f$VGINFO)
print "$val" >> $lvfile
#### End of Tany Addendum ####

#val=$(/usr/sbin/sblvminfo query -Tl -tN -d hd9var -f$VGINFO)
#print "$val" >> $lvfile
if [[ -n "$RLIST" ]]; then
	for mpt in $RLIST
	do
		val=$(/usr/sbin/sblvminfo query -Tl -tN -d "$mpt" -f$VGINFO)
		lv=$(/usr/sbin/sblvminfo query -Tl -tl -d "$mpt" -f$VGINFO)
		print "$val" >> $lvfile
		print "$lv" >> $restfile
	done
fi

#
# TSMBA device will use a different method of restore verus the other
# device types, plus a tsmba device will restore all of rootvg
#
if [[ "$DEVTYPE" = "TSMBA" ]]; then
	if [[ ! -f $DSMC_FILESPACE_FILE ]]; then
		SetTSMBAInfo "1"

		# If install device is network, contact the server,
		# and just get the list of installation images.
		if [[ -z "$NORMAL" ]]; then
			grep -w $(basename $INSTDEV) $NETSTAT >/dev/null 2>&1              
   	         if [[ $? -ne 0 ]]; then
					# Network has not yet been configured
					tsm_sysnet -c || exit $?
				fi
		fi

		sbdsmc -al -o $DSMC_FILESPACE_FILE $SBDSMC_OPTIONS
	fi
	
	sysrestvgdsmc "1" "$DSMC_FILESPACE_FILE" "$VGINFO_ORG" "$VGINFO" "rootvg"

else
	PostionTapeDrive
	sysrestvg 1 $lvfile

fi

ttymsg -bl60 -i8 -c -s "Syncing data to disk.  This may take several minutes."
sync;sync;sync
print "\nBase Operating System restored.\n"
sleep 3

cd /
#####
# Reconfigure Base Operating System
#####
ttymsg -l60 -i8 -c -s "Reconfiguring Base Operating System"
print

# If POWER backup, we need to run an fsck on / and /usr filesystems
# and then mount them under MROOT
if [ $TYPE = POWER ]; then
	exec 4</tmp/..corefs
	while read -u4 lvnum
	do
		dir=$(/usr/sbin/sblvminfo query -Tl -tm -f$VGINFO -n$lvnum)
		lv=$(/usr/sbin/sblvminfo query -Tl -tl -f$VGINFO -n$lvnum)
		print "Checking $dir filesystem .."
		fsck -y /dev/$lv >/dev/null 2>/tmp/..fscheck
		if [ $? -eq 8 ]; then
			cat /tmp/..fscheck
			syserror "Failure checking (fsck) $dir filesystem" 2
		fi
		[ $dir = /var ] && continue
		mount /dev/$lv ${MROOT}$dir || \
			syserror "Unable to mount ${MROOT}$dir filesystem" 2
	done
fi
rm -f /tmp/..corefs

# Copy RAM devices to disk
print "Copying files from RAM to hard disk..."

if [ ! -z "$NIM_INFO_FILE" ]; then
	cp  /tmp/niminfo $MROOT/etc/niminfo
fi

cd $MROOT/dev && find . ! -type d -exec \rm {} \;
cd /dev && ls | backbyname -irf$MROOT/tmp/ram.devs >/dev/null 2>&1
cd $MROOT/dev && restbyname -xqf$MROOT/tmp/ram.devs >/dev/null 2>&1 || \
	syserror "Could not copy devices from RAM disk to hard disk." 2
[ ! -z "$SCRIPT" ] && cp /$SCRIPT /mnt
rm -f $MROOT/tmp/ram.devs 2>/dev/null
rm -f $MROOT/dev/ram*

# Copy volume group maps from RAM to hard disk.
cd /etc && find ./vg -print | backbyname -irf$MROOT/tmp/ram.vg  >/dev/null 2>&1
cd $MROOT/etc && restbyname -xqf$MROOT/tmp/ram.vg >/dev/null 2>&1 || \
	syserror "Could not copy volume group data from RAM disk to hard disk." 2
rm -f $MROOT/tmp/ram.vg 2>/dev/null
cd /

# Replace restored database with RAM configured object database.
rm -rf $MROOT/tmp/sb_objrepos
mkdir $MROOT/tmp/sb_objrepos || \
	syserror "Error saving device configuration from previous system" 2
cp $MROOT/etc/objrepos/Cu* $MROOT/tmp/sb_objrepos || \
	syserror "Error saving device configuration from previous system" 2
cp /etc/objrepos/Cu* $MROOT/etc/objrepos || \
	syserror "Error copying device configuration to hard disk" 2

# Copy sysreconfig to /usr/sbin for first boot
cp /usr/lpp/sysback/inst/sysreconfig $MROOT/usr/sbin

# Copy sysback install programs still needed from install media to disk
# to ensure we continue running under the same version
mkdir $MROOT/usr/lpp/sysback $MROOT/usr/lpp/sysback/inst \
	$MROOT/usr/lpp/sysback/scripts 2>/dev/null
cp /usr/lpp/sysback/sysback.lib $MROOT/usr/lpp/sysback 2>/dev/null
cp /usr/lpp/sysback/inst/sysmakevg /usr/lpp/sysback/inst/sysinstall \
	/usr/lpp/sysback/inst/sysrestvg /usr/lpp/sysback/inst/sysnet \
	/usr/lpp/sysback/inst/sysinst.lib /usr/lpp/sysback/inst/install.device \
	/usr/lpp/sysback/inst/sysmain /usr/lpp/sysback/inst/sysrestvgdsmc \
	$MROOT/usr/lpp/sysback/inst 2>/dev/null
cp /usr/lib/libsysback.a $MROOT/usr/lib 2>/dev/null
cp /usr/sbin/ttymsg /usr/sbin/sbread /usr/sbin/sbread2 /usr/sbin/sbclient \
	/usr/sbin/sbfwd /usr/sbin/sbfwd2 /usr/sbin/sbdevice \
	/usr/sbin/sblvminfo /usr/sbin/sysnfs /usr/sbin/sbchfscheck $MROOT/usr/sbin

cp /tmp/sblang $MROOT/tmp

#
# If the RDA_PRESCRIPT exist in the ramfs area, then
# copy it to $MROOT filesystem
#
if [[ -n "$RDA_PRESCRIPT" ]]; then
	if [[ -x "$RDA_PRESCRIPT" ]]; then
		dir=$(dirname $RDA_PRESCRIPT)
		mkdir -p $MROOT/$dir 
		cp $RDA_PRESCRIPT $MROOT/$RDA_PRESCRIPT
	fi
fi

#Copy TSM programs if they exist
if [ -f /tmp/libApiDS.a ]; then
	cp /usr/lpp/sysback/sbtsm $MROOT/usr/lpp/sysback

	cp -r /tmp/libApiDS.a /tmp/en_US $TSM_CLIENT $DSM_SYS \
		$DSMI_CONFIG $MROOT/tmp
fi


# If a post-install program came from diskette, move it to root filesystem
cp /tmp/diskette/install.post* $MROOT/usr/lpp/sysback/scripts 2>/dev/null
chmod +x $MROOT/usr/lpp/sysback/scripts/install.post 2>/dev/null
rm -r /tmp/diskette 2>/dev/null


# If the POSTINST variable was set during network boot, get the
# post-install program from the boot server.
# Bootserver may not have this client enabled for remote access, so
# must use non-sysback transfer
if [ -n "$POSTINST" -a -n "$REMOTE" ]
then 
	rc=0
	mkdir /postinst.$$
	mount -r -vnfs -ointr,hard bootserver:$POSTINST /postinst.$$
	(( rc=$rc+$? ))
	cp postinst.$$ $MROOT/usr/lpp/sysback/scripts/install.post.svr
	(( rc=$rc+$? ))
	if [[  $rc != 0 ]]
		   then syserror "Cannot find specified post-install script ($POSTINST) on the server - ignored" 1
		   else chmod +x $MROOT/usr/lpp/sysback/scripts/install.post.svr && \
					POSTINST=/usr/lpp/sysback/scripts/install.post.svr
		fi
	umount /postinst.$$
	rmdir /postinst.$$
fi

# Copy any special console definition file to disk for disk boot support
if [ -f /etc/consdef ]
then
	cp /etc/consdef $MROOT/etc
fi

# If user changed the lv name or mount point, must reapply changes 
# to restored filesystems file
if [ -s "$FS_SEDFILE" ]
   then cp $MROOT/etc/filesystems /tmp/filesystems
		sed -f $FS_SEDFILE /tmp/filesystems > $MROOT/etc/filesystems
		rm /tmp/filesystems
fi

# Replace each stanza in the restored filesystems file with changed
# stanzas from the vginfo file.
# This is necessary to keep user comments and NFS stanzas, etc in the 
# original file and keep all filesystems in the same order
grep "^/.*:$" /etc/filesystems | cut -d: -f1 | uniq > /tmp/..buffer
/usr/sbin/sblvminfo convert -Tf -f$VGINFO -F/tmp/..buffer > /tmp/..buffer1
exec 4</tmp/..buffer1
while read -u4 lvnum
do
	# Get stanza for filesystem - remove blank line at end
	/usr/sbin/sblvminfo query -Ts -tf -f$VGINFO -F /etc/filesystems -n$lvnum > /tmp/fsstanza
	
	#Update stanza
	/usr/sbin/sblvminfo update -Ts -f$VGINFO -F $MROOT/etc/filesystems -s/tmp/fsstanza -n$lvnum > /tmp/filesystems.tmp
	cp /tmp/filesystems.tmp $MROOT/etc/filesystems
	rm /tmp/filesystems.tmp
done
rm /tmp/fsstanza /tmp/..buffer*

# Copy restored /etc/filesystems file to RAM
cp $MROOT/etc/filesystems /etc

# Copy RAM hosts file to real root
if [ ! -z "$REMOTE" ]
   then mv $MROOT/etc/hosts $MROOT/etc/hosts.bk 2>/dev/null
		cp /etc/hosts $MROOT/etc 2>/dev/null

		# Disable domain name services
		export NSORDER=local
fi

# Copy RAM temp files to temp filesystem
if [ ! -d $MROOT/tmp ]
   then mkdir $MROOT/tmp
fi
ls /tmp | while read file
do
	cp -r /tmp/$file $MROOT/tmp
done

# Save network install settings for next install
if [ -f $NETINFO ]
   then cp $NETINFO $MROOT/usr/lpp/sysback/inst/netinfo
fi

sync;sync

####
# Unmount / and /usr filesystems and remount over RAM
####
print "Changing to restored base operating system .."
if [[ "$INSTMODE" = "noprompt" ]]; then
	showled 0xA52 "Changing to restore base OS"
fi
cd /

# Clean out shared libraries in RAM
cp $MROOT/usr/sbin/slibclean /etc
/etc/slibclean

# Change LIBPATH now so that the umount command will find its shared libraries
# in /lib rather than under $MROOT/usr or /usr, which we are going to unmount
export LIBPATH=/usr/lib:/lib
if [ $BOOTTYPE = $NET ]
   then cp /usr/sbin/mount /etc/mount 2>/dev/null
		ln -f /etc/mount /etc/umount
   else ln /usr/sbin/mount /usr/sbin/umount 2>/dev/null
fi

# Umounting the CD device
case $FIRSTDEV in
	/dev/cd*)
		if [ ! -z "$REMOTE" ]; then
			OIFS="$IFS"
			IFS="="
			sbclient instserver "env" | grep "CLIENT_HOST=" | read x thostname
			IFS="$OIFS"
			sbclient instserver "sb_cdmnt -u 11 -h $thostname"
		else
			umount_cd $FIRSTDEV $CDMOUNTPT
		fi
     	;;
esac


#
# umount any of the /usr/tivoli filesystems
#
mount | grep -w /mnt/usr/tivoli/tsm/client/api >/dev/null && \
	unmountfs /mnt/usr/tivoli/tsm/client/api
mount | grep -w /mnt/usr/tivoli/tsm/client/ba >/dev/null && \
	unmountfs /mnt/usr/tivoli/tsm/client/ba
mount | grep -w /mnt/usr/tivoli/tsm/client >/dev/null && \
	unmountfs /mnt/usr/tivoli/tsm/client
mount | grep -w /mnt/usr/tivoli/tsm >/dev/null && \
	unmountfs /mnt/usr/tivoli/tsm
mount | grep -w /mnt/usr/tivoli >/dev/null && unmountfs /mnt/usr/tivoli

if [[ -f $DEBUGNFSMOUNTED ]]; then
	DEBUGMOUNT=$(cat $DEBUGNFSMOUNTED)
	rm -f $DEBUGNFSMOUNTED
	if [[ -f $NFSMOUNTDIRINFO ]]; then
		cat $NFSMOUNTDIRINFO | while read a b
		do
			if [[ "$a" = "DEBUG_DIR" ]]; then
				export DEBUG_DIR=$b
			fi
			if [[ "$a" = "NFS_DIR" ]]; then
				export NFS_DIR=$b
			fi
		done
		DEBUGOUT=${DEBUG_DIR}/${DEBUGFILE}
		export DEBUGOUT
	fi
fi
if [[ -n "$DEBUGMOUNT" ]] && [[ "$DEBUG_DIR" != "/usr" ]]; then
	TTY=$(/usr/bin/tty)
	exec 2>${TTY}
	sync
	NFSMountUnmount "u" "$SYSNFSOUT_1"  "$SYSNFSOUT_2"
fi

#
# Unmounts all filesystems in rootvg with the exception of hd4 /
#
UnMountFilesystems


# Link LIBPATH to RAM root to allow mounting over /.
ln -fs /../usr/lib $MROOT/usr/lib 2>/dev/null

# In case of a problem mounting /usr, copymount command to /
rm -f $MROOT/etc/mount $MROOT/etc/umount
cp /usr/sbin/mount $MROOT/etc/mount 2>/dev/null
ln $MROOT/etc/mount $MROOT/etc/umount 2>/dev/null

if [ $BOOTTYPE = $NET ]; then
	mkdir -p $MROOT/usr/lib1_sb
	cp /usr/ccs/lib/libc.a.min $MROOT/usr/lib1_sb/libc.a
fi

sync 2>/dev/null

export PATH=/etc:/usr/bin:/usr/sbin:/usr/lpp/sysback/inst:/usr/lib/methods:/../etc:/../usr/bin:/../usr/sbin:/../etc/methods:/../usr/lib/methods:/../usr/lpp/sysback/inst:/usr/tivoli/tsm/client/ba/bin:/usr/tivoli/tsm/client/api/bin

if [ $BOOTTYPE = $NET ]; then
	export LIBPATH=/usr/lib1_sb:/usr/lib:/../usr/lib
else
	export LIBPATH=/usr/lib:/../usr/lib
fi

# Unmount real root
unmountfs $MROOT 


# Finally, re-mount / and /usr and /tmp over RAM root
# These are the only filesystems required for bootlv processing
mount -f -t bootfs || syserror "Unable to re-mount / or /usr filesystems" 2
mkdir /tmp 2>/dev/null
mount /tmp 2>/dev/null # If it fails, we may not have one
chmod 1777 /tmp 

# Make sure /var is also mounted. This should also have a type of bootfs
# but some users change the filesystem info
if [ $TYPE != POWER ]
   then mkdir /var 2>/dev/null
		mount /var 2>/dev/null && chfs -t bootfs /var
		mkdir /var/tmp 2>/dev/null
fi

if [ $BOOTTYPE = $NET ]; then
	mount /dev/hd4 /mnt 2>/dev/null
	rm -rf /mnt/usr/lib1_sb 2>/dev/null
	sync;sync;sync;
	umount /mnt 2>/dev/null
fi


if [[ -n "$DEBUGMOUNT" ]]; then
	if [[ -f $NFSMOUNTDIRINFO ]]; then
		cat $NFSMOUNTDIRINFO | while read a b
		do
			if [[ "$a" = "DEBUG_DIR" ]]; then
				export DEBUG_DIR=$b
			fi
			if [[ "$a" = "NFS_DIR" ]]; then
				export NFS_DIR=$b
			fi
		done
	fi

	export DEBUG_DIR="/mnt${NFS_DIR}"

	print "DEBUG_DIR $DEBUG_DIR" > $NFSMOUNTDIRINFO
	print "NFS_DIR $NFS_DIR" >> $NFSMOUNTDIRINFO

	/usr/sbin/sysnfs -f $DEBUGNFSINFO -F /tmp/netinfo -b $BOOTDEV
	rc=$?
	if [[ -n "$SBDEBUG" ]] && [[ $rc -eq 0 ]]; then
		DEBUGOUT="${DEBUG_DIR}/${DEBUGFILE}"
		export DEBUGOUT
		touch $DEBUGOUT 2>/dev/null
		if [[ $? -eq 0 ]]; then
			exec 2>>$DEBUGOUT
			export XSET="set -x"
			$XSET
			sync;sync;sync
		else
			unset XSET
			set +x
			sync;sync;sync
		fi
	fi
fi


# Mounting up the CD device 
case $FIRSTDEV in
	/dev/cd*)
		if [ ! -z "$REMOTE" ]; then
			export CDMOUNTPT_1=/.sbcd_11
			export SB_DATA_1=$CDMOUNTPT_1/usr/sys/sysback_images
			OIFS="$IFS"
			IFS="="
			sbclient instserver "env" | grep "CLIENT_HOST=" | read x thostname
			IFS="$OIFS"
			vfs=$(sbclient instserver "sb_cdmnt -td $FIRSTDEV")
			if [[ -z "$vfs" ]]; then
				vfs="cdrfs"
			fi
			sbclient instserver "sb_cdmnt -v$vfs -m 11 -d $FIRSTDEV -h $thostname"
		else
			export CDMOUNTPT=/mnt
			export SB_DATA=$CDMOUNTPT/usr/sys/sysback_images
			mount_cd $FIRSTDEV $CDMOUNTPT
		fi
	;;
esac


if [[ "$INSTMODE" = noprompt ]]; then 
	showled 0xA46 "post rootvg install processing"
fi

######
# Post-rootvg install processing
######
if [[ -n "$SBDEBUG" ]];then

	if [[ -f $NFSMOUNTDIRINFO ]]; then
		cat $NFSMOUNTDIRINFO | while read a b
		do
			if [[ "$a" = "DEBUG_DIR" ]]; then
				export DEBUG_DIR=$b
			fi
			if [[ "$a" = "NFS_DIR" ]]; then
				export NFS_DIR=$b
			fi
		done
		DEBUGOUT=${DEBUG_DIR}/${DEBUGFILE}
		export DEBUGOUT
	fi

	touch $DEBUGOUT 2>/dev/null
	if [[ $? -eq 0 ]]; then
		exec 2>>$DEBUGOUT
		set -x
	else
		set +x
	fi
else
	set +x
fi

unset MROOT

sync;sync

# Delete installation configurations from ODM databases.
/usr/bin/odmdelete -quniquetype=runtime -o PdAt >/dev/null 2>&1
/usr/bin/odmdelete -qattribute=block_size -o CuAt >/dev/null 2>&1


# If this was a network boot from a NIM SPOT resource, the NIM lpp_source
# resource was specified also at boot image creation. For this type of network
# boot, we automatically want to mount the lpp_source to retrieve any needed
# device support / filesets required that are not in the NIM spot. If the
# NIMLPPSOURCE variable is not set, then this is a "classic" boot and
# processing simply continues as usual.

if [[  -n "$NIMLPPSOURCE" ]]
then 
	nimlppsource=/tmp/nimlppsource.$$
	POSTINSTDEVICE=$nimlppsource
	if [[ ! -d $nimlppsource ]]
	then
		mkdir $nimlppsource || print "\nUnable to create directory for $NIMLPPSOURCE."
	fi
	mount -r $SPOTSRV:$NIMLPPSOURCE $nimlppsource 
	if [[ $? != 0 ]]
	then
		print "\nUnable to mount $NIMLPPSOURCE"
		unset nimlppsource
	fi

fi

#
# Run the post install device support if it is set
#
if [ ! -z "$POSTINSTDEVICE" ]
	then
	#Creating directories and files for the installp to run happy
	mkdir -p /var/adm/sw >/dev/null 
	mkdir -p /var/adm/ras >/dev/null 
	mkdir -p /var/spool/cron/crontabs >/dev/null
	> /var/spool/cron/crontabs/root 
	if [ -z "$REMOTE" ]; then
		case $FIRSTDEV in
			/dev/cd*)
				read_cd_volume
				OLDCDNUM="$CDNUM"
				OLDCDVOLID="$CDVOLID"
				umount_cd $FIRSTDEV $CDMOUNTPT
				if [ "$FIRSTDEV" = "$POSTINSTDEVICE" ]
					then
					if [ "$CDNUM" -ne 1 ] 
						then
						sbcdeject.sh -ts -v1 -f $FIRSTDEV
					fi
				fi
			;;
		esac
	fi
		/usr/lpp/sysback/inst/install.device $POSTINSTDEVICE
		rc=$?
		if test $rc -ne 0
			then syserror "Errors in Installing Device Support" 1
			print -n "Press Enter to continue ==> "
			read a
		fi

	if [ -z "$REMOTE" ]; then
		case $FIRSTDEV in
			/dev/cd*)
				mount_cd $FIRSTDEV $CDMOUNTPT
				if [ "$FIRSTDEV" = "$POSTINSTDEVICE" ]
					then
					read_cd_volume 2>/dev/null
					if [ $? -ne 0 ]
						then
						umount_cd $FIRSTDEV $CDMOUNTPT
						sbcdeject.sh -f $FIRSTDEV -tr -v $OLDCDNUM -i $OLDCDVOLID -m $CDMOUNTPT
					fi
					if [ $CDNUM -ne $OLDCDNUM -o $CDVOLID -ne $OLDCDVOLID ]
						then
						umount_cd $FIRSTDEV $CDMOUNTPT
						sbcdeject.sh -f $FIRSTDEV -tr -v $OLDCDNUM -i $OLDCDVOLID -m $CDMOUNTPT
					fi
				fi
   	         ;;
		esac
	fi
fi

sync;sync

# If user created a post-rootvg script, execute now
if [ -x /usr/lpp/sysback/scripts/install.postroot ]
   then print "\07"
		#Creating directories and files for the installp to run 
		#happy
		mkdir -p /var/adm/sw >/dev/null 
		mkdir -p /var/adm/ras >/dev/null
		mkdir -p /var/spool/cron/crontabs >/dev/null 
		> /var/spool/cron/crontabs/root

		/usr/lpp/sysback/scripts/install.postroot
		rc=$?
		if test $rc -ne 0
		   then syserror "Custom post-rootvg script failed!" 1
				print -n "Press Enter to continue ==> "
				read a
		fi
fi

# Run the Script from the device install diskette
[[ -n "$SCRIPT" ]]  && ksh /$SCRIPT

# If no dump logical volume exists, use first paging space for dump device
grep "^LV .* rootvg .* sysdump " $VGINFO >/dev/null
if [ $? -ne 0 ]; then
	# Get paging device
	/usr/sbin/sblvminfo check -Tl -tv -f $VGINFO -u rootvg | while read lvnum
	do
		set_lv $lvnum
		if [ "$type" != "paging" ]; then
			continue
		fi
		# Use paging space as dump dev
		print "Setting paging space $lvname as primary dump device.\n"
		sysdumpdev -Pp /dev/$lvname >/dev/null
	done

else # There are sysdump devices
	unset FIRSTDUMP
	/usr/sbin/sblvminfo check -Tl -tv -f$VGINFO -u rootvg | while read lvnum
	do
		set_lv $lvnum ""
		if [ "$type" != "sysdump" ]; then
			continue
		fi
		if [[ -z "$FIRSTDUMP" ]];then
			print "Setting logical volume $lvname as primary dump device.\n"
			sysdumpdev -Pp /dev/$lvname
			FIRSTDUMP=1
		else
			print "Setting logical volume $lvname as secondary dump device.\n"
			sysdumpdev -Ps /dev/$lvname
		fi
	done

fi

# Extract device configuration and attribute information from the old database
# to be merged on first boot after installation.
print "Retrieving previous device configuration .."
ODMDIR=/etc/objrepos
export ODMDIR

case "$RECOVERY_DEVICES" in
	y|Y|yes|Yes|YES) 
		RECOVERY_DEVICES="YES"
		export RECOVERY_DEVICES
	;;
	n|N|no|No|NO)
		RECOVERY_DEVICES="NO"
		export RECOVERY_DEVICES
	;;
	*)
		RECOVERY_DEVICES="CLASSIC"
		export RECOVERY_DEVICES
	;;
esac
			

if [[ "$RECOVERY_DEVICES" = "CLASSIC" ]]; then
	/usr/lpp/bosinst/rda -e -p /tmp/sb_objrepos -d /tmp/sb_objrepos/CuDv.sav \
		-a /tmp/sb_objrepos/CuAt.sav >/dev/null 2>&1
else
	/usr/lpp/bosinst/rda -e -p /tmp/sb_objrepos -d /tmp/sb_objrepos/CuDv.sav \
		-a /tmp/sb_objrepos/CuAt.sav >/dev/null -c sys0 2>&1
fi

sync;sync

# Set keyboard map
set -- $(grep 'swkb_path = ' /tmp/sb_objrepos/CuAt.sav)
[ ! -z "$3" ] && chkbd $3


# Clear temp install files in /tmp created by mkvgback command
cd /tmp
rm -f *mkvgback *backupfiles *excludedirs *mkvgback *lvlist
rm -f *sberror *toc *[1-9]vginfo
cd /

# Link to appropriate kernel for the machine being installed
kernel=$(bootinfo -z 2>/dev/null)
case "$kernel" in
	""|0)   kernel=up;;
	1)      kernel=mp;;
esac
[ $PLATFORM = rs6ksmp ] && kernel=mp    # smp machine requires mp kernel
if [ -f /usr/lib/boot/unix_$kernel ]
   then # link to speficied kernel - otherwise use restored unix
		ln -fs /usr/lib/boot/unix_$kernel /usr/lib/boot/unix 
		ln -fs /usr/lib/boot/unix_$kernel /unix
fi

read_kern64

if [[ "`bootinfo -y 2>/dev/null`" = "32" ]]; then
	CHRP64="n"
fi

#
# link kernal to unix_mp if we are using a 32 bit kernal
#
if [[ "$CHRP64" = "n" ]] || [[ "$CHRP64" = "N" ]]; then
	if [ -s /usr/lib/boot/unix_mp ]; then
		ln -fs /usr/lib/boot/unix_mp /unix >/dev/null 2>&1
		ln -fs /usr/lib/boot/unix_mp /usr/lib/boot/unix >/dev/null 2>&1
	else
		ln -fs /usr/lib/boot/unix_up /unix >/dev/null 2>&1
		ln -fs /usr/lib/boot/unix_up /usr/lib/boot/unix >/dev/null 2>&1
	fi
fi

# If chrp 64 bit and CHRP64 is yes, relink kernel
if [[  "$CHRP64" = "y" ]] || [[ "$CHRP64" = "Y" ]]; then
	if [ -s /usr/lib/boot/unix_64 ]; then
		ln -fs /usr/lib/boot/unix_64 /unix >/dev/null 2>&1
		ln -fs /usr/lib/boot/unix_64 /usr/lib/boot/unix >/dev/null 2>&1
	else
		ln -fs /usr/lib/boot/unix_mp /unix >/dev/null 2>&1
		ln -fs /usr/lib/boot/unix_mp /usr/lib/boot/unix >/dev/null 2>&1
	fi
fi

if [[ -z "$CHRP64" ]] && [[ "`bootinfo -y 2>/dev/null`" = "64" ]];then
	if [ -s /usr/lib/boot/unix_64 ]; then
		ln -fs /usr/lib/boot/unix_64 /unix >/dev/null 2>&1
		ln -fs /usr/lib/boot/unix_64 /usr/lib/boot/unix >/dev/null 2>&1
	else
		ln -fs /usr/lib/boot/unix_mp /unix >/dev/null 2>&1
		ln -fs /usr/lib/boot/unix_mp /usr/lib/boot/unix >/dev/null 2>&1
	fi
fi

sync;sync

# Initialize boot logical volume(s) for subsequent IPL's.
rebuild_bootlvs
rc=$?

#For some reason, standard error is lost at this point.
#Reinitialize standard error.      

if [[ -n "$SBDEBUG" ]]; then
	if [[ -f $NFSMOUNTDIRINFO ]]; then
		cat $NFSMOUNTDIRINFO | while read a b
		do
			if [[ "$a" = "DEBUG_DIR" ]]; then
				export DEBUG_DIR=$b
			fi
			if [[ "$a" = "NFS_DIR" ]]; then
				export NFS_DIR=$b
			fi
		done
		DEBUGOUT=${DEBUG_DIR}/${DEBUGFILE}
		export DEBUGOUT
	fi
	touch $DEBUGOUT 2>/dev/null
	if [[ $? -eq 0 ]]; then
		exec 2>>$DEBUGOUT
		set -x
	else
		TTY=$(/usr/bin/tty)
		exec 2>${TTY}
	fi
else
	TTY=$(/usr/bin/tty)
	exec 2>${TTY}
fi

sync;sync

# If we didnt find a boot lv, then create a default one now
if [ $rc != 0 ]
   then print "Attempting to create a default boot logical volume ..."

		# Get the name of the first disk in the rootvg
		getlvminfo -V rootvg -pN1 | read rvgdisk x

		# Make the boot LV
		lvname=$(mklv -t boot -a e rootvg 1 $rvgdisk || \
			syserror "mklv command failed in creating boot logical volume" 2)

		# Update the boot logical volume
		bosboot -a -d /dev/$rvgdisk -l /dev/$lvname || syserror \
			"bosboot command failed in initializing boot logical volume" 2

		# Set bootlist to our new boot lv's disk
		bootlist -m normal $rvgdisk
fi

# Remove floppy drive type attribute from reconfig
cp /tmp/sb_objrepos/CuAt.sav /tmp/CuAt.sav
grep -v "fdtype" /tmp/CuAt.sav > /tmp/sb_objrepos/CuAt.sav
rm -f /tmp/CuAt.sav

if [[ "$RECOVERY_DEVICES" = "YES" ]]; then
	odm_backup
fi

# Clear Vital Product Database
odmdelete -o CuVPD >/dev/null

sync;sync

if [[ -n "$REMOTE" ]];then
	# Add port info to restored services file
	grep "^sbnet" /etc/services >/dev/null 2>&1
	if  [[ $? -ne 0 ]]; then
		print "sbnet\t\t1239/tcp\t\t\t# Sysback Remote Backup/Install" \
			>> /etc/services
	fi
fi

#
#  Adding the /proc: filesystem in the /etc/filesystems file
#  if it is missing
#
if [ $VERSION -ge 5 ]; then
    [ ! -d "/proc" ] && mkdir /proc > /dev/null 2>&1
    grep "^/proc:" /etc/filesystems >/dev/null 2>&1
    if [ $? -ne 0 ]; then
        print "\n/proc:" >> /etc/filesystems
        print "\tdev\t\t= /proc"  >> /etc/filesystems
        print "\tvol\t\t= /proc" >> /etc/filesystems
        print "\tmount\t\t= true" >> /etc/filesystems
        print "\tcheck\t\t= false" >> /etc/filesystems
        print "\tfree\t\t= false" >> /etc/filesystems
        print "\tvfs\t\t= procfs" >> /etc/filesystems
        sync;sync
    fi
fi


#####
# Create or import other volume groups
#####
/usr/sbin/sblvminfo query -Tv -a -f$VGINFO >/tmp/..buffer
exec 4</tmp/..buffer
while read -u4 vgnum
do
	set_vg $vgnum ""
	[ $vgname = rootvg ] && continue

	# If recovery install, force import of all other VGs
	[ ! -z "$RECOVERY" ] && vgopt=I

	case $vgopt in
		C)      # Create
			sysmakevg $vgname
			;;
		I)      # Import
			pvname=$(print $PVlist | cut -f1 -d' ')
			if [ "$pvname" = "" ]
			   then syserror "There are no physical volumes selected - Volume group $vgname not imported" 1
					continue
			fi
			ttymsg -l60 -i8 -c -s "Importing \"$vgname\" Volume Group"

			#import and varyon volume group or just import 
			if [ "$autoon" = y ]
			then
				importvg -y $vgname $pvname >/dev/null || {
				syserror "Unable to import Volume Group $vgname using $pvname" 1
				continue
			}
			else
				importvg -ny $vgname $pvname > /dev/null || {
				syserror "Unable to import Volume Group $vgname using $pvname" 1
				continue
			}
			fi

			# Set auto-varyon option
			if [ $autoon = y ] 
				then
				chvg -a y $vgname >/dev/null
			else
				chvg -a n $vgname >/dev/null
			fi

			# Set quorum option
			[ $quorum = n ] && chvg -Qn $vgname >/dev/null
			print "Imported successfully."

			#
			# We need to mount the /usr/tivoli filesystem if the
			# install device is a TSM or TSMBA install and the
			# /usr/tivoli filesystem exist in a importvg volume group
			#
			getlvminfo -V $vgname -l | while read lv
			do
			    mountpt=$(getMountpt $lv)
				if [[ -n "$mountpt" ]]; then
					CheckTivoliFS_2 "$mountpt" "$vgname"
					retcode=$?
					if [[ $retcode -ne 0 ]]; then
						make_dirs $mountpt
						mount /dev/$lv $mountpt
					fi
				fi
			done
			;;
	esac
done

sync;sync

# Turn off quorum checking for all VGs if specified
/usr/sbin/sblvminfo query -Tv -a -f$VGINFO >/tmp/..buffer
if [[ -n "$RECOVERY" ]]; then
	print "1" > /tmp/..buffer  #rootvg only
fi
exec 4</tmp/..buffer
while read -u4 vgnum
do
	set_vg $vgnum ""
	if [ $vgopt != D -a $quorum = n ]
	   then print "Turning off quorum checking for volume group $vgname .."
			chvg -Qn $vgname || syserror "Unable to turn quorum checking off for volume group $vgname." 1
	fi
	if [ $vgopt != D -a $VERSION -ge 5 ]; then
			grep "^VG51 $vgname " $VGINFO | read $VG51FIELDS
			case "$vghotspare" in
				0) hotspare="n";;
				1) hotspare="y";;
				2) hotspare="Y";;
				*) hotspare="n";;
			esac
			chvg -s $autosync -h $hotspare $vgname || syserror "Unable to set autosync and hotspare for volume group $vgname." 1
	fi
done

unset AIX_NO_SAVEBASE
savebase

# Reset logical volume permissions
print "Resetting logical volume permissions .."
/usr/sbin/sblvminfo query -Tl -a -f$VGINFO > /tmp/..buffer
exec 4</tmp/..buffer
while read -u4 lvnum
do
	lvname=$(/usr/sbin/sblvminfo query -Tl -tl -n$lvnum -f$VGINFO)
	set_lvperm $lvnum ""
	if [ -b /dev/$lvname ]; then
		set_lvperm $lvnum ""
		[ -z "$user" ] && continue
		chown $user.$group /dev/$lvname /dev/r$lvname
		chmod 0000 /dev/$lvname /dev/r$lvname
		for perm in u+$uperm g+$gperm o+$operm
		do
			sperm=
			[[ "$perm" = *[sS]* ]] && sperm="$(print - $perm | cut -c1-2)s"

			perm="$(print - $perm  | sed 's/[st]/x/g' | sed 's/[ST-]//g')"
			[ ! -z "$(print $perm | cut -c3)" ] && \
				chmod $perm /dev/$lvname /dev/r$lvname
			[ ! -z "$sperm" ] && \
				chmod $sperm /dev/$lvname /dev/r$lvname
		done
		[[ "$operm" = *[tT]* ]] && chmod +t /dev/$lvname /dev/r$lvname
	fi
done

if [[ -z "$RECOVERY" ]]; then
	# Create a list of all lvs & filesystems which have been created. Also
	# must know if the data for the VG is on the backup so we know what
	# to restore later
	[ $TYPE != POWER ] && print "Mounting filesystems .."

	/usr/sbin/sblvminfo query -Tl -a -f$VGINFO > /tmp/..buffer
	exec 4</tmp/..buffer
	while read -u4 lvnum
	do
		set_lv $lvnum ""
		# Make sure the LV was created
		[ ! -b /dev/$lvname ] && continue

		# Make sure the VG was created (not imported)
		set_vg 0 "$VGNAME"
		[ $vgopt != C ] && continue

		# See if LV data is on the backup
		data=y
		if [[ "$DEVTYPE" != "TSMBA" ]]; then
			/usr/sbin/sblvminfo check -Tt -tl -F$TOCFILE -f$VGINFO -n$lvnum
			if [ $? -ne 0 ]; then
				data=n
			fi
		fi
		print "$lvnum $data"
	done | sort -n > /tmp/..lvlist
	rm -f /tmp/..buffer*

	# Mount filesystems in alpha order to prevent parent filesystems from being 
	# mounted over child filesystems (i.e. mount /data over /data/files)
	if [ $TYPE != POWER ]; then
		unset FOUNDTIVOLIFS
		exec 4</tmp/..lvlist 
		while read -u4 lvnum data
		do
			mountpt=$(/usr/sbin/sblvminfo query -Tl -tm -f$VGINFO -n$lvnum)
			lvname=$(/usr/sbin/sblvminfo query -Tl -tl -f$VGINFO -n$lvnum)
			vgname=$(/usr/sbin/sblvminfo query -Tl -tv -f$VGINFO -n$lvnum)
			case $mountpt in
				"-"|/|/usr|/tmp|/var) 
					# Already mounted or not a FS
					set_fspermissions $lvnum 2 ""
					continue;;
				/usr/lpp/sysback)
					# Must copy needed install programs to this dir
					# before mounting over /usr/lpp/sysback
					MROOT=/mnt
					mkdir $MROOT 2>/dev/null
					mount /dev/$lvname $MROOT
					mkdir $MROOT/inst 2>/dev/null
					cp /usr/lpp/sysback/inst/sys* $MROOT/inst
					sync
					umount $MROOT
					unset MROOT
					;;
			esac
			[ "$data" = n ] && continue # dont mount if not restoring

			make_dirs $mountpt 2>/dev/null
			CheckTivoliFS_2 "$mountpt" "$vgname"
			retcode=$?
			if [[ $retcode -ne 0 ]]; then
				make_dirs /mnt${mountpt} 2>/dev/null
				mount /dev/$lvname /mnt${mountpt} || \
					syserror "Unable to re-mount $mountpt filesystem" 2
					FOUNDTIVOLIFS=1
			else
				mount /dev/$lvname $mountpt || \
					syserror "Unable to re-mount $mountpt filesystem" 2
				set_fspermissions $lvnum 2 ""
                                
                                #Checking if EFS is enabled for this Filesystem
                                checkefs=$(/usr/sbin/sblvminfo query -TC -tE -f $VGINFO -d$lvname)
                                if [ "$checkefs" = "yes" ]; then
                                unset EFSADDED
                                fi
			fi

		done

		#
		# If we have a /usr/tivoli... type filesystem for a TSM restore
		# then nfs mount the TIVOLI FS's from the SPOTSRV
		#
		if [[ -n "$FOUNDTIVOLIFS" ]]; then
			NFSMountTivoliFS
		fi
	fi

	sync;sync


	# Now create a list of the logical volumes that will be restored
	LVLIST=
	>$lvfile
	exec 4</tmp/..lvlist
	while read -u4 lvnum data
	do
		mountpt=$(/usr/sbin/sblvminfo query -Tl -tm -f$VGINFO -n$lvnum)
		[ $mountpt = / -o $mountpt = /usr ] && continue # already restored
		[ $TYPE = POWER -a $mountpt = /tmp ] && continue # not on power install
		[ $data = n ] && continue # data not on the backup
		echo "$lvnum" >> $lvfile
	done

	sync;sync

	# Finally, restore the rest or rootvg and all other VG data
	if [ $TYPE = POWER ]
	   then ttymsg -l60 -i8 -c -s "Restoring Logical Volume Data"
			# Unmount /var since we'll be copying over the raw LV
			mount | grep -w /var >/dev/null && unmountfs /var
	   else ttymsg -l60 -i8 -c -s "Restoring Filesystem and Logical Volume Data"
	fi


	if [[ "$DEVTYPE" = "TSMBA" ]]; then
		if [[ ! -f $DSMC_FILESPACE_FILE ]]; then
			SetTSMBAInfo "1"
			sbdsmc -al -o $DSMC_FILESPACE_FILE $SBDSMC_OPTIONS
		fi

		/usr/sbin/sblvminfo query -Tv -a -f$VGINFO >/tmp/..buffer
		exec 4</tmp/..buffer
		while read -u4 vgnum
		do
			set_vg $vgnum ""
			if [[ "$vgname" = "rootvg" ]] || [[ "$vgopt" != "C" ]]; then
				continue
			fi

			sysrestvgdsmc "2" "$DSMC_FILESPACE_FILE" "$VGINFO_ORG" "$VGINFO" "$vgname"
		done
	else
		sysrestvg 2 $lvfile
	fi

	sync;sync

	# If POWER install, fsck and mount all filesystems
	if [ $TYPE = POWER ]
	   then exec 4</tmp/..lvlist
			while read -u4 lvnum data
			do
				mountpt=$(/usr/sbin/sblvminfo query -Tl -tm -f$VGINFO -n$lvnum)
				lvname=$(/usr/sbin/sblvminfo query -Tl -tl -f$VGINFO -n$lvnum)
				case $mountpt in
				"-"|/|/usr|/tmp) continue;; # already mounted
				esac
				if [ "$data" != n ]
				   then # Check only the filesystems we just restored
						print "Checking $mountpt filesystem .."
						fsck -y /dev/$lvname >/dev/null 2>/tmp/..fscheck
						if test $? -eq 8
						   then cat /tmp/..fscheck
								syserror "Failure checking (fsck) $mountpt filesystem" 2
						fi
				fi
				make_dirs $mountpt 2>/dev/null
				mount /dev/$lvname $mountpt || \
					syserror "Unable to mount $mountpt filesystem" 2
				set_fspermissions $lvnum 2 ""
			done
	fi

	# Create directories for non-jfs filesystems
	lsfs | sed "s/  */ /g" | while read x x dir type x
	do
		case $type in
			nfs) mkdir $dir 2>/dev/null;;
		esac
	done

	# Remove filesystem stanzas user chose not to recreate
	/usr/sbin/sblvminfo query -Tl -a -f$VGINFO | while read lvnum
	do
		mountpt=$(/usr/sbin/sblvminfo query -Tl -tm -f$VGINFO -n$lvnum)
		lvname=$(/usr/sbin/sblvminfo query -Tl -tl -f$VGINFO -n$lvnum)
		[ $mountpt = "-" ] && continue
		[ -b /dev/$lvname ] && continue
		rmfs /dev/$lvname >/dev/null 2>&1
		print Filesystem $mountpt no longer referenced.
	done
fi 

sync;sync

# If paging space not created, remove from swapspaces file
/usr/sbin/sblvminfo query -Tl -a -f$VGINFO > /tmp/..buffer4
exec 4</tmp/..buffer4
while read -u4 lvnum
do
	type=$(/usr/sbin/sblvminfo query -Tl -tt -f$VGINFO -n$lvnum)
	lvname=$(/usr/sbin/sblvminfo query -Tl -tl -f$VGINFO -n$lvnum)
	[ $type != paging ] && continue
	[ -b /dev/$lvname ] && continue
	mv /etc/swapspaces /etc/swapspaces.sv
	egrep -p -v "^$lvname:|/$lvname$" /etc/swapspaces.sv > /etc/swapspaces
	print Paging space $lvname no longer active.
done

#
# Set fsquota values
#
/usr/sbin/sblvminfo query -Tl -a -f$VGINFO > /tmp/..lvlist
if [ $TYPE != POWER ]; then
	rm -f $SETCHFS
	touch $SETCHFS 2>/dev/null
cat > $SETCHFS <<END
/usr/sbin/ttymsg -l60 -i8 -c -s "Setting Filesystem(s) Quotas"
if [[ -n "$SBDEBUG" ]]; then
	exec 2>>$CHFSOUT
	export XSET="set -x"
fi
$XSET
END

	exec 4</tmp/..lvlist 
	while read -u4 lvnum data
	do
		set_fs2 $lvnum ""	
		mountpt=$(/usr/sbin/sblvminfo query -Tl -tm -f$VGINFO -n$lvnum)
		lvname=$(/usr/sbin/sblvminfo query -Tl -tl -f$VGINFO -n$lvnum)
		if [[ "$mountpt" = "-" ]]; then
			continue
		fi
		if [[ "$data" = "n" ]]; then
			 continue
		fi
		if [[ "$jfs2" != "y" ]]; then
			continue
		fi
		set_fs2ext $lvnum ""
		set_fsquota "$mountpt" "$quota"
	done
		chmod +x $SETCHFS
fi


if [ ! -z "$REMOTE" ]
   then # If install device is remote tape, change block size back to original
		grep "^/dev/rmt" $NETINSTDEVS | read devname x
		[ ! -z "$devname" ] && sysnet -b $devname
		grep "^vdev" $NETINSTDEVS | read devname x
		[ ! -z "$devname" ] && sysnet -b $devname

		# Resume default host name resolution and enable restored hosts file
		rm -f /etc/hosts
		mv /etc/hosts.bk /etc/hosts 2>/dev/null
# dont see any reason to not leave NSORDER set still dont
# want to use standard name services
#		unset NSORDER
fi
# configure boot network interface
rm -f /tmp/mktcpip
if [[ -n $CONFIGIF ]]
then
	unset gopt
	if [[ $BOOT_GATE_IP != undefined && -n $BOOT_GATE_IP ]]
	then 
		gopt="-g $BOOT_GATE_IP"
	fi
	unset mopt
	if [[ $SUBMASK != undefined && -n $SUBMASK ]]
	then 
		mopt="-m $SUBMASK"
	fi
	/usr/sbin/mktcpip -h $HOSTNAME -i $LNETDEV -a $CLIENT_IPADDR  $mopt  $gopt
	# save this command for reinvocation in sysreconfig
	print /usr/sbin/mktcpip -h $HOSTNAME -i $LNETDEV -a $CLIENT_IPADDR  $mopt  $gopt > /tmp/mktcpip
fi


if [[ -n $OVDESTINFO ]]
then
DESTINFO=/etc/SDR_dest_info 
	# handle special cloning case where backup made on different 
	# SP complex and /etc/SDR_dest_info is not correct for this
	# complex. Copy the correct one from the CWS
	mv  $DESTINFO $DESTINFO.old
	# our tiny hosts file is gone, so back to the original variable
	tftp -g $DESTINFO  $BOOT_SERV_IP $DESTINFO image || print "Unable to copy $DESTINFO from SP control workstation"
	chmod 644 $DESTINFO >/dev/null 2>&1
	# if DESTINFO is wrong,then hosts probably doesnt have the bootserver
	if ! grep -q $BOOT_SERV_IP /etc/hosts 
	then
		[[ -n $NIM_MASTER_HOSTNAME ]] && print $BOOT_SERV_IP $NIM_MASTER_HOSTNAME >>/etc/hosts
	fi
fi

# fix niminfo file if this is a nim assisted boot
if [[ -n $NIMNAME && -f /etc/niminfo ]]
then
awkprog1='{
	if ( match($0 , "NIM_HOSTNAME" ) )
	{
		printf "export NIM_HOSTNAME=%s\n",  NIM_HOSTNAME 
	}
	else if ( match($0, "NIM_NAME") )
	{
		printf "export NIM_NAME=%s\n",  NIM_NAME 
	}
	else if ( match($0, "NIM_MASTER_HOSTNAME") )
	{
		printf "export NIM_MASTER_HOSTNAME=%s\n",  NIM_MASTER_HOSTNAME 
	}
	else 
		print $0
}'
	awk -v NIM_HOSTNAME=$HOSTNAME -v NIM_NAME=$NIMNAME -v NIM_MASTER_HOSTNAME=$NIM_MASTER_HOSTNAME "$awkprog1" /etc/niminfo >/tmp/niminfo.$$ || print Unable to modify /etc/niminfo file
	 [[ -s /tmp/niminfo.$$ ]] &&  mv /tmp/niminfo.$$ /etc/niminfo && chmod 644 /etc/niminfo
	
fi


# POSTINST must be run with real /etc/hosts file
# ssp-psspscript assumes it can call nimclient which tries to contact
# host in /etc/niminfo
# If user created a post-install script, execute now.
# If the POSTINST variable is set during network boot, execute the
# script copied over from the server. Otherwise, use local install.post 
# by default it it exists.
[ -z "$POSTINST" ] && POSTINST=/usr/lpp/sysback/scripts/install.post
if [ -x $POSTINST ]
   then print "Running Post-Install script"
		$POSTINST
		rc=$?
		if test $rc -ne 0
		   then syserror "Custom post-install script failed!" 1
		fi
fi

SB_PASS="" 
# Remove sysback if no license on cloned machine
oldlic="$(grep ^SERIAL $VGINFO | cut -d' ' -f2)"
newlic="$(uname -m)"
if [ ! -f /tmp/nolicprompt -a "$oldlic" != "$newlic" ]
   then 
	SB_PASS=1
else
	SB_PASS=""
fi

if [ ! -z "$SB_PASS" -o ! -z "$REMSB" ]
	then
		while true
		do
			if [ ! -z "$REMSB" ]
			   then # User pre-defined whether ot not to remove Sysback
					case "$REMSB" in
						y|Y) REMSB=y;;
						n|N) REMSB=n;;
						*) REMSB=n;;
					esac

					if [ $REMSB = y -o $REMSB = n ]
					   then ans=$REMSB
					   else REMSB=
							continue
					fi
			   else # Prompt user
					print "\n\n"
					ttymsg -l60 -i8 -v'|' -h'-' -bs "THIS SYSTEM WAS INSTALLED FROM A BACKUP ORIGINATING FROM ANOTHER MACHINE

If you do not have a license of System Backup & Recovery or TSM for System Backup and Recovery (used to install this system) for this machine, you should select to remove SysBack and TSM for System Backup and Recovery at this time."
					print -n "\nShould Sysback and/or TSM for System Backup and Recovery be removed from this system? (yes/no) ==> "
					read ans
			fi
			case $ans in
				yes|y) # Copy programs we'll need later
					print "Removing Sysback from this system .."
					mv /usr/sbin/ttymsg /usr/sbin/ttymsg.sav
					if [ -f /usr/lpp/sysback/sysback.rte.al.save -a \
							-f /usr/lpp/sysback/rmsysback ]
					   then # Remove sysback
							/usr/lpp/sysback/rmsysback
					fi
					installp -gu tivoli.tsm.client.sysback.rte
					mv /usr/sbin/ttymsg.sav /usr/sbin/ttymsg
					break;;
				no|n)
					break;;
			esac
		done
fi

if [ ! -z "$SB_PASS" -o ! -z "$REMNET" ]
then
		# List network interfaces configured and allow user to remove
		# if they do not want network configured the same on this system
	# We now configure the netboot device, so exclude inet0
	# from the old list
	if [[ -n $LNETDEV && -n $CONFIGIF ]]
	then
	# before scanning for old stuff, kill the netboot
	# device from the cuat.sav 
	# the following malarky is necessary because 
	# egrep -vp does not exclude the stanza for LNETDEV
	# sounds buggy to me. Till thats fixed use this:
			egrep -p  "^$LNETDEV" /tmp/sb_objrepos/CuAt.sav >/tmp/egrepp
			diff /tmp/sb_objrepos/CuAt.sav /tmp/egrepp | egrep '^<' |sed 's/< //' > /tmp/DIFF
			mv /tmp/DIFF /tmp/sb_objrepos/CuAt.sav
			rm -f /tmp/DIFF /tmp/egrepp
	# at this point the netboot interface is gone from CuAt.sav
	fi
	for type in $(LANG=C lsdev -Pc if | cut -f2 -d' ')
	do
		grep -p "^${type}[0-9]*:$" /tmp/sb_objrepos/CuAt.sav >>/tmp/grep.save
		if test $? -eq 0
		   then print "^${type}[0-9]*:$" >> /tmp/...netconfigs
		fi
	done
	if [[ -s /tmp/grep.save ]]
	then # A prior network was configured
				while true
				do
					ans=
					ttymsg -l60 -i8 -v'|' -h'-' -bs "The following network attributes were configured on the original system"
					cat /tmp/grep.save
					print "\t----------------------------------------------------------------"

					if [ ! -z "$REMNET" ]
					   then # User pre-defined whether ot not to remove network
							case "$REMNET" in
								y|Y) REMNET=y;;
								n|N) REMNET=n;;
								*) REMNET=n;;
							esac
							if [ $REMNET = y -o $REMNET = n ]
							   then ans=$REMNET
							   else REMNET=
									continue
							fi
					   else # Prompt user
							print -n "If the above attributes are not correct for this machine, you should\nselect to remove the customized network attributes at this time.\n\nDo you wish to REMOVE the customized network configuration\nfrom this system? (yes/no) ==> "
							read ans
					fi

					case "$ans" in
						no|n)   break;;
						yes|y)  cp /tmp/sb_objrepos/CuAt.sav /tmp
								egrep -v -p -f /tmp/...netconfigs \
								/tmp/CuAt.sav > /tmp/sb_objrepos/CuAt.sav
								ttymsg -l60 -i8 -s "The prior network configuration has been deleted to prevent network conflicts."
								break;;
						*)		continue;;
					esac
				done
				rm -f /tmp/...netconfigs /tmp/CuAt.sav /tmp/grep.save
		fi
fi

print "\n"
ttymsg -cl70 -i3 -s"SYSTEM INSTALLATION COMPLETE"

if [ "$(bootinfo -k 2>/dev/null)" = 3 ]
   then # Key is already in normal position (or there is no key)
		ttymsg -l30 -i22 -cbs"System will now reboot"
		sleep 5

   else # Key switch is not in the NORMAL position
	if [[ "$INSTMODE" = noprompt ]]; then
		showled 0xA48 "reboot"
	fi
		print -n "\07\n\n\tYou must turn the system key switch to the NORMAL position\n\tand press ENTER to reboot.\n\n\t==> "
		read a
fi

unset VAL

if [[ "$RECOVERY_DEVICES" = "YES" ]]; then
	VAL="${VAL}-r "
fi

if [[ -n "$RDA_PRESCRIPT" ]]; then
	VAL="${VAL}-f $RDA_PRESCRIPT "
fi 
	 

# Create a temporary inittab file that runs the device reconfig program
# without attempting to initialize other system functions
# moved this block which was previously done much earlier to right
# before its needed at first reboot. Fake inittab interfers with
# SP psspscript


#
# The quotas need to be set on the second boot when all of the
# filesystem are mounted.  The sbchfscheck will add the entry in and
# remove it once the command is executed from the inittab
#
grep -q "/usr/sbin/sbchfscheck" /etc/inittab
if [[ $? -ne 0 ]]; then
	echo "sbchfscheck:2:wait:/usr/sbin/sbchfscheck" >> /etc/inittab
fi

cp /etc/inittab /etc/inittab.sav
if test $? -eq 0
   then cat > /etc/inittab <<-END
	: Temporary inittab for reapplying device config database
	: Original inittab file is renamed to /etc/inittab.sav
	init:2:initdefault:
	brc::sysinit:/sbin/rc.boot 3 >/dev/console 2>&1
	sbchfscheck:2:wait:/usr/sbin/sbchfscheck >/dev/console 2>&1
	sysreconfig:2:wait:/usr/sbin/sysreconfig $VAL >/dev/console 2>&1
END
fi

showled 0xfff
#Cleanup time: Pack it in, Pack it out.
print -n "\n\n\n\tPlease wait ...\n\n\t"
cd /
vglist="$(grep ^TOC $VGINFO)"
rm -f /etc/mount /etc/umount
rm -f $PVINFO $NETSTAT $NETINFO $BOOTDISKS $NETINSTOPTS $BOOTDISKS
rm -f $FS_SEDFILE $LV_SEDFILE $INSTDEVDESC $INSTDEVLIST $INSTDEVINFO $SPACEFILE
rm -f $EXTRACT $INSTERR $PVVGLIST $BUTYPE $TEMPFILE $LVMDEVLIST
rm -f $DSM_SYS $DSMI_CONFIG $TSM_CLIENT $TSMINFO $TSMNETDEVS $TSMINSTOPTS
rm -fr /tmp/$$tmpfile /tmp/$$buffer /tmp/en_US /tmp/libApiDS.a /tmp/mkvg.err 

#
# Remove /var/efs/efsenabled file if we have added for restore
# and there is no efsenabled filesystem
if [[  -n "$EFSADDED" ]]; then
    rm -f /var/efs/efsenabled
fi
# Renaming debug.out file to be debug.out.mmddyy
#
if [ -f /tmp/debug.out ]; then
	ID=$(date "+%m%d%y")
	mv /tmp/debug.out /tmp/debug.out.$ID
fi

umount -f $nimlppsource >/dev/null 2>&1
[ ! -z "$nimlppsource" ] && rmdir $nimlppsource >/dev/null 2>&1
cd /tmp
rm -f ..[a-z]* ...blksz date *.ppmap
cd /

#
# Fast Reboot
#
# In case this is a rs6ksmp, do a fast boot
mpcfg -cf 11 1 >/dev/null 2>&1

killall
sync
umount all 2>/dev/null
sync
# Varyoff all volume groups
/usr/sbin/sblvminfo query -TT -f$VGINFO > $vgfile | while read vgnum
do
	vg=$(/usr/sbin/sblvminfo query -Tv -tv -f$VGINFO -n$vgnum)
	varyoffvg $vg 2>/dev/null
done

rm -f $VGINFO $vgfile $lvfile $$* $VGINFO_ORG



unset AIX_NO_SAVEBASE
savebase


sync
sleep 5

reboot -ql

exit 0
