#!/sbin/sh -
# %W% %G% %U% - %Q%
#ident "%Z%unixvm:%M% %I%"

# Copyright (c) 2000 VERITAS Software Corporation.  ALL RIGHTS RESERVED.
# UNPUBLISHED -- RIGHTS RESERVED UNDER THE COPYRIGHT
# LAWS OF THE UNITED STATES.  USE OF A COPYRIGHT NOTICE
# IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
# OR DISCLOSURE.
# 
# THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND
# TRADE SECRETS OF VERITAS SOFTWARE.  USE, DISCLOSURE,
# OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
# EXPRESS WRITTEN PERMISSION OF VERITAS SOFTWARE.
# 
#               RESTRICTED RIGHTS LEGEND
# USE, DUPLICATION, OR DISCLOSURE BY THE GOVERNMENT IS
# SUBJECT TO RESTRICTIONS AS SET FORTH IN SUBPARAGRAPH
# (C) (1) (ii) OF THE RIGHTS IN TECHNICAL DATA AND
# COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013.
#               VERITAS SOFTWARE
# 1600 PLYMOUTH STREET, MOUNTAIN VIEW, CA 94043


# This file contains commands to be executed after the root fsck but before
# anything else on the system executes.

# Set umask to a reasonable value so that any files created are not
# security risks.
umask 22

INTTY=/dev/console
if [ "$1" = "now" ]
then
	MYTTY=`eval tty 2>/dev/null`
	[ "$MYTTY" != "" -a "$MYTTY" != "not a tty" ] && INTTY=$MYTTY
fi
 
exec < $INTTY

: ${VOLROOT_DIR:=$__VXVM_ROOT_DIR}
. ${VOL_SCRIPTS_LIB:-$VOLROOT_DIR/usr/lib/vxvm/lib}/vxcommon
. ${VOLADM_LIB:-/usr/lib/vxvm/voladm.d/lib}/vxadm_lib.sh
 
set_OS_variables

SAVEDIR=/VXVM3.0-UPGRADE
upgrade_reconf=$SAVEDIR/online.plexes

LICCHK=/usr/lib/vxvm/bin/vxliccheck

bail()
{
	rm -f $reconfigfile
	exit 30
}

initdisk()
{
	_init_dg=$1
	_init_dev=${2}$VOL_FULL_SLICE
	_init_disk=$3
	initdev=$2
	vxdisk define $_init_dev > /dev/null 2>&1 	# may already be defined
	if not ecmd vxdisk online $_init_dev; then
		export initdev; ewritemsg -M vxvmshm:1328 "Definition of $initdev failed." $0 "$@"
		return 10
	fi

	set_pub_attr $_init_dev
#	if not ecmd vxdisk -f init $_init_dev \
#	    puboffset=$VOL_PUB_OFFSET publen=$VOL_PUB_LEN ; then
#		export initdev; ewritemsg -M vxvmshm:151 "Initialization of $initdev failed." $0 "$@"
#		return 10
#	fi
	if not ecmd vxdisk -f init $_init_dev ; then
		export initdev; ewritemsg -M vxvmshm:1329 "Initialization of $initdev failed." $0 "$@"
		return 10
	fi
	
	if [ "X$_init_disk" != X ]
	then
		diskopt="$_init_disk=$_init_dev"
	else
		diskopt="$_init_dev"
	fi
	
	if [ "X$_init_dg" != "Xrootdg" ] &&
	   not vxdg list "$_init_dg" > /dev/null 2>&1; then
		ecmd vxdg init "$_init_dg" "$diskopt"
	else
		ecmd vxdg -g "$_init_dg" adddisk $diskopt
	fi
	if [ $? -ne 0 ]; then
		export _init_dg initdev; ewritemsg -M vxvmshm:1327 \
 			"Addition of $initdev to $_init_dg disk group failed." $0 "$@"
		return 10
	fi
	if [ -f $mkdbfile -a $first_disk = no ]; then
		if $VOLD -k -m enable $VOLDOPTS; then
			ewritemsg -M vxvmshm:319 \
	 "The Volume Daemon has been enabled for transactions."

			rm -f $mkdbfile
			sync
			first_disk=yes
		else
			vxdctl -k stop 2> /dev/null
			ewritemsg -M vxvmshm:318 \
				"The Volume Daemon could not be enabled."
			return 10
		fi
	fi 
}

# remove_swap - remove swap areas on the given disk
#
# If not all swap areas can be removed, then we cannot encapsulate this
# disk.
remove_swap()
{
	
	rmswaplist=`swap -l 2> /dev/null |
		sed -n -e "s%^\(/dev/dsk/\${1}s[0-7]\).*%\1%p" \
		       -e "s%^\(/dev/ap/dsk/\${1}s[0-7]\).*%\1%p"`

	if [ -n "$rmswaplist" ]
	then
		for rmsw in $rmswaplist; do
			if [ -x /usr/sbin/dumpadm ]
			then
				grep $rmsw /etc/dumpadm.conf > /dev/null
				if [ $? -eq 0 ]
				then
				     DUMPADMDIR=/etc/vx/dumpadm.d
				     mkdir -p $DUMPADMDIR 2>/dev/null
				     rm -f $DUMPADMDIR/dumpadm.* 2>/dev/null
				     cp /etc/dumpadm.conf \
						 $DUMPADMDIR/dumpadm.conf.orig
				     dumpadm > $DUMPADMDIR/dumpadm.out.orig
				     > /etc/vx/.dumpadm
				else
				     dumpadm -u	
				fi
			fi
			if ecmd swap -d $rmsw 2> /dev/null
			then
				swap_removed="$swap_removed $rmswaplist"
			else
				disk=$1 rmsw=$rmsw ewritemsg -M vxvmshm:108 \
				 "Cannot delete swap area $rmsw from disk $disk"
				return 1
			fi
		done
	fi

	return 0
}

reboot=no; export reboot
first_disk=no
set_OS_variables
swap_removed=

# Remove volumes not needed because of vxunroot

if [ -f $rmvols ]
then
        exec 3<&0 < $rmvols
        while read vol; do
                vxedit -rf rm $vol
        done
        exec 0<&3 3<&-
        rm -f $rmvols
fi

if [ -f $rmvmdisks ]; then
	exec 3<&0 < $rmvmdisks
	while read disk setup_opts; do
		export disk; ewritemsg -M vxvmshm:500 \
		  "Volume Manager: Removing $disk from Volume Manager control."
		dm=`vxdisk -q list $disk |
			sed -n 's/disk:.*name=\(.*\) id=.*/\1/p'`

		### delete any sd of this dm that is preserving priv area
		### n.b. Can only find sd if sd_putil0 string "PRIVATE" used.
		for nukesd in `vxprint -q -sn -e "sd_putil0 ~ /PRIVATE/"`; do
			privdm=`vxprint -F %disk $nukesd`
			if [ "$dm" = "$privdm" ]
			then
				vxedit -f rm $nukesd
			fi
		done

		disk=`vxdisk list $disk | grep '^Device' | \
			 awk '{print $2}'`
		dogi_slice_to_device $disk disk

		### OK, now we can get rid of this volume
		if not ecmd vxdg rmdisk $dm
		then
			export dm; ewritemsg -M vxvmshm:376 \
"The removal of $dm from rootdg failed. It will be marked as
   reserved so no space from it is accidentally allocated"
			ecmd vxedit set reserved=on $dm
		else
			ecmd vxdiskunsetup $disk
		fi
	done
	exec 0<&3 3<&-
	rm -f $rmvmdisks
fi

[ -f $reconfigfile ] || exit 0

if [ -f $mkdbfile ]; then
	xcmd vxiod set 10
	xcmd $VOLD -k -r reset -m disable
	xcmd vxdctl init
	xcmd vxdctl initdmp
	xcmd vxdg init rootdg
fi

[ -d $STATEDIR ] || volmkdirs
xcmd cd $STATEDIR

rm -f $reconfigfile
rm -f $pnewerr $pcaperr
sync

if [ -f $pnewfile -o -f $pcapfile ]; then
	ewritemsg -M vxvmshm:324 \
		"The Volume Manager is now reconfiguring (partition phase)..."
fi

# Could test lic separately, but currently that wouldn't matter
if [ -x $LICCHK ]
then
	$LICCHK -f 90
	licavail=$?
fi

if [ -f $pnewfile ]; then
	if [ "$licavail" -eq 1 ]
	then
		ewritemsg -M vxvmshm:873 \
				"No valid license.  Will not initialize disks"
	fi
	exec 3<&0 < $pnewlist
	while read disk setup_opts; do
		if [ "$licavail" -eq 1 ]
		then
			echo $disk >> $pnewerr
			continue
		fi
		setup_opts=

		# We save the old value of $disk in $old_disk because $disk
		# will now contain the dmpnode name of that disk. $old_disk
		# needs to be written to $newlist and not $disk.

		old_disk=$disk
		if [ ! -f $mkdbfile ]
		then

		# At all places where vxdmpadm is used, if vxdmp module is
		# not installed or if some other error occurs, we use the old
		# value of $disk since in such cases the dmpnode name and value
		# of $disk is going to be the same.

			dmpout=`/usr/sbin/vxdmpadm getdmpnode \
					nodename=${disk} 2>/dev/null | tail +3 \
					| cut -d " " -f 1`
			if [ -n "$dmpout" ]
			then
				disk=$dmpout
			fi
		fi
		dogi_slice_to_device $disk disk
		export disk; ewritemsg -M vxvmshm:498 \
			"Volume Manager: Partitioning $disk as a new disk."

		if not ecmd vxdisksetup $setup_opts $disk; then
			disk="$disk" ewritemsg -M vxvmshm:375 \
				"The partitioning of $disk failed."
			echo $disk >> $pnewerr
		else
			echo $old_disk >> $newlist
			xcmd touch $newfile
			xcmd touch $reconfigfile

		fi
	done
	exec 0<&3 3<&-
fi

if [ -f $pcapfile ]; then
	if [ "$licavail" -eq 1 ]
	then
		ewritemsg -M vxvmshm:872 \
				"No valid license.  Will not encapsulate disks"
	fi
	exec 3<&0 < $pcaplist
	while read disk; do
		if [ "$licavail" -eq 1 ]
		then
			echo $disk >> $pcaperr
			continue
		fi
		failed=
		dogi_slice_to_device $disk disk

		# $old_disk is needed by remove_swap() and vxcap-part
		# and also needs to be written to $caplist

		old_disk=$disk
		if [ ! -f $mkdbfile ]
		then
			dmpout=`/usr/sbin/vxdmpadm getdmpnode \
				nodename=${disk} 2>/dev/null | \
				tail +3 | cut -d " " -f 1`
		
			if [ -n "$dmpout" ]
			then
				disk=$dmpout
			fi
		fi
		dogi_slice_to_device $disk disk
		export disk; ewritemsg -M vxvmshm:499 \
		  "Volume Manager: Partitioning $disk as an encapsulated disk."

               
		if not ecmd remove_swap $old_disk ||
		   not ecmd vxcap-part $old_disk
		then
			export disk; ewritemsg -M vxvmshm:375 \
				"The partitioning of $disk failed."
			echo $disk >> $pcaperr
		else
			echo $old_disk >> $caplist
			xcmd touch $capfile
			xcmd touch $reconfigfile
		fi
	done
	exec 0<&3 3<&-
fi

if [ -s $pnewerr -o -s $pcaperr ]; then
	(
		if [ -s $pnewerr ]; then
			ewritemsg -M vxvmshm:363 "The following disks failed partitioning:"
			cat $pnewerr
		fi
		if [ -s $pcaperr ]; then
			ewritemsg -M vxvmshm:361 "The following disks failed encapsulation:"
			cat $pcaperr
		fi
	) | voladm_display
	voladm_continue
	ewritemsg -M vxvmshm:515 \
"You can either continue now, or reverse all changes the Volume Manager
  has made during this reconfiguration."

	if voladm_yorn -M vxvmshm:438 "Undo changes made during partition phase" n; then
		rm -f $tmpfile1
		if [ -f $pnewlist ]
		then
			xcmd cat $pnewlist | awk '{print $1}' >> $tmpfile1
		fi
		if [ -f $pcaplist ]
		then
			xcmd cat $pcaplist >> $tmpfile1
		fi
		exec 3<&0 < $tmpfile1
		while read disk setup_opts; do
			[ -s $DISKDIR/$disk/vtoc ] || continue
			old_disk=$disk
			if [ ! -f $mkdbfile ]
			then
				dmpout=`/usr/sbin/vxdmpadm getdmpnode \
					nodename=${disk} 2>/dev/null | \
					tail +3 | cut -d " " -f 1`
				if [ -n "$dmpout" ]
				then
					disk=$dmpout
				fi
			fi
			dogi_slice_to_device $disk disk
			dogi_device_rawpath $disk disk_rawpath

			primary_node=$disk_rawpath 

			if [ -f $DISKDIR/$old_disk/primary_node ] 	
			    then   
			    exec 3<&0 < $DISKDIR/$old_disk/primary_node
			    read node
			    dogi_slice_to_device $node addr 
			    dogi_device_rawpath $addr primary_node
                        fi  

			export disk; ewritemsg -M vxvmshm:551 "undo $disk...."
			echo 'y' |
			  $EDVTOC -f $DISKDIR/$old_disk/vtoc $primary_node >/dev/null
		done
		exec 0<&3 3<&-
		rm -f $pnewerr $pcaperr $newlist $caplist
		sync
	fi
fi

rm -f $pcapfile $pcaplist $pnewfile $pnewlist

if [ $reboot = "yes" ]; then
	ewritemsg -M vxvmshm:392 \
	 "The system will now be rebooted to continue the reconfiguration."

	cd /
	sync;sync;uadmin 2 1
fi

# do a vxmend online of all plexes which were offlined as part of the
# upgrade process. At this stage everything should have mounted on volumes

if [ -f $upgrade_reconf ]; then
	sh $upgrade_reconf > /dev/null
	[ $? -eq 0 ] || {
		echo "
Failed to online some plexes of the volumes created before the upgrade.
You may attempt to online them manually or consult the documentation
for further assistance"
	voladm_continue
	}
	rm -f $upgrade_reconf
fi

if not [ -f $newfile -o -f $capfile ]; then
	# if any swap areas were removed, add them back
	if [ -n "$swap_removed" ]
	then
		swapadd -1
	fi
	quit 0
fi

ewritemsg -M vxvmshm:323 \
"The Volume Manager is now reconfiguring (initialization phase)..."
rm -f $newerr $caperr

# # make sure at least 0 length files exist for both, so loops work

[ -f $newlist ] || xcmd touch $newlist
[ -f $caplist ] || xcmd touch $caplist

exec 3<&0 < $newlist
while read disk; do
	dmpout=`/usr/sbin/vxdmpadm getdmpnode nodename=${disk} 2>/dev/null | \
			tail +3 | cut -d " " -f 1`
	if [ -n "$dmpout" ]
	then
		disk=$dmpout
	fi
	dogi_slice_to_device $disk disk
	if [ -s $DISKDIR/$disk/dmname ]; then
		dmname=`cat $DISKDIR/$disk/dmname`
		export dmname disk; ewritemsg -M vxvmshm:496 \
			"Volume Manager: Adding $dmname ($disk) as a new disk."
	else
		dmname=
		export disk; ewritemsg -M vxvmshm:494 \
			"Volume Manager: Adding $disk as a new disk."
	fi
	if [ -s $DISKDIR/$disk/dg ]; then
		dgname=`cat $DISKDIR/$disk/dg`
	else
		dgname=rootdg
	fi
	if not initdisk "$dgname" $disk "$dmname"; then
		echo $disk >> $newerr
		continue;
	fi
done
exec 0<&3 3<&-

exec 3<&0 < $caplist
while read disk; do
	dmpout=`/usr/sbin/vxdmpadm getdmpnode \
		nodename=${disk} 2>/dev/null |  tail +3 | cut -d " " -f 1`
	old_disk=$disk
	if [ -n "$dmpout" ]
	then
		disk=$dmpout
	fi
	dogi_slice_to_device $disk disk
	export disk
	if [ -s $DISKDIR/$old_disk/dmname ]; then
		dmname=`cat $DISKDIR/$old_disk/dmname`
		export dmname disk; ewritemsg -M vxvmshm:497 \
	"Volume Manager: Adding $dmname ($disk) as an encapsulated disk."
	else
		dmname=
		export disk; ewritemsg -M vxvmshm:495 \
			"Volume Manager: Adding $disk as an encapsulated disk."
	fi
	if [ -s $DISKDIR/$old_disk/dg ]; then
		dgname=`cat $DISKDIR/$old_disk/dg`
	else
		dgname=rootdg
	fi
	if not remove_swap $old_disk || not initdisk "$dgname" $disk "$dmname"; then
		echo $disk >> $caperr
		continue
	fi
	vxcap-vol $old_disk
	status=$?
	if [ $status -ne 0 -a $status -ne 101 -a $status -ne 102 ]; then
		export disk; ewritemsg -M vxvmshm:329 \
			"The creation of encapsulated volumes for $disk failed."
		echo $disk >> $caperr
		continue
	fi

	# if vxcap-vol encapsulated the root file system, then we must
	# arrange to start the root file system volume out of the kernel.
	# If we encapsulated a mounted file system then we must reboot.
	if [ $status -eq 102 ]
	then
		if not vxroot $disk; then
			ewritemsg -M vxvmshm:337 \
				"The encapsulation of the Boot Disk failed."
		fi
		reboot=yes
	elif [ $status -eq 101 ]
	then
		reboot=yes
	fi
done
exec 0<&3 3<&-

rm -f $newfile $capfile $newlist $caplist

if [ -s $newerr -o -s $caperr ]; then
	if [ -s $newerr ]; then
		ewritemsg -M vxvmshm:362 \
			"The following disks failed initialization:"
		voladm_display $newerr
		voladm_continue
	fi
	if [ -s $caperr ]; then
		ewritemsg -M vxvmshm:361 \
			"The following disks failed encapsulation:"
		voladm_display $caperr
		voladm_continue
	fi
	rm -f $newerr $caperr
fi

if [ $reboot = "yes" ]; then
	ewritemsg -M vxvmshm:393 \
		"The system will now be rebooted."
	cd /
	sync;sync;uadmin 2 1
fi
# if any swap areas were removed, add them back
if [ -n "$swap_removed" ]
then
	swapadd -1
fi
quit 0
