#!/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

: ${VOLROOT_DIR:=$__VXVM_ROOT_DIR}
. ${VOL_SCRIPTS_LIB:-$VOLROOT_DIR/usr/lib/vxvm/lib}/vxcommon

bail()
{
	quit 10
}

set_rootdisk
  
[ -n "$verbose" ] && VOL_VERBOSE=yes


usage()
{
	CMD=$0
	export CMD; egettxt "Usage: $CMD [-c] [-g diskgroup] [-N] [medianame=]accessname
       $CMD -k -a|accessname..." vxvmshm:994 $CMD >&2
	quit 1
}

getnames()
{
	echo "%names" > $tmpfile1
	if [ -n "$debug_input_dir" -a -f "$debug_input_dir/install-db" ] ||
	   [ ! -f $mkdbfile ]
	then
		vxprint -AQqn >> $tmpfile1
	fi
	if [ -s $pcaplist ]; then
		for i in `cat $pcaplist`; do
			grep '^#vxmake vol ' $DISKDIR/$i/newpart |
				awk '{print $3}' >> $tmpfile1
		done
	fi
	echo "%fstab" >> $tmpfile1
	exec 3<&0 < $SYSROOT/etc/vfstab
	while read blk chr mpoint fstyp pass auto opts; do
		case $blk in
		'#'*)	continue;;
		esac

		echo "$blk $mpoint $fstyp" >> $tmpfile1
	done
	exec 0<&3 3<&-
}

getusage()
{
	#
	# Check if there exist a file system on any partition. This is
	# because we canot rely on partition tags anymore
	#
	 
	echo "%usage" >> $tmpfile1
	for slice in 0 1 2 3 4 5 6 7; do
		dogi_device_slice $disk $slice dskpath
		dskpath=${VOL_DISK_RAWPATH}/$dskpath
		(fstyp $dskpath 2>&1) > /dev/null
		if [ $? -eq 0 ] ; then
			echo 1 >> $tmpfile1
		else
			echo 0 >> $tmpfile1
		fi
	done
}

getdmpnode()
{
	if [ -f /usr/sbin/vxdmpadm ]
	then
		dmp_node_name=`/usr/sbin/vxdmpadm getdmpnode nodename=$1 \
				2> /dev/null | tail +3 | \
				awk '{print $1}'`

		if [ -n "$dmp_node_name" ]
		then
			dogi_slice_to_device $dmp_node_name tmpdisk
			eval "${2}=$tmpdisk"
		fi
	fi
}

set_OS_variables
opt_dg=rootdg
opt_create=
opt_commit=yes
opt_kill_encap=
opt_all=
opt_adm=

while getopts :Ng:ckavA#: c
do
	case $c in
	N)	opt_commit=;;
	g)	opt_dg=$OPTARG;;
	c)	opt_create=yes;;
	k)	opt_kill_encap=yes;;
	a)	opt_all=yes;;
	v)	verbose=yes; VOL_VERBOSE=yes;;
	A)	opt_adm=yes;;
	'#')	debug_input_dir=$OPTARG;;
	?)	usage;;
	esac
done
shift `expr $OPTIND - 1`

# if -k was specified, abort encapsulation requests.  -a with no
# arguments implies aborting all encapsulation requests.

if [ -n "$opt_kill_encap" ]
then
	if [ $# -eq 0 ]
	then
		[ -n "$opt_all" ] || usage
		rm -f $reconfigfile
		rm -f $pcapfile $pcaplist $pcapfile
		rm -f $relfile $reltmpslcfile $relrestfile $relsavefile
		rm -f $relvtocfile
		exit 0
	fi
	[ -f "$pcaplist" ] || exit 0
	for disk in "$@"
	do
		getdmpnode $disk disk

		grep -v "^$disk\$" $pcaplist > $pcaplist.new
		mv $pcaplist.new $pcaplist

		dogi_slice_to_device $disk disk
		if [ "X$disk" = "X$rootdisk" ]
		then
			rm -f $relfile $reltmpslcfile $relrestfile $relsavefile
			rm -f $relvtocfile
		fi
	done
	exit 0
fi
if [ $# -ne 1 ]
then
	usage
fi

if expr "$1" : ".*\=" > /dev/null 2>&1 ; then
	dmname=`expr "$1" : "\(.*\)\="`
	disk=`expr "$1" : ".*\=\(.*\)"`
else
	dmname=
	disk=$1
fi

getdmpnode $disk disk

if vxcheckda $disk > /dev/null 2> /dev/null
then
	if dogi_is_whole_slice $disk
	then
		dogi_slice_to_device $disk disk
	fi
fi

# Make sure that if the requested disk to encapsulate names a root
# metadisk then the AP facility has been set up to manage this
# metadisk; otherwise, do not allow the encapsulation.
#
okay_to_encap_root=
case $disk in
	mc*)
		if [ "X$disk" = "X$rootdisk" ]
		then
			# has apboot been run with mc?
			if grep "rootdev:" $SYSROOT/etc/system \
				| grep "/pseudo/ap_dmd" > /dev/null 2>&1
			then
				okay_to_encap_root=yes
			fi
		else
			okay_to_encap_root=yes
		fi
		;;
	*)
		okay_to_encap_root=yes
		;;
esac
if [ -z "$okay_to_encap_root" ] 
then
	export disk; ewritemsg -M vxvmshm:1154 \
"Disk cannot be encapsulated...  

  Disk $disk is a root metadisk and as such requires that
  the AP facility put such a disk under its control before the Volume 
  Manager encapsulates it.

  Try running the appropriate AP operation to bring $disk 
  under AP boot control.  Then try to encapsulate this disk."
	quit 1 
fi


# Make sure the disk isn't currently in use. Only check if
# vxconfigd is enabled.

voldmode=`vxdctl mode 2>/dev/null`
case "$voldmode" in
	"mode: enabled") dogi_darecs_on_device $disk > $tmpfile1 ;;
	*) >$tmpfile1 ;;
esac

if [ -s $tmpfile1 ]
then
	exec 3<&0 < $tmpfile1
	read da type dm dg flags
	if [ "X$dm" != "X-" ]
	then
		export da dm type dg; ewritemsg -M vxvmshm:610 \
"Disk $da is already being used as $type disk $dm in disk group $dg;
	Disk cannot be encapsulated."
		quit 1
	fi
	dogi_whole_slice $disk wholeaddr
	if [ "X$da" != "X$wholeaddr" ] ||
	   [ "X$type" != "Xsliced" ]
	then
		export da dm type dg; ewritemsg -M vxvmshm:610 \
"Disk $da is already being used as $type disk $dm in disk group $dg;
	Disk cannot be encapsulated."
		exit 1
	fi
	exec <&3 3<&-
fi

# if the disk is already listed for encapsulation, remove the old
# encapsulation

if grep "^$disk\$" $pcaplist > /dev/null 2> /dev/null
then
	grep -v "^$disk\$" $pcaplist > $pcaplist.new
	mv $pcaplist.new $pcaplist
	dogi_slice_to_device $disk disk
	if [ "X$disk" = "X$rootdisk" ]
	then
		rm -f $relfile $reltmpslcfile $relrestfile $relsavefile
		rm -f $relvtocfile
	fi
fi
 

[ -d $DISKDIR ] || xcmd mkdir $DISKDIR
[ -d $DISKDIR/$disk ] || xcmd mkdir $DISKDIR/$disk

rm -f $DISKDIR/$disk/vtoc
rm -f $DISKDIR/$disk/dmname
rm -f $DISKDIR/$disk/dg
rm -f $DISKDIR/$disk/primary_node

if [ -n "$opt_create" ] && [ "X$opt_dg" != "Xrootdg" ]; then
	if [ -f $mkdbfile ]; then
		ewritemsg -M vxvmshm:326 \
"The Volume Manager must be installed to use the -c option.
  Run vxinstall to install the Volume Manager."
	fi
	echo $opt_dg > $DISKDIR/$disk/dg
elif [ "X$opt_dg" != "Xrootdg" ]; then
	if not vxdg -q list "$opt_dg" > /dev/null 2>&1
	then
		export opt_dg; ewritemsg -M vxvmshm:155 \
			"Disk group $opt_dg does not exist." >&2
		quit 1
	fi
	echo $opt_dg > $DISKDIR/$disk/dg
fi

	dogi_device_rawpath $disk drawpath

if [ -n "$debug_input_dir" ]
then
	cp "$debug_input_dir/vtoc" $DISKDIR/$disk/vtoc 2> /dev/null
	[ -f "$debug_input_dir/vtoc" ]
else
	ecmd $PRTVTOC -f $DISKDIR/$disk/vtoc $drawpath 2>&1 > /dev/null
fi
if [ $? != 0 ]; then
	export disk; ewritemsg -M vxvmshm:310 \
		"The $disk disk does not appear to be prepared for this system."
	if [ -z "$opt_commit" ]; then
		ewritemsg -M vxvmshm:84 \
			"Add it as a new disk through the vxdiskadm command."
	fi
	quit 100
fi

[ -s $DISKDIR/$disk/vtoc ] || bail


if [ -n "$debug_input_dir" ]
then
	eval `cat "\$debug_input_dir/stat"`
else
	eval `vxparms -s $drawpath`
	if [ -n "$STAT_DISK_TYPE" ] && [ "X$STAT_DISK_TYPE" != Xdisk ]
	then
		type=$STAT_DISK_TYPE ewritemsg -M vxvmshm:109 \
			'Cannot encapsulate $type devices'
	fi
fi
if [ -n "$debug_input_dir" -a -f "$debug_input_dir/rootdisk" ]
then
	rootdisk=$disk
fi
if [ "X$disk" = "X$rootdisk" ]
then
	r_op=-r
	if [ -n "$debug_input_dir" ]
	then
		eval `cat "\$debug_input_dir/parms"`
	else
		eval `vxparms`
	fi
	if [ "X$opt_dg" != "Xrootdg" ]
	then
		export disk opt_dg; ewritemsg -M vxvmshm:137 \
'Disk $disk is the root disk.  It can be encapsulated only into the
  rootdg disk group.'
		quit 1
	fi
	pc=`uname -m`;
	if [ "X$pc" != "Xi86pc" ]; then
		if [ "0$PROM_VERSION" -lt 2 ]; then
			ewritemsg -M vxvmshm:180 \
				"Encapsulation of root disk is not supported on systems with old PROM versions." >&2
			quit 1	
		fi
	fi

	if [ "X$STAT_MAX_BOOT_SECTOR" != X ]; then
		p_op="-p $STAT_MAX_BOOT_SECTOR"
	else
		p_op=
	fi
else
	r_op=
	p_op=
fi
[ -n "$STAT_SECPERCYL" ] && c_op="-c $STAT_SECPERCYL"

getnames
if [ -n "$debug_input_dir" ]
then
	(echo %usage; cat "$debug_input_dir/usage") >> $tmpfile1
else
	getusage
fi

cat $DISKDIR/$disk/vtoc $tmpfile1 > $tmpfile2

if [ "X${dmname}" != X ]; then
	echo $dmname > $DISKDIR/$disk/dmname
fi

[ -n "$debug_input_dir" ] && cat $tmpfile2 > $DISKDIR/$disk/slicer-input


diskpath=

if [ -f /usr/sbin/vxdmpadm ]
then

	/usr/sbin/vxdmpadm getsubpaths dmpnodename=$disk \
		2>/dev/null | tail +3 | grep -v "=" > $tmpfile1

	exec 3<&0 < $SYSROOT/etc/vfstab
	while read blk chr mpoint fstyp pass auto opts; do
		case $blk in
		'#'* | '')      #  Ignore comments, empty lines
				continue ;;
		'-')            #  Ignore no-action lines
				continue ;;
		esac
		echo "$blk" >> $tmpfile4
	done

	exec 3<&0 < $tmpfile1
	while read line 
	do
		subpath=`echo $line | cut -f 1 -d " "`
		dogi_slice_to_device $subpath devicename
		grep -s "$devicename" $tmpfile4 2>/dev/null 1>/dev/null
		if [ $? -eq 0 ]
		then
			diskpath=$devicename
			break
		fi
	done
	exec 0<&3 3<&-

	if [ "X${diskpath}" = "X" ]
	then
		diskpath=$disk
	fi
else
	diskpath=$disk
fi

if [ -d $VOL_AP_DISK_RAWPATH ]        # AP is present
	then
		dogi_device_blkpath $disk dblkpath
		q_op="-q $dblkpath"
	fi

get_primary_path $disk path 

dogi_slice_to_device $path device

echo $device  > $DISKDIR/$disk/primary_node

if [ "X${dmname}" != X ]
then
	vxslicer $c_op $r_op $p_op $q_op -d "$dmname=$diskpath" \
		< $tmpfile2 > $DISKDIR/$disk/newpart 2> $tmpfile3
	ret=$?
else
	vxslicer $c_op $r_op $p_op $q_op -d "$diskpath" \
		< $tmpfile2 > $DISKDIR/$disk/newpart 2> $tmpfile3
	ret=$?
fi

if [ $ret = 0 ]
then
	echo $disk >> $pcaplist
	xcmd touch $pcapfile
else
	if [ $ret = 100 ]; then
		echo $disk >> $pnewlist
		touch $pnewfile
		if [ -n "$opt_adm" ] 
		then
			if [ ! -f $reconfigfile ]
			then
				xcmd touch $reconfigfile
			fi		
		else
			export disk; ewritemsg -M vxvmshm:309 \
		"The $disk disk appears to be empty. Adding as a new disk."
		fi	
		quit 0
	fi
	reason=`cat $tmpfile3`
	export disk reason; ewritemsg -M vxvmshm:213 \
"It is not possible to encapsulate $disk, for the following reason:
     <${reason}>   " >&2
	quit 1
fi

[ -d $STATEDIR ] || volmkdirs
if grep '^#reloc' $DISKDIR/$disk/newpart > /dev/null 2>&1; then
	[ $disk != $rootdisk ] && bail
	xcmd touch $reltmpslcfile
	xcmd touch $relvtocfile
	xcmd touch $relsavefile
	xcmd touch $relrestfile
	xcmd touch $relfile
fi

if [ -n "$opt_commit" ]; then
	xcmd touch $reconfigfile
fi

export disk; ewritemsg -M vxvmshm:311 \
"The $disk disk has been configured for encapsulation."
quit 0
