#!/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 .data file from the backup # image (-f 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 .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 .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/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 .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 .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//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//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