#!/bin/ksh
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# bos72V src/bos/usr/bin/mkszfile/mkszfile.sh 1.42.17.24 
#  
# Licensed Materials - Property of IBM 
#  
# COPYRIGHT International Business Machines Corp. 1989,2020 
# 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 
# @(#)801.42.17.24 src/bos/usr/bin/mkszfile/mkszfile.sh, cmdbsys, bos72V, v2020_34A8 8/17/20 09:07:00
#
# COMPONENT_NAME: (CMDBSYS)
#
# FUNCTIONS: mkszfile.sh
#
# ORIGINS: 27
#
# (C) COPYRIGHT International Business Machines Corp. 1989, 1997
# 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: mkszfile
#   NOTE: mkvgdata and mkwpardata are "symbolic" links to mkszfile command.
#
# FILE DESCRIPTION: High-level shell command for creating the Volume
#   Group(VG) or Workload Partition (WPAR) Data file. 
#   This file captures the Volume Group characteristics; the Physical 
#   Volumes (and sizes) in the VG, 
#   all the  characteristics of the non-jfs Logical Volumes and MOUNTED
#   Filesystems (jfs Logical Volumes) associate with the VG or WPAR.
#   This will exclude NFS, CD-ROM, and other "special" file systems.

#   If the Volume Group is the rootvg, then the System LANG environment
#   variable is also captured.
#   Specifying the "-X" flag, will cause mkszfile to expand the /tmp
#   file system if needed for work space.
#   Specifying the "-m" flag, will cause mkszfile to generate "maps" of
#   the physical layout of the physical partitions used by each Logical
#   Volume.
#   Mkszfile will determine if there is sufficient work space available
#   in the file systems for the image data file and logical volume map
#   file(s) and also (for rootvg) will determine if enough work space is
#   available in /tmp to generate a Boot image.
#   For user Volume Groups, the image data file and map file(s) are all
#   created in the /tmp filesystem, in Directory /tmp/vgdata/<vgname>/
#   For the rootvg Volume Group, the image data file is placed in the
#   / filesystem and map file(s) are created in the /tmp/vgdata/rootvg/
#   directory.
#   For workload partitions, the image data file and map file(s) are 
#   all created in the /tmp filesystem, in directory /tmp/wpardata/<wparname>.
#
# INPUT FLAGS:
#        -X  Expand /tmp if needed.
#        -m  Generate Physical Partition Location Data
#        -G  Global only.  Excludes WPAR file systems (mkszfile only)
#        -N  Mounts filesystems in WPARS in the Defined state
#        VGname  Name of VG to generate data on (mkvgdata only)
#        WPARName Name of WPAR to generate data on (mkwpardata only)
#        NOTE: the -f flag for the mkszfile command is no longer used, for
#              compatibility to existing scripts, the -f flag will be
#              excepted from the commandline but no action will be taken
#              and no error will be returned.
#
# OUTPUT:
#        Error messages (Standard Error)
#        Image Data file (/image.data for rootvg or
#                   /tmp/vgdata/<vgname>/<vgname>.data for user VGs or
#                   /tmp/wpardata/<wparname>/image.data for WPARs)
#        Map Files in /tmp/vgdata/<vgname>/<LVname>.map or
#                   /tmp/wpardata/<wparname>/<LVname>.map for WPARs
#
# RETURN VALUE DESCRIPTION:
#                             0         Successful
#                             non-zero  Unsuccessful
#
# EXTERNAL PROCEDURES CALLED: lsvg, lslv, lsjfs, lsjfs2, df, bootinfo
#				bosboot
#
# GLOBAL VARIABLES: none
#
########################## Function Declarations #########################

############################## canonical #####################################
#
# NAME: canonical()
#
#
# DESCRIPTION: output the pathname in canonical form - rebased to the
#              root directory for the entity being backed up.  This is
#              only of interest for mkwpardata
#
# INPUT:
#        $1 = pathname
#
# OUTPUT:
#        Rebased pathname
#
##########
canonical ()
{
    fn=$1
 
    if [ "$NAME" != "mkwpardata" ]
    then
       echo $fn
    else
       if [ "$fn" = "$WPAR_BASE" ]
       then
	   echo /
       else
           echo $fn | ${sed} "s:$WPAR_BASE::"
       fi
    fi
}

############################## cleanup_m #####################################
#
# NAME: cleanup_m()
#
#
# 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 exit value of $1)
##########
cleanup_m ()
{
ec=$1
error=$2

[ -n "$PID" ] && kill $PID >/dev/null 2>&1
[[ "$ec" !=  "0" ]] && echo

case "$ec"
in
   "$USAGE_SZ")    # mkszfile usage error
	   error="`${dspmsg} -s $MSGSET $MSGCAT 37 '
Usage:  %s [-X] [-d directory] [-m] [-G | -N] [-x filename]\n\n\
-X\tExpand /tmp if needed.\n\
-d directory\tDirectory to contain image.data file.\n\
-m\tGenerate Physical Partition maps.\n\
-G\tExcludes file systems for WPARS in the image.data file.\n\
-N\tIncludes file systems for WPARS in the Defined state in the image.data file.\n\
-x filename\tExcludes file systems listed in file.\n\n ' $NAME`" 1>&2 ;;

   "$USAGE_VG" | "$INVALID_VG")    # mkvgdata usage error
	   if [ "$ec" = "$INVALID_VG" ]
	   then
	   ${dspmsg} -s 1 $MSGCAT 6 \
	   "0512-009 %s: Invalid or missing Volume Group Name.\n\n" $NAME 1>&2
	   fi
	   error="`${dspmsg} -s $MSGSET $MSGCAT 40 '
Usage:  %s [-X] [-m] [-x filename] vgname\n
-X\tExpand /tmp if needed.\n\
-m\tGenerate Physical Partition maps.\n\
-x filename\tExcludes file systems listed in file.\n\
vgname\tName of volume group to backup.\n\n' $NAME`" 1>&2 ;;

   "$FILE_EC")    # Error creating a file or directory
	   error="`${dspmsg} -s $MSGSET $MSGCAT 22  \
		'0512-022 %s: An Error occurred creating the Image Data File or
the Physical Partition Map Files. Make sure you have write permission
to the /tmp and / directories.\n\n' $NAME`" ;;

   "$USAGE_WP" | "$INVALID_WPAR")    # mkvgdata usage error
	   if [ "$ec" = "$INVALID_WPAR" ]
	   then
	   ${dspmsg} -s 1 $MSGCAT 72 \
	   "0512-065 %s: Invalid or missing Workload Partition Name.\n\n" $NAME 1>&2
	   fi
	   error="`${dspmsg} -s $MSGSET $MSGCAT 32 '
Usage:  %s [-X] [-m] wparName\n\n\
-X\t\tExpand /tmp if needed.\n\
-m\t\tGenerate Physical Partition maps\n\
wparName\tName of workload partition to backup.\n\n' $NAME`" 1>&2 ;;



   *)      ;;      # Error Message Passed in, in $2

esac

# Cleanup locks and unmount file systems mounted by mkwpardata
if [  $NAME = "mkwpardata" ] && [ "$ec" != "$USAGE_WP" ] && \
   [ "$ec" != "$INVALID_WPAR" ] && [ "$ec" != "$LOCK_EC" ] && \
   [ "$ec" != "$INSIDE_WPAR" ]
then
        cd /
        # If any filesystems were mounted by this process, unmount them in
        # reverse order.
        typeset i=${#DEVS_MOUNTED[*]}
        while [[ $i -gt 0 ]]; do
                i=$((i-1))
                unmount_dev ${DEVS_MOUNTED[$i]}
        done
fi

# Remove $WORKDIR, if any, created by init_baselib while using mkwpardata
if [ $NAME = "mkwpardata" ] && [ -n "$WORKDIR" ] 
then
    rm -rf "$WORKDIR" > /dev/null 2>&1
fi

### Unmount filesysms of WPARS in the Defined State ######
if [ $NNFLAG = "yes" ]
then
        unmount_wpar_fs
fi

[[ "$ec" !=  "0" ]] && echo "\n${error}\n"
trap '' 1 2 15
exit "$ec"
}

##########################################################
fail_if_wpar ()
{
    # Check to make sure that this is running in the
    # global environment or in the rootvg wpar.
    if [[ "$WPARID" != "0" ]]; then
        if [[ "$NAME" = "mkwpardata" ]]; then
            cleanup_m "$INSIDE_WPAR" \
                "`${dspmsg} -s 1 wpars.cat 484 \
                '%s: 0960-540  Operation is not permitted in a workload partition.' $NAME`"
        fi
        ${lsvg} rootvg >/dev/null 2>&1
        if [[ $? -ne 0 ]] && [[ "$NAME" = "mkszfile" ]]; then
            cleanup_m "$INSIDE_WPAR" \
                "`${dspmsg} -s 1 wpars.cat 550 \
		'%s: 0960-612  Operation is not permitted in a workload partition with no rootvg.' $NAME`"
        fi
        TMP_OUT=$(${lsvg} 2>/dev/null)
        if [[ -z $TMP_OUT ]]; then
            cleanup_m "$INSIDE_WPAR" \
		"`${dspmsg} -s 1 wpars.cat 551 \
		'%s: 0960-613  Operation is not permitted in a workload partition with no volume group.' $NAME`"
        fi
    fi
}

###########################  getoptions  ##################################
#
# NAME: getoptions()
#
# DESCRIPTION: parse the commandline arguements, check prerequsites: usage
#
# INPUT:
#        $* = the commandline arguements
#
# OUTPUT:
#        sets variables FORCE and MAPS
#
# RETURN VALUE DESCRIPTION:
#        exits on error or
#        returns successful to program
##########
getoptions()
{
    if [ $NAME = "mkszfile" ]
    then
       set -- `${getopt} Xd:fmGNx: $*`     # mkszfile options
    elif [ $NAME = "mkvgdata" ]
    then
       set -- `${getopt} Xmx: $*`        # mkvgdata options
    else
       set -- `${getopt} Xm $*`        # mkwpardata options
    fi
    if [ "$1" == "" ]
    then
	 cleanup_m "$USAGE_EC" ""
    fi

    while [ $1 != -- ]         ## Parse flag arguements
    do
	    case $1 in
		    "-X")   XXFLAG="-X"  ;;	#Expand /tmp if needed
		    "-d")   IMG_DIR=$2     # Alternate output directory
                            shift;;
		    "-f")   ;;       ## No-op, no error - continue
		    "-m")   MAPS="yes"  ;;
		    "-N")   NNFLAG="yes" ;;
		    "-G")   XWPARFLAG="yes" ;;
		    "-x")   XFSLIST=$2    # File system exclusion list
                            shift;;
		     *) cleanup_m "$USAGE_EC" "";;
	    esac
	    shift
    done

    if [[ $NNFLAG = "yes" && "$XWPARFLAG" = "yes" ]]
    then
       cleanup_m "$USAGE_EC"
    fi

    if [[ -n "$IMG_DIR" ]] && ( [[ ! -d "$IMG_DIR" ]] || [[ ! -w "$IMG_DIR" ]] )
    then
       cleanup_m "$INVALID_DIR" "`${dspmsg} -s $MSGSET $MSGCAT 38 '0512-071 %s: Cannot create %s.\n' $NAME ${IMG_DIR}/image.data`"
    fi

    if [[ -n "$XFSLIST" ]] && [[ ! -f "$XFSLIST" ]]
    then
       cleanup_m "$INVALID_FILE" "`${dspmsg} -s $MSGSET $MSGCAT 39 '0512-072 %s: Cannot access %s.\n' $NAME ${XFSLIST}`"
    fi

    if [ $NAME = "mkszfile" ]
    then
	 VG="rootvg"
    elif [ $NAME = "mkwpardata" ]
    then
	 set `${getopt} $*`     #Get Name of WPAR to Backup.
	 WPAR=$1
	 [ "$WPAR" = "" ]  && cleanup_m "$INVALID_WPAR" ""  # valid WPAR name?
	 [[ `${lswpar} -qca type $WPAR  2>/dev/null` != 'S' ]] && \
		cleanup_m "$INVALID_WPAR" ""
	 WPAR_BASE=`${lswpar} -qca directory $WPAR`

	 # Load WPAR and install shell utilities
	 . /usr/lib/wpars/libcor_sh || return 1
	 init_baselib `basename $0` || return 1
	 cor_init_vars
	 export GLOBALCMD="mkwpardata" # GLOBALCMD is used by wpar lock facility

         mount_wpar_fs 

    else
	 set `${getopt} $*`     #Get VG Name of VG to Backup.
	 VG=$1
	 [ "$VG" = "" ]  && cleanup_m "$INVALID_VG" ""  # valid VG name?
	 ${lsvg} $VG  >/dev/null  2>&1
	 [ $? -ne 0 ] &&  cleanup_m "$INVALID_VG" ""
     fi
}

###########################  mk_mapfile  ##################################
#
# NAME: mk_mapfile()
#
# DESCRIPTION: Creates the map files
#
# INPUT:
#        $1 = lv_name (i.e. hd1)
#
# OUTPUT:
#        map files created for the lv in the $DATA_DIR directory
#        map file name is $LV_NAME.map
#
# RETURN VALUE DESCRIPTION:
#        returns sucessful

mk_mapfile()
{
      LV_NAME=$1
      ${rm} -f $DATA_DIR/$LV_NAME.map     # remove any old map data
      set -- `LC_ALL=C ${lslv} -m $LV_NAME | ${grep} "^0001"`
      CP1=$2          # 1st copy of LV
      CP2=$4          # 2nd copy of LV (mirror)
      CP3=$6          # 3rd copy of LV (2nd mirror)
      [ -n "$CP1" ] && LC_ALL=C ${lslv} -m $LV_NAME | ${tail} +3l | ${awk} '{print $3 ":" $2}' > $DATA_DIR/$LV_NAME.map
      [ -n "$CP2" ] && LC_ALL=C ${lslv} -m $LV_NAME | ${tail} +3l | ${awk} '{print $5 ":" $4}' >> $DATA_DIR/$LV_NAME.map
      [ -n "$CP3" ] && LC_ALL=C ${lslv} -m $LV_NAME | ${tail} +3l | ${awk} '{print $7 ":" $6}' >> $DATA_DIR/$LV_NAME.map
}

###########################  mount_wpar_fs ################################
#
# NAME: mount_wpar_fs()
#
# DESCRIPTION: Mounts unmounted wpar file systems if necessary.  Uses
#              libcor_sh functions
#
# INPUT:
#        none - $WPAR must be set
#
# OUTPUT:
#        DEVS_MOUNTED array is set if any file systems had to be mounted
#
# RETURN VALUE DESCRIPTION:
#        not set

mount_wpar_fs()
{
         # If WPAR is not active, need to mount the file systems
         WPARSTATE=`${lswpar} -qca state $WPAR`
         case "$WPARSTATE" in
             'A') ;;
             'D') # Mount file systems.  If any are mounted as a result
                  # then FS_MOUNTED will be set to 1, and DEVS_MOUNTED
                  # will be set to the list of mounts which were
                  # performed.  If it fails, it will error off
                 cor_mount_fs $WPAR >/dev/null
                 ;;
         esac
}

###################################
#
#  input:  logical volume 's name (like /dev/abc)
#
#  ouput:  type of fs created on lv
#
###################################

function get_fs_type
{
  typeset    lv=$1
  typeset    fs_type=""
  typeset    str=""
  typeset    field=""
  typeset -i i=0

  str=$(LC_ALL=C lsfs -c $lv | grep $lv)

  OLD_IFS=$IFS
  IFS=":"
  for field in $str
  do
     (( i = i + 1 ))
     if [[ $i -eq 3 ]] ; then
        fs_type=$field
        break
     fi
  done
  IFS=$OLD_IFS
  echo $fs_type
}


########################## Function Declarations #########################

################################# main ########################################
#
# set up environment
#

if [ "$MKSZDEBUG" ]; then
 set -x
   for i in $(typeset +f); do
      typeset -ft $i
   done
fi

export PATH="/usr/bin:/usr/sbin:/etc:$PATH"
NAME=`/usr/bin/basename $0`       # Command invoked mkszfile, mkvgdata, or mkwpardata
MSGCAT=mksysb.cat        # message catalog name
MSGSET=2
USAGE_SZ=1              # mkszfile usage err exit code
USAGE_VG=2              # mkvgdata usage err exit code
USAGE_WP=9              # mkwpardata usage err exit code
USAGE_EC=$USAGE_SZ      # set mkszfile usage error
[ $NAME = "mkvgdata" ] && USAGE_EC=$USAGE_VG    # set mkvgdata usage error
[ $NAME = "mkwpardata" ] && USAGE_EC=$USAGE_WP  # set mkwpardata usage error

NO_SPACE_EC=3          # No Space err exit code
TRAP_EC=4              # Trap/Interrupt Encountered err exit code
INVALID_VG=5           # invalid VG specified for mkvgdata
FILE_EC=6              # Error creating a file or dir
OTHER_VGS=7             # Error saving other VG data 
INVALID_WPAR=10        # invalid WPAR specified for mkwpardata
INSIDE_WPAR=11         # command running inside a WPAR 
LV_FS_TYPE_ERR=12      # mismatched type between fs and lv 
BOSBOOT_EC=13         # bosboot returns error
INVALID_DIR=14         # invalid directory specified for image.data

ONEMEG=1048576         # One Meg to use for calculations
SIXTEEN_MB=32768       # Minimum jfs2 size
ONE_K=1024             # 1 Kbytes
FOUR_K=4096            # 4 Kbytes - Min size of file
BLK_SZ=512             # Block Size used for calculations
MIN_FILE_BLKS=8        # Minimum Num. of blks allocated per file
MAPS="no"              # Do not generate Maps (Default)
NNFLAG="no"            # Do not mount filesystem for WPARS in the Defined State
XWPARFLAG="no"         # Exclude WPAR filesystems (Default is no)
stripewarn=		# Set to yes, if maps in use and striped lv's
VG="_"
WPAR_LV_SIZE=0	
IMG_DIR=               # Directory to hold image.data file
XFSLIST=               # File containing list of file systems to exclude
PID= 		       # Initializing PID variable

##    Full-Path to commands used
awk=/usr/bin/awk
cp=/usr/bin/cp
cut=/usr/bin/cut
date=/usr/bin/date
df=/usr/bin/df
dspmsg=/usr/bin/dspmsg
expr=/usr/bin/expr
fsdb=/usr/sbin/fsdb
getlvcb=/usr/sbin/getlvcb
getlvodm=/usr/sbin/getlvodm
getopt=/usr/bin/getopt
grep=/usr/bin/grep
mkdir=/usr/bin/mkdir
rm=/usr/bin/rm
tail=/usr/bin/tail
wc=/usr/bin/wc
uname=/usr/bin/uname
bootinfo=/usr/sbin/bootinfo
bosboot=/usr/sbin/bosboot
lqueryvg=/usr/sbin/lqueryvg
lquerylv=/usr/sbin/lquerylv
lsattr=/usr/sbin/lsattr
lsdev=/usr/sbin/lsdev
lsjfs=/usr/sbin/lsjfs
lsjfs2=/usr/sbin/lsjfs2
lslv=/usr/sbin/lslv
lsfs=/usr/sbin/lsfs
lsvg=/usr/sbin/lsvg
lswpar=/usr/sbin/lswpar
mkwpar=/usr/sbin/mkwpar
mount=/usr/sbin/mount
lslpp=/usr/bin/lslpp
egrep=/usr/bin/egrep
oslevel=/usr/bin/oslevel
sed=/usr/bin/sed
sort=/usr/bin/sort


WPARID=`/usr/bin/uname -W`
# Disallow in a workload partition
fail_if_wpar
BLK_SZ2=`${expr} $ONEMEG \/ $BLK_SZ`
if [[ $SAVEWPAR -ne 1 ]]; then
    PLATFORM=`${bootinfo} -p`
fi
	#
	# Trap on exit/interrupt/break to clean up
	#
trap "cleanup_m $TRAP_EC \"`${dspmsg} -s 1 $MSGCAT 4 '0512-007 %s: Abnormal program termination.' $NAME`"\"  1 2 15

getoptions $*               # parse commandline arguements

###################################################################
## Load cmdbsys_lib functions (just if we -N flag is selected).
###################################################################
if [ "$NNFLAG"="yes" ]
then
   . /usr/lpp/bosinst/cmdbsys_lib
fi

# Establish data repository variables
if [ $NAME != mkwpardata ]
then 
      DATA_BASEDIR=/tmp/vgdata      # base data Directory
      DATA_DIR=$DATA_BASEDIR/$VG    # vg data Directory
      if [[ "$WPARID" != "0" ]] && [[ "$NAME" = "mkszfile" ]] 
      then
           MAP_DIR=./.savewpar_dir         # lv map files Directory - relative to rootvg wpar restore directory
      else
           MAP_DIR=$DATA_DIR		    # lv map files Directory
      fi 
      if [ $VG = "rootvg" ]
      then
          VG_DATA=${IMG_DIR}/image.data # Rootvg image data file
      else
          VG_DATA=$DATA_DIR/$VG.data    # User vg image data file
      fi
      ###################################################################
      ## Generate logical volume list, (LVs potentially excluded later)
      ###################################################################
      VGLIST=$VG
      LVLIST=`LC_ALL=C ${lsvg} -l $VG | ${tail} +3l |${awk} '{ if ( -n $3 ) {print $1} }'`
else
      DATA_BASEDIR=/tmp/wpardata      # base data Directory
      DATA_DIR=$DATA_BASEDIR/$WPAR    # image.data Directory
      MAP_DIR=./.savewpar_dir         # lv map files Directory - relative to
                                      # wpar restore directory
      FSLIST=`${lswpar} -qcM -a vfs,mountpoint $WPAR | ${grep} ^jfs | ${cut} -d: -f2`
      LVLIST=`${lswpar} -qcM -a vfs,device $WPAR | ${grep} ^jfs | ${cut} -d: -f2 | sed 's:/dev/::'`
      VGLIST=`for lv in $LVLIST
              do
                 ${lslv} $lv | head -1 | ${awk} '{print $NF}' 
              done | ${sort} -u`
      VG_DATA=$DATA_DIR/image.data  # image.data output file
      # If there are no LVs (remote file systems only), disable maps
      [ -n "$LVLIST" ] || MAPS="no"
fi 
FS_TMP=$DATA_DIR/fs_data_tmp  # temp fs_data
FS_MOUNT=$DATA_DIR/mount_tmp  # temp mount list

#

ROOT_LV=`LC_ALL=C ${df} / | ${tail} +2l | ${awk} '{ if ( (length($7) == 1) && ($1 ~ /dev/) ) { gsub ("/dev/", "", $1); print $1 } }' `
TMP_LV=`LC_ALL=C ${df} /tmp | ${tail} +2l | grep /dev | ${awk} '{gsub ("/dev/", "", $1); print $1}' `
FREETMPBLKS=`LC_ALL=C ${df} /dev/$TMP_LV | ${tail} +2l | ${awk} '{print $3}'`

# about 735 bytes for "Single Entry" stanzas
IMAGE_DATA_SZ=735
for VG in $VGLIST
do
 VGID=`${getlvodm} -v $VG`
 ###################################################################
 #
 #     ESTIMATE size of the VG.DATA file (in num of Partitions)
 #
 ### Estimate of bytes needed for "source_disk_data" stanzas
 SP_HDISK=`${lqueryvg} -g $VGID -c 2>/dev/null| ${awk} '{print $1 * 160}'` # about 160 bytes
						        ##  per hdisk
 SP_LV=`${lqueryvg} -g $VGID -n 2>/dev/null| ${awk} '{print $1 * 606}'`  # about 606 bytes
						        ## per Logical Volume
 ### Estimate of bytes needed for "fs_data:" stanzas
 SP_FS=`LC_ALL=C ${lsvg} -l $VG | ${awk} '$2 ~/jfs/ { print $1 } ' |  # about 1200 bytes
		 ${wc} -l | ${awk} '{print $1 * 1200}'`       ## per filesystem
 ### Add up all stanza values for estimate of # bytes for the image.data
 (( IMAGE_DATA_SZ = IMAGE_DATA_SZ + SP_HDISK + SP_LV + SP_FS ))
done


#### Convert IMAGE_DATA_SZ to 512 byte blks (rounded up)
  ADD_ONE=0
  REM=`${expr} $IMAGE_DATA_SZ % $BLK_SZ` && ADD_ONE=1
  IMAGE_DATA_SZ=`${expr} $IMAGE_DATA_SZ \/ $BLK_SZ`
  IMAGE_DATA_SZ=`${expr} $IMAGE_DATA_SZ \+ $ADD_ONE`
  REM=`${expr} $IMAGE_DATA_SZ % $MIN_FILE_BLKS` &&  \
			  REM=`${expr} $MIN_FILE_BLKS \- $REM`
  IMAGE_DATA_SZ=`${expr} $IMAGE_DATA_SZ \+ $REM`
#### Add in the size of the WPAR specification file for mkwpardata
  if [ $NAME = mkwpardata ]
  then 
      WPAR_SPEC_SZ=`${mkwpar} -e $WPAR -W -w -o - | ${wc} -c`
      if [[ $WPAR_SPEC_SZ -eq 0 ]]
      then
		cleanup_m "$NO_SPACE_EC"   #MJS
      fi
      #### Convert WPAR_SPEC_SZ to 512 byte blks (rounded up)
      REM=`${expr} $WPAR_SPEC_SZ % $BLK_SZ` && ADD_ONE=1
      WPAR_SPEC_SZ=`${expr} $WPAR_SPEC_SZ \/ $BLK_SZ`
      WPAR_SPEC_SZ=`${expr} $WPAR_SPEC_SZ \+ $ADD_ONE`
      REM=`${expr} $WPAR_SPEC_SZ % $MIN_FILE_BLKS` &&  \
			      REM=`${expr} $MIN_FILE_BLKS \- $REM`
      WPAR_SPEC_SZ=`${expr} $WPAR_SPEC_SZ \+ $REM`
      IMAGE_DATA_SZ=`${expr} $IMAGE_DATA_SZ \+ $WPAR_SPEC_SZ`
  fi

###   If excluding WPAR file systems, add in more space for the WPAR LV 
###   list.
      if [[ "$XWPARFLAG" = yes ]]
      then
         WPAR_LV_SIZE="`${lswpar} -M -qca vfs,device 2>/dev/null | ${grep} "^jfs" | ${awk} -F: '{print $2}' | ${wc} -c`"
         #### Convert WPAR_LV_SIZE to 512 byte blks (rounded up)
         REM=`${expr} $WPAR_LV_SIZE % $BLK_SZ` && ADD_ONE=1
         WPAR_LV_SIZE=`${expr} $WPAR_LV_SIZE \/ $BLK_SZ`
         WPAR_LV_SIZE=`${expr} $WPAR_LV_SIZE \+ $ADD_ONE`
         REM=`${expr} $WPAR_LV_SIZE % $MIN_FILE_BLKS` &&  \
			      REM=`${expr} $MIN_FILE_BLKS \- $REM`
         WPAR_LV_SIZE=`${expr} $WPAR_LV_SIZE \+ $REM`
      fi
###################################################################
  MUSTHAVE_TMP_BLKS=$IMAGE_DATA_SZ

if [ $VG = "rootvg" ] && [ $NAME != mkwpardata ] && [ "$WPARID" = "0" ] # Check for space for /image.data file
then
      FREEROOTBLKS=`LC_ALL=C ${df} / | ${tail} +2l | ${awk} '{ if ( length($7) == 1 ) {print $3} }'`
      if [ "$FREEROOTBLKS" -lt "$IMAGE_DATA_SZ" ]
      then
		KBYTES=`${expr} $IMAGE_DATA_SZ \/ 2 ` #Convert to KBytes
		REM=`${expr} $IMAGE_DATA_SZ \% 2`
		[ "$REM" -ne 0 ] && KBYTES=`${expr} $KBYTES \+ 1` 
		cleanup_m "$NO_SPACE_EC" \
		"`${dspmsg} -s $MSGSET $MSGCAT 18 \
		'0512-018 %s: The backup could not continue because the %s Kbytes
of free work space on the / filesystem that are necessary
were not found.  Before you reissue this command, you
should extend the / filesystem (chfs) or free up space to provide a
total of %s Kbytes of free work space in the / filesystem.\n\n' $NAME $KBYTES $KBYTES`"
      fi

      # Get space needed for bosboot, required at mksysb and bosinstall time
      if [ -c /dev/ipldevice ]; then
         B_OPTS=" -qvd /dev/ipldevice "
      else
         B_OPTS=" -qv "
      fi
      BOOT_BLKS=`LC_MESSAGES=C ${bosboot} $B_OPTS | ${tail} -1l | ${awk} '{print $2 * 2}'`
      if [ "$BOOT_BLKS" = "" ]; then
         cleanup_m $BOSBOOT_EC ""
      fi

      # Worst case scenario is a tape device
      #   Note: if no tape device in PdDv then bosboot error msg goes to null and
      #         return value is less then above bosboot call.
      TAPE_BLKS=`LC_MESSAGES=C ${bosboot} -qvd /dev/rmt 2>/dev/null | ${tail} -1l | ${awk} '{print $2 * 2}'`
            [ "$TAPE_BLKS" -gt "$BOOT_BLKS" ] && BOOT_BLKS=$TAPE_BLKS
      MUSTHAVE_TMP_BLKS=`${expr} $MUSTHAVE_TMP_BLKS + $BOOT_BLKS`

else

###   For non-rootvg, need space in /tmp for /etc/filesystems
      filesystem_size=`${wc} -c /etc/filesystems | ${awk} '{print $1}'`
      #### Convert IMAGE_DATA_SZ to 512 byte blks (rounded up)
      ADD_ONE=0
      (( REM=$filesystem_size % $BLK_SZ )) && ADD_ONE=1
      (( filesystem_size = $filesystem_size / $BLK_SZ ))
      (( filesystem_size = $filesystem_size + $ADD_ONE ))
      (( REM=$filesystem_size % $MIN_FILE_BLKS )) && \
            (( REM=$MIN_FILE_BLKS - $REM ))
      (( filesystem_size = $filesystem_size + $REM ))

      #### Convert IMAGE_DATA_SZ to 512 byte blks (rounded up)
      ADD_ONE=0
      (( REM=$filesystem_size % $BLK_SZ )) && ADD_ONE=1
      (( filesystem_size = $filesystem_size / $BLK_SZ ))
      (( filesystem_size = $filesystem_size + $ADD_ONE ))
      (( REM=$filesystem_size % $MIN_FILE_BLKS )) && \
            (( REM=$MIN_FILE_BLKS - $REM ))
      ###################################################################

###   Sum of image_data and filesystem space needs
      (( MUSTHAVE_TMP_BLKS = $MUSTHAVE_TMP_BLKS + $filesystem_size ))

fi

################################################################
#     ESTIMATE size needed for the MAP files
#
if [ "$MAPS" = "yes" ]      # calculate space needed for the maps
then
    MAP_BLKS=`LC_ALL=C ${lsvg} -l $VG | ${tail} +3l | \
${grep} -v "pmhibernation" | ${awk} 'BEGIN{x=0} {
		    y = $4 * 12
		    if ( y <= '$FOUR_K' )
		       x++
		    else
		    {   x += (y % '$FOUR_K') ?  \
				 (int(y / '$FOUR_K') + 1) : \
				 int(y / '$FOUR_K')
		     }
		   }
		   END{ print (x * '$MIN_FILE_BLKS')}'`
    MUSTHAVE_TMP_BLKS=`${expr} $MUSTHAVE_TMP_BLKS \+ $MAP_BLKS `
fi

##############################################
#
#      ###   CHECK IF ENOUGH FREE SPACE EXISTS IN /tmp    ######
#

if [ $FREETMPBLKS -lt $MUSTHAVE_TMP_BLKS ]
then
     KBYTES=`${expr} $MUSTHAVE_TMP_BLKS \/ 2 ` #Convert to KBytes
     REM=`${expr} $MUSTHAVE_TMP_BLKS \% 2`
     [ "$REM" -ne 0 ] && KBYTES=`${expr} $KBYTES \+ 1` 

     if [ -n "$XXFLAG" ] 
     then
	((EXPAND_BLKS = MUSTHAVE_TMP_BLKS - FREETMPBLKS))
	dspmsg -s 1 $MSGCAT 29 'Expanding /tmp.\n'
         chfs -a size=+$EXPAND_BLKS /tmp
             if [[ $? != 0 ]]
             then
         	 cleanup_m "$NO_SPACE_EC" \
                 "`dspmsg -s $MSGSET $MSGCAT 26 \
'0512-041 %s: The /tmp file system could not be expanded.\n' $NAME`"
             fi
     else

         cleanup_m "$NO_SPACE_EC" \
         "`${dspmsg} -s $MSGSET $MSGCAT 23 \
         '0512-023 %s: The backup could not continue because the %s KBytes
of free work space in the /tmp filesystem that are necessary
were not found.  To make backup, do one of the following:
\t  (1) Specify that the /tmp filesystem can be expanded.  
\t      (From the commandline, specify the -X option.)
\t  (2) Use the chfs command to extend the /tmp filesystem.
\t  (3) Free up space to provide a total of %s Kbytes of free work space
\t      in the /tmp filesystem.\n\n' $NAME $KBYTES $KBYTES`"
     fi

fi   ### End of TMP space check

########## We GOT enough  space to continue

${mkdir} -p $DATA_DIR
[ "$?" != 0 ] && cleanup_m "$FILE_EC" ""
${rm} -fr $DATA_DIR/*			## Clean any old data files
if [ $VG != "rootvg" ] || [ "$NAME" = "mkwpardata" ]
then
  ${cp} /etc/filesystems $DATA_DIR
fi

if [[ "$WPARID" != "0" ]] && [[ "$NAME" = "mkszfile" ]] 
then
    typeset WPAR=`uname -n`
    echo wpar $WPAR > $DATA_DIR/image.info
else
    # Write image type information file
    case "$NAME" in
        "mkszfile")   echo rvg rootvg > $DATA_DIR/image.info;;
        "mkvgdata")   echo uvg $VG > $DATA_DIR/image.info;;
        "mkwpardata") echo wpar $WPAR > $DATA_DIR/image.info;;
        *)            echo unknown $VG > $DATA_DIR/image.info;;
    esac
fi

###########  Save Estimated Minimum  /tmp sizes

TMP_MIN_FS_SZ=`LC_ALL=C ${df} -IM /dev/$TMP_LV | ${tail} +2l | ${awk} '{print $4 + '$MUSTHAVE_TMP_BLKS'}'`
ROOT_MIN_FS_SZ=`LC_ALL=C ${df} -IM /dev/$ROOT_LV | ${tail} +2l | ${awk} '{print $4 + '$IMAGE_DATA_SZ'}'`

# Start progress message
if [ -n "$MKSYSB_CALL" ]
then

  if [ $NAME = "mkwpardata" ] 
  then
      echo
      ${dspmsg} -s $MSGSET $MSGCAT 33 'Creating information file (/image.data) for %s.' $WPAR
  elif [ $VG = "rootvg" ] 
  then
      echo
      ${dspmsg} -s $MSGSET $MSGCAT 24 'Creating information file (/image.data) for rootvg.'
  else
      echo
      ${dspmsg} -s $MSGSET $MSGCAT 25 'Creating information file for volume group %s.' $VG
  fi


  # As a progress indicator print dots every 15 seconds while
  # creating the image.data or vg.data file
  while :; do
        sleep 15
        echo ".\c"
  done &

  PID=$!
fi

################### Mounting unmounted filesystems for WPARS ############
if [ "$NAME" = "mkszfile" ] && [ "$NNFLAG" = "yes" ]
then
        mount_fs_wpar
fi

################### Start Processing image.data file    #################
#For each line, print command output in file image.data
{
#####   SYSTEM INFO
	print "image_data:"
	print "\tIMAGE_TYPE= bff"
	print "\tDATE_TIME= "`${date}`
	print "\tUNAME_INFO= "`${uname} -a`
	[ $NAME = mkwpardata ] && print "\tWPAR_NAME= ${WPAR}"
    	if [[ "$WPARID" != "0" ]] && [[ "$NAME" = "mkszfile" ]] 
    	then
        	print "\tWPAR_NAME= "`uname -n`
    	fi
	if [ $VG = "rootvg" ]
	then
	     print "\tPRODUCT_TAPE= no"
	     ## generate list of vgs
	     for vg in `${lsvg} -o | ${grep} -v "$VG"`  #For all active VGs
	     do
		USERVGS="$USERVGS$vg "   # Concatenate vg to list
	     done
	     print "\tUSERVG_LIST= $USERVGS"
	     mkdir -p /tmp/bos/oldvgs
	     [[ "$?" != 0 ]] && cleanup_m "$OTHER_VGS" ""
	     > /tmp/bos/oldvgs/.oldvgs
	     [[ "$?" != 0 ]] && cleanup_m "$OTHER_VGS" ""
	     for vg in `${lsvg} | ${grep} -v "$VG"`  #For all defined VGs
	     do
		if [ "`${getlvodm} -u $vg`" = "y" ]
		then
			vgid=`${getlvodm} -v $vg`
			[[ -z "$vgid" ]] && continue
			auto_on=`odmget -q"name=$vg AND attribute=auto_on" CuAt \
       	                 2>/dev/null | grep "value =" | head -n 1 | cut -d'"' -f2`
			auto_on=${auto_on:-y}
			quorum_required=`odmget -q"name=$vg AND attribute=quorum" CuAt \
       	                 2>/dev/null | grep "value =" | head -n 1 | cut -d'"' -f2`
			[[ "$quorum_required" != n ]] && quorum_required=y
			pvname=`${getlvodm} -P | grep $vg | head -n 1 | cut -d' ' -f1`
			[[ -z "$pvname" ]] && continue
			conc_capable=n
			conc_auto_on=n
			[[ `${lqueryvg} -p $pvname -X 2>/dev/null` = 0 ]] && \
				echo "$vg $vgid $auto_on $quorum_required $conc_capable $conc_auto_on" \
				>> /tmp/bos/oldvgs/.oldvgs
		fi
	     done
	     print "\tPLATFORM= $PLATFORM"
	fi
    print "\tOSLEVEL= "`LANG=C ${lslpp} -Lcq bos.rte 2> /dev/null | cut -d":" -f3`
	OSLEVEL_R=`LANG=C ${oslevel} -r 2> /dev/null | ${awk} '{print $1}'`
	OSLEVEL_S=`LANG=C ${oslevel} -s 2> /dev/null | ${awk} '{print $1}'`
	[ "$OSLEVEL_R" = "" ] && OSLEVEL_R=`LANG=C ${lslpp} -Lcq bos.rte 2> /dev/null | cut -d":" -f3 | sed -e "s/\.//g"`
	[ "$OSLEVEL_S" = "" ] && OSLEVEL_S=`LANG=C ${lslpp} -Lcq bos.rte 2> /dev/null | cut -d":" -f3 | sed -e "s/\.//g"`
	print "\tOSLEVEL_R= "$OSLEVEL_R
	print "\tOSLEVEL_S= "$OSLEVEL_S
  	print "\tCPU_ID= "`${uname} -m`

	# Get LPAR_ID
    LANG=C ${uname} -Ls | while read junk nodeid nodename
    do
        if [[ $nodeid = "1" ]] && [[ $nodename = NULL ]] || [[ $nodeid = "-1" ]]
        then
            LPAR_ID=
        else
            LPAR_ID=$nodeid
        fi
    done
	print "\tLPAR_ID= "$LPAR_ID

	print ""
	print "logical_volume_policy:"
	print "\tSHRINK= no"
	print "\tEXACT_FIT= "$MAPS
	print ""
	if [ $VG = "rootvg" ]
	then
	    print "ils_data:"
	    print "\tLANG= "`echo` $LANG
	    print ""
	fi

#####   BEGIN VG DATA               ##############
	# generate list of hdisks
       for VG in $VGLIST
       do
	VGID=`${getlvodm} -v $VG`
	VGHDISKLIST=
	for hd in `LC_ALL=C ${lsvg} -p $VG | ${tail} +3l | ${awk} '{print $1}'`
	do
	     pvid="`${getlvodm} -p $hd`"
	     if [ "`lquerypv -p $pvid -N $hd -S`" = "0" ]
		then
	         HDISKLIST="$HDISKLIST$hd "
	         VGHDISKLIST="$VGHDISKLIST$hd "
	     fi
	done
	print "##Command used for vg_data; ${lsvg}\n" # list command used
	# Get lsvg output in a "language independent" format
	COL1=`LC_ALL=C ${lsvg} $VG |    \
	${awk} 'BEGIN{FS=":"} {print $2}' | ${awk} 'BEGIN{ORS=":"}{print $1}'`
	COL2=`LC_ALL=C ${lsvg} $VG |    \
	${awk} 'BEGIN{FS=":"} {print $3}' | ${awk} 'BEGIN{ORS=":"}{print $1}'`
	print "vg_data:"  #Cut & Paste follows for data fields.
	print "\tVGNAME= "$VG
	print "\tPPSIZE= "`echo $COL2 |${awk} 'BEGIN{FS=":"} {print $2}'`
	print "\tVARYON= "`echo $COL2 |${awk} 'BEGIN{FS=":"} {print $9}'`
	print "\tVG_SOURCE_DISK_LIST= $VGHDISKLIST"
	print "\tQUORUM= "`echo $COL2 |${awk} 'BEGIN{FS=":"} {print $6}'`
	[[ `${lqueryvg} -g $VGID -X 2>/dev/null` = 32 ]] && print "\tENH_CONC_CAPABLE= yes" \
		|| print "\tENH_CONC_CAPABLE= no" 
	[[ `${lqueryvg} -g $VGID -x 2>/dev/null` = 1 ]] && print "\tCONC_AUTO= yes" \
		|| print "\tCONC_AUTO= no" 

        ## Determine if BIG vg, SVG vg, or old style vg, based on 
        ## vgtype:  2 = SVG, 1 = BIG, and 0 = old style
	maxlvs=$(${lqueryvg} -g $VGID -N)
	vgtype=$(${lqueryvg} -g $VGID -j)
	if [ $vgtype -eq 2 ]
	then
	    print "\tBIGVG= svg"
	    bigvg=svg
	elif [ $vgtype -eq 1 ]
	then
	    print "\tBIGVG= yes"
	    bigvg=yes
	else
	    print "\tBIGVG= no"
	    bigvg=no
	fi

	## Get MAX PVs and MAX PPs per PV to determine tfactor
        maxpvs=$(${lqueryvg} -g $VGID -m)
        maxppspvs=$(${lqueryvg} -g $VGID -f)
        ## Calculate tfactor
	if [ $vgtype -ne 2 ]
	then
	    (( tfact = maxppspvs/1016 ))
	    print "\tTFACTOR= $tfact"
	else
	    print "\tTFACTOR= 1"
	    print "\tMAXLVS= $maxlvs"
	    (( maxppspervg = maxppspvs/1024 ))
	    print "\tMAXPPSPERVG= $maxppspervg"
	fi
	print "\tCRITVG= "`echo $COL2 |${awk} 'BEGIN{FS=":"} {print $15}'`
        print "\tCRITPVS= "`echo $COL2 |${awk} 'BEGIN{FS=":"} {print $16}'`
        print "\tENCRYPTVG= "`echo $COL1 |${awk} 'BEGIN{FS=":"} {print $17}'`

	# Mirror pools are only supported on scalable VGs (rootvg isn't)
	if [[ $VG != "rootvg" && $bigvg == "svg" ]]
	then
		# Mirror Pool Support
		print "\tMIRROR_POOL_STRICT= "`echo $COL1 | ${awk} 'BEGIN{FS=":"} {print $13}'`

		# Save lsvg -P $VG output. Also keep a counter of the number of hdisks.
		hdisk_with_mirror_pool_count=`LC_ALL=C ${lsvg} -P $VG | ${awk} '{if(NR > 1)print}' | ${wc} -l | ${awk} '{print $1}'`
		print "\tHDISK_WITH_MIRROR_POOL_COUNT= $hdisk_with_mirror_pool_count"
		i=0
		LC_ALL=C ${lsvg} -P $VG | ${awk} '{if(NR > 1)print}' | while read line
		do
			# Note HDISK_${i} does not correlate with the actual hdisk number.
			hdisk=`echo $line | ${awk} '{print $1}'`
			mirror_pool=`echo $line | ${awk} '{print $2}'`
			print "\tHDISK_${i}_AND_MIRROR_POOL= $hdisk $mirror_pool"
			((i+=1))
		done
	fi
	print ""

       done
######  END VG DATA               #################

#####   START HARD DISK DATA.
	print "##Command used for source_disk_data; ${bootinfo}\n" # list command used
	for h in $HDISKLIST  #hard disk data.
	do
	print "source_disk_data:"   # Cut & Paste follows for fields.
		print "\tPVID= "`${getlvodm} -p $h`
		print "\tPHYSICAL_LOCATION= "`LC_ALL=C ${lsdev} -C -F 'physloc' -l $h`
		print "\tCONNECTION= "`${lsdev} -Cc disk \
					-F 'parent//connwhere' -l $h`
		print "\tLOCATION= "`LC_ALL=C ${bootinfo} -o $h`
		print "\tSIZE_MB= "`LC_ALL=C ${bootinfo} -s $h`
		print "\tHDISKNAME= $h"
		print ""
	done  # with hard disk data.
#####   END HARD DISK DATA.

    # NFS-based WPARs will have no volume groups to process, so check
    if [[ -n "$VGID"  ]]
    then

######  BEGIN LV_DATA and FS_DATA             ###############
# only non-jfs LVs and mounted jfs or jfs2 LVs (filesystems)
	PPBYTES=`${lqueryvg} -g $VGID -s 2>/dev/null| ${awk} '{printf "%d",2 ^ $1}'` # Get Partition Size
	PPSIZE=`${expr} $PPBYTES \/ $ONEMEG`   # Get Partition Size in MBytes
        VGTYPE=`${lqueryvg} -g $VGID -j 2>/dev/null` # Get Volume Group Type

	FSLIST=

	# See if Hardware Dump exists and if so get lv and fs name
	hdexist=$(ODMDIR=/etc/objrepos odmget -q attribute=fwdump_dev SWservAt | grep value)
        if [[ -n $hdexist && $FORCE_ALT -ne 1 ]]
       	then
	    # get lvname and fs name
	    hdlvname=`echo $hdexist | grep value | cut -d"\"" -f2 | sed -e "s/\/dev\///"`

	    # Remove LV name from LVlist
	    LVLIST=`echo $LVLIST | sed -e "s/ $hdlvname$//" | sed -e "s/^$hdlvname //" | sed -e "s/ $hdlvname / /"`

	    # Note - we don't need the fs name, since we build the fs list based on
	    # the LV processing, and we won't be processing the Hardware Dump LV
	fi

	# Exclude WPAR LVs if applicable
        if [[ $WPAR_LV_SIZE -ne 0 ]]
        then
           ${lswpar} -M -qca vfs,device 2>/dev/null | ${grep} "^jfs" | ${awk} -F/ '{print $NF}'  > $DATA_DIR/wparlvs
           LVLIST=`for lv in $LVLIST
	   do
	       ${grep} -q "^$lv$" $DATA_DIR/wparlvs && continue
	       echo $lv
	   done`
           ${rm} -f $DATA_DIR/wparlvs
        fi

	# Exclude user-specified file systems if -x specified
        if [[ -n $XFSLIST ]]
	then
           ### remove tabs, blanks, and especially blank lines
           /usr/bin/cat $XFSLIST | sed 's/	 //g;s/^  *//g;s/  *$//g;/^$/d' | while read xfs
           do
              ${lsfs} -c $xfs | ${awk} -F: '($3 ~ "jfs") {print $2}' | ${sed} 's:/dev/::'  
           done > $DATA_DIR/xlvs

           LVLIST=`for lv in $LVLIST
	   do
	       ${grep} -q "^$lv$" $DATA_DIR/xlvs && continue
	       echo $lv
	   done`
           ${rm} -f $DATA_DIR/xlvs
        fi

	print "##Command used for lv_data; ${lslv}\n" # list command used
	LC_ALL=C ${lsfs} -c -a | ${awk} 'BEGIN{FS=":"} $2 ~ /^\/dev\// {gsub ("/dev/", "", $2); print $2}' > $FS_MOUNT
	for LV in $LVLIST
	do
            VG=`${lslv} $LV | head -1 | ${awk} '{print $NF}'`
	    # Get lslv output in a "language independent" format
	    LV_DATA=`LC_ALL=C ${lslv} $LV`
	    COL1=`echo "$LV_DATA" | cut -c-82 | \
		    ${awk} 'BEGIN{FS=":"} {print $2}' |  \
		    ${awk} 'BEGIN{ORS=":"} { if ( $1 == "inner" ) { print $1 $2} else {print $1}}'`
	    COL2=`echo "$LV_DATA" | ${awk} 'BEGIN{FS=":"} {print $3}' |  \
			     ${awk} 'BEGIN{ORS=":"}{print $1}'`
	    echo $COL1 | awk 'BEGIN{FS=":"} {print $1 " " $2 " " $3 " " $4 " " $5 " " $6 " " $7 " " $8 " " $9 " " $10 " " $11 " " $12 " " $13 " " $14 " " $15 " " $16 " " $17}' | read la1 la2 la3 la4 la5 la6 la7 la8 la9 la10 la11 la12 la13 la14 la15 la16 la17
	    echo $COL2 | awk 'BEGIN{FS=":"} {print $1 " " $2 " " $3 " " $4 " " $5 " " $6 " " $7 " " $8 " " $9 " " $10 " " $11}' | read lb1 lb2 lb3 lb4 lb5 lb6 lb7 lb8 lb9 lb10 lb11
	    LV_TYP=$la4
	    LV_label=$lb11
	    if [ "$LV_TYP" = "pmhibernation" ]    # If LV for Power Mgmt, skip.
	    then
		continue
	    fi
	    # If we have an unmounted multibos instance on the system, don't backup the standby_bootlv
	    # because it will be empty and will not be bootable. 
	    if [ "$LV_label" = "standby_bootlv" ]
	    then
		# if we are on a system with an unmounted multibos instance skip backing up the standby_lv
		MB_lv=`grep hd4 /etc/multibos/data/sbylvlist` 
   		${mount} | ${egrep} -q /dev/$MB_lv
		[ $? -ne 0 ] && continue
	    fi

	    MNT_PT=$la11
	    NOFS=0     ## reset NO FileSystem in LV flag.
	    # Is LV a jfs or jfs2 Filesystem?
	    if [[ "$LV_TYP" = "jfs" || "$LV_TYP" = "jfs2" ]]
	    then
                LC_ALL=C ${mount} | ${awk} '$1 ~ /^\/dev\// {gsub ("/dev/", "", $1); print $1} ' | ${egrep} -q "^$LV$"
		if [ $? -ne 0 ]   ## Is the filesystem mounted?
		then
			    #  LV Not mounted OR has no Filesystem
			    # If LV has a Filesystem then skip it
			    #  otherwise save the LV attributes.
			${egrep} -q "^$LV$" $FS_MOUNT
			[ "$?" -eq 0 ] && continue
		else
		     if [ "$MNT_PT" = "N/A" ] #Yes, is Fs defined in /etc/filesystems
		     then              ### No, print warning msg
			 echo $LV |  \
			 ${awk} '{system ( "'${dspmsg}' -s '$MSGSET' '$MSGCAT' 20 \"0512-020 %s: The logical volume %s does not have an entry in\n/etc/filesystems which is needed to accurately define the mount point.\nAs a result, it will not be backed up.  If you want it to be included\nin the backup, add a stanza for it in the /etc/filesystems file and\nreissue this command before running mksysb.\n\n\" '$NAME' " $1 " 1>&2" )}'
			 continue
		     else             ### yes, it is mounted
			 FSLIST="$FSLIST $LV"    ## add to FS list
			 NOFS=1     ## set NO FileSystem in LV flag.
		     fi
		fi
	    fi
	    print "lv_data:"
	    print "\tVOLUME_GROUP= $VG"
	    L_S_DISK=""
	    for S_DISK in `LC_ALL=C ${lslv} -l $LV | ${tail} +3l | ${awk} '{print $1}'`
	    do
		    L_S_DISK="$L_S_DISK$S_DISK "
	    done
	    print "\tLV_SOURCE_DISK_LIST= $L_S_DISK"
	    LVID=$la2
	    print "\tLV_IDENTIFIER= $LVID"
	    print "\tLOGICAL_VOLUME= $la1"
	    print "\tVG_STAT= $la3"
	    print "\tTYPE= $la4"
	    (( MAX_MAX_LPS = $maxpvs * $maxppspvs ))
	    MAX_LPS=$la5
	    [ "$MAX_LPS" -gt "$MAX_MAX_LPS" ] && MAX_LPS=$MAX_MAX_LPS
	    print "\tMAX_LPS= $MAX_LPS"
	    print "\tCOPIES= $la6"
	    NUM_LPs=$la7
	    print "\tLPs= $NUM_LPs"
	    print "\tSTALE_PPs= $la8"
	    print "\tINTER_POLICY= $la9"
	    [ "$la10" = "innermiddle" ] && la10="inner middle"
	    [ "$la10" = "inneredge" ] && la10="inner edge"
	    print "\tINTRA_POLICY= $la10"
	    [ "$MNT_PT" = "N/A" ] && MNT_PT=""
	    print "\tMOUNT_POINT= `canonical $MNT_PT`"
            if [ "$VGTYPE" -gt 0 ]; then
                # Big or Scalable VG
                print "\tMIRROR_WRITE_CONSISTENCY= $la14"
            else
                print "\tMIRROR_WRITE_CONSISTENCY= $la12"
            fi
            SUPER_STRICT=`echo "$LV_DATA" | ${grep} superstrict | \
                ${grep} yes`
            if [ -n "$SUPER_STRICT" ]; then
                print "\tLV_SEPARATE_PV= ss"
            else
                if [ "$VGTYPE" -gt 0 ]; then
                    # Big or Scalable VG
                    print "\tLV_SEPARATE_PV= $la15"
                else
                    print "\tLV_SEPARATE_PV= $la13"
                fi
            fi
	    print "\tPERMISSION= $lb2"
	    print "\tLV_STATE= $lb3"
	    print "\tWRITE_VERIFY= $lb4"
	    print "\tPP_SIZE= $lb5"
	    print "\tSCHED_POLICY= $lb6"
	    print "\tPP= $lb7"
	    print "\tBB_POLICY= $lb8"
	    print "\tRELOCATABLE= $lb9"
	    print "\tUPPER_BOUND= $lb10"
	    LBL=`${getlvodm} -B $LV`
	    [ "$LBL" = "None" ] && LBL=""
	    print "\tLABEL= `canonical $LBL`"
	    if [ "$MAPS" = "yes" ]
	    then
		    mk_mapfile $LV

		    print "\tMAPFILE= $MAP_DIR/$LV.map"
	    else
		    print "\tMAPFILE="
	    fi
	    if [ "$NOFS" -eq 1 ]  ## Does LV have a filesystem defined.
	    then
		  fs=$LV
		  print "fs_data:" >> $FS_TMP
		  set -- `LC_ALL=C ${df} -IM /dev/$fs | ${tail} +2l`
		  # Convert all the links in the FS_NAME to their true path
		  FS_NAME="$2"
		  LINKCHECK=yes

		  # Loop to resolve all links in FS_NAME (links to links)
		  while [[ "$LINKCHECK" = yes ]]
		  do
		      OLDIFS=$IFS;IFS="/";TEMPDIR=""
		      LINKFLAG=
		      # Loop to resolve first level of links in FS_NAME
		      for j in `dirname "$FS_NAME"`
		      do
		    	TEMPDIR="$TEMPDIR/$j";
		        if [ -L "$TEMPDIR" ]
		        then
		           # Do not put dollar_sign curly braces around the commands
		           if [ "`ls -l "$TEMPDIR"|awk '{print $NF}'|cut -c1`" = "/" ]
		           then
		              TEMPDIR=`ls -l "$TEMPDIR"|awk '{print $NF}'`
		           else
			      TEMPDIR=${TEMPDIR%/*}/`ls -l "$TEMPDIR"|awk '{print $NF}'`
		              TEMPDIR=`echo "$TEMPDIR" |awk '{ gsub ("//","/",$1); print $1 }'`
		   	   fi
			   LINKFLAG=yes
			   LINKCHECK=yes
		        else
			   [ -z "$LINKFLAG" ] && LINKCHECK=
	    	        fi
		      done

		      if [[ -n "$OLDIFS" ]]
		      then
		         IFS=$OLDIFS
		      else
		         unset IFS
		      fi

                      # Verify that file system name is valid
                      ${lsfs} "$TEMPDIR/`basename $FS_NAME`" >/dev/null 2>&1
                      if [ "$?" -eq 0 ]
                      then
                         [ "$LINKFLAG" = yes ] && FS_NAME="$TEMPDIR/`basename $FS_NAME`"
                      else
                         LINKCHECK=
                      fi
		  done

	          # Final check to resolve link at basename of mount point
	          if [ -L "$FS_NAME" ]
	          then
	               TEMPDIR="$FS_NAME"
	               # Do not put dollar_sign curly braces around the commands
	               if [ "`ls -l "$TEMPDIR"|awk '{print $NF}'|cut -c1`" = "/" ]
	               then
		           TEMPDIR=`ls -l "$TEMPDIR"|awk '{print $NF}'`
	               else
	                   TEMPDIR=${TEMPDIR%/*}/`ls -l "$TEMPDIR"|awk '{print $NF}'`
	                   TEMPDIR=`echo "$TEMPDIR" |awk '{ gsub ("//","/",$1); print $1 }'`
	               fi
	               FS_NAME="$TEMPDIR"
	          fi

	          # Set fields in fs_data stanzas.
	          print "\tFS_NAME= `canonical $FS_NAME`" >> $FS_TMP
	          FS_LV=$1
	          FS_SIZE=$3
	          FS_MIN_SIZE=$4

                  # Make sure the type of this lv matches with
                  # the type of fs which is created on this lv
                  #
                  if [[ "$LV_TYP" = "jfs" || "$LV_TYP" = "jfs2" ]]; then
                     fs_type=$(get_fs_type $FS_LV)
                     if [[ "$fs_type" != "$LV_TYP" ]] ; then
                        #  display error message and terminate
                        ${dspmsg}  -s $MSGSET $MSGCAT 35 \
                                     "\n%s ATTENTION: The type of the logical volume %s does not match \n\
with filesystem's type.\n" $NAME $FS_LV 1>&2
                        cleanup_m $LV_FS_TYPE_ERR ""
                     fi
                  fi

		  # jfs2 filesystem minimum size 16 MB and inline
		  # log cannot be greater than 10% of filesystem

	          if [[ "$LV_TYP" = "jfs2" ]]; then
	                (( FS_MIN_SIZE = $FS_MIN_SIZE + 500 ))
	                if [[ $FS_MIN_SIZE -gt $FS_SIZE ]]; then
                            # If there is not 500 blocks free in filesystem,
                            # then print mesg and set FS_MIN_SIZE=FS_SIZE.
                            echo $FS_NAME | \
                               ${awk} '{system ( "'${dspmsg}' -s '$MSGSET' '$MSGCAT' 30 \"\n0512-064 %s: ATTENTION: The %s filesystem does not have %s Kbytes\nof free work space, a restore of a backup including %s may fail.\nTo avoid this possibility, do one of the following:\n\" '$NAME' " $1 " 250 " $1 " 1>&2" )}'
                            echo $FS_NAME | \
                               ${awk} '{system ( "'${dspmsg}' -s '$MSGSET' '$MSGCAT' 36 \"\t  (1) Use the chfs command to extend the %s filesystem.\n\t  (2) Free up space to provide a total of %s Kbytes of\n\t      free work space in the %s filesystem.\n\n\" " $1 " 250 " $1 " 1>&2" )}'
                            FS_MIN_SIZE=$FS_SIZE
			    ${rm} $VG_DATA
			    cleanup_m "$NO_SPACE_EC" ""
                        fi
	                [ $FS_MIN_SIZE -lt $SIXTEEN_MB ] && FS_MIN_SIZE=$SIXTEEN_MB
	                FS_MIN_LOG=`LC_ALL=C ${lsjfs2} $FS_LV |${tail} +2l | \
                             ${awk} 'BEGIN{FS=":"} {print $16}'`
                        (( FS_MIN_LOG = FS_MIN_LOG * 20480 ))
	                [ $FS_MIN_SIZE -lt $FS_MIN_LOG ] && FS_MIN_SIZE=$FS_MIN_LOG
	          fi

	          if [ $fs = $TMP_LV -o $fs = $ROOT_LV ]
	          then
	                if [ $fs = $TMP_LV ]
	                then
	                    [ $FS_MIN_SIZE -lt $TMP_MIN_FS_SZ ] && FS_MIN_SIZE=$TMP_MIN_FS_SZ
	                else
	                    [ $FS_MIN_SIZE -lt $ROOT_MIN_FS_SZ ] && FS_MIN_SIZE=$ROOT_MIN_FS_SZ
	                fi
	          fi
	          print "\tFS_SIZE= $FS_SIZE" >> $FS_TMP
	          print "\tFS_MIN_SIZE= $FS_MIN_SIZE" >> $FS_TMP
	          print "\tFS_LV= $FS_LV" >> $FS_TMP
	          if [[ "$LV_TYP" = "jfs" ]]; then
	                FSEXT=`LC_ALL=C ${lsjfs} /dev/$fs |${tail} +2l`
                        echo $FSEXT | awk 'BEGIN{FS=":"} {print $13 " " $14 " " $15 " " $16 " " $17}' | read f1 f2 f3 f4 f5
                        print "\tFS_FS= $f1" >> $FS_TMP
                        print "\tFS_NBPI= $f2" >> $FS_TMP
                        print "\tFS_COMPRESS= $f3" >> $FS_TMP
                        print "\tFS_BF= $f4" >> $FS_TMP
                        FS_AGSIZE=$f5
	                if [ "$FS_AGSIZE" -eq 8 -o "$FS_AGSIZE" -eq 16 -o "$FS_AGSIZE" -eq 32 -o "$FS_AGSIZE" -eq 64 ]
	  	        then
	                    print "\tFS_AGSIZE= "`echo $FS_AGSIZE` >> $FS_TMP
	                else
	                    print "\tFS_AGSIZE= " >> $FS_TMP
	                fi
	                print "" >> $FS_TMP
	          elif [[ "$LV_TYP" = "jfs2" ]]; then
	                 FSEXT=`LC_ALL=C ${lsjfs2} /dev/$fs |${tail} +2l`
			 echo $FSEXT | awk 'BEGIN{FS=":"} {print $13 " " $14 " " $15 " " $16 " " $17 " " $18 " " $19 " " $20 " " $21}' | read f13 f14 f15 f16 f17 f18 f19 f20 f21
	                 print "\tFS_JFS2_BS= $f13" >> $FS_TMP
	                 print "\tFS_JFS2_SPARSE= $f14" >> $FS_TMP
	                 print "\tFS_JFS2_INLINELOG= $f15" >> $FS_TMP
	                 print "\tFS_JFS2_SIZEINLINELOG= $f16" >> $FS_TMP
	                 print "\tFS_JFS2_EAFORMAT= $f17" >> $FS_TMP
	                 print "\tFS_JFS2_QUOTA= $f18" >> $FS_TMP
	                 print "\tFS_JFS2_DMAPI= $f19" >> $FS_TMP
	                 print "\tFS_JFS2_VIX= $f20" >> $FS_TMP
	                 print "\tFS_JFS2_EFS= $f21" >> $FS_TMP
	                 print "" >> $FS_TMP
	          fi
		  NUMLP=$FS_MIN_SIZE

		  # LV size in MB
		  REM=`${expr} $NUMLP \% $BLK_SZ2`
		  NUMLP=`${expr} $NUMLP \/ $BLK_SZ2`
		  [ $REM -ne 0 ] && NUMLP=`${expr} $NUMLP \+ 1`
		  # LV size in partitions
		  LV_MIN_LPS=`${expr} $NUMLP \/ $PPSIZE`
		  REM=`${expr} $NUMLP \% $PPSIZE` && \
			 LV_MIN_LPS=`${expr} $LV_MIN_LPS \+ 1`

		  print "\tLV_MIN_LPS= $LV_MIN_LPS"
	     else
		  print "\tLV_MIN_LPS= $NUM_LPs"
	     fi

	    STRIPE_WIDTH=`echo "$LV_DATA" | ${grep} "STRIPE WIDTH" | ${awk} 'BEGIN{FS=":"} {print $2}' | ${awk} '{print $1}'`
	    STRIPE_SIZE=`echo "$LV_DATA" | ${grep} "STRIPE SIZE" | ${awk} 'BEGIN{FS=":"} {print $2}' | ${awk} '{print $1}'`
	    DEV_SUBTYPE=`echo "$LV_DATA" | ${grep} "DEVICESUBTYPE" | ${awk} 'BEGIN{FS=":"} {print $2}' | ${awk} '{print $1}'`
	    print "\tSTRIPE_WIDTH= $STRIPE_WIDTH"
	    print "\tSTRIPE_SIZE= $STRIPE_SIZE"

	    SERIALIZE_IO=$la14
            [ "$SERIALIZE_IO" = YES ] && SERIALIZE_IO="yes" || SERIALIZE_IO="no"
	    print "\tSERIALIZE_IO= $SERIALIZE_IO"
        # Add tag data if present
        TAG=$(LC_ALL=C ${getlvcb} -f "$LV")
        # Print it if valid
        if [[ -n $TAG ]]; then
           print "\tFS_TAG= $TAG"
        else
           print "\tFS_TAG="
        fi
	    print "\tDEV_SUBTYP=$DEV_SUBTYPE"

	    # LV_USERID, LV_GROUPID, LV_MODES are only used on non-rootvg
	    # volume groups that have the BIGVG attribute.
	    if [ -n "$bigvg" ] && [ "$VG" != rootvg ]
	    then
		print "\tLV_USERID= "`LC_ALL=C ${lquerylv} -L "$LVID" -u`
		print "\tLV_GROUPID= "`LC_ALL=C ${lquerylv} -L "$LVID" -g`
		print "\tLV_MODES= "`LC_ALL=C ${lquerylv} -L "$LVID" -m`
	    fi
	    stripesz=
	    stripesz=$STRIPE_SIZE
	    if [[ $MAPS = "yes" && -n $stripesz && $VG = "rootvg" ]]
	    then
		stripewarn=yes
	    fi

		if [[ $VG != "rootvg" && $bigvg == "svg" ]]
		then
			COPY_1_MIRROR_POOL=`echo "$LV_DATA" | ${grep} "COPY 1 MIRROR POOL" | ${awk} 'BEGIN{FS=":"} {print $2}' | ${awk} '{print $1}'`
			COPY_2_MIRROR_POOL=`echo "$LV_DATA" | ${grep} "COPY 2 MIRROR POOL" | ${awk} 'BEGIN{FS=":"} {print $2}' | ${awk} '{print $1}'`
			COPY_3_MIRROR_POOL=`echo "$LV_DATA" | ${grep} "COPY 3 MIRROR POOL" | ${awk} 'BEGIN{FS=":"} {print $2}' | ${awk} '{print $1}'`
			print "\tCOPY_1_MIRROR_POOL= $COPY_1_MIRROR_POOL"
			print "\tCOPY_2_MIRROR_POOL= $COPY_2_MIRROR_POOL"
			print "\tCOPY_3_MIRROR_POOL= $COPY_3_MIRROR_POOL"
		fi

		print ""

	done # With lv_data
#######    END LV DATA          #################

#######    PRINT FS DATA         #################
    fi

	print "##Commands used for fs_data; ${df}, ${lsjfs}, and ${lsjfs2}\n"
	[[ -s "$FS_TMP" ]] && cat $FS_TMP
#####    END FS DATA           #################

	if [ $NAME != mkwpardata ]
	then
	   if [ $VG = "rootvg" ]
	   then
              if [[ "$WPARID" = "0" ]]; then
	          print "post_install_data:"
	          print "\tBOSINST_FILE= "
              fi
	   else
	       print "post_restvg:"
	       print "\tRESTVG_FILE= "
	   fi
	fi
}  > $VG_DATA
[ "$?" != 0 ] && cleanup_m "$FILE_EC" ""

if [ $NAME = mkwpardata ]
then
      ${mkwpar} -e $WPAR -W -w -o - > $DATA_DIR/wpar.spec
fi

if [[ $stripewarn = "yes" ]]
then
    ## Issue warning that the lv will be recreated with strips,
    ## and will not use the maps file  

    ${dspmsg} -s $MSGSET $MSGCAT 28 \
"\n0512-053 %s: WARNING:  The creation of\n\
map files was specified, however,\n\
at least one logical volume was striped.\n\
Striped logical volumes can not be created\n\
with map files.  The striped logical volume may not\n\
be recreated in exactly the same place.\n" $NAME

fi

if [ -n "$MKSYSB_CALL" ]
then
   kill $PID >/dev/null 2>&1
   unset PID
   echo
fi

#### Check for duplicate filesystem/logical volumes in volume group data file
dup_entry=`cat $VG_DATA | ${awk} '{if($0 ~ "FS_NAME" || $0 ~ "LOGICAL_VOLUME") {print $0}}' | sort | uniq -d | ${awk} '{print $2}'`
if [ "$dup_entry" ]
then
   ${dspmsg} -s $MSGSET $MSGCAT 29 \
   "\n0512-056 %s: Duplicate fs_data and/or lv_data stanza %s \n\
specified in the %s file.  The backup cannot continue.\n" $NAME $dup_entry $VG_DATA
fi
rm -r $FS_TMP $FS_MOUNT 2>/dev/null

### reset trap, cleanup any side effects, and exit 0
cleanup_m 0