#!/bin/ksh
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# bos72X src/bos/usr/bin/restvg/restvg.sh 1.115.2.1 
#  
# Licensed Materials - Property of IBM 
#  
# COPYRIGHT International Business Machines Corp. 1993,2021 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
# @(#)081.115.2.1 src/bos/usr/bin/restvg/restvg.sh, cmdbsys, bos72X, x2021_50A1 12/9/21 12:59:47
# COMPONENT_NAME: (CMDBSYS)
#
# FUNCTIONS: restvg.sh
#
# ORIGINS: 27
#
# (C) COPYRIGHT International Business Machines Corp. 1993
# All Rights Reserved
# Licensed Materials - Property of IBM
#
# US Government Users Restricted Rights - Use, duplication or
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
#
## [End of PROLOG]

#################
#
# FILE NAME: restvg
#
# FILE DESCRIPTION: High-level shell command for restoring a volume group.
#   The restvg command will create the Volume Group, Logical Volumes and
#   Filesystems as specified in the <vgname>.data file from the backup
#   image (-f <device/file> default is /dev/rmt0).
#   If the value "EXACT_FIT" is set to "yes" and the LV Maps are included
#   in the backup image. restvg will create the Logical Volumes with the
#   specified map files.
#   The Exact_Fit will be overridden by the "SHRINK" parameter, either by
#   the -s flag or by the "SHRINK = yes" value in the <vgname>.data file.
#   The user will be prompted before the actual creation of the VG begins,
#   unless the -q flag is used.
#   The target disks are taken for the <vgname>.data file or may be
#   specified on the command line.  The target disks MUST not belong to
#   any volume group.
#   Only User volume groups may be restored by the restvg command.

#
# RETURN VALUE DESCRIPTION:
#                             0         Successful
#                             non-zero  Unsuccessful
#
#
# EXTERNAL PROCEDURES CALLED: mkvg, mklv, mkfs commands
#
# GLOBAL VARIABLES: none
#

################################# cleanup #######################################
#
# NAME: cleanup ()
#
# DESCRIPTION: Unset traps, issue error message and exit w/ an error code
#
# INPUT:
#        $1 = exit code
#        $2 = error message if not null
#
# OUTPUT:
#        Error messages (Standard Error)
#
# RETURN VALUE DESCRIPTION:
#                           exits with a return code of $1
#
# NOTE: This function will not return (i.e., it will exit the entire
#       script with an exit value of $1)
#
cleanup ()
{
ec=$1
error=$2

case "$ec"
in
	"$USAGE_EC" )    # restvg usage error
		error="`${dspmsg} -s $MSGSET $MSGCAT 26 '
Usage:  %s [-q] [-s] [-n] [-d filename] [-P PPsize] [-b blocks]
        [-r] [-l] [-f device] diskname...\n
-q\tDo not prompt before creating the Volume Group
-s\tCreate the Logical Volumes to the Minimum Size as specified
  \tin the vgname.data file.
-n\tDo not use the existing MAP files.
-d filename\tUse the specified file as the vgname.data file instead of
           \tthe vgname.data from the backup image.  May be absolute or
           \trelative pathname.
-P PPsize\tPhysical partition size in megabytes.
-b blocks\tNumber of 512-byte blocks to read in a single
	 \tinput operation
-r\tRecreate volume group filesystem structure only
-l\tPreview volume group backup information only
-f device\tName of device to restore the information from.
	 \tDefault is /dev/rmt0
diskname...\tlist of target disk devices to overwrite the disks
	   \tspecfied in the vgname.data file.\n\n' $NAME`" 1>&2 ;;

	"$EXIT_EC" | "$TRAP_EC")
		;;

	*)      ;;
esac
if [ $OLDBLOCKSZ -ne $ZEROBLKSZ ]
then
    /usr/sbin/chdev -l $BASE_DEV1 -a block_size=$OLDBLOCKSZ >/dev/null 2>&1
fi
# If CD device, unmount CD
if [[ $UNMOUNTCD -eq 1 ]]
then
    ${umount} $CDMOUNTPT 2>/dev/null
fi
if [ "$AUTORESUME" = "yes" ]; then
    if [ -z "$OLDDEVICE" ]; then
        OLDDEVICE=$DEVICE
    fi
    /usr/sbin/cdutil -r $OLDDEVICE > /dev/null 2>&1
fi

${rm} -r $VGDATA_TMPDIR $FIRST_BLK $VGDATA_LIST > /dev/null 2>&1

[ -n "$error" ] && echo "\n${error}\n"
trap '' 1 2 15
exit "$ec"
}
####################################################
getoptions ()
{
    # Parse command line arguments
    set -- `${getopt} b:f:P:d:lrqsn? $*`     # restvg options
    if [ "$1" == "" ]
    then
        cleanup "$USAGE_EC" ""
    fi

    while [ $1 != -- ]            ## Parse flag arguements
    do
	case $1 in
		"-n") USEMAP="no" ;;  ## Do not use existing maps
		"-b") BOPT="-b $2"; shift ;;  ## get number of blocks
		"-P") PPsize=$2 ; shift   ;;  ## get physical partition size
		"-q") PROMPT="no";;   ## Do Not prompt before Creating VG
		"-r") STRUCTFLAG="yes";;  ## Set the restore structure flag
		"-s") SHRINK="yes";;  ## Set Shrink = yes
					## get backup device:
		"-f") DEVICEFLAG="yes"; DEVICE=$2; shift ;;  
					## User provided vgname.data:
		"-d") VGDATAFLAG="yes"; VGNAME_DATA=$2; shift 
			VGNAME_DATA=$(relative_to_absolute $VGNAME_DATA) ;;
		"-l") LSFLAG="yes" ;; ## List User VG backup properties
		"-?") cleanup "$USAGE_EC" "";;  ## Display usage message
	esac
	shift
    done

    set `${getopt} $*`     #Get list of target disks
    TDisks=$*   ## Get Target Disks from CmdLine
    [ -n "$TDisks" ] && REMAP=yes   ## Will need to remap the hdisk names
	## Check each target disk to make sure it does not belong to a VG
    validate_disks
}

#####  Get Stanza Data from data file

function get_stanza_data
{
    STANZA=$1    ## Stanza Name
    ATTR="$2"    ## Field Name=
    DSK=$3       ##      Unique Field Name Value (may be null)
    RECORD=$4    ## Field Name for stanza line you seek the data from.

    ## Screen out lines (VG_SOURCE_DISK_LIST and LV_SOURCE_DISK_LIST)
    ## that could be larger than grep supports.

    if [ "$DSK" = "" ]
    then
        DSK1="$DSK"
        ${sed} '/:$/i\
' $IMAGE_DATA | ${awk} '{if($0 !~ "VG_SOURCE_DISK_LIST" && $0 !~ "LV_SOURCE_DISK_LIST") {print $0}} ' | ${grep} -p "^"$STANZA: | \
        ${egrep} -p "^[ 	]+$ATTR[ 	]*=[ 	]*$DSK1" |  \
        ${egrep} "^[ 	]+$RECORD[ 	]*" | \
            ${sed} -e "s/[ 	]*=/ =/" -e "s/ =[ 	]*/ = /" | \
            ${awk} '{ for (i = 3; i <= NF; i++)
                        { print $i } }'
    else
        ## Change user data search field to include from "=" to the
        ## end of the line to ensure that only the specific search
        ## criteria is met.  This makes the field even more unique.
        DSK1="[ 	]+$ATTR[ 	]*\=[ 	]*"$(echo $DSK | sed 's!/!\\/!g')"(\n|$)"

        ## First awk finds stanza containing unique search criteria.
        ## Second sed takes out blanks surrounding "=" (equals)
        ## Next awk finds data we desire and prints even if it is
        ## separated by spaces.
        ${sed} '/:$/i\
' $IMAGE_DATA | \
	    ${awk} 'BEGIN {FS="\n"; RS=""} $0 ~ /^'"$STANZA:"'/ && $0 ~ /'"$DSK1"'/ {print $0}' | \
	    sed 's/[ 	]*=[ 	]*/=/g' | \
	    ${awk} 'BEGIN {FS="="} $0 ~ /^[ 	]+'"$RECORD"'/ {print $2}'
    fi
    return 0
}

# Get_PP_Size
# Given a disk that is part of a volume group,
# the function calculates the PP Size and
# returns it.
#
# Arguments:
#             DISK - The PP Size for this disk will
#                     be obtained. This is a required
#                     argument.
#
# Returns:
#             PP Size
#
function Get_PP_Size
{

   typeset ERROR='eval return 1'
   typeset disk=$1

   [[ -z "$disk" ]] && $ERROR

   typeset pp_size_raw
   typeset pp_size_factor
   typeset pp_size

   pp_size_raw=`lqueryvg -sp $1`
   pp_size_factor=$(( pp_size_raw - 20 ))
   pp_size=$(( 1 << pp_size_factor ))

   echo $pp_size
}


## Check the number of Target disks
##    if less than the number of source disks then return error....
function chk_num_disks
{
   CNT=`echo $VGDisks | ${awk} '{print NF}'`
   TCNT=`echo $TDisks | ${awk} '{print NF}'`
   [ $CNT -gt $TCNT ] &&  return 1
   return 0
}

## Check the sizes of the Target disks
##    if less than the size of the source disks then exit.....
function chk_disk_sizes
{
   CNT=0
   for dk in $VGDisks
   do
      CNT=`${expr} $CNT + 1`
      vg_dsk_size=`get_stanza_data "source_disk_data" "HDISKNAME"  $dk "SIZE_MB"`
      tdk=`echo $TDisks | ${awk} '{ print $'$CNT' }'`
      T_DSK_Size=`${bootinfo} -s $tdk`
      [ $T_DSK_Size -lt $vg_dsk_size ] && return 1
   done
   return 0
}

## compare_options -
## Takes to options as parameters and determines if
## they are mutually exclusive or should be used 
## together.
function compare_options
{
########################################################################
## If the first option is set, the second option must also be set
########################################################################

        if [ "$1" = "IN_CONJUNCTION" ]; then
                if [ "$3" = "yes" -a "$5" = "no" ]; then
                        MESG=`/usr/bin/dspmsg -s 5  mksysb.cat 89 \
"0512-308 $NAME: option -$2 must be used in conjunction \n\
with the -$4 option.\n" "$2" "$4" "$NAME"`
                        print "$MESG"
                        cleanup "$USAGE_EC"
                fi

########################################################################
## The options are mutually exclusive and cannot be called together
########################################################################

        elif [ "$1" = "MUTUALLY_EXCLUSIVE" ]; then
                if [ "$3" = "yes" -a "$5" = "yes" ]; then
                        MESG=`/usr/bin/dspmsg -s 5  mksysb.cat 90 \
"0512-309 $NAME: option -$2 and -$4 are mutually exclusive.\n"\
"$2" "$4" "$NAME"`
                        print "$MESG"
                        cleanup "$USAGE_EC"
                fi
        fi
}

## determine_conflicting_options -
## This function will decide which options are mutually 
## exclusive, and which must be used in conjunction.
function determine_conflicting_options
{

	# If -r flag is given, then we must have either
	# a -f device, or a -d vgname.data file also.
	if [ "$STRUCTFLAG" = "yes" ] && \
		[ "$DEVICEFLAG" = "no" ] && \
		[ "$VGDATAFLAG" = "no" ]; then
		MESG=`/usr/bin/dspmsg -s 5  mksysb.cat 89 \
"0512-308 $NAME: option -%s must be used in conjunction \n\
with the -%s option.\n" "r" "f" $NAME`
		print "$MESG"
		print "\nOR: \n"
		MESG=`/usr/bin/dspmsg -s 5  mksysb.cat 89 \
"0512-308 $NAME: option -%s must be used in conjunction \n\
with the -%s option.\n" "r" "d" $NAME`
		print "$MESG"
		cleanup "$USAGE_EC"
	fi

	# If -d flag is given, then we must have either
	# a -f device, or a -r also.
	if [ "$VGDATAFLAG" = "yes" ] && \
		[ "$DEVICEFLAG" = "no" ] && \
		[ "$STRUCTFLAG" = "no" ]; then
		MESG=`/usr/bin/dspmsg -s 5  mksysb.cat 89 \
"0512-308 $NAME: option -%s must be used in conjunction \n\
with the -%s option.\n" "d" "f" $NAME`
		print "$MESG"
		print "\nOR: \n"
		MESG=`/usr/bin/dspmsg -s 5  mksysb.cat 89 \
"0512-308 $NAME: option -%s must be used in conjunction \n\
with the -%s option.\n" "d" "r" $NAME`
		print "$MESG"
		cleanup "$USAGE_EC"
	fi

        compare_options "IN_CONJUNCTION" \
                        l $LSFLAG          f $DEVICEFLAG

}

## map Disks - map a list of disks ($TDisks) to the
## Disks listed in the Data  file ($VGDisks)
##    Requires that $TDisks list be equal or larger than $VGDisks
##    Will return re-mapped disk list in $mlist

function map_disks
{
   LIST=$*
   mlist=""
   NF=`echo $VGDisks | ${awk} ' { print NF } '`
   for VGDK in $LIST
   do
       CF=0
       FIELD=""
       while ((CF<NF))
       do
       ((CF=CF+1))
       FIELD=`echo $VGDisks | ${awk} ' { print $'$CF' } '`
       if [[ $FIELD = $VGDK ]]
       then
          mlist="$mlist `echo $TDisks | ${awk} '{ print $'$CF' }'`"
          ((CF=NF))
       fi
       done
   done
 return 0
}

function relative_to_absolute
{
typeset given_path=$1

typeset absolute

   if [[ $given_path = [/~]* ]] ; then
      print $given_path
   else
      absolute=$(pwd)/${given_path}
      print $absolute
   fi
}



## check each disk listed in $TDisks to assure that:
##  - the disk exists
##  - the disk does not belong to a Volume Group
##  this function will not return on error, but will exit

function validate_disks
{
    for td in $TDisks
    do
       JNK=`${bootinfo} -s $td`
       [ $? -ne 0 ] && cleanup "$EXIT_EC" \
       "`${dspmsg} -s $MSGSET $MSGCAT 16 \
	'0512-036 %s: Target Disk %s is invalid.  Restore of Volume Group canceled.' $NAME $td`"
       ${getlvodm} -j $td >/dev/null 2>&1
       [ $? -eq 0 ] && cleanup "$EXIT_EC" \
       "`${dspmsg} -s $MSGSET $MSGCAT 17 \
	'0512-037 %s: Target Disk %s Already belongs to a Volume Group.  Restore of Volume Group canceled.' $NAME $td`"
    done
}
######  end of function declarations ###############
######  start of main (Main) routine ###############

	#
	# set up environment
	#
export PATH="/usr/bin:/usr/sbin:/etc:$PATH"
NAME=`/usr/bin/basename $0`
WIN_OUT=`tty`
MSGCAT=mksysb.cat       ## Message catalog name
MSGSET=3                ## Message set number
MSGSET1=1               ## Message set number
USAGE_EC=1              ## Exit code for usage error
EXIT_EC=2               ## Exit code
TRAP_EC=4               ## Exit code for trap
DEVICE="/dev/rmt0"      ## Initialize backup device to rmt0
LSBACKUP_DEVICE=""      ## Set the listing backup device to null
BOPT=                   ## Blocks for the B option to restore
USEMAP="yes"            ## Option to not use existing map files
PROMPT="yes"            ## Prompt before Creating VG
TDisks=                 ## Initialize target disk list to NULL
MAX_UPPER=              ## Maximum Upper bound when using superstrict
SHRINK=                 ## Set Shrink = null
STRUCTFLAG="no"         ## Set the structure restore flag = no
Exact_Fit="no"          ## Set Exact fit = no (setting from vgname.data file)
REMAP=                  ## Remap hdisk names
PPsize=0                ## User provided physical partition size
Psize_data=0            ## Physical partition size from vg.data file
NumZero=0               ## The number 0
DEVICEFLAG="no"		## Set device flag to no unless -f flag is given.
FIRST_BLK=/tmp/first_blk.$$ ## Contains vgdata.files$$ name
VGDATA_DIR=/tmp/vgdata  ## VG data Directory
VGDATA_LIST=            ## File listing vg.data files in archive
VGDATA_TMPDIR=/tmp/vgdata.$$
VGDATA_MAP=$VGDATA_DIR/new.map$$
VGNAME_DATA=""          ## Initialize vgname.data file to null
VGDATAFLAG="no"		## Set VGDATAFLAG to no unless -d flag is given.
CDMOUNTPT=$VGDATA_TMPDIR/cdmount
TMP_FILESYSTEMS=$VGDATA_TMPDIR/filesystems.$$
TMP_VGFILESYSTEMS=$VGDATA_TMPDIR/filesystems.vg.$$
TMP_ETCFILESYSTEMS=$VGDATA_TMPDIR/filesystems.etc.$$
FS8MB=16384             ## FS Size which when less than FSAGSIZE becomes NULL
NRWFLAGS=1357           ## Suffixes on rmt indicating no-rewind
LOGDEV=                 ## Log Logical Volume for volume group
LOGDEV2=                ## Log Logical Volume for volume group (jfs2)
ZEROBLKSZ=0
OLDBLOCKSZ=0
tapedevice="no"
tapeblksz_exists="no"
AUTOMOUNTCD=
AUTORESUME="no"
UNMOUNTCD=0
CDVOLUME=
CDLASTVOLUME="no"
MEDIA_FILESYSTEM="cdrfs"

##    Full-Path to commands used
awk=/usr/bin/awk
cat=/usr/bin/cat
chpv=/usr/sbin/chpv
cp=/usr/bin/cp
crfs=/usr/sbin/crfs
dd=/usr/bin/dd
dspmsg=/usr/bin/dspmsg
expr=/usr/bin/expr
getopt=/usr/bin/getopt
grep=/usr/bin/grep
egrep=/usr/bin/egrep
fgrep=/usr/bin/fgrep
ls=/usr/bin/ls
mkdir=/usr/bin/mkdir
mount=/usr/sbin/mount
rm=/usr/bin/rm
rmdir=/usr/bin/rmdir
bootinfo=/usr/sbin/bootinfo
getlvodm=/usr/sbin/getlvodm
restore=/usr/sbin/restore
mkvg=/usr/sbin/mkvg
varyonvg=/usr/sbin/varyonvg
sed=/usr/bin/sed
mv=/usr/bin/mv
mklv=/usr/sbin/mklv
chlv=/usr/sbin/chlv
mkfs=/usr/sbin/mkfs
chfs=/usr/sbin/chfs
logform=/usr/sbin/logform
mt=/usr/bin/mt
chvg=/usr/sbin/chvg
diff=/usr/bin/diff
umount=/usr/sbin/umount
head=/usr/bin/head

	#
	# Trap on exit/interrupt/break to clean up
	#

trap "cleanup $TRAP_EC \"`${dspmsg} -s 1 $MSGCAT 4 '0512-007 %s: Abnormal program termination.' $NAME`"\"  1 2 15

getoptions $*    # Parse the commandline arguements
determine_conflicting_options 
DEVICE=$(relative_to_absolute $DEVICE)

###################################################
## Check for listing properties of a vg backup
###################################################
if [[ $LSFLAG = "yes" ]]; then
    listvgbackup -s -f $DEVICE -l
    cleanup 0
fi

###################################################
## Check and see if -r flag (restore vg/lv 
## structure without restoring data) is set
###################################################
if [[ $STRUCTFLAG = "yes" ]]; then

    # If no <vgname>.data file or device is specified
    # then we cannot restore anything! Give usage and abort.
    if [[ -z $VGNAME_DATA ]] && \
       [[ -z $DEVICE ]]; then
        cleanup "$USAGE_EC"
    fi
    if [[ $VGNAME_DATA != "" ]]; then
        DEVICE=""  # We don't need a device if we have the image.data file
    fi
fi

#############################################################
## $DEVICE is only null when -d and -r are used together.
## We don't need a device to reconstruct the volume
## group, when we have the image.data.
#############################################################
if [[ $DEVICE != "" ]]; then
    cd /  >/dev/null 2>&1

    # Create a temporary directory for file storage and CD mount point
    oldumask=$(umask)
    umask 077
    ${mkdir} -p $VGDATA_TMPDIR/tmp/vgdata
    RC=$?
    if [[ $RC -ne 0 ]] 
    then
        cleanup "$EXIT_EC" \
        "`${dspmsg} -s $MSGSET1 $MSGCAT 40 \
        '0512-050 Could not create temporary directory %s\n' $VGDATA_TMPDIR`"
    fi
    umask $oldumask
    
    BASE_DEV=`/usr/bin/basename $DEVICE | /usr/bin/cut -d . -f1`
    BASE_DEV1=`/usr/bin/basename $DEVICE`
    
    if [[ "$DEVICE" = /dev/* ]]
    then
        USBMS_DEV=`/usr/sbin/lsdev -C -c usbms -l $BASE_DEV -Sa | \
                   /usr/bin/wc -l`
        MS_DEV=`/usr/sbin/lsdev -C -c disk -t mstor -l $BASE_DEV -Sa | \
                   /usr/bin/wc -l`
        # Check if device is tape
        if [ `/usr/sbin/lsdev -C -c tape -l $BASE_DEV -Sa | /usr/bin/wc -l` -eq 1 ]
        then
            tapedevice=yes
        # If tapedevice - save current block size, and set block size to 0,
        # before reading first images from tape.
            OLDBLOCKSZ=`LC_ALL=C /usr/sbin/lsattr -E -O -a block_size -l $BASE_DEV | /usr/bin/grep -v block_size`
            [[ $OLDBLOCKSZ -ne $ZEROBLKSZ ]] && /usr/sbin/chdev -l $BASE_DEV1 -a block_size=0 >/dev/null 2>&1
    
        # Check if device is CD
        elif [ `/usr/sbin/lsdev -C -c cdrom -l $BASE_DEV -Sa | /usr/bin/wc -l` -eq 1 ] || \
             [ $USBMS_DEV -eq 1 ] || \
             [ $MS_DEV -eq 1 ]
        then
            BOPT=
            if [ -s "/usr/sbin/cdcheck" ] && [ $USBMS_DEV -ne 1 ] && [ $MS_DEV -ne 1 ]; then
                AUTOMOUNTCD="`/usr/sbin/cdcheck -a $DEVICE 2>/dev/null`"
            fi
            if [ -n "$AUTOMOUNTCD" ]; then
                /usr/sbin/cdutil -s -k $DEVICE > /dev/null 2>&1
                if [ $? -eq 0 ]; then   ## cdutil command return code
                    AUTORESUME=yes
                fi
            fi

            ${mkdir} $CDMOUNTPT
            RC=$?
            if [[ $RC -ne 0 ]]
            then
                cleanup "$EXIT_EC" \
                "`${dspmsg} -s $MSGSET1 $MSGCAT 40 \
                '0512-050 Could not create temporary directory %s\n' $CDMOUNTPT`"
            fi
            sleep 10
            ${mount} -v'cdrfs' -r $DEVICE $CDMOUNTPT 2>/dev/null
            RC=$?
            if [[ $RC -ne 0 ]]
            then
                MEDIA_FILESYSTEM=udfs
                ${mount} -v'udfs' -r $DEVICE $CDMOUNTPT 2>/dev/null
            fi
            RC=$?
            if [[ $RC -ne 0 ]]
            then
                cleanup "$EXIT_EC" \
                "`${dspmsg} -s $MSGSET1 $MSGCAT 43 \
	        '0512-055 %s: Failed mounting %s to mount point %s.\n' $NAME $DEVICE $CDMOUNTPT`"
            fi
            UNMOUNTCD=1
            OLDDEVICE=$DEVICE
            DEVICE=$CDMOUNTPT/usr/sys/inst.images/savevg_image 
        else
	    # Device is not available
	    cleanup "$EXIT_EC" \
	    "`${dspmsg} -s $MSGSET1 $MSGCAT 37 \
	    '0512-046 %s: Device %s is not in the available state.\n' $NAME $DEVICE `"
        fi
    elif [[ ! -s "$DEVICE" ]]
    then
        # Device is not a tape or cd and the file does not exist or is empty
        cleanup "$EXIT_EC" \
        "`${dspmsg} -s $MSGSET1 $MSGCAT 42 \
        '0512-054 %s: File %s does not exist or is empty.\n' $NAME $DEVICE`"
    fi
    
    # get data file and maps (if available)
    cd $VGDATA_TMPDIR >/dev/null 2>&1
    VGDATA_TMPDIR_LIST=`ls $VGDATA_TMPDIR`

    ######################################################################
    ## If we are working from tape, since the drive is set at zero, we can
    ## try to dd off a block of the size the tape was set at before hand.
    ## (if it was zero before, then we will go ahead and dd off the large
    ## (2048k) block size, using conv=noerror.
    ######################################################################
    if [[ "$tapedevice" = "yes" ]]; then

       if [[ "$OLDBLOCKSZ" -ne 0 ]]; then
          ${dd} if=$DEVICE bs=$OLDBLOCKSZ count=1 of=$FIRST_BLK > /dev/null 2>&1
    
          ######################################################################
          ## If that last dd didn't work, then the tape was probably backed up
          ## at zero, so we will try the larger block size to get one block.
          ######################################################################
          if [[ $? -ne 0 ]]; then
             ${mt} -f $DEVICE bsf 1 > /dev/null 2>&1
             ${dd} if=$DEVICE bs=51200 count=1 \
                   of=$FIRST_BLK conv=noerror > /dev/null 2>&1
          fi
          ######################################################################
          ## If that last dd didn't work, then try 2048k.
          ######################################################################
          if [[ $? -ne 0 ]]; then
             ${mt} -f $DEVICE bsf 1 > /dev/null 2>&1
             ${dd} if=$DEVICE bs=2048k count=1 \
                   of=$FIRST_BLK conv=noerror > /dev/null 2>&1
          fi
       else
          ######################################################################
          ## We have to try a larger block size to garuantee at least one block.
          ######################################################################
          ${dd} if=$DEVICE bs=51200 count=1 \
                of=$FIRST_BLK conv=noerror > /dev/null 2>&1
          ######################################################################
          ## If that last dd didn't work, then try 2048k.
          ######################################################################
          if [[ $? -ne 0 ]]; then
             ${mt} -f $DEVICE bsf 1 > /dev/null 2>&1
             ${dd} if=$DEVICE bs=2048k count=1 \
                   of=$FIRST_BLK conv=noerror > /dev/null 2>&1
          fi
       fi
    else
       ######################################################################
       ## We aren't dealing with a tape, so let's dd the first 1k block.
       ######################################################################
       ${dd} if=$DEVICE bs=1k count=1 of=$FIRST_BLK 2>/dev/null
    fi
    ########################################################
    ## Let's see if it's a backup/restore formatted file...
    ## If not, then abort.
    ########################################################
    WHAT_IS_IT=`LANG=C /usr/bin/file $FIRST_BLK | /usr/bin/awk '{print $2}'`
    if [[ "$WHAT_IS_IT" = "backup/restore" ]]; then
        ${restore} -xqf $FIRST_BLK >/dev/null 2>&1 &
    else
        cleanup "$EXIT_EC" \
            "`/usr/bin/dspmsg -s $MSGSET $MSGCAT 27 \
       '0512-059 %s: The backup %s is not a %s volume group backup.\nRecreation of Volume Group structure canceled.' $NAME $DEVICE ""`"
    fi
    PID=$!
    while [[ -n $PID ]]
    do
        VGDATA_LIST=`find $VGDATA_TMPDIR -print | grep vgdata.files`
        if [[ -n "$VGDATA_LIST" ]]
        then
            # Found vgdata.files
            kill $PID >/dev/null 2>&1
            PID=
        elif [ "$VGDATA_TMPDIR_LIST" != "`ls $VGDATA_TMPDIR`" ]
        then
            # Backup possibly not a volume group backup
            sleep 5
            kill $PID >/dev/null 2>&1
            PID=
        else
            # Still getting file list from backup, is restore done?
            PID=`ps $PID | grep $PID | awk '{print$1}'`
        fi
    done
    
    # set VGDATA_FILE to unique file if found
    VGDATA_FILE=`ls $VGDATA_TMPDIR/tmp/vgdata | grep "vgdata.files*[0-9]"`
    if [[ -z $VGDATA_FILE ]]
    then
    # Look for non-unique VGDATA_LIST file and set if found.
        VGDATA_FILE=`ls $VGDATA_TMPDIR/tmp/vgdata | grep "vgdata.files"`
    fi
    # Backup is not a volume group backup
    if [[ -z $VGDATA_FILE ]]
    then
        kill $PID >/dev/null 2>&1
        cd / >/dev/null 2>&1
        cleanup "$EXIT_EC" \
     	    "`${dspmsg} -s $MSGSET $MSGCAT 2 \
       	    '0512-025 %s: The image data file does not exist.  Restore of Volume Group canceled.' $NAME`"
    fi
    # restore vgdata.files again to be sure entire file is restored
    [[ $DEVICE = /dev/rmt+([0-9])\.[$NRWFLAGS] ]] && ${mt} -f $DEVICE bsf 1
    VGDATA_LIST=/tmp/vgdata/$VGDATA_FILE
    ${restore} -xqf $DEVICE $BOPT .$VGDATA_LIST >/dev/null
    cd /  >/dev/null 2>&1
    
    [[ $DEVICE = /dev/rmt+([0-9])\.[$NRWFLAGS] ]] && ${mt} -f $DEVICE bsf 1
    ${restore} -xqf $DEVICE $BOPT  `${cat} $VGDATA_TMPDIR$VGDATA_LIST` >/dev/null
    
    ${cat} $VGDATA_TMPDIR$VGDATA_LIST | ${grep} tapeblksz >/dev/null 2>&1
    [[ $? -eq 0 ]] && tapeblksz_exists=yes
    VG=`cat $VGDATA_TMPDIR$VGDATA_LIST | ${grep} -v "/backup\.data" | ${grep} "\.data" | awk -F/ '{print$4}'`         # Get Volume group name
    if [ "$VG" = "" ]
    then
        VG=`cat $VGDATA_TMPDIR$VGDATA_LIST | ${grep} "\filesystems" | awk -F/ '{print$4}'`
    fi  
    VG_DIR=$VGDATA_DIR/$VG         # vg data Directory
fi
    
if [[ -z $VGNAME_DATA ]]
then
    IMAGE_DATA=$VG_DIR/$VG.data    # vg Image.data file
elif [[ -f $VGNAME_DATA && -r $VGNAME_DATA ]]
then
    IMAGE_DATA=$VGNAME_DATA
    VG=`cat $IMAGE_DATA | grep VGNAME | awk '{print $2}'`
    VG_DIR=$VGDATA_DIR/$VG         # vg data Directory
else
    cleanup "$EXIT_EC" "$(${dspmsg} -s $MSGSET $MSGCAT 25 \
        '0512-058 %s: The file %s could not be accessed.\
Restore of Volume Group canceled.' $NAME $VGNAME_DATA)"
fi

VG_FILESYSTEMS=$VG_DIR/filesystems  # A copy of /etc/filesystems
TAPEBLKSZ=$VG_DIR/tapeblksz
	#
	# check prerequsites:
	#
if [ -z $VG ]                  ## No volume group name found
then                             ## exit error
    cleanup "$EXIT_EC" \
	"`${dspmsg} -s $MSGSET $MSGCAT 2 \
	'0512-025 %s: The image data file does not exist.  Restore of Volume Group canceled.' $NAME`"
fi

if [ "$VG" = "rootvg" ]
then                             ## exit error
    cleanup "$EXIT_EC" \
	"`${dspmsg} -s $MSGSET $MSGCAT 3 \
	'0512-026 %s: The %s command cannot restore the %s Volume Group.  Restore of Volume Group canceled.' $NAME $NAME $VG`"
fi

[ ! -s $IMAGE_DATA ]  &&  cleanup "$EXIT_EC" \
	"`${dspmsg} -s $MSGSET $MSGCAT 2 \
	'0512-025 %s: The image data file does not exist.  Restore of Volume Group canceled.' $NAME`"

################ Get LV Allocation Policy ##########################

if [ -z "$SHRINK" ]       # Shrink not specified on cmdline
then
    SHRINK=`get_stanza_data "logical_volume_policy" "SHRINK" "" "SHRINK"`
fi
if [ "$SHRINK" = "no" ] 
then
      Exact_Fit=`get_stanza_data "logical_volume_policy" "EXACT_FIT" "" "EXACT_FIT"`
      if [ "$Exact_Fit" = "yes" ]
      then
            [ "$USEMAP" = "no" ] && Exact_Fit="no"
      fi
fi

################ mkvg - Volume Group ##########################
VGDisks=`get_stanza_data "vg_data" "VGNAME" $VG "VG_SOURCE_DISK_LIST"`
if [ -z "$TDisks" ]              ## Get target disks for vg data file
then
    REMAP="no"                # No need to remap disk names
    TDisks=$VGDisks
fi
Psize_data=`get_stanza_data "vg_data" "VGNAME" $VG "PPSIZE"`
if [ "$Exact_Fit" != "yes" ]
then
    # Determine the best PPsize based on the largest disk
    PPsize_Best=0
    MAX_HD_SIZE=0
    for td in $TDisks
    do
        PPsize_PV=0
        PPsize_PV=`${bootinfo} -P 0 -s $td`
        if [ $PPsize_PV -gt $PPsize_Best ]
        then
            PPsize_Best=$PPsize_PV
        fi
	HDSIZE=`${bootinfo} -s $td`
	if [ $HDSIZE -gt $MAX_HD_SIZE ]
	then
	    MAX_HD_SIZE=$HDSIZE
	fi
    done

    # if no PPsize was provided on the command line
    if [ $PPsize -eq $NumZero ]
    then
	PPsize=$Psize_data
    fi
        if [ $PPsize -lt $PPsize_Best ]
	then
            BIGVG=`get_stanza_data "vg_data" "VGNAME" $VG "BIGVG"`
            TFACTOR=`get_stanza_data "vg_data" "VGNAME" $VG "TFACTOR"`
	    if [ -z "$TFACTOR" ]
            then
		PPsize=$PPsize_Best

            # if svg volume group, use Best size only
            # if a larger disk is selected
	    elif [ "$BIGVG" = "svg" ]
            then
                DISK_SIZE_LIST=`${grep} -p ^source_disk_data: $IMAGE_DATA | \
                    ${egrep} "^[ 	]+SIZE_MB" | ${awk} '{print $2}' | \
                    sort -r`
                LARGEST_DISK=`echo $DISK_SIZE_LIST | ${awk} '{print $1}'`
                [ $LARGEST_DISK -lt $MAX_HD_SIZE ] && PPsize=$PPsize_Best
	    else
		(( TFACTORLIMIT = TFACTOR * 1016 ))
		(( MAXPPS = MAX_HD_SIZE / PPsize ))
		if [ $TFACTORLIMIT -lt $MAXPPS ]
		then
		    PPsize=$PPsize_Best
		fi
		[ $TFACTOR -eq 1 ] && PPsize=$PPsize_Best
	    fi
	fi
else
   # if using ExactFit, we only use the Psize from vgname.data
   PPsize=$Psize_data
fi

################ PROMPT Before Continuing #####################
  ${dspmsg} -s $MSGSET $MSGCAT 4 "
  Will create the Volume Group:\t%s
  Target Disks:\t" $VG   1>&2
  echo "$TDisks"
  ${dspmsg} -s $MSGSET $MSGCAT 15 \
"  Allocation Policy:
  \tShrink Filesystems:\t%s
  \tPreserve Physical Partitions for each Logical Volume:\t%s\n\n"  \
   $SHRINK $Exact_Fit   1>&2
if [ "$PROMPT" = "yes" ]
then
  ${dspmsg} -s $MSGSET $MSGCAT 22 "
Enter y to continue: "  1>&2
read resp
  OLDLANG=$LANG
  LANG=C
  yescheck=`locale yesstr | cut -f1 -d:`
  ycheck=`locale yesstr | cut -f2 -d:`
  ucycheck=`locale yesstr | cut -f3 -d:`
[ "$resp" = "$ycheck" -o "$resp" = "$ucycheck" -o "$resp" = "$yescheck" ] || cleanup 0
LANG=$OLDLANG
fi
################ Prceed with Creating the Volume Group#########
if  [ "$Exact_Fit" = "yes" ]
then
    if [ "$REMAP" = "yes" ]    ## Target disks were specified on cmdline
    then
	chk_num_disks
	[ $? -ne 0 ] && cleanup "$EXIT_EC" \
	"`${dspmsg} -s $MSGSET $MSGCAT 6 \
	'0512-027 %s: Need to specify more Disks, need at least %s.  Restore of Volume Group canceled.' $NAME $CNT`"
    fi
    chk_disk_sizes
    [ $? -ne 0 ] && cleanup "$EXIT_EC" \
    "`${dspmsg} -s $MSGSET $MSGCAT 7 \
    '0512-028 %s: One or more Disks are of the wrong size.  Restore of Volume Group canceled.' $NAME`"

else    ### check for total DASD (Will data fit in specified disks)
    if [ "$SHRINK" = "yes" ]
    then
	PARTS="LV_MIN_LPS"
    else
	PARTS="LPs"
    fi
    partitions=`get_stanza_data "lv_data" $PARTS  "" $PARTS`
    
    partitions_needed=0
    for ep in $partitions
    do
      (( partitions_needed = $partitions_needed + $ep ))
    done

    ## Do not need to use new Partition sizes because the
    ## relation ship of partitions_needed to ppsize remains
    ## the same
    NDASD=`${expr} $partitions_needed  \* $Psize_data`   ## DASD Needed
    TDASD=0
    for td in $TDisks
    do
	  DSKDASD=`${bootinfo} -s $td`
	  TDASD=`${expr} $TDASD \+ $DSKDASD`
    done
    [ $TDASD -lt $NDASD ] && cleanup "$EXIT_EC" \
	"`${dspmsg} -s $MSGSET $MSGCAT 8 \
	'0512-029 %s: There is not enough Room in the specified disks for the volume group.  Restore of Volume Group canceled.' $NAME`"
    if [ "$REMAP" = "yes" ]
    then
	chk_num_disks
	[ $? -ne 0 ]  && REMAP="no"
    fi
fi

################ mkvg - Volume Group ##########################
#####  Get rest of data for mkvg command
typeset CRITVG=no; typeset CRITVGFLAG=""
typeset CRITPVS=no; typeset CRITPVSFLAG=""
typeset ENCRYPTVG=no; typeset ENCRYPTVGFLAG=""


TMPV=`get_stanza_data "vg_data" "VGNAME" $VG "VARYON"`
if [ "$TMPV" = "yes" ]
then
    Varyon=""
else
    Varyon="-n "
fi

TMP_ENH_CONC_CAPABLE=`get_stanza_data "vg_data" "VGNAME" $VG "ENH_CONC_CAPABLE"`
[[ "$TMP_ENH_CONC_CAPABLE" = yes ]] && CONC_CAPABLE="-C"

TMP_CONC_AUTO=`get_stanza_data "vg_data" "VGNAME" $VG "CONC_AUTO"`
[[ "$TMP_CONC_AUTO" = yes ]] && CONC_AUTO="-x" || CONC_AUTO=

BIGVG=`get_stanza_data "vg_data" "VGNAME" $VG "BIGVG"`
if [ "$BIGVG" = "yes" ]
then
    BIGVGFLAG="-B" 
elif [ "$BIGVG" = "svg" ]
then
    BIGVGFLAG="-S" 
    MAXLVS=256
    MAXPPSPERVG=
    MAXLVS=`get_stanza_data "vg_data" "VGNAME" $VG "MAXLVS"`
    if [[ $MAXLVS -gt 256 ]]
    then
        BIGVGFLAG="$BIGVGFLAG -v $MAXLVS"
    fi
    MAXPPSPERVG=`get_stanza_data "vg_data" "VGNAME" $VG "MAXPPSPERVG"`
    if [ -n "$MAXPPSPERVG" ]
    then
        BIGVGFLAG="$BIGVGFLAG -P $MAXPPSPERVG"
    fi
else
    BIGVGFLAG=""
fi

TFACTOR=`get_stanza_data "vg_data" "VGNAME" $VG "TFACTOR"`
[[ $TFACTOR -gt 1 ]] && TFACTORFLAG="-t $TFACTOR" || TFACTORFLAG=""

CRITVG=`get_stanza_data "vg_data" "VGNAME" $VG "CRITVG"`
CRITPVS=`get_stanza_data "vg_data" "VGNAME" $VG "CRITPVS"`
ENCRYPTVG=`get_stanza_data "vg_data" "VGNAME" $VG "ENCRYPTVG"`

[[ "$CRITVG" = yes ]] && CRITVGFLAG="-r y" || CRITVGFLAG=""
[[ "$CRITPVS" = yes ]] && CRITPVSFLAG="-e y" || CRITPVSFLAG=""
[[ "$ENCRYPTVG" = yes ]] && ENCRYPTVGFLAG="-k y" || ENCRYPTVGFLAG=""


   ## Check each target disk to make sure it does not belong to a VG
validate_disks

     ## Create the volume Group
if [[ -z $BIGVGFLAG && -z $TFACTORFLAG ]]
then
    # try first with PPsize as specified
    ${mkvg} -f $CONC_CAPABLE $CONC_AUTO -y $VG $CRITVGFLAG $CRITPVSFLAG $ENCRYPTVGFLAG -s $PPsize $Varyon $TDisks >/dev/null 2>&1
    if [[ $? -ne 0 ]]
    then
        # try without PPsize (1042661)
        ${mkvg} -f $CONC_CAPABLE $CONC_AUTO -y $VG $CRITVGFLAG $CRITPVSFLAG $ENCRYPTVGFLAG $Varyon $TDisks
        [[ $? -ne 0 ]] && cleanup "$EXIT_EC" \
        "`${dspmsg} -s $MSGSET $MSGCAT 10 \
        '0512-031 %s: Unable to create the Volume Group %s.  Restore of Volume Group canceled.' $NAME $VG`"

        # Get the new PPsize
        set -- $TDisks

        PPsize=`Get_PP_Size $1`
    fi
else
    echo y | LANG=C ${mkvg} -f $CONC_CAPABLE $CONC_AUTO -y $VG $BIGVGFLAG $TFACTORFLAG $CRITVGFLAG $CRITPVSFLAG $ENCRYPTVGFLAG -s $PPsize $Varyon $TDisks >/dev/null 2>&1
    if  [[ $? -ne 0 ]]
    then
        # try without PPsize and Tfactor (1042661)
        echo y | LANG=C ${mkvg} -f $CONC_CAPABLE $CONC_AUTO -y $VG $BIGVGFLAG $CRITVGFLAG $CRITPVSFLAG $ENCRYPTVGFLAG $Varyon $TDisks
        [[ $? -ne 0 ]] && cleanup "$EXIT_EC" \
        "`${dspmsg} -s $MSGSET $MSGCAT 10 \
        '0512-031 %s: Unable to create the Volume Group %s.  Restore of Volume Group canceled.' $NAME $VG`"

        # Get the new PPsize
        set -- $TDisks

        PPsize=`Get_PP_Size $1`
    fi
fi

${varyonvg} $VG  >/dev/null 2>&1    ## Varyon the Volume Group
    [ $? -ne 0 ] && cleanup "$EXIT_EC" \
    "`${dspmsg} -s $MSGSET $MSGCAT 10 \
    '0512-030 %s: Unable to varyon the Volume Group %s.  Restore of Volume Group canceled.' $NAME $VG`"

# Determine if we should attempt to restore the mirror pool information
# Target disk list must be >= the source disk if we are to restore mirror pools.
# Also, mirror pools are only supported on scalable VGs. A rootvg cannot be scalable.
# Finally, if the user enters the -n flag ($USEMAP == "no") then we shouldn't
# restore mirror pools, so let's check that the -n flag was NOT entered ($USEMAP == "yes")
RESTORE_MIRROR_POOL="no"
chk_num_disks
if [[ $? -eq 0 && $VG != "rootvg" && $BIGVG = "svg" && $USEMAP = "yes" ]]
then
    RESTORE_MIRROR_POOL="yes"
fi

if [[ $RESTORE_MIRROR_POOL = "yes" ]]
then
    # Create Mirror Pools
    # We saved the lsvg -P $VG output when we ran mkvgdatafile
    # The output of that command lists a hdisk and it's associated mirror pool
    # First let's grab the hdisk names, then we need to call map_disks on them
    # to get the new hdisk names. There's no harm in calling map_disks if the
    # source disks are the same as the target disks.

    # The goal is to do this:
    # (In this example the target hdisks are hdisk7, hdisk8 and hdisk9)
    # Saved lsvg -P $VG output      New lsvg -P $VG output
    # hdisk1 PoolA         ->       hdisk7 PoolA
    # hdisk2 None          ->       hdisk8 None
    # hdisk3 PoolB         ->       hdisk9 PoolB
    HDISK_WITH_MIRROR_POOL_COUNT=`get_stanza_data "vg_data" "VGNAME" $VG "HDISK_WITH_MIRROR_POOL_COUNT"`
    MIRROR_POOL_HDISKS=""
    i=0
    while [[ $i -lt $HDISK_WITH_MIRROR_POOL_COUNT ]]
    do
        # Note HDISK_${i} does not correlate with the actual hdisk number.
        HDISK_AND_MIRROR_POOL=`get_stanza_data "vg_data" "VGNAME" $VG "HDISK_${i}_AND_MIRROR_POOL"`
        HDISK=`echo $HDISK_AND_MIRROR_POOL | ${awk} '{print $1}'`
        MIRROR_POOL_HDISKS="$MIRROR_POOL_HDISKS $HDISK"
        ((i+=1))
    done

    # Now we convert the old hdisk names to the new hdisk names.
    # mlist stores the new disk names and we convert into an array for use below.
    map_disks $MIRROR_POOL_HDISKS
    set -A MIRROR_POOL_HDISK_ARRAY $(echo $mlist)

    # Now that we have the new hdisk names, assign the mirror pools to them.
    # Go through the lsvg -P $VG output again and get the name of each mirror pool.
    # Use the same index for both the MIRROR_POOL_HDISK_ARRAY and HDISK_${i}_AND_MIRROR_POOL
    # entry in the vgdata file.
    i=0
    while [[ $i -lt $HDISK_WITH_MIRROR_POOL_COUNT ]]
    do
        # Note HDISK_${i} does not correlate with the actual hdisk number.
        HDISK_AND_MIRROR_POOL=`get_stanza_data "vg_data" "VGNAME" $VG "HDISK_${i}_AND_MIRROR_POOL"`
        MIRROR_POOL=`echo $HDISK_AND_MIRROR_POOL | ${awk} '{print $2}'`
        HDISK=${MIRROR_POOL_HDISK_ARRAY[$i]}
        if [[ -n $HDISK && -n $MIRROR_POOL && $MIRROR_POOL != "None" ]]
        then
            ${chpv} -p $MIRROR_POOL $HDISK
            if [[ $? -ne 0 ]]
            then
                # If we fail at any point creating a mirror pool, let's not do any
                # mirror pool operations later, since they'll result in errors.
                RESTORE_MIRROR_POOL="no"
                break
            fi
        fi
        ((i+=1))
    done

    # If we had an error above, let's undo the assignment of the mirror pools
    # Don't want to leave the user in a partial state of mirror pool restoration
    if [[ $RESTORE_MIRROR_POOL = "no" ]]
    then
        for td in $TDisks
        do
            ${chpv} -P $td
        done
    fi
fi

################ Volume Group created ##########################

MAX_UPPER=`echo $TDisks | ${awk} '{print NF}'`
################ remap the map files  ##########################
if [ "$Exact_Fit" = "yes" ] && [ "$REMAP" = "yes" ]
then
 MAPDATA=`get_stanza_data "lv_data" "LOGICAL_VOLUME"  "" "MAPFILE"`

 SED_STR=
 for hd in $VGDisks
 do
   map_disks $hd
   # the map_disks function puts blanks in mlist, which have to
   # be removed
   mlist_nb=`echo $mlist | awk '{print $1}'`

   # The disk names in VGDisks are from the <vgname>.data file.
   # The disk names from mlist are those provided on the command_line.
   # We are replacing the VGDisk names with those from the command_line
   # in the map files.  Prefix(abc) replacement so that it will not be found
   # as a match in later looping, then take out prefix.  This can happen 
   # when disks are selected in a different order than originally.
   SED_STR="$SED_STR -e s/^$hd:/abc$mlist_nb:/ "
 done
 for mapfile in $MAPDATA         ## Remap the map files
 do
     ${sed} $SED_STR -e s/abc// $mapfile > $VGDATA_MAP
     ${mv} $VGDATA_MAP $mapfile
 done
fi

################ mklv - Logical Volume ##########################
#####  Get data for mklv command
# get list of all logical volumes in image data file
LVS=`get_stanza_data "lv_data" "LOGICAL_VOLUME"  "" "LOGICAL_VOLUME"`

# Userid, groupid, permissions - used only on bigvg lvs.
LVUSERIDFLAG=""
LVGROUPIDFLAG=""
LVMODESFLAG=""

for lv in $LVS
do           ## For each Logical Volume
  LVDisks=`get_stanza_data "lv_data" "LOGICAL_VOLUME"  $lv "LV_SOURCE_DISK_LIST"`    # Physical Volumes
  LVTYPE=`get_stanza_data "lv_data" "LOGICAL_VOLUME"  $lv "TYPE"`    # -t LV Type
  MAXLP=`get_stanza_data "lv_data" "LOGICAL_VOLUME"  $lv "MAX_LPS"`     # -x Maximun Number of Logical Partitions
  COPY=`get_stanza_data "lv_data" "LOGICAL_VOLUME"  $lv "COPIES"`      # -c Number of Copies
  if [ "$SHRINK" = "yes" ]
  then
     LPS=`get_stanza_data "lv_data" "LOGICAL_VOLUME"  $lv "LV_MIN_LPS"`   # number of Logical Partitions (Minimum)
  else
     LPS=`get_stanza_data "lv_data" "LOGICAL_VOLUME"  $lv "LPs"`   # number of Logical Partitions
  fi
  INTER=`get_stanza_data "lv_data" "LOGICAL_VOLUME"  $lv "INTER_POLICY"`    # -e Inter Policy
  INTRA=`get_stanza_data "lv_data" "LOGICAL_VOLUME"  $lv "INTRA_POLICY"`    # -a  Intra-Policy
  MIRROR=`get_stanza_data "lv_data" "LOGICAL_VOLUME"  $lv "MIRROR_WRITE_CONSISTENCY"`   # -w Mirror Writes
  STRICT=`get_stanza_data "lv_data" "LOGICAL_VOLUME"  $lv "LV_SEPARATE_PV"`   # -s Strict Allocation Policy
  VERIFY=`get_stanza_data "lv_data" "LOGICAL_VOLUME"  $lv "WRITE_VERIFY"`   # -v Write-Verify State
  SCH=`get_stanza_data "lv_data" "LOGICAL_VOLUME"  $lv "SCHED_POLICY"`      # -d Scheduling Policy
  BADBLK=`get_stanza_data "lv_data" "LOGICAL_VOLUME"  $lv "BB_POLICY"`   # -b Badblock Policy
  RELOCATE=`get_stanza_data "lv_data" "LOGICAL_VOLUME"  $lv "RELOCATABLE"` # -r Relocation Flag
  UPPER=`get_stanza_data "lv_data" "LOGICAL_VOLUME"  $lv "UPPER_BOUND"`    # -u Upper bound
  LABEL=`get_stanza_data "lv_data" "LOGICAL_VOLUME"  $lv "LABEL"`    # -L Label
  if [ "$Exact_Fit" = "yes" ]
  then
  MAPF=`get_stanza_data "lv_data" "LOGICAL_VOLUME"  $lv "MAPFILE"`      # -m Map File
  fi
  STRIPE_WIDTH=`get_stanza_data "lv_data" "LOGICAL_VOLUME"  $lv "STRIPE_WIDTH"`    # 
  STRIPE_SIZE=`get_stanza_data "lv_data" "LOGICAL_VOLUME"  $lv "STRIPE_SIZE"`    # -S stripe size 
  SERIALIZE_IO=`get_stanza_data "lv_data" "LOGICAL_VOLUME"  $lv "SERIALIZE_IO"`
  DEV_SUBTYPE=`get_stanza_data "lv_data" "LOGICAL_VOLUME"  $lv "DEV_SUBTYP"`    # -T lvcb location 
  if [ "$BIGVG" = "yes" ] || [ "$BIGVG" = "svg" ]
  then
     LVUSERID=`get_stanza_data "lv_data" "LOGICAL_VOLUME"  $lv "LV_USERID"`
     LVGROUPID=`get_stanza_data "lv_data" "LOGICAL_VOLUME"  $lv "LV_GROUPID"`
     LVMODES=`get_stanza_data "lv_data" "LOGICAL_VOLUME"  $lv "LV_MODES"`
  fi
  if [[ $RESTORE_MIRROR_POOL = "yes" ]]
  then
     COPY_1_MIRROR_POOL=`get_stanza_data "lv_data" "LOGICAL_VOLUME"  $lv "COPY_1_MIRROR_POOL"`
     COPY_2_MIRROR_POOL=`get_stanza_data "lv_data" "LOGICAL_VOLUME"  $lv "COPY_2_MIRROR_POOL"`
     COPY_3_MIRROR_POOL=`get_stanza_data "lv_data" "LOGICAL_VOLUME"  $lv "COPY_3_MIRROR_POOL"`
  fi
  # Some values must be converted so that mklv will take them as parameters.

  AFLAG=""
  case "$INTRA" in
	  middle         ) AFLAG="-a m" ;;
	  center         ) AFLAG="-a c" ;;
	  edge           ) AFLAG="-a e" ;;
	  'inner middle' ) AFLAG="-a im" ;;
	  'inner edge'   ) AFLAG="-a ie" ;;
	  *              ) AFLAG=""      ;;
  esac

#Defect:1042657 removing "-b y" when $BADBLK is relocatable as 
#mklv sets this by default. In case of 4K DISK "-b y" is not a valid 
#flag 
  BFLAG=""
  case "$BADBLK" in
	  relocatable     ) BFLAG="";;
	  non-relocatable ) BFLAG="-b n" ;;
	  *               ) BFLAG=""  ;;
  esac

  DFLAG=""
  case "$SCH" in
	  parallel            ) DFLAG="-d p" ;;
	  sequential          ) DFLAG="-d s" ;;
	  parallel/sequential ) DFLAG="-d ps" ;;
	  parallel/round      ) DFLAG="-d pr" ;;
	  *                   ) DFLAG=""   ;;
  esac

  EFLAG=""
  case "$INTER" in
	  minimum ) EFLAG="-e m" ;;
	  maximum ) EFLAG="-e x" ;;
	  *       ) EFLAG=""     ;;
  esac

  RFLAG=""
  case "$RELOCATE" in
	  yes ) RFLAG="-r y" ;;
	  no  ) RFLAG="-r n" ;;
	  *   ) RFLAG=""     ;;
  esac

  SFLAG=""
  case "$STRICT" in
	  yes ) SFLAG="-s y" ;;
	  no  ) SFLAG="-s n" ;;
	  ss  ) SFLAG="-s s"
	  [ $UPPER -gt $MAX_UPPER ] && UPPER=$MAX_UPPER ;;
	  *   ) SFLAG="" ;;
  esac

  VFLAG=""
  case "$VERIFY" in
	  on  ) VFLAG="-v y" ;;
	  off ) VFLAG="-v n" ;;
	  *   ) VFLAG="" ;;
  esac

  WFLAG=""
  case "$MIRROR" in
	  on  ) WFLAG="-w y" ;;
	  off ) WFLAG="-w n" ;;
	  *   ) WFLAG=""  ;;
  esac

  ZFLAG=""
  case "$SERIALIZE_IO" in
          yes ) ZFLAG="-o y" ;;
          no  ) ZFLAG="-o n" ;;
          *   ) ZFLAG="" ;;
  esac

  CFLAG=""; [ -n "$COPY" ]   && CFLAG="-c $COPY"
  DSFLAG=""; [ -n "$DEV_SUBTYPE" ]  && DSFLAG="-T O"
  LFLAG=""; [ -n "$LABEL" ]  && LFLAG="-L $LABEL" || LFLAG="-L None"
  TFLAG=""; [ -n "$LVTYPE" ] && TFLAG="-t $LVTYPE"
  UFLAG=""; [ -n "$UPPER" ]  && UFLAG="-u $UPPER"
  XFLAG=""; [ -n "$MAXLP" ]  && XFLAG="-x $MAXLP"

  YFLAG="-y $lv"

  MFLAG=""
  MFLAG_PLUS=""
  if [ -s "$MAPF" -a "$Exact_Fit" = yes ]
  then
	  MFLAG="-m $MAPF"
          # Cannot use -a, -e, -s, and -u flags with the -m flag.
          # Save flag values and set using chlv after mklv.
          if [ -n "$AFLAG" ] || [ -n "$EFLAG" ] || [ -n "$SFLAG" ] || \
             [ -n "$UFLAG" ]; then
                MFLAG_PLUS="$AFLAG $EFLAG $SFLAG $UFLAG"
          fi
          AFLAG= EFLAG= SFLAG= UFLAG=
  elif [ ! -s "$MAPF" -a "$Exact_Fit" = yes ]
  then
     cleanup "$EXIT_EC" \
    "`${dspmsg} -s $MSGSET $MSGCAT 11 \
    '0512-032 %s: The map file for the Logical Volume %s does not exist or is not readable. Restore of Volume Group canceled.' $NAME $lv`"
  fi

  SSFLAG=
  if [ -n "$STRIPE_SIZE" -a "$STRIPE_SIZE" != None ]
  then
	SSFLAG="-S $STRIPE_SIZE"
	if [ -n "$STRIPE_WIDTH" ]
	then
		UFLAG="-u $STRIPE_WIDTH"
	fi
	# Cannot use -d, -e, -r, -s, and w flags with the -SS flag.
	DFLAG= EFLAG= RFLAG= SFLAG= WFLAG=
  fi

  if [ "$REMAP" = "yes" ]
  then
	map_disks $LVDisks
	LVDisks="$mlist"
  else
	[ -n "$TDisks" ] && LVDisks="$TDisks"
  fi

  ## Adjust Logical Partition numbers if needed
  if [ "$Exact_Fit" != "yes" -a $PPsize -ne $Psize_data ]
  then
      (( mb = $Psize_data * $LPS ))
      (( LPS = $mb / $PPsize ))
      (( LPSrem = $mb % $PPsize ))
      if [ $LPSrem -ne 0 ]
      then 
         (( LPS += 1 ))
      fi
      if [ -n "$MAXLP" ] && [ $MAXLP -lt $LPS ]
      then
          MAXLP=$LPS
          XFLAG="-x $MAXLP"
      fi
  fi
  if [ "$BIGVG" = "yes" ] || [ "$BIGVG" = "svg" ]
  then
     [ -n "$LVUSERID" ] && LVUSERIDFLAG="-U $LVUSERID"
     [ -n "$LVGROUPID" ] && LVGROUPIDFLAG="-G $LVGROUPID"
     [ -n "$LVMODES" ] && LVMODESFLAG="-P $LVMODES"
  fi

  if [[ "$COPY" -gt 1 && -n $SSFLAG ]]
  then
     # First try the mklv by specifying list of disks.
     ${mklv} -f $AFLAG $BFLAG $CFLAG $DFLAG $EFLAG "$LFLAG" $MFLAG \
     $RFLAG $SSFLAG $SFLAG $TFLAG $UFLAG $VFLAG $WFLAG $XFLAG $LVUSERIDFLAG \
     $LVGROUPIDFLAG $LVMODESFLAG $YFLAG $ZFLAG $DSFLAG $VG $LPS \
     $LVDisks
     rc="$?"
  else
     # First try the mklv by specifying list of disks.
     ${mklv} $AFLAG $BFLAG $CFLAG $DFLAG $EFLAG "$LFLAG" $MFLAG $RFLAG $SSFLAG \
     $SFLAG $TFLAG $UFLAG $VFLAG $WFLAG $XFLAG $LVUSERIDFLAG \
     $LVGROUPIDFLAG $LVMODESFLAG $YFLAG $ZFLAG $DSFLAG $VG $LPS \
     $LVDisks
     rc="$?"
  fi
  # If mklv failed, try the mklv again without the list of disks, without
  # LV striping.
  if [ $rc -ne 0 -a "$Exact_Fit" != yes ]
  then
     ${dspmsg} -s $MSGSET $MSGCAT 23 \
     "Warning: mklv failed creating logical volume %s.  Retrying mklv\n\
     without striping (-S flag), without an upperbound value (-u flag),\n\
     and without a list of disks.\n" $lv
     ${mklv} $AFLAG $BFLAG $CFLAG $DFLAG $EFLAG "$LFLAG" $RFLAG \
     $SFLAG $TFLAG $UFLAG $VFLAG $WFLAG $XFLAG $LVUSERIDFLAG \
     $LVGROUPIDFLAG $LVMODESFLAG $YFLAG $ZFLAG $DSFLAG $VG $LPS
     rc="$?"
     # If mklv failed, try the mklv again without upperbound and/or strictness.
     if [ $rc -ne 0 ]
     then
        ## Superstrict cannot be set without upper bound.
        if [ "$SFLAG" = "-s s" ]
        then
           ${mklv} $AFLAG $BFLAG $CFLAG $DFLAG $EFLAG "$LFLAG" $RFLAG \
           $TFLAG $VFLAG $WFLAG $XFLAG $LVUSERIDFLAG \
           $LVGROUPIDFLAG $LVMODESFLAG $YFLAG $ZFLAG $DSFLAG $VG $LPS
           rc="$?"
        else
           ${mklv} $AFLAG $BFLAG $CFLAG $DFLAG $EFLAG "$LFLAG" $RFLAG \
           $SFLAG $TFLAG $VFLAG $WFLAG $XFLAG $LVUSERIDFLAG \
           $LVGROUPIDFLAG $LVMODESFLAG $YFLAG $ZFLAG $DSFLAG $VG $LPS
           rc="$?"
        fi
     fi
  fi

  # If mklv failed, call error routine.
  if [ $rc -ne 0 ]
  then
     cleanup "$EXIT_EC" \
    "`${dspmsg} -s $MSGSET $MSGCAT 12 \
    '0512-033 %s: Failed creating the Logical Volume %s.  Restore of Volume Group canceled.' $NAME $lv`"
  fi

  # Set lv attributes that cannot be set at mklv time when using maps.
  if [ -n "$MFLAG_PLUS" ]
  then
   ${chlv} $MFLAG_PLUS $lv
  fi

  if [[ "$LVTYPE" = "jfslog" ]]
  then
   echo y | LANG=C ${logform} /dev/$lv
   LOGDEV=/dev/$lv
  elif [[ "$LVTYPE" = "jfs2log" ]]
  then
   echo y | LANG=C ${logform} /dev/$lv
   LOGDEV2=/dev/$lv
  fi

  if [[ $RESTORE_MIRROR_POOL = "yes" ]]
  then
    MIRROR_POOL_FLAGS=""
    [[ $COPY_1_MIRROR_POOL != "None" ]] && MIRROR_POOL_FLAGS="-m copy1=$COPY_1_MIRROR_POOL"
    [[ $COPY_2_MIRROR_POOL != "None" ]] && MIRROR_POOL_FLAGS="$MIRROR_POOL_FLAGS -m copy2=$COPY_2_MIRROR_POOL"
    [[ $COPY_3_MIRROR_POOL != "None" ]] && MIRROR_POOL_FLAGS="$MIRROR_POOL_FLAGS -m copy3=$COPY_3_MIRROR_POOL"
    [[ -n $MIRROR_POOL_FLAGS ]] && ${chlv} $MIRROR_POOL_FLAGS $lv
  fi

done    ## Create LV

################ Logical Volumes Created ##########################

if [[ $RESTORE_MIRROR_POOL = "yes" ]]
then
    ### Handle Mirror Pool strictness settings
    # LVs can be in violation of Mirror Pool Strictness if they were created before the setting was set.
    # User might not know this issue since chvg does not check existing LVs when turning on strictness.
    # If we set the Mirror Pool Setting at VG creation time we can see errors when we create the LVs above,
    # because they may violate the strictness setting. Instead we'll set Mirror Pool Strictness after we
    # create all the LVs.
    MIRROR_POOL_STRICT=`get_stanza_data "vg_data" "VGNAME" $VG "MIRROR_POOL_STRICT"`
    if [[ $MIRROR_POOL_STRICT == "super" ]]
    then
        ${chvg} -M s $VG
    elif [[ $MIRROR_POOL_STRICT == "on" ]]
    then
        ${chvg} -M y $VG
    elif [[ $MIRROR_POOL_STRICT == "off" ]]
    then
        ${chvg} -M n $VG
    fi
fi


################ mkfs - Filesystems  ##########################
#####  Get data for mkfs command
FSLIST=`get_stanza_data "fs_data" "FS_NAME"  "" "FS_LV"`   # Get list of Filesystems

for lfs in $FSLIST
do
  ##
  ## determine filesystem type - jfs or jfs2
  ##

  ALTERED_FS=0
  lfs_base=`basename $lfs`
  LV_TYP=`get_stanza_data "lv_data" "LOGICAL_VOLUME"  $lfs_base "TYPE"`

  ##
  ## handle common fields - FS_NAME, and FS_LV
  ## (FS_SIZE is common, but must be calculated separately for jfs & jfs2.)
  ##

  ## Filesystem name
  FSNAME=`get_stanza_data "fs_data" "FS_LV"  $lfs "FS_NAME"`

  ## -d Device Name
  FSLV=`get_stanza_data "fs_data" "FS_LV"  $lfs "FS_LV"`

  if [[ $LV_TYP = "jfs" ]]; then

    ##
    ## handle fields unique to jfs - FS_FS, FS_NBPI, FS_COMPRESS,
    ## FS_BF, and FS_AGSIZE.  Also, calculate FS_SIZE.
    ##

    ## -a Frag Attribute
    FSFRAG=`get_stanza_data "fs_data" "FS_LV"  $lfs "FS_FS"`

    ## -a NBPI Attribute
    FSNBPI=`get_stanza_data "fs_data" "FS_LV"  $lfs "FS_NBPI"`

    ## -a Compress Attribute
    FSCOMPRS=`get_stanza_data "fs_data" "FS_LV"  $lfs "FS_COMPRESS"`

    ## -a >2GB File Support
    FSBF=`get_stanza_data "fs_data" "FS_LV" $lfs "FS_BF"`

    ## -a Allocation Group Size
    FSAGSIZE=`get_stanza_data "fs_data" "FS_LV" $lfs "FS_AGSIZE"`

    if [ "$SHRINK" != "yes" ]
    then
      ## -a Size Attribute
      FSSIZE=`get_stanza_data "fs_data" "FS_LV"  $lfs "FS_SIZE"`
    else
    {
      newlv=""
      newlv=${lfs##*/}
      ## number of Logical Partitions (Minimum)
      LPS=`get_stanza_data "lv_data" "LOGICAL_VOLUME"  $newlv "LV_MIN_LPS"`
      (( FSSIZE = $LPS * $PPsize * 2048 * $Psize_data / $PPsize ))

      # if fs size is less than 8mb, let Allocation Group size be default
      if [ "$FSSIZE" -lt "$FS8MB" ]
      then
        FSAGSIZE=""
      fi
    }
    fi

  elif [[ $LV_TYP = "jfs2" ]]; then

    ##
    ## handle fields unique to jfs2 - FS_JFS2_BS, FS_JFS2_SPARSE,
    ## FS_JFS2_INLINELOG, and FS_JFS2_SIZEINLINELOG
    ## (FS_SIZE is common, but must be calculated separately for jfs & jfs2.)
    ##

    if [ "$SHRINK" != "yes" ]
    then
      ## -a Size Attribute
      FSSIZE=`get_stanza_data "fs_data" "FS_LV"  $lfs "FS_SIZE"`
    else
    {
      newlv=""
      newlv=${lfs##*/}
      ## number of Logical Partitions (Minimum)
      LPS=`get_stanza_data "lv_data" "LOGICAL_VOLUME"  $newlv "LV_MIN_LPS"`
      (( FSSIZE = $LPS * $PPsize * 2048 * $Psize_data / $PPsize ))
    }
    fi

    ## -o Allocation Group Block Size
    FSAGBS=$(get_stanza_data "fs_data" "FS_LV" $lfs "FS_JFS2_BS")

    ## -o sparse/dense option
    FSSPARSE=$(get_stanza_data "fs_data" "FS_LV" $lfs "FS_JFS2_SPARSE")

    ## -o Inline Log option
    FSINLINE=$(get_stanza_data "fs_data" "FS_LV" $lfs "FS_JFS2_INLINELOG")

    ## -o Inline Log Size option
    FSINLINESZ=$(get_stanza_data "fs_data" "FS_LV" $lfs "FS_JFS2_SIZEINLINELOG")

    ## -o ea option
    FSEAFORMAT=$(get_stanza_data "fs_data" "FS_LV" $lfs "FS_JFS2_EAFORMAT")

    ## -o quota option
    FSQUOTA=$(get_stanza_data "fs_data" "FS_LV" $lfs "FS_JFS2_QUOTA")

    ## DMAPI
    FSDMAPI=$(get_stanza_data "fs_data" "FS_LV" $lfs "FS_JFS2_DMAPI")

    ## VIX 
    FSVIX=$(get_stanza_data "fs_data" "FS_LV" $lfs "FS_JFS2_VIX")

    ## EFS encrypted file system
    FSEFS=$(get_stanza_data "fs_data" "FS_LV" $lfs "FS_JFS2_EFS")

  fi


# Some values must be converted so that mkfs will take them as parameters.

## Save /etc/filesystems file temporarily

# Prevent duplicate Filesystem entries.
# Search based on logical volume name, because filesystem name
# may have changed to remove links

if [[ "$DEVICE" != "" ]]; then
    ${cp} /etc/filesystems $TMP_FILESYSTEMS
    { echo ;
    ${sed} '/:$/i\
' $VG_FILESYSTEMS | ${grep} -p "[ 	]*"$FSLV"[ 	]*$" | ${sed} '/^$/d' ; } > $TMP_VGFILESYSTEMS
    { echo ;
    ${sed} '/:$/i\
' /etc/filesystems | ${grep} -p "[ 	]*"$FSLV"[ 	]*$" | ${sed} '/^$/d' ; } > $TMP_ETCFILESYSTEMS
    ${diff} $TMP_VGFILESYSTEMS $TMP_ETCFILESYSTEMS > /dev/null
    [ $? -ne 0 ] && ${cat} $TMP_VGFILESYSTEMS >> /etc/filesystems
fi

# If filesystem name is not in /tmp/vgdata/<vgname>/filesystems
# then it was altered when links were removed or did not exist at backup.
${grep} -q "[ 	]*dev[ 	]*=[ 	]*$FSLV"$ $VG_FILESYSTEMS
ALTERED_FS=$?

if [[ $LV_TYP = "jfs" ]]; then

    # If device is null, then we do crfs, else mkfs.
    if [[ $DEVICE = "" || $ALTERED_FS != 0 ]]; then
        CRFS_VFLAG="-v jfs"
        SFLAG=""; [ -n "$FSSIZE" ] && CRFS_SFLAG="-a size=$FSSIZE"
        AFLAG=""
        [ -n "$FSFRAG" ] && AFLAG="-a frag=$FSFRAG"
        [ -n "$AFLAG" -a -n "$FSNBPI" ] && AFLAG="$AFLAG -a nbpi=$FSNBPI"
        [ -z "$AFLAG" -a -n "$FSNBPI" ] && AFLAG="-a nbpi=$FSNBPI"
        [ -n "$AFLAG" -a -n "$FSCOMPRS" ] && AFLAG="$AFLAG -a compress=$FSCOMPRS"
        [ -z "$AFLAG" -a -n "$FSCOMPRS" ] && AFLAG="-a compress=$FSCOMPRS"
        [ -n "$AFLAG" -a -n "$FSBF" ] && AFLAG="$AFLAG -a bf=$FSBF"
        [ -z "$AFLAG" -a -n "$FSBF" ] && AFLAG="-a bf=$FSBF"
        [ -n "$AFLAG" -a -n "$FSAGSIZE" ] && AFLAG="$AFLAG -a ag=$FSAGSIZE"
        [ -z "$AFLAG" -a -n "$FSAGSIZE" ] && AFLAG="-a ag=$FSAGSIZE"
    else
        VFLAG="-V jfs"
        SFLAG=""; [ -n "$FSSIZE" ] && SFLAG="-s $FSSIZE"
        OFLAG=""
        [ -n "$FSFRAG" ] && OFLAG="-o frag=$FSFRAG"
        [ -n "$OFLAG" -a -n "$FSNBPI" ] && OFLAG="$OFLAG,nbpi=$FSNBPI"
        [ -z "$OFLAG" -a -n "$FSNBPI" ] && OFLAG="-o nbpi=$FSNBPI"
        [ -n "$OFLAG" -a -n "$FSCOMPRS" ] && OFLAG="$OFLAG,compress=$FSCOMPRS"
        [ -z "$OFLAG" -a -n "$FSCOMPRS" ] && OFLAG="-o compress=$FSCOMPRS"
        [ -n "$OFLAG" -a -n "$FSBF" ] && OFLAG="$OFLAG,bf=$FSBF"
        [ -z "$OFLAG" -a -n "$FSBF" ] && OFLAG="-o bf=$FSBF"
        [ -n "$OFLAG" -a -n "$FSAGSIZE" ] && OFLAG="$OFLAG,ag=$FSAGSIZE"
        [ -z "$OFLAG" -a -n "$FSAGSIZE" ] && OFLAG="-o ag=$FSAGSIZE"
    fi
  elif [[ $LV_TYP = "jfs2" ]]; then
    # If device is null, then we do crfs, else mkfs.
    if [[ $DEVICE = "" || $ALTERED_FS != 0 ]]; then
        CRFS_VFLAG="-v jfs2"
        SFLAG=""; [[ -n "$FSSIZE" ]] && CRFS_SFLAG="-a size=$FSSIZE"
        AFLAG=""
        [[ -n "$FSAGBS" ]] && AFLAG="-a agblksize=$FSAGBS"
        [[ -n "$AFLAG" && "$FSSPARSE" = "no" ]] && AFLAG="$AFLAG -a dense"
        [[ -z "$AFLAG" && "$FSSPARSE" = "no" ]] && AFLAG="-a dense"
        [[ -n "$AFLAG" && "$FSINLINE" = "yes" ]] && AFLAG="$AFLAG -a log=INLINE -a logsize=$FSINLINESZ"
        [[ -z "$AFLAG" && "$FSINLINE" = "yes" ]] && AFLAG="-a log=INLINE -a logsize=$FSINLINESZ"
        [[ -n "$AFLAG" && -n "$FSEAFORMAT" ]] && AFLAG="$AFLAG -a ea=$FSEAFORMAT"
        [[ -z "$AFLAG" && -n "$FSEAFORMAT" ]] && AFLAG="-a ea=$FSEAFORMAT"
        [[ -n "$AFLAG" && -n "$FSQUOTA" && "$FSQUOTA" != "no" ]] && AFLAG="$AFLAG -a quota=$FSQUOTA"
        [[ -z "$AFLAG" && -n "$FSQUOTA" && "$FSQUOTA" != "no" ]] && AFLAG="-a quota=$FSQUOTA"
        [[ -n "$AFLAG" && "$FSEFS" = "yes" ]] && AFLAG="$AFLAG -a efs=yes"
        [[ -z "$AFLAG" && "$FSEFS" = "yes" ]] && AFLAG="-a efs=yes"
    else
        VFLAG="-V jfs2"
        SFLAG=""; [[ -n "$FSSIZE" ]] && SFLAG="-s $FSSIZE"
        OFLAG=""
        [[ -n "$FSAGBS" ]] && OFLAG="-o agblksize=$FSAGBS"
        [[ -n "$OFLAG" && "$FSSPARSE" = "no" ]] && OFLAG="$OFLAG,dense"
        [[ -z "$OFLAG" && "$FSSPARSE" = "no" ]] && OFLAG="-o dense"
        [[ -n "$OFLAG" && "$FSINLINE" = "yes" ]] && OFLAG="$OFLAG,log=INLINE"
        [[ -z "$OFLAG" && "$FSINLINE" = "yes" ]] && OFLAG="-o log=INLINE"
        [[ -n "$OFLAG" && -n "$FSINLINESZ" ]] && OFLAG="$OFLAG,logsize=$FSINLINESZ"
        [[ -z "$OFLAG" && -n "$FSINLINESZ" ]] && OFLAG="-o logsize=$FSINLINESZ"
        [[ -n "$OFLAG" && -n "$FSEAFORMAT" ]] && OFLAG="$OFLAG,ea=$FSEAFORMAT"
        [[ -z "$OFLAG" && -n "$FSEAFORMAT" ]] && OFLAG="-o ea=$FSEAFORMAT"
        [[ -n "$OFLAG" && "$FSEFS" = "yes" ]] && OFLAG="$OFLAG,efs=yes"
        [[ -z "$OFLAG" && "$FSEFS" = "yes" ]] && OFLAG="-o efs=yes"
    fi
  fi

  if [[ "$DEVICE" != "" && $ALTERED_FS = 0 ]]; then
      echo "y" | LANG=C ${mkfs} $VFLAG $SFLAG $OFLAG $FSLV >/dev/null 2>&1
  else
      ${crfs} $CRFS_VFLAG -m $FSNAME -A"`locale nostr | awk -F: '{print $1}'`" -p rw -t"`locale nostr | awk -F: '{print $1}'`" $SFLAG $AFLAG -d $FSLV > /dev/null
  fi

  if [[ $? -ne 0 ]] && \
     [[ -n $DEVICE ]]
  then
      ${mv} $TMP_FILESYSTEMS /etc/filesystems       # Restore /etc/filesystems
      cleanup "$EXIT_EC" \
    "`${dspmsg} -s $MSGSET $MSGCAT 13 \
    '0512-034 %s: Failed creating the Filesystem %s.  Restore of Volume Group canceled.' $NAME $FSNAME`"
  fi
  [[ "$DEVICE" != "" && "$FSQUOTA" != "no" ]] &&  ${chfs} -a quota=$FSQUOTA $FSLV > /dev/null 2>&1
  if [ "$FSDMAPI" = "yes" ]
  then
      chfs -a managed=yes $FSNAME
      FSDMAPI="no"
  fi

# Check to see if vix is already set.
  if [ -n "$FSVIX" ]
  then
      set_vix=`LC_ALL=C /usr/sbin/lsjfs2 $FSNAME | \
               /usr/bin/tail +2l | ${awk} 'BEGIN{FS=":"} {print $20}'`
      if [ "$set_vix" != "$FSVIX" ]
      then
          chfs -a vix=$FSVIX $FSNAME
      fi
      FSVIX=""
  fi

done

############### Mount the newly created Filesystems  #####################

# Get list of Filesystems (sorted)
MNTLIST=`get_stanza_data "fs_data" "FS_NAME"  "" "FS_NAME" | sort`

for fs in $MNTLIST
do
  [ ! -d $fs ] &&  ${mkdir} -p $fs >/dev/null 2>&1   # create directory
  FSLV=`get_stanza_data "fs_data" "FS_NAME" $fs "FS_LV"`
  # Mount filesystem
  if [ -d $fs ]
  then
     # First look in filesystems file bundled with vg backup for log device,
     # else use LOGDEV, LOGDEV2, or INLINE log.
     EF_LOGDEV=`${grep} -p "^"${fs}: $VG_FILESYSTEMS | \
       ${grep} "[ 	]*log[ 	]*=[ 	]*" | ${awk} '{ print $3 }'`
     [ -n "$EF_LOGDEV" ] &&  ${mount} -o nomanager -o log=$EF_LOGDEV $FSLV $fs >/dev/null 2>&1
     if [ $? -ne 0 ]
     then
        [ -n "$LOGDEV" ] &&  ${mount} -o nomanager -o log=$LOGDEV $FSLV $fs >/dev/null 2>&1 
     else
        chfs -a log=$EF_LOGDEV $FSLV
        continue
     fi
     if [ $? -ne 0 ]
     then
        [ -n "$LOGDEV2" ] &&  ${mount} -o nomanager -o log=$LOGDEV2 $FSLV $fs >/dev/null 2>&1 
     else
        chfs -a log=$LOGDEV $FSLV
        continue
     fi
     if [ $? -ne 0 ]
     then
        ${mount} -o nomanager -o log=$FSLV $FSLV $fs >/dev/null 2>&1 
     else
        chfs -a log=$LOGDEV2 $FSLV
        continue
     fi
     if [ $? -ne 0 ]
     then
        cleanup "$EXIT_EC" \
        "`${dspmsg} -s $MSGSET $MSGCAT 14 \
        '0512-035 %s: Failed Mounting the Filesystem %s.  Restore of Volume Group canceled.' $NAME $fs`"
     else
        chfs -a log=INLINE $FSLV
     fi
  else
     cleanup "$EXIT_EC" \
     "`${dspmsg} -s $MSGSET $MSGCAT 14 \
     '0512-035 %s: Failed Mounting the Filesystem %s.  Restore of Volume Group canceled.' $NAME $fs`"
  fi
done

################ Filesystems Created And Mounted ##########################
### Before restoring files from media, check to see if we aren't supposed 
### to restore any files (-r option), also check if tape block size info
### exists, and if so, check and change block size if needed.
###########################################################################

if [[ $STRUCTFLAG = "yes" ]]; then
   # We are all finished! ( no restore )
   cleanup 0
fi

[[ $DEVICE = /dev/rmt+([0-9])\.[$NRWFLAGS] ]] && ${mt} -f $DEVICE bsf 1

RestoreRC=0
if [[ $tapedevice = yes ]]
then
    if [[ $tapeblksz_exists = yes ]]
    then
        if [[ -s $TAPEBLKSZ ]]
        then
            set -- `cat $TAPEBLKSZ`
	    TBLOCKSZ=$1
	    if [[ $TBLOCKSZ -ne $ZEROBLKSZ ]]
	    then
	        /usr/sbin/chdev -l $BASE_DEV1 -a block_size=$TBLOCKSZ >/dev/null 2>&1	
	    fi
	    ### Restore the Files from the media
	    ${restore} -xvqf $DEVICE $BOPT
	    RestoreRC="$?"

	    if [[ $OLDBLOCKSZ -ne $TBLOCKSZ ]]
	    then
	        /usr/sbin/chdev -l $BASE_DEV1 -a block_size=$OLDBLOCKSZ >/dev/null 2>&1
	    fi
        else  ## tapeblksz file is empty
        ### Reset block size to original value, if tapeblksz file is null
        ### and restore images
        [[ $OLDBLOCKSZ -ne $ZEROBLKSZ ]] && /usr/sbin/chdev -l $BASE_DEV1 -a block_size=$OLDBLOCKSZ >/dev/null 2>&1
        ${restore} -xvqf $DEVICE $BOPT
 	RestoreRC="$?"
        fi
    else ## image does not have tapeblksz file
    ### Reset block size to original value, if tapeblksz file is not included
    ### and restore images
        [[ $OLDBLOCKSZ -ne $ZEROBLKSZ ]] && /usr/sbin/chdev -l $BASE_DEV1 -a block_size=$OLDBLOCKSZ >/dev/null 2>&1
        ${restore} -xvqf $DEVICE $BOPT
	RestoreRC="$?"
    fi
elif [ $UNMOUNTCD -eq 1 ]
then
    # savevg on CD
    CDVOLUME=$(grep "^VOLUME=" $CDMOUNTPT/mkcd.data | cut -d= -f2)
    grep -q LASTVOLUME $CDMOUNTPT/mkcd.data
    [ $? -eq 0 ] && CDLASTVOLUME=yes

    # Check if CD is multivolume
    if [ "$CDLASTVOLUME" = "yes" ]
    then
	if [[ -s $DEVICE"2" ]]     ## Is the backup greater than 2GB DVD
	then
	(

                # This child process (subshell) will terminate eventually
                # if there is any error because of the way it is
                # written.  Don't need to check for return code from "dd"

		READ_LARGE_DVD=yes
		IMAGE1=yes
		while [ $READ_LARGE_DVD = yes ]; do
			if [ $IMAGE1 = yes ]
			then
				## Part 1 of greater than 2GB
				${dd} bs=2048 if=$DEVICE 2>/dev/null
				IMAGE1=no
			else
				## Part 2 of greater than 2GB
				${dd} bs=2048 if=$DEVICE"2" 2>/dev/null
				READ_LARGE_DVD=no
			fi
		done
	) | ${restore} -xvqSf -
	else
		${restore} -xvqf $DEVICE $BOPT
	fi
	RestoreRC="$?"
    else
	## Create a subshell to prompt for the CDs and dd the image
	## from each CD, which is piped to restbyname
	(
	while [ "$CDLASTVOLUME" = "no" ]; do
	    (( NEXTVOL = CDVOLUME + 1 ))
	    if [ $CDVOLUME -gt 1 ]; then
		${umount} $CDMOUNTPT >$WIN_OUT 2>&1
		volrc=255
		${dspmsg} BosMenus.cat -s 10 104 \
"Please remove volume %s, insert volume %s, and press the ENTER key.\n" \
		"$OLDCDVOLUME" "$CDVOLUME" > $WIN_OUT 2>&1
		read -u0 answer
		while [ $volrc -ne 0 ]; do
		    >/dev/null 2>&1 <$OLDDEVICE
		    if [ $? -eq 0 ]
		    then
			${mount} -rv $MEDIA_FILESYSTEM $OLDDEVICE $CDMOUNTPT
			if [ -s $CDMOUNTPT/mkcd.data ]
			then
			    NEWCDVOL=$(${grep} "^VOLUME=" $CDMOUNTPT/mkcd.data | cut -d= -f2)
			    if [ $NEWCDVOL -eq $CDVOLUME ]
			    then
				volrc=0
			    else
				${umount} $CDMOUNTPT >$WIN_OUT 2>&1
				${dspmsg} BosMenus.cat -s 10 104 \
"Please remove volume %s, insert volume %s, and press the ENTER key.\n" \
				"$NEWCDVOL" "$CDVOLUME" > $WIN_OUT 2>&1
				read -u0 answer
			    fi
	 		fi
		    fi
		done
		CDVOLUME=$(grep "^VOLUME=" $CDMOUNTPT/mkcd.data | cut -d= -f2)
		grep -q LASTVOLUME $CDMOUNTPT/mkcd.data > /dev/null 2>&1
		if [ $? -eq 0 ]; then
		    CDLASTVOLUME=yes
		fi
	    fi
	    OLDCDVOLUME=$CDVOLUME
 	    (( CDVOLUME = CDVOLUME + 1 ))
 	    ${dd} bs=2048 if=$CDMOUNTPT/usr/sys/inst.images/savevg_image 2>/dev/null

            # terminate child process (subshell), if "dd" encounters error
            #
            if [ $? -ne 0 ] ; then
               exit
            fi

		## >2GB of data on media DVD?
		if [ -s $DEVICE"2" ]
		then
			## Part two of > 2GB
			${dd} bs=2048 if=$CDMOUNTPT/usr/sys/inst.images/savevg_image2 2>/dev/null
                        # terminate child process (subshell), if "dd" encounters error
                        #
                        if [ $? -ne 0 ] ; then
                            exit
                        fi
		fi
	done
	) | ${restore} -xvqSf - 
	RestoreRC="$?"
    fi
else
    ${restore} -xvqf $DEVICE $BOPT
    RestoreRC="$?"
fi

if [ "$RestoreRC" -ne 0 ]
then
    echo "`${dspmsg} -s $MSGSET $MSGCAT 20 \
    '0512-051 %s: Restore Completed.\n\tThe restore command completed with errors.\n\tThe messages displayed on Standard Error contained additional\n\tinformation.\n' $NAME`"
fi

# Unmount and then remount filesystems to
# clear up managed filesystem information
for fs in `echo "$MNTLIST" | sort -r`
do
   ${umount} $fs
done

RemountRC=0
for fs in $MNTLIST
do
   FSLV=`get_stanza_data "fs_data" "FS_NAME" $fs "FS_LV"`
   ${mount} $FSLV
   RemountRC="$?"
   if [ "$RemountRC" -ne 0 ]
   then
      echo "`${dspmsg} -s $MSGSET $MSGCAT 20 \
      '0512-052 %s: Failed mounting the filesystem %s\nafter the restore of the volume group.\nPlease correct the mount point, and mount after the remake\nof the volume group is complete.\n' $NAME $fs`"
      RemountRC=0
   fi
   ${grep} -q $fs: $VG_FILESYSTEMS
   # If filesystem name is not in /tmp/vgdata/<vgname>/filesystems
   # then it was altered when links were removed.
   if [ $? -ne 0 ]
   then
      ${umount} $FSLV
      FS_ORIG=$( ${sed} '/:$/i\
' $VG_FILESYSTEMS | ${grep} -p "[ 	]*"$FSLV"[ 	]*" | ${head} -n1 | ${awk} 'BEGIN{FS=":"} {print $1}' )
      ${mount} $FS_ORIG
      RemountRC="$?"
      if [ "$RemountRC" -ne 0 ]
      then
         echo "`${dspmsg} -s $MSGSET $MSGCAT 20 \
         '0512-052 %s: Failed mounting the filesystem %s\nafter the restore of the volume group.\nPlease correct the mount point, and mount after the remake\nof the volume group is complete.\n' $NAME $fs`"
      fi
   fi

done

### Preserve disable QUORUM attribute on volume group
QUORUM=`get_stanza_data "vg_data" "VGNAME" $VG "QUORUM"`
	if [[ "$QUORUM" -eq 1 ]]
	then
		${chvg} -Q n $VG
	fi

### Get any post exec file to exec
POST_EXEC=`get_stanza_data "post_restvg" "RESTVG_FILE"  "" "RESTVG_FILE"`
$POST_EXEC         ## execute any file specified

cleanup 0