#!/sbin/sh -
# $Id: vxvm-startup2.sh,v 1.12.65.13.2.1 2003/12/23 20:31:28 pgondi Exp $
#ident	"@(#)vxvm:$Source: /project/unixvm-cvs/src/sol/cmd/vxvm/init.d/vxvm-startup2.sh,v $"

# Copyright (c) 2001 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 startup script must be run AFTER /, /usr, and /var are mounted.
# This script starts some I/O daemons, rebuilds the /dev/vx/dsk and
# /dev/vx/rdsk directories, imports all disk groups, and starts all
# volumes that were not started earlier in the boot sequence.

# This startup script must be run before bcheckrc.  This starts all
# volumes without performing any recovery.  bcheckrc requires that
# the stand and var volumes be started, but we might as well start
# all of them now.

PATH=/usr/lib/vxvm/bin:/sbin:/usr/sbin:/usr/bin

# Set the locale information for message localization. This
# function can be used at boot time or called by other
# commands in user space (such as vxinstall.) At boot time
# we do not want localized messages, so we check for an
# environment variable to see when we are called. The variable
# will not exist at boot time.

OLC_MESSAGES=LC_MESSAGES
export OLC_MESSAGES
if [ $L10N_CMD ]
then
	#  L10N_CMD exists and is set to require localized
	#  messages.

	if [ $L10N_CMD = 1 ]
	then

		LC_MESSAGES=C
		export LC_MESSAGES
	fi
else

	#  L10N_CMD does not exist (or could be set to NULL)
	#  Assume we are booting the system and no localized
	#  messages are required.

	LC_MESSAGES=C
	export LC_MESSAGES
fi

# Retry connecting vold for 1 minute, fail otherwise
__VXVM_RETRY_SET="yes"
export __VXVM_RETRY_SET

# do not start if the upgrade_start script was run and the upgrade_finish
# has not be run yet, because /etc/vx/slib does not have right libraries
# till the upgrade_finish is run

if [ -f /VXVM3.5-UPGRADE/.start_runed ]
then
	echo "NOTICE: VxVM upgrade is not complete"
	exit 0
fi


# Need to make sure Veritas private slib stuff is up to date.
# Long term solution is to eliminate these shared
# library dependency altogether.

# Copy all library files needed for vxconfigd from /usr/lib to /etc/vx/slib
# Stop vxconfigd before copying libraries as to avoid corruption.
LD_LIBS=/etc/lib:/usr/lib/lwp:/usr/lib:/usr/platform/`uname -i`/lib;
SO_LIBS=`LD_LIBRARY_PATH=$LD_LIBS ldd /sbin/vxconfigd | awk '$NF ~ /\/usr\// { print $NF; }'`;

stop_vold=0;
for SO_LIB in ${SO_LIBS};
do
	name=`basename ${SO_LIB}`
	cmp -s ${SO_LIB} /etc/vx/slib/${name} || {
		[ $stop_vold -eq 0 ] && {
			stop_vold=1; vxdctl stop;
		}
		cp -f ${SO_LIB} /etc/vx/slib;
	}
done

#
# Incident 71754/Sun bug ID 4479171, pending a patch to libthread.so,
# we need to use /usr/lib/lwp/libthread.so for Solaris 8/9 . Since this
# library doesn't exist in 2.6/7, check if it exists. Compare if the files
# differ, if so copy from system. Should administrator want to use the
# library from /usr/lib instead, they should comment out relevant portion.
#

if [ -f /usr/lib/lwp/libthread.so.1 ]
then
        cmp -s /usr/lib/lwp/libthread.so.1 /etc/vx/slib/libthread.so.1 ||
                cp /usr/lib/lwp/libthread.so.1 /etc/vx/slib/libthread.so.1
elif [ -f /usr/lib/libthread.so.1 ]
then
        cmp -s /usr/lib/libthread.so.1 /etc/vx/slib/libthread.so.1 ||
                cp /usr/lib/libthread.so.1 /etc/vx/slib/libthread.so.1
fi

# if the volume manager hasn't yet been initialized, don't bother
# starting vxconfigd.  The install-db file indicates that initialization
# has NOT yet happened.

if [ -f "/etc/vx/reconfig.d/state.d/install-db" ]
then
	echo "NOTICE: VxVM not started"
	exit 0
fi

egettxt "VxVM general startup..." vxvmshm:503

# start some I/O daemons, if there aren't any already running
case "`vxiod`" in
"0 "*) vxiod set 10;;
esac

if [ ! -x /sbin/vxconfigd ]; then
	egettxt \
	"vxvm: Volume configuration daemon is not executable
	No volumes started" \
	vxvmshm:574
	exit
fi

# enabled vxconfigd to force a rebuild of /dev/vx/dsk and /dev/vx/rdsk
# directories, and to import all disk groups.  If vxconfigd is not yet
# running, then run it.
vxdctl enable 2> /dev/null
if [ $? -eq 4 ]; then
	LD_LIBRARY_PATH=$LD_LIBS vxconfigd
fi

vxdctl initdmp 2> /dev/null

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

CONFNEW=$SAVEDIR/etc/dumpadm.conf.new
CONFORIG=$SAVEDIR/etc/dumpadm.conf.orig
OUTORIG=$SAVEDIR/etc/dumpadm.out.orig
DUMPCONF=/etc/dumpadm.conf
DUMPADMDIR=/etc/vx/dumpadm.d
SWAPDEV=$SAVEDIR/swapdev

# Protocol for dumpadm handling:
#
#   Upon encapsulation, will save /etc/dumpadm.conf & dumpadm output
#   IF dedicated partition, will remain so.
#   IF swap partition, will adjust to first swap added by VM.
#   IF subsequently user changes dump partition, will start using that.
#   IF user needs to change back to using swap, will need to remove
#	CONFORIG file
#

swapdev=
get_swapdev()
{
	dumpvol=
	exec < /etc/vfstab
	while read dev rdev mpoint fstype more
	do
		case $fstype in
		swap)
			case $dev in
			\#*)    continue;;
			/dev/vx/dsk/rootdg/*)
				dumpvol="`expr "\$dev" : \
					'/dev/vx/dsk/rootdg/\(.*\)'`"
				;;
			/dev/vx/dsk/*)
				dumpvol="`expr "\$dev" : \
						'/dev/vx/dsk/\(.*\)'`"
				;;
			esac
			break
			;;
		esac
	done

	[ -n "$dumpvol" ] && {
		dump_ghost=`vxprint -se \
		   "sd_pl_offset=1 && assoc.assoc=\"$dumpvol\"" \
		   -F "%path %dev_offset %len\n"`
		dump_dev_rec=`vxprint -se \
			"sd_pl_offset=0 && assoc.assoc=\"$dumpvol\" && \
			len >= assoc.assoc.len" \
			-F "%path %dev_offset %len\n"`
		[ -n "$dump_ghost" ] &&
			dump_dev_rec="${dump_dev_rec}${dump_ghost}"
		echo "${dump_dev_rec}\c" | awk '$0!="" { print $0 }' |
		{
			while read path devoffset sdlen
			do
			       # get the disk offset of the subdisk
			       dogi_path_to_slice $path base_slice
			       [ -n "$base_slice" ] || continue
			       dogi_slice_rawpath $base_slice base_rawpath
			       STAT_PSTARTSEC=
			       STAT_DISK_TYPE=
			       eval "`vxparms -s $base_rawpath 2> /dev/null`"
			       [ -n "$STAT_PSTARTSEC" ] || continue
			       [ "X$STAT_DISK_TYPE" = Xdisk ] || continue
			       [ -n $devoffset -a $devoffset -eq 1 ] && {
					devoffset=`expr 0`;
					sdlen=`expr $sdlen + 1`
			       }
			       diskoffset=`expr $devoffset + $STAT_PSTARTSEC`

			       # locate a partition that matches the beginning
			       # of that subdisk, and that is not longer
			       # than the subdisk
			       dogi_slice_to_device $base_slice base_device
			       old_device=$base_device
			       path=`vxdisk list $base_device 2>/dev/null | \
					grep "^c[0-9]*t\{0,1\}[0-9]*d[0-9]*" | \
					awk '$2 == "state=enabled" {print $1}'`
			       path=`echo $path`
			       if [ "X$path" != "X" ]
			       then
				  base_device=`echo $path | cut -d "s" -f 1`
			       fi

			       if [ -z "$base_device" ]
			       then
				  base_device=$old_device
			       fi
			       for slice_num in 1 0 2 3 4 5 6 7
				do
				  dogi_device_slice $base_device $slice_num \
								try_slice
				  dogi_slice_rawpath $try_slice try_rawpath
				  STAT_PSTARTSEC=
				  STAT_PNUMSEC=
				  eval "`vxparms -s $try_rawpath`"
				  [ -n "$STAT_PSTARTSEC" -a \
					-n "$STAT_PNUMSEC" ] || continue
				  [ $STAT_PSTARTSEC -eq $diskoffset ] \
								|| continue
				  [ $STAT_PNUMSEC -le $sdlen ] || continue
				  [ -n "$base_device" ] || continue

				  # set the dump device
				  dogi_slice_blkpath $try_slice swapdev
				  rm -f $SWAPDEV
				  echo $swapdev > $SWAPDEV
				  found=yes
				  break
				done
				[ "X$found" = "Xyes" ] && break
			done
		}
	}
}

if [ -x /usr/sbin/dumpadm -a -f /etc/vx/.dumpadm -a -d $SAVEDIR ]
then
	if [ ! -r $CONFORIG ]
	then
		if [ -d $DUMPADMDIR ]
		then
			cp $DUMPADMDIR/* $SAVEDIR/etc
			rm -rf $DUMPADMDIR 2>/dev/null
		else
			> $CONFORIG	# if removed, assume back to swap
			rm $CONFNEW 2>/dev/null
		fi
	fi

	get_swapdev swapdev
	if [ -f $SWAPDEV ]; then
		swapdev=`cat $SWAPDEV`
		rm -f $SWAPDEV
	else
		echo "VxVM: Could not find $SWAPDEV."
	fi

	if [ ! -r $CONFNEW ]
	then
		dumpdev=`grep "Dump device:" $OUTORIG 2>/dev/null \
				 | grep -v swap | awk -F= '{print $3}'`
		if [ -n "$dumpdev" ]
		then
			cp $CONFORIG $CONFNEW
			cp $CONFORIG $DUMPCONF
			dumpadm -u -d $dumpdev
			[ -n "$swapdev" -a X$swapdev = X$dumpdev ] &&
				/usr/lib/vxvm/bin/vxswapctl set $swapdev 2> /dev/null
		fi
	elif [ -r $DUMPCONF ]
	then
		diff $DUMPCONF $CONFNEW > /dev/null
		if [ $? -ne 0 ]
		then
			cp $DUMPCONF $CONFNEW
		fi
		dumpdev=`grep "^DUMPADM_DEVICE" $DUMPCONF \
							| awk -F= '{print $2}'`
		dumpadm -u -d $dumpdev
		[ -n "$swapdev" -a X$swapdev = X$dumpdev ] &&
			/usr/lib/vxvm/bin/vxswapctl set $swapdev 2> /dev/null
	fi
	if [ -z "$dumpdev" -a -n "$swapdev" ]
	then
		dumpdev=$swapdev
		echo "vxvm: NOTE: Setting partition $dumpdev as the dump device"
		dumpadm -u -d $dumpdev
		/usr/lib/vxvm/bin/vxswapctl set $swapdev 2> /dev/null
		cp $DUMPCONF $CONFNEW
	fi
fi

# Reattach drives that were inaccessible when vxconfigd first started, to
# handle loadable disk drivers.  Also, start volumes, but don't
# perform plex recovery.  Wait until we go multi-user to do that.
if [ "X`env LC_ALL=C vxdctl mode 2> /dev/null`" = "Xmode: enabled" ]; then
	vxreattach
	vxrecover -n -s
else
	egettxt \
	"vxvm: Vold is not enabled for transactions
	No volumes started" \
	vxvmshm:573
	exit
fi
