#!/sbin/sh -
# $Id: vxmirror.sh,v 1.9.45.8 2002/08/06 17:12:37 pgondi Exp $
#ident "$Source: /project/unixvm-cvs/src/sol/cmd/vxvm/support/vxmirror.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


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

progname=vxmirror
usage=`progname="$progname" egettxt \
	"Usage:\t$progname [-o verify|override] [-t tasktag] [-d yes|no] media [newmedia ...]
	$progname [-d yes|no] [-o verify|override] -a [newmedia ...]
	$progname -d yes|no
	$progname -D" vxvmshm:1375`

a_all=
verbose=
Verbose=
v_opt=
V_opt=
g_diskgroup=rootdg
setdiskgroup=
d_default=
d_set_default=
D_query_default=
t_taskarg=
default_file=${VOL_DEFAULTS_FILE:=/etc/default/vxassist}
tmpfile1=${TMPDIR:-/tmp}/vx1.$$
o_flag=
o_op=
rval=

# Libarray rule violation error code.
VEX_ARRAY_INCOMPAT=66

doit()
{
	echo "! $*" >&2
	"$@"
}
quit()
{
	rm -f "$tmpfile1"
	exit $1
}

options()
{
	#
	# The "verify" and "override" flag (EMC Foundations suite specific)
	# are mutually exclusive and should not be specified together.
	#

	if [ -n "$o_flag" ]
	then
		if [ "X$1" = "Xverify" -a "X$o_op" = "Xoverride" ] || \
			[ "X$1" = "Xoverride" -a "X$o_op" = "Xverify" ]
		then
			egettxt "vxvm:vxmirror: ERROR: verify and override flags are mutually exclusive "\
			vxvmshm:1391
			echo "$usage"
			quit 1
		fi
		if [ "$1" != "$o_op" ]
		then
			echo "$usage"
			quit 1
		fi
	else
		o_flag="-o"
		o_op="$1"
		if [ "X$o_op" != "Xverify" -a "X$o_op" != "Xoverride" ]
		then
			egettxt "vxvm:vxmirror: ERROR: keyword verify or override expected "\
			vxvmshm:1390
			echo "$usage"
			quit 1
		fi
	fi
}

# Function to check emc license.
check_emc_lic()
{
	[ -x $LICCHK ] && $LICCHK -f "VXSYM_LIC"
	if [ $? -eq 0 -a -s /usr/lib/libarray.so ]
	then
		strings /usr/lib/libarray.so | grep \
			"EMC foundation suite" >/dev/null 2>&1
		return $?
	fi
	return 1
}

# Set path for vxliccheck 
LICCHK=/usr/sbin/vxliccheck

# check if TimeFinder license is present or not
# if lic is present then only verify|oveeride is useful
emc_lic=
check_emc_lic
emc_lic=$?

trap "quit 1" INT HUP QUIT TERM

while getopts :avVg:d:Dt:o: c
do
	case $c in
	a)	a_all=yes;;
	v)	verbose=yes; v_opt=-v;;
	V)	Verbose=yes; V_opt=-V;;
	g)	g_diskgroup=$OPTARG
		setdiskgroup=1;;
	d)	d_set_default=yes; d_default=$OPTARG;;
	D)	D_query_default=yes;;
	t)	t_taskarg="-t $OPTARG";;
	o)	options $OPTARG ;;
	?)	echo "$usage" >&2; exit 1;;
	esac
done
shift `expr $OPTIND - 1`

if [ -n "$D_query_default" ] && [ $# -gt 0 -o -n "$a_all" ]
then
	echo "$usage" >&2
	quit 1
fi

# if -d was specified, set the default mirroring policy to yes or no

if [ -n "$d_set_default" ]
then
	[ -z "$setdiskgroup" ] || {
		egettxt "vxvm:vxmirror: WARNING: -g option is ignored with -d"\
								vxvmshm:880
	}
	case $d_default in
	[Yy][Ee][Ss] | [Yy] | [Tt][Rr][Uu][Ee] | [Tt] | [Oo][Nn] | 1)
		d_default=yes;;
	[Nn][Oo] | [Nn] | [Ff][Aa][Ll][Ss][Ee] | [Ff] | [Oo][Ff][Ff] | 0)
		d_default=no;;
	*) echo "$usage" >&2; quit 1;;
	esac

	if [ -f $default_file ]
	then
		grep -v '^mirror[ 	]*=' < $default_file \
			> $default_file.new
	fi
	echo "mirror=$d_default		#MIRROR_DEFAULT" >> $default_file.new
	mv $default_file.new $default_file || quit 1
	if [ -z "$D_query_default" ] && [ -z "$a_all" ] && [ $# -eq 0 ]
	then
		quit 0
	fi
fi

# if -D was specified, print the default mirroring policy as yes or no

if [ -n "$D_query_default" ]
then
	if [ ! -f $default_file ]
	then
		egettxt "no" vxvmshm:550
	else
		line=`grep 'mirror[ 	]*=' $default_file | sed -n '$p'`
		bool=`expr "\$line" : '^mirror[ 	]*=\([a-zA-Z01]*\).*'`
		case $bool in
		[Tt][Rr][Uu][Ee] | [Yy][Ee][Ss] ) egettxt "yes" vxvmshm:577;;
		* ) egettxt "no" vxvmshm:550;;
		esac
	fi
	quit 0
fi

# if -a wasn't specified, the first argument is the name of the disk
# to mirror

if [ -z "$a_all" ]
then
	if [ $# -eq 0 ]
	then
		echo "$usage" >&2
		quit 1
	fi
	dmname=$1
	shift
fi

# with -a, get all volumes that are candidates for mirroring, otherwise
# limit to volumes that are on the given disk.  Volumes that are candidates
# for mirroring are volumes that are not currently mirrored and that
# are composed of subdisks on only one disk.

if [ -n "$a_all" ]
then
	vnames=`vxprint -g "\$g_diskgroup" -F "%vname" -s \
		-e "( assoc.pl_log ? !assoc.assoc.v_logging :
		    assoc.assoc.v_pl_num == 1 ) &&
		    !any(assoc.aslist.sd_disk != sd_disk)" | 
			awk '{if (k[$1]!=1) {print;k[$1]=1}}'`
else
	vnames=`vxprint -g "\$g_diskgroup" -F "%vname" -s \
		-e "sd_dm_name==\\"\$dmname\\" &&
		( assoc.pl_log ? !assoc.assoc.v_logging :
		    assoc.assoc.v_pl_num == 1 ) &&
		    !any(assoc.aslist.sd_disk != sd_disk)" | 
			awk '{if (k[$1]!=1) {print;k[$1]=1}}'`
fi
if [ -z "$vnames" ]
then
	progname="$progname" egettxt \
		"$progname: No non-redundant volumes to mirror; see vxassist" vxvmshm:730 >&2
	quit 1
fi

succeed_list=
fail_list=

handle_special=

#  Check to see if the source disk has an extra reserved cylinder. LTM
is_extra_cylinder $dmname $g_diskgroup
rval=$?
if [ $rval -eq 0 ]
then 
	target_disk=`echo $@|wc -w`
	if [ $target_disk -eq 1 ]
	then
	    IS_USED=`vxprint -g "\$g_diskgroup" -F "%sd_num" $@`
	    IS_SLICED=`vxprint -g "\$g_diskgroup" -F "%da_type" $@`
	    if [ $IS_USED -eq 0 ] && [ "$IS_SLICED" = "sliced" ]
	    then 
		disk_reinit_no_cyl $@ $dmname $g_diskgroup
	    fi
	fi
fi

# get the name of the root volume, if there is one
rootvol=`vxprint -g rootdg -nve 'v_usetype="root"' | head -1`
rootmkpart=

if [ "X$g_diskgroup" = "Xrootdg" ] &&
   list_member $rootvol $vnames
then
	# mirroring the root volume requires creation of a partition 0
	# on the destination disk that maps the root volume's mirror on
	# that disk.

	rootmkpart=yes
fi

# go through the list of volumes and mirror them all in order

for vol in $vnames
do
	[ -n "$fail_list" ] && {
		append_list fail_list "$vol"
		continue
	}
	[ -n "$Verbose" ] && {
		vol="$vol" egettxt "  Mirror volume $vol ..." vxvmshm:22
	}
	doit vxassist $o_flag $o_op $t_taskarg $v_opt -g "$g_diskgroup" mirror "$vol" "$@"
	rval=$?
	if [ $rval -eq 0 ]
	then
		append_list succeed_list "$vol"
	else
		append_list fail_list "$vol"
	fi
done

if [ $emc_lic -ne 0 -o "X$o_op" != "Xverify"  ]
then
	[ -n "$rootmkpart" ] && doit vxbootsetup $v_opt
fi

if [ -n "$fail_list" ]
then
	if [ "X$o_op" = "Xverify" -a $emc_lic -eq 0 ]
	then
		progname="$progname" egettxt \
		"$progname: The following volumes cannot be mirrored:" vxvmshm:1331 >&2

	else
		progname="$progname" egettxt \
		"$progname: The following volumes were not mirrored:" vxvmshm:54 >&2
	fi
	for i in $fail_list; do echo $i; done |
	awk '
	BEGIN { col=2; printf "  "; }
	    {
		if (col + length + 1 > 64) {
		    col=2; printf "  ";
		}
		printf(" %s", $1);
	    }
	END { print; }
	' >&2

	#
	# Check for EMC Foundation suite specific error.
	# If the return value of the vxassist command was VEX_ARRAY_INCOMPAT
	# then the error was EMC specific and that has to be returned,
	# else return 1.
	#

	if [ $rval -eq $VEX_ARRAY_INCOMPAT ]
	then
		quit $rval
	fi

	quit 1
fi

quit 0
