#!/bin/ksh # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # bos72X src/bos/usr/bin/mksysb/mksysb.sh 1.21.26.66 # # Licensed Materials - Property of IBM # # COPYRIGHT International Business Machines Corp. 1989,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 # @(#)78 1.21.26.66 src/bos/usr/bin/mksysb/mksysb.sh, cmdbsys, bos72X, x2021_15A7 4/12/21 13:25:07 # # COMPONENT_NAME: (CMDBSYS) # # FUNCTIONS: mksysb.sh # # ORIGINS: 27 # # (C) COPYRIGHT International Business Machines Corp. 1989, 1995 # 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: mksysb # NOTE: savevg command is a "symbolic" link to mksysb command # # FILE DESCRIPTION: High-level shell command for backing up the mounted # file systems in the volume group. # If the -i flag is specified, then the mkszfile/mkvgdata command will # be called. # If -m is specified, then the mkszfile/mkvgdata command will be called # with the -m flag to create maps of the physical partitions. # Mksysb is passed the name of the backup device to use. Savevg uses # the -f parameter to specify the name of the backup device to # use and has a default of /dev/rmt0, and is passed the name of the # Volume Group to backup. # File/Directory Names listed in the /etc/exclude.<$ARG> file will be # excluded from the backup. # Mksysb calls bosboot to generate a "boot" image, bosboot requires # working space in /tmp directory, to get amount required issue the # following command: bosboot -qad . # # RETURN VALUE DESCRIPTION: # 0 Successful # non-zero Unsuccessful # # # EXTERNAL PROCEDURES CALLED: mkszfile(mkvgdata/mkwpardata) must be called # prior to mksysb(savevg/savewpar) or the -i or -m flags must be specified, # mkszfile(mkvgdata/mkwpardata) to # create the data file, which is placed at the beginning of the # backup media. # Bosboot, mkinsttape, backup commands. # # GLOBAL VARIABLES: none # ################################################################################# ######################### kill_pid #################################### ## ## Name: kill_pid ## ## Function: The kill_pid function is responsible for stopping ## the progress indicator pid. ## ## Parameters: The background progress indicator pid. ## ## Returns: None ## ## ######################################################################## function kill_pid { typeset PID=$1 typeset cnt=0 typeset PIDTEST=0 while [ -n "$PID" -a $PIDTEST -eq 0 -a $cnt -lt 10 ] do kill $PID >/dev/null 2>&1 sleep 2 (( cnt = $cnt + 1 )) ps $PID >/dev/null 2>&1 PIDTEST=$? done } ## end of kill_pid ############################## 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 savewpar # # INPUT: # $1 = pathname # # OUTPUT: # Rebased pathname # ########## canonical () { fn=$1 if [ "$NAME" != "savewpar" ] then echo $fn else if [ "$fn" = "$WPAR_BASEDIR" ] then echo / else echo $fn | ${sed} "s:$WPAR_BASEDIR::" fi fi } ################################# check_edition ############################## # # NAME: check_edition # # DESCRIPTION: set edition, will not set edition if /save_bosinst.data_file # exist # # check_edition () { edition=`/usr/sbin/chedition -l` /usr/bin/grep "^[ ]*INSTALL_EDITION" $BOSINST_DATA >/dev/null 2>&1 if [ "$?" -eq 1 ] then # If INSTALL_EDITION is not present, then add it IFS_SAVE=$IFS IFS=" " while read line do echo "$line" | awk -F"\n" -v ED=$edition '{if ($0 !~ "^[ ]*INSTALL_METHOD" ) {print $0} else {print $0 "\n" " INSTALL_EDITION = " ED}}' >> $tmp_newbidata done < $BOSINST_DATA IFS=$IFS_SAVE else # If INSTALL_EDITION is present, then set to current value sed -e "s/^[ ]*INSTALL_EDITION[ ]*=[ ]*[a-zA-Z]*/ INSTALL_EDITION = $edition/" $BOSINST_DATA > $tmp_newbidata fi ${cp} "$tmp_newbidata" "$BOSINST_DATA" } ################################# check_root_link ############################## # Called only by savewpar # Creates a link to the data directory within the wpar at /.savewpar_dir. # # If the file is a symbolic link, remove it. # # If the file already exists or is a symbolic link to something else, then # it will try to move the interfering file. # # check_root_link () { if [ -L ${WPAR_BASEDIR}/${DATALNKF} ] then rm -f ${WPAR_BASEDIR}/${DATALNKF} fi # Fix link or move interfering files out of the way if possible if [ -e ${WPAR_BASEDIR}/${DATALNKF} ] && [ ! -L ${WPAR_BASEDIR}/${DATALNKF} ] then ${dspmsg} -s $MSGSET $MSGCAT 75 \ "Renaming %$1s to %$2s.\n" \ ${WPAR_BASEDIR}/${DATALNKF} ${WPAR_BASEDIR}/${DATALNKF}.$$ mv ${WPAR_BASEDIR}/${DATALNKF} ${WPAR_BASEDIR}/${DATALNKF}.$$ fi ${ln} -sf $DATA_DIR ${WPAR_BASEDIR}/${DATALNKF} && DLNKMADE="yes" return $? } ################################# 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 () { trap '' 1 2 15 # Ignore trap while cleaning up ec=$1 error=$2 # Kill any running progress message kill_pid "$PID" rm -f $mksysb_tmpdir/_mksysb.$$ case "$ec" in "$USAGE_MB") # mksysb usage error error="`${dspmsg} -s $MSGSET $MSGCAT 108 ' Usage:\t%s [-X] [-V] [-i] [-m] [-e] [-b blocks] [-p] [-v] [-a] [-A] [-F filename] [-t temp_dir] [-Z] [-G | -N] [-M] [-P] [-x filename] [-T] [-C] device\n\ -X\tExpand /tmp if needed.\n\ -V\tVerify backup readability (tape only).\n\ -i\tCreate the /image.data file.\n\ -m\tCreate the /image.data file and physical partition maps.\n\ -e\tExclude the files/directories.\n\ -v\tList files as they are backed up.\n\ -p\tDo not pack files as they are backed up.\n\ -b blocks\tNumber of 512-byte blocks to write in a single\n\ \toutput operation.\n\ -a\tDo not backup extended attributes or NFS4 ACLs\n\ -A\tBack up DMAPI filesystem files.\n\ -F filename\tA previously created mksysb image to put on tape.\n\ -t temp_dir\tFile system for temporary space. Used with -F.\n\ -M \tCreate backup suitable for use with multibos.\n\ -G \tExclude file systems from WPARS.\n\ -N \tBackup file systems for WPARS in the Defined state.\n\ -Z\tDo not back up Encrypted File System (EFS) information.\n\ -P\tExclude files from packing option listed in /etc/exclude_packing.rootvg.\n\ -x filename\tExclude file systems listed in file.\n\ -T\tCreate backup using snapshots.\n\ -C\tCreate a new /usr/lpp/bos.alt_disk_install/boot_images/bosboot.disk.chrp\n\ boot image, for use with alt_disk_mksysb installations.\n\ device\tName of device to receive the backup information.\n\ \tExample: %s /dev/rmt0\n' $NAME $NAME`" 1>&2 ;; "$USAGE_SV" | "$INVALID_VG") # savevg usage error if [ "$ec" = "$INVALID_VG" ] then ${dspmsg} -s $MSGSET $MSGCAT 6 \ "0512-009 %s: Invalid or missing Volume Group Name.\n" $NAME 1>&2 fi error="`${dspmsg} -s $MSGSET $MSGCAT 100 ' Usage:\t%s [-X] [-V] [-i] [-m] [-e] [-b blocks] [-f device] [-p] [-v] [-r] [-a] [-A] [-Z] [-P] [-x filename] [-T] vgName\n\ -X\tExpand /tmp if needed.\n\ -V\tVerify backup readability (tape only).\n\ -i\tCreate the .data file.\n\ -m\tCreate the .data file and physical partition maps.\n\ -e\tExclude the files/directories listed in /etc/exclude..\n\ -v\tList files as they are backed up.\n\ -p\tDo not pack files as they are backed up.\n\ -b blocks\tNumber of 512-byte blocks to write in a single\n\ \toutput operation.\n\ -f device\tName of device to receive the backup information.\n\ \tDefault is /dev/rmt0\n\ -r\tBack up the user Volume Group information files only.\n\ -a\tDo not backup extended attributes or NFS4 ACLs\n\ -A\tBack up DMAPI filesystem files.\n\ -Z\tDo not backup Encrypted File System (EFS) information.\n\ -P\tExclude files from packing option listed in /etc/exclude_packing..\n\ -x filename\tExclude file systems listed in file.\n\ -T\tCreate backup using snapshots.\n\ vgName\tName of Volume Group to backup.\n' $NAME`" 1>&2 ;; "$USAGE_WPAR" | "$INVALID_WPAR") # savewpar usage error if [ "$ec" = "$INVALID_WPAR" ] then ${dspmsg} -s $MSGSET $MSGCAT 72 \ "0512-065 %s: Invalid or missing Workload Partition Name.\n" $NAME 1>&2 fi error="`${dspmsg} -s $MSGSET $MSGCAT 101 ' Usage:\t%s [-X] [-V] [-i] [-m] [-e] [-b blocks] [-f device] [-p] [-v] [-B] [-N] [-a] [-A] [-Z] [-P] [-T] wparName\n\n\ -X\tExpand /tmp if needed.\n\ -V\tVerify backup readability (tape only).\n\ -i\tCreate the image.data file.\n\ -m\tCreate the image.data file and physical partition maps.\n\ -e\tExclude the files/directories listed in /etc/exclude..\n\ -v\tList files as they are backed up.\n\ -p\tDo not pack files as they are backed up.\n\ -b blocks\tNumber of 512-byte blocks to write in a single\n\ \toutput operation.\n\ -f device\tName of device to receive the backup information.\n\ \tDefault is /dev/rmt0\n\ -B\tDo not backup files from writeable namefs mounts in the mount group.\n\ -N\tBackup files from writeable NFS mounts in the mount group.\n\ -a\tDo not backup extended attributes or NFS4 ACLs\n\ -A\tBack up DMAPI filesystem files.\n\ -Z\tDo not back up Encrypted File System (EFS) information.\n\ -P\tExclude files from packing option listed in /etc/exclude_packing..\n\ -T\tCreate backup using snapshots.\n\ wparName\tName of Workload Partition to backup.\n' $NAME`" 1>&2 ;; "$CMD_EC" | "$TRAP_EC" | "$NO_SPACE_EC") [ -f "$DEVICE" ] && ${rm} -f "$DEVICE" ;; "$INVALID_ALT") ${dspmsg} -s $MSGSET $MSGCAT 81 \ "0512-070 %s: Fileset bos.alt_disk_install.boot_images must be\n\ installed and match the level of the system.\n" $NAME 1>&2 ;; "$BOOT_FAIL") ${dspmsg} -s $MSGSET $MSGCAT 107 \ "0512-076: bosboot failed creating the new bosboot.disk.chrp boot image.\n\ The original has been put back into /usr/lpp/bos.alt_disk_install/boot_images." 1>&2 ;; *) ;; esac ${rm} "$archive_lst" "$mounted_list" "$mounted_list_final" "$tmp_tdd" "$tmp_newbidata" "$FILE_LIST" > /dev/null 2>&1 if [ "$UDF" = "yes" ] ; then ${umount} $MOUNTP > /dev/null 2>&1 fi ${rm} -fr "$mksysb_tmpdir" > /dev/null 2>&1 # Unmount and remove snapshots snap_remove if [[ "$NEWBOOT" = "yes" ]] then # if BOOTSAVE, move it back [[ -f $BOOTSAVE ]] && mv $BOOTSAVE $BOOTNEW [[ -f $BOOTTMP ]] && rm $BOOTTMP [[ -d /tmp/boot_images ]] && ${rmdir} /tmp/boot_images fi if [ $NAME = "mksysb" ] && [ $oldblksize ] then [ -n "$tapedev" ] && { ${chdev} -l $tapedev -a block_size=${oldblksize:-1024} \ >/dev/null 2>&1 if [ -n "$oldextfm" ] then ${chdev} -l $tapedev -a extfm=$oldextfm \ >/dev/null 2>&1 fi ${tctl} -f /dev/$tapedev rewind >/dev/null 2>&1 } elif [ $NAME = "savewpar" ] && [ "$ec" != "$USAGE_WPAR" ] && [ "$ec" != "$INVALID_WPAR" ] && [ "$ec" != "$LOCK_EC" ] && [ "$ec" != "$INSIDE_WPAR" ] then cd / # If we made a link to the data directory, clean it up # so that we don't have problems later [[ -n "$DLNKMADE" ]] && rm -f ${WPAR_BASEDIR}/${DATALNKF} cor_unlockcorral "$WPAR" stop_rootvgwpar_if_was_defined # 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 ############################################################### #### if we mount any file system for WPARS in the Defined state #### now is the time to unmount them. ############################################################### if [ "$NNFLAG" = "yes" ] then unmount_wpar_fs fi if [ $NAME = "savewpar" ] then # Remove $WORKDIR, if any, created by init_baselib [ -n "$WORKDIR" ] && rm -rf "$WORKDIR" > /dev/null 2>&1 fi [ -n "$TMPDIR" ] && rm -fr $TMPDIR > /dev/null 2>&1 [ -n "$error" ] && echo "\n${error}\n" exit "$ec" } ########################################################## copy_backup() { ${dspmsg} -s $MSGSET $MSGCAT 67 'Copying backup to tape.' while :; do ${sleep} 10 echo ".\c" done & # dd command does not support 0 block size if [ "$oldblksize" -eq 0 ] then oldblksize=512 fi PID=$! ${dd} if=$BACKUPFILE of=$device bs=$oldblksize conv=sync >/dev/null 2>&1 [ "$?" -ne 0 ] && cleanup_m "$CMD_EC" \ "`${dspmsg} -s $MSGSET $MSGCAT 11 \ '0512-008 %s: The %s command failed with return code of %s. Backup canceled.' $NAME $dd $rc`" # Kill dots from 'Copying backup to tape.' message kill_pid "$PID" echo "" } ########################################################## done_backup() { ret_code=$1 # # Backup completed # if [ "$ret_code" -gt 1 ] then echo "`${dspmsg} -s $MSGSET $MSGCAT 2 \ '0512-005 %s: Backup Completed.\n\tThe backup command completed with errors.\n\tThe messages displayed on Standard Error contained additional\n\tinformation.' $NAME`" rc="$CMD_EC" elif [ "$ret_code" -eq 1 -o "$BAD_FIND" -eq 1 ] then echo "`${dspmsg} -s $MSGSET $MSGCAT 31 \ '0512-003 %s may not have been able to archive some files.\nThe messages displayed on the Standard Error contained additional\ninformation.\n' $NAME`" [[ "$SNAPFLAG" = "y" ]] && rc="$CMD_EC" || rc=0 else if [[ "$VERIFYFLAG" = "no" ]] || \ [[ "$DEVICE" != *"rmt"* ]]; then echo "`${dspmsg} -s $MSGSET $MSGCAT 20 \ '0512-038 %s: Backup Completed Successfully.' $NAME`" rc=0 fi fi # If backup was successful and verify flag is set, then we will verify # the tape backup. if [[ "$VERIFYFLAG" = "yes" ]] && \ [[ "$DEVICE" = *"rmt"* ]]; then /usr/bin/dspmsg -s $MSGSET $MSGCAT 56 "\nVerifying readability..." print "\n" MULTI_VOL=`grep "Volume " $mksysb_tmpdir/_mksysb.$$|grep "on $DEVICE"|wc -l|awk '{ print $1 }'` if [[ $MULTI_VOL -gt 1 ]]; then /usr/bin/dspmsg -s 1 bbyname.cat 15 "Mount volume %s on %s.\n\ \tPress Enter to continue. " "1" $DEVICE print "\n" read fi ## If no-rewind flags were used on device name, then ## don't add one to the end. ## Backup one image and start the restore. if [[ $DEVICE = /dev/rmt+([0-9])\.[1357] ]]; then if [[ "$VG" = "rootvg" ]]; then ## rootvg needs to skip to fourth image. ## For restore suppress stdout NOT stderr (so error messages and ## multivolume prompts get seen.) /usr/bin/tctl -f $DEVICE rewind > /dev/null 2>&1 /usr/sbin/restore -Tvq $BFLAG -f $DEVICE -s 4 >/dev/null rc="$?" else ## uservg backups start at the beginning /usr/bin/mt -f $DEVICE bsf 1 > /dev/null 2>&1 /usr/sbin/restore -Tvq $BFLAG -f $DEVICE > /dev/null rc="$?" fi else ## Else add a no-rewind flag and restore. if [[ "$VG" = "rootvg" ]]; then ## rootvg needs to skip to fourth image. ## For restore suppress stdout NOT stderr (so error messages and ## multivolume prompts get seen.) /usr/sbin/restore -Tvq $BFLAG -f $DEVICE.1 -s 4 >/dev/null rc="$?" else ## uservg backups start at the beginning /usr/sbin/restore -Tvq $BFLAG -f $DEVICE.1 > /dev/null rc="$?" fi SUBCOMMAND=rewind ${tctl} -f $DEVICE rewind # wait for tape to rewind rc1="$?" [[ "$rc1" -ne 0 ]] && cleanup_m "$CMD_EC" \ "`${dspmsg} -s $MSGSET $MSGCAT 36 \ '0512-044 %s: Cannot access device %s.\n\ttctl %s failed with return code %s.' $NAME $DEVICE $SUBCOMMAND $rc `" fi if [[ $rc -ne 0 ]]; then print "\n" /usr/bin/dspmsg -s $MSGSET $MSGCAT 58 "\n0512-063 Attention: The media on %s is not readable! \n\tReplace media and try running backup again.\n" $DEVICE cleanup_m "$CMD_EC" else print "\n" echo "`${dspmsg} -s $MSGSET $MSGCAT 20 \ '0512-038 %s: Backup Completed Successfully.' $NAME`" fi fi TAPE_BOOTABLE=`bootinfo -e` [ "$NAME" = "mksysb" -a "$BOOTABLE" -eq 1 -a "$TAPE_BOOTABLE" -ne 1 ] && \ echo "`${dspmsg} -s $MSGSET $MSGCAT 25 \ '0512-043 %s: WARNING: This system does not support booting\n\tfrom a tape device. To install the mksysb image you will need\n\tto boot your system from bootable media.\n' $NAME`" } ########################################################## fail_if_wpar () { # Check to make sure that this is running in the # global environment. WPARID=`/usr/bin/uname -W` if [[ "$WPARID" != "0" ]]; then if [[ "$NAME" = "savewpar" ]]; then cleanup_m "$INSIDE_WPAR" \ "`${dspmsg} -s 1 wpars.cat 484 \ '%s: 0960-540 Operation is not permitted in a workload partition.' $NAME`" fi if [[ "$NAME" = "mksysb" ]]; then # we don't allow mksysb to run in a WPAR. cleanup_m "$INSIDE_WPAR" \ "`${dspmsg} -s 1 wpars.cat 484 \ '%s: 0960-540 Operation is not permitted in a workload partition.' $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 } ########################################################## fail_if_lvup () { # Check to make sure that there is no AIX liveupdate # in progress. LVUPRUN=`/usr/lib/corrals/corralquery -l` if [[ "$LVUPRUN" != "0" ]]; then if [ "$NAME" = "savewpar" ] || [ "$NAME" = "mksysb" ] || [ "$NAME" = "savevg" ] then # we don't allow savewpar, mksysb and savevg to run during an AIX live update. cleanup_m "$LVUP_RUN" \ "`${dspmsg} -s 1 wpars.cat 762 \ '%s: 0960-821 This command is not permitted during an AIX live update.' $NAME`" fi fi } ########################################################## 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. if [ "$DSK" = "" ] then DSK1="$DSK" /usr/bin/sed '/:$/i\ ' $IMAGE_DATA | /usr/bin/awk '{if($0 !~ "VG_SOURCE_DISK_LIST" && $0 !~ "LV_SOURCE_DISK_LIST") {print $0}}' | /usr/bin/grep -p "^"$STANZA: | \ /usr/bin/egrep -p "^[ ]+$ATTR[ ]*=[ ]*$DSK1" | \ /usr/bin/egrep "^[ ]+$RECORD[ ]*=" | \ /usr/bin/sed -e "s/[ ]*=/ =/" -e "s/ =[ ]*/ = /" | \ /usr/bin/awk '{ for (i = 3; i <= NF; i++) { print $i } }' else NEWDSK=$(echo "$DSK" | sed ' s/[+]/\\&/g') DSK1=$NEWDSK"$" ## fgrep added to handle . and _ characters in user data search ## fields (DSK). ## First grep searches for stanza types. ## fgrep eliminates problems with . and _ characters. ## First egrep ensures that only the specific search criteria is ## met (eliminates preceding and trailing characters). /usr/bin/sed '/:$/i\ ' $IMAGE_DATA | /usr/bin/awk '{if($0 !~ "VG_SOURCE_DISK_LIST" && $0 !~ "LV_SOURCE_DISK_LIST") {print $0}}' | /usr/bin/grep -p "^"$STANZA: | /usr/bin/fgrep -p -w $DSK | \ /usr/bin/egrep -p "^[ ]+$ATTR[ ]*=[ ]*$DSK1" | \ /usr/bin/egrep "^[ ]+$RECORD[ ]*=" | \ /usr/bin/sed -e "s/[ ]*=/ =/" -e "s/ =[ ]*/ = /" | \ /usr/bin/awk '{ for (i = 3; i <= NF; i++) { print $i } }' fi return 0 } ########################################################## get_backup_size () { BACKUPSIZE=0 BACKUPSHRINKSIZE=0 # Total up the size of the un-shrunken backup (when restored) # based off PP_SIZE times the number of PP from image.data. # This code gets all the info needed for size calculation from all # the lv_data stanzas in image.data # # savewpar can span multiple vgs so this has to be done in a # loop now vg_list=`get_stanza_data "vg_data" "VGNAME" "" "VGNAME"` for vg in $vg_list do PPSZ=`get_stanza_data "vg_data" "VGNAME" "$vg" "PPSIZE"` LV_LIST=`get_stanza_data "lv_data" "VOLUME_GROUP" "$vg" "LOGICAL_VOLUME"` VGBACKUPSIZE=`get_stanza_data "lv_data" "VOLUME_GROUP" "$vg" "PP" | ${awk} '{sumb += $1} END {print sumb}'` [[ -z $VGBACKUPSIZE ]] && VGBACKUPSIZE=1 (( VGBACKUPSIZE = VGBACKUPSIZE * PPSZ )) (( BACKUPSIZE = BACKUPSIZE + VGBACKUPSIZE )) for each_lv in $LV_LIST do TYPE=`get_stanza_data "lv_data" "LOGICAL_VOLUME" $each_lv "TYPE"` if [[ "$TYPE" != "jfs" && "$TYPE" != "jfs2" ]]; then LPs=`get_stanza_data "lv_data" "LOGICAL_VOLUME" $each_lv "LPs"` COPIES=`get_stanza_data "lv_data" "LOGICAL_VOLUME" $each_lv "COPIES"` (( TMPSZ = $LPs * $PPSZ * $COPIES )) (( BACKUPSHRINKSIZE = $BACKUPSHRINKSIZE + $TMPSZ )) fi done done # Okay, we want to add the file_system min sizes to the # paging, log and boot space (already in megs) so we # convert to megabytes and add 1 (meg) to account for # kornshell truncation remainder (due to divides). FSSHRINKSIZE=`${grep} FS_MIN_SIZE $IMAGE_DATA | \ LC_ALL=C ${awk} 'BEGIN{FS="="} {sums += $2/2048+1} END {print sums}'` [[ -z "$FSSHRINKSIZE" ]] && FSSHRINKSIZE=0 || FSSHRINKSIZE=`echo $FSSHRINKSIZE | LC_ALL=C ${awk} '{printf "%.2f", $0}'` (( BACKUPSHRINKSIZE = $BACKUPSHRINKSIZE + $FSSHRINKSIZE )) # If this is a savewpar backup, need to add in any space for # any writeable namefs and nfs mounted file systems if [ $NAME = "savewpar" ] then for i in $nfs_list $namefs_list do MISCFILESIZE=`${du} -s -x $i | ${cut} -f1` # In 512-byte blocks (( MISCFILESIZE = ( MISCFILESIZE + 2047 ) / 2048 )) # MB (( BACKUPSHRINKSIZE = BACKUPSHRINKSIZE + MISCFILESIZE )) (( BACKUPSIZE = BACKUPSIZE + MISCFILESIZE )) done fi } #################################################### getoptions () { # Parse command line arguments if [ $NAME = "mksysb" ] then set -- `${getopt} VXb:eiCmpPvaAF:t:x:ZNMGT? $*` # mksysb options elif [ $NAME = "savewpar" ] then set -- `${getopt} VXb:ef:impPvaABNRZT? $*` # savewpar options else set -- `${getopt} VXZb:ef:impPrvaAx:ZT? $*` # savevg options fi if [ "$1" == "" ] then cleanup_m "$USAGE_EC" "" fi while [ $1 != -- ] ## Parse flag arguements do case $1 in "-V") VERIFYFLAG="yes" ;; ## Verify the readability if tape "-X") XXFLAG="-X" ;; ## pass -X to mkszfile "-Z") ZFLAG="" ;; ## do not call backup with -Z "-b") BOPT="$2"; BFLAG="-b $BOPT" ;; ## get -b parameter "-i") IMAGE="y" ;; ## Create image.data file "-m") IMAGE="y"; MAPS="-m";; ## Create Maps data "-M") verify_alt_boot MULTIFLAG="yes";; ## Verify alt_disk boot image exist "-C") verify_alt_boot verify_boot_levels NEWBOOT="yes";; ## Verify alt_disk boot image exist "-e") EX="yes" ;; ## use exclude file "-v") VFLAG="-v" ;; ## pass -v to backup "-p") PFLAG="" ;; ## don't pass -p flag to backup "-a") AFLAG="" ;; ## don't pass -U flag to backup "-P") EXFLAG="-e" ;; ## use exclude_packing file "-N") if [ $NAME = "savewpar" ] then NFSFLAG="y" ## Include rw NFS filesystems - savewpar elif [ $NAME = "mksysb" ] then NNFLAG="y" ## Include in the backup filesystems in WPARS in the Defined State IMAGE="y" ## we create a new image.data file fi ;; "-R") if [ $NAME = "savewpar" ] then METADATAONLY="y" ## Back up meta data only. (i.e. specfile) fi ;; "-r") RFLAG="y" ;; ## backup metadata only "-f") DEVICE=$2 ;; ## get backup device for savevg "-A") DMAPIFLAG="y" ;; ## back up DMAPI filesystem "-B") NAMEFSFLAG="n" ;; ## do not back up namefs-mounted files (savewpar) "-F") BACKUPFILE=$2 VG="rootvg" verify_image ;; ## volume group backup file "-t") TMPDIR=$2/mksysb.$$ mkdir -p $TMPDIR ;; ## temp space for bootpkg "-T") SNAPFLAG="y" ;; ## Use snapshots "-G") GFLAG="-G" ;; # Global file systems only - no WPAR files "-x") XFSLIST=$2; XFSFLAG="-x $XFSLIST" # FS list to exclude shift;; "-?") cleanup_m "$USAGE_EC" "";; ## Display usage message esac shift done if [[ $BOPT != "NONE" && $BOPT != +([0-9]) ]]; then cleanup_m "$USAGE_EC" "" fi if [[ $SNAPFLAG = "y" && -n "$BACKUPFILE" ]]; then dspmsg -s 5 $MSGCAT 90 \ '0512-331 %s: option %s and %s are mutually exclusive.\n' $NAME -T -F cleanup_m "$USAGE_MB" "" fi if [[ -n "$XFSLIST" ]] && [[ ! -f "$XFSLIST" ]]; then cleanup_m "$BAD_FILE" \ "`${dspmsg} -s 2 $MSGCAT 39 \ '0512-072 %s: Cannot access %s.\n' $NAME $XFSLIST`" fi if [[ $NAME != "mksysb" && $NEWBOOT = "yes" ]]; then dspmsg -s 1 $MSGCAT 106 \ '0512-075 %s: option %s is only supported with the mksysb command.\n' $NAME -C cleanup_m "$USAGE_MB" "" fi if [[ $IMAGE != "y" && $NEWBOOT = "yes" ]]; then dspmsg -s 1 $MSGCAT 109 \ '0512-077 %s: option %s is required with %s.\n' $NAME -i -C cleanup_m "$USAGE_MB" "" fi set `${getopt} $*` #Get Device/Volume Group Name if [ $NAME = "mksysb" ] then DEVICE=$1 VG="rootvg" [ -n "$TMPDIR" -a -z "$BACKUPFILE" ] && cleanup_m "$USAGE_EC" "" [ -n "$NNFLAG" -a -n "$GFLAG" ] && cleanup_m "$USAGE_EC" "" elif [ $NAME = "savevg" ] then VG=$1 if [ "$VG" = "rootvg" ] && [ "$RFLAG" = "y" ] then cleanup_m "$INVALID_VG" "" ## Only user volume groups allowed. fi [ "$DEVICE" = "" ] && DEVICE="/dev/rmt0" [ "$VG" = "" ] && cleanup_m "$INVALID_VG" "" ${lsvg} $VG >/dev/null 2>&1 [ $? -ne 0 ] && cleanup_m "$INVALID_VG" "" else VG=null WPAR=$1 [ "$WPAR" = "" ] && cleanup_m "$INVALID_WPAR" "" wpar_lscorral_cache "$WPAR" ROOTVGWPAR=$LSWPAR_rootvgwpar ROOTVGWPARSTATE_AT_BACKUPSTART=$LSWPAR_state WPAR_OSTYPE=$LSWPAR_ostype [[ "$LSWPAR_type" != 'S' ]] && cleanup_m "$INVALID_WPAR" "" cor_lockcorral "$WPAR" || cleanup_m "$LOCK_EC" "" # If WPAR is not active, need to mount the file systems WPARSTATE=$LSWPAR_state 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 if [[ "$ROOTVGWPAR" != "yes" ]]; then cor_mount_fs $WPAR >/dev/null else start_rootvgwpar_if_defined fi ;; esac [ "$DEVICE" = "" ] && DEVICE="/dev/rmt0" fi # Are there any jfs2 file systems in the volume group, no need to use # snapshots if no jfs2 file systems if [ "$SNAPFLAG" = "y" ] then LANG=C lsvg -l $VG | awk '{print $2 " " $6}' | grep -w jfs2 | grep open >/dev/null 2>&1 if [ "$?" -ne 0 ] then SNAPFLAG= else FREE_SP=`LANG=C lsvg $VG | grep "FREE PP" | awk 'BEGIN{FS=":"} {print $3}'` FREE_SP=`echo $FREE_SP | awk 'BEGIN{FS=" "} {print $1}'` (( FREE_SP = $FREE_SP / 2 )) fi fi if [ "$DEVICE" = "" ] then cleanup_m "$USAGE_EC" "" fi osversion=`/usr/bin/uname -v` || osversion=7 osrelease=`/usr/bin/uname -r` || osrelease=1 # Disable use of -Z flag within Version 5 WPARs if [[ -n "$ZFLAG" ]] then if [[ $osversion -eq 5 ]] then ZFLAG="" # Encrypted file systems not supported prior to version 6 fi fi # Disable use of -a flag within Version 5.2 WPARs if [[ -n "$AFLAG" ]] then if [[ $osversion -eq 5 ]] && [[ $osrelease -eq 2 ]] then AFLAG="" # No ACL or extended attribute backups prior to 5.3 fi fi BASEDEV=`${basename} $DEVICE` DEVCLASS="`/usr/sbin/lsdev -r class -l $BASEDEV`" DEVTYPE="`/usr/sbin/lsdev -r type -l $BASEDEV`" if [[ "$DEVCLASS" = "disk" && "$DEVTYPE" = "mstor" ]] then MASS_STORAGE=1 fi if [[ "$VERIFYFLAG" = "yes" || -n "$BACKUPFILE" ]] && \ [[ "$DEVICE" != *"rmt"* && "$DEVCLASS" != "cdrom" && "$DEVCLASS" != "usbms" && $MASS_STORAGE -ne 1 ]]; then cleanup_m "$USAGE_EC" "" fi [ `${expr} "$DEVICE/" : "[/]"` -eq 0 ] && cleanup_m "$CMD_EC" \ "`${dspmsg} -s $MSGSET $MSGCAT 3 \ '0512-006 %s: Backup device or file name must start with a '/'.' $NAME`" EXCL_DEV="" # exclude archive file but not device (ie. rmt0) [ `${dirname} $DEVICE` != "/dev" ] && EXCL_DEV="$DEVICE" } #################################################### # # savewpar only - find writable namefs mounts to # process - /ro/w matches ro as a word. Do not # include /proc no matter how it was mounted. get_writable_namefs_mounts () { namefs_list=`/usr/sbin/lswpar -qcM -a vfs,device,nodename,mountpoint,options $WPAR | ${grep} ^namefs | ${awk} -F: '($5 !~ /ro/w) && ($2 != "/proc") {print $4}' | ${grep} -v '^/proc$'` } #################################################### # # savewpar only - find writable NFS mounts to # process - /ro/w matches ro as a word get_writable_nfs_mounts () { nfs_list=`/usr/sbin/lswpar -qcM -a vfs,device,nodename,mountpoint,options $WPAR | ${grep} ^nfs | ${awk} -F: '$5 !~ /ro/w {print $4}'` } #################################################### make_bootape () { device=$1 typeset olddir="" echo "" ## This function is only called if the volume group backed up is ## rootvg. If the command used is mksysb, then we create real images ## and if the command used is savevg (not mksysb) then we create dummy ## images, but in both cases, the location on the tape must be the same. ## ## Note: Tape device is not bootable on IA64, so we will create dummy ## images from mksysb in this case. if [ $NAME = "mksysb" -a $BOOT_PLATFORM -ne 4 ] then ${dspmsg} -s $MSGSET $MSGCAT 32 'Creating tape boot image ' else ${dspmsg} -s $MSGSET $MSGCAT 41 'Creating pseudo tape boot image ' fi # As a progress indicator print dots every 10 seconds during # the system backup while :; do ${sleep} 10 echo ".\c" done & PID=$! SUBCOMMAND=rewind ${tctl} -f $device rewind rc="$?" [ "$rc" -ne 0 ] && cleanup_m "$CMD_EC" \ "`${dspmsg} -s $MSGSET $MSGCAT 36 \ '0512-044 %s: Cannot access device %s.\n\ttctl %s failed with return code %s.' $NAME $device $SUBCOMMAND $rc `" # # put the bosboot image on the tape (if not on IA64) # if [ "$NAME" = "mksysb" ] then KERNEL="-k /usr/lib/boot/unix_64" # # Check to see if machine is IA64. If so, make dummy images # if [ "$BOOT_PLATFORM" -eq 4 ] then echo "Dummy Boot Image" | ${dd} of=$device bs=512 conv=sync >/dev/null 2>&1 rc="$?" [ "$rc" -ne 0 ] && cleanup_m "$CMD_EC" \ "`${dspmsg} -s $MSGSET $MSGCAT 11 \ '0512-008 %s: The %s command failed with return code of %s. Backup canceled.' $NAME $dd $rc`" else if [ -z "$BACKUPFILE" ] then ${bosboot} -d$device -a $KERNEL > $BOSBOOT_LOG 2>&1 rc="$?" ${cat} $BOSBOOT_LOG >&2 else [ -z "$TMPDIR" ] && TMPDIR=$mksysb_tmpdir bootpkg -m $BACKUPFILE -d tape -l $TMPDIR -O rc="$?" [ "$rc" -ne 0 ] && cleanup_m "$CMD_EC" \ "`${dspmsg} -s $MSGSET $MSGCAT 18 \ '0512-016 %s: Attempt to create a bootable tape failed:\n\tbosboot -d %s -a failed with return code %s.' $NAME $device $rc`" dd if=$TMPDIR/tape.bi of=$device bs=512 conv=sync >/dev/null 2>&1 rc="$?" fi [ "$rc" -ne 0 ] && cleanup_m "$CMD_EC" \ "`${dspmsg} -s $MSGSET $MSGCAT 18 \ '0512-016 %s: Attempt to create a bootable tape failed:\n\tbosboot -d %s -a failed with return code %s.' $NAME $device $rc`" fi else # # put a "dummy" bosboot image on the tape # echo "Dummy Boot Image" | ${dd} of=$device bs=512 conv=sync >/dev/null 2>&1 rc="$?" [ "$rc" -ne 0 ] && cleanup_m "$CMD_EC" \ "`${dspmsg} -s $MSGSET $MSGCAT 11 \ '0512-008 %s: The %s command failed with return code of %s. Backup canceled.' $NAME $dd $rc`" fi # # put the bosinst image on the tape # if [ -n "$BACKUPFILE" ] then olddir=`pwd` cd $TMPDIR ${mkdir} -p $TMPDIR/usr/lpp/bosinst/tape echo "/tmp/vgdata" >> $TMPDIR/tapefiles1 ${sed} -e 's:^/:./:g' $TMPDIR/tapefiles1 > $TMPDIR/tapefiles2 mv $TMPDIR/tapefiles1 $TMPDIR/usr/lpp/bosinst/tape/tapefiles1 xargs /usr/sbin/restore -xqdf $BACKUPFILE < $TMPDIR/tapefiles2 > /dev/null cd $olddir fi ${mkinsttape} $device $TMPDIR >/dev/null rc=$? [ "$rc" -ne 0 ] && cleanup_m "$CMD_EC" \ "`${dspmsg} -s $MSGSET $MSGCAT 19 \ '0512-021 %s: Attempt to create a bootable tape failed:\n\tmkinsttape %s failed with return code %s.' $NAME $device $rc`" # # place a dummy toc on the tape # echo "Dummy tape TOC" | ${dd} of=$device bs=512 conv=sync >/dev/null 2>&1 [ "$NAME" = "mksysb" ] && BOOTABLE=1 # tape is bootable # Kill dots from 'Creating tape boot image.' message kill_pid "$PID" echo "" } #################################################### ## Create backup.data file with lv/fs info, and ## lslpp info (if rootvg backup). #################################################### make_backup_data () { [[ ! -d $DATA_BASEDIR ]] && mkdir $DATA_BASEDIR [[ ! -d $DATA_DIR ]] && mkdir $DATA_DIR [[ ! -d $DATA_DIR/vgdata ]] && mkdir $DATA_DIR/vgdata get_backup_size echo "================================" > $BACKUP_DATA if [ "$NAME" != "savewpar" ]; then if [ "$VG" = "rootvg" ]; then lsvg -l rootvg >> $BACKUP_DATA 2> /dev/null echo "================================" >> $BACKUP_DATA lslpp -L >> $BACKUP_DATA 2> /dev/null echo "================================" >> $BACKUP_DATA lslpp -Lc >> $BACKUP_DATA 2> /dev/null else lsvg -l $VG >> $BACKUP_DATA 2> /dev/null fi else # Grab the wpar lv and fs information and format it like lsvg -l # for consistency localfs_devs=`${lswpar} -qcM -a vfs,device $WPAR | ${grep} ^jfs | ${awk} -F: '{print $2}' | ${sed} 's:^/dev/::'` vg_list=`get_stanza_data "vg_data" "VGNAME" "" "VGNAME"` # A WPAR backup can span multiple volume groups, so check # them all: for wpar_vg in $vg_list do ${lsvg} -l $wpar_vg | ( read line; printf "$line\n" read line; printf "$line\n" # Print out the lv information for every lv which is # the device for one of the WPAR file systems while read line do lvdev=`echo $line | ${awk} '{print $1}'` echo $localfs_devs | ${grep} -q -w "$lvdev" if [ $? -eq 0 ] then mountpt=`echo $line | ${awk} '{print $NF}'` wparmnt=`canonical $mountpt` printf "$line\n" | ${sed} "s:${mountpt}$:$wparmnt:" fi done ) >> $BACKUP_DATA done echo "================================" >> $BACKUP_DATA if [[ $WPAR_OSTYPE = 0 ]] then # if WPAR is active(A) or active in service mode(S) /usr/sbin/lswpar -qca state $WPAR | /usr/bin/grep -E 'A|S' > /dev/null 2>&1 if [[ $? == 0 ]]; then ${clogin} $WPAR /usr/bin/lslpp -L >> $BACKUP_DATA 2> /dev/null else # WPAR state is not in A or S. ${chroot} $WPAR_BASEDIR /usr/bin/lslpp -L >> $BACKUP_DATA 2> /dev/null fi else ${chroot_cre} $WPAR_OSTYPE $WPAR_BASEDIR /usr/bin/lslpp -L >> $BACKUP_DATA 2> /dev/null fi echo "================================" >> $BACKUP_DATA if [[ $WPAR_OSTYPE = 0 ]] then # if WPAR is active(A) or active in service mode(S) /usr/sbin/lswpar -qca state $WPAR | /usr/bin/grep -E 'A|S' > /dev/null 2>&1 if [[ $? == 0 ]]; then ${clogin} $WPAR /usr/bin/lslpp -Lc >> $BACKUP_DATA 2> /dev/null else # WPAR state is not in A or S. ${chroot} $WPAR_BASEDIR /usr/bin/lslpp -Lc >> $BACKUP_DATA 2> /dev/null fi else ${chroot_cre} $WPAR_OSTYPE $WPAR_BASEDIR /usr/bin/lslpp -Lc >> $BACKUP_DATA 2> /dev/null fi fi echo "================================" >> $BACKUP_DATA echo "#Shrink Size:Full Size:VG Data Only:Multibos" >> $BACKUP_DATA if [ "$RFLAG" = "y" ]; then echo "$BACKUPSHRINKSIZE:$BACKUPSIZE:yes" >> $BACKUP_DATA echo "" ${dspmsg} -s $MSGSET $MSGCAT 61 'Backing up user Volume Group information files only.' else echo "$BACKUPSHRINKSIZE:$BACKUPSIZE:no:$MULTIFLAG" >> $BACKUP_DATA fi if [ "$NAME" = "savewpar" ] && [ -n "$nfs_list" ] then echo "================================" >> $BACKUP_DATA for i in $nfs_list do dfdata=`${df} $i | ${tail} +2l | ${awk} '{print $1,$2,$3}'` diskusage=`${du} -s -x $i` echo $dfdata $diskusage >> $BACKUP_DATA done fi if [ "$NAME" = "savewpar" ] && [ -n "$namefs_list" ] then # NFS data has to come before namefs data, so add the delimiter # for the section if there was no NFS data if [ ! -n "$nfs_list" ] then echo "================================" >> $BACKUP_DATA fi echo "================================" >> $BACKUP_DATA for i in $namefs_list do dfdata=`${df} $i | ${tail} +2l | ${awk} '{print $1,$2,$3}'` diskusage=`${du} -s -x $i` echo $dfdata $diskusage >> $BACKUP_DATA done fi } ################################# rebase ####################################### # # NAME: rebase () # # DESCRIPTION: output path rebased to base directory for backup # # INPUT: # $1 = pathname # # OUTPUT: # global path to pathname # # # rebase () { fn=$1 if [ "$NAME" != "savewpar" ] then echo $fn elif [ "$fn" = "/" ] then echo $WPAR_BASEDIR else echo $WPAR_BASEDIR${fn} fi } #################################################### tddupdate () { NOPVID=0000000000000000 rm "$tmp_tdd" >/dev/null 2>&1 ${sed} '/^[a-z_]*:$/i\ ' $BOSINST_DATA | ${grep} -vp ^target_disk_data: > "$tmp_newbidata" # Need to be sure rootvg is not part of the volume group name DISKLIST=$( ${lspv} | ${awk} '{print $1 " " $3}' | egrep " rootvg$" | ${cut} -d" " -f1 ) for disk in $DISKLIST do pvid= pvid=$( ${getlvodm} -p $disk 2>/dev/null ) pvid=${pvid:-"$NOPVID"} # # Do not add hot spare disks. # if [ "`lquerypv -p $pvid -N $disk -S`" = "0" ] then physical_location= conn= loc= size= echo >> "$tmp_tdd" echo "target_disk_data:" >> "$tmp_tdd" pvid=$( ${getlvodm} -p $disk 2>/dev/null ) pvid=${pvid:-"$NOPVID"} echo " PVID = "$pvid >> "$tmp_tdd" physical_location=$( ${lsdev} -Cc disk -F "physloc" -l $disk ) echo " PHYSICAL_LOCATION = "$physical_location >> "$tmp_tdd" conn=$( ${lsdev} -Cc disk -F "parent//connwhere" -l $disk ) conn=${conn:-"//"} echo " CONNECTION = "$conn >> "$tmp_tdd" loc=$( ${bootinfo} -o $disk ) echo " LOCATION = "$loc >> "$tmp_tdd" size=$( ${bootinfo} -s $disk ) echo " SIZE_MB = "$size >> "$tmp_tdd" echo " HDISKNAME = "$disk >> "$tmp_tdd" fi done ${cat} "$tmp_tdd" >> "$tmp_newbidata" ${cp} "$tmp_newbidata" "$BOSINST_DATA" } verify_boot_image () { SUBCOMMAND=rewind ${tctl} -f $DEVICE $SUBCOMMAND rc="$?" [ "$rc" -ne 0 ] && cleanup_m "$CMD_EC" \ "`${dspmsg} -s $MSGSET $MSGCAT 36 \ '0512-044 %s: Cannot access device %s.\n\ttctl %s failed with return code %s.'\ $NAME $DEVICE $SUBCOMMAND $rc `" ${dd} if=$DEVICE of=/dev/null bs=512 conv=sync >/dev/null 2>&1 rc="$?" [ "$rc" -ne 0 ] && cleanup_m "$CMD_EC" \ "`${dspmsg} -s $MSGSET $MSGCAT 57 \ '\n0512-061 Attention: The boot image created on %s is corrupt! \n\tReplace media and try running backup again.\n' $DEVICE`" } # No secondary dump VG resource variables #################################################### nosdd() { ${sed} '/^[a-z_]*:$/i\ ' $BOSINST_DATA | ${grep} -vp ^secondary_dumpvg_disk_data: > "$tmp_newbidata" ${sed} s'/.*SECONDARY =.*/ SECONDARY = /' $tmp_newbidata > "$tmp_newbidata.tmp" ${sed} s'/.*SEC_VGNAME =.*/ SEC_VGNAME = /' $tmp_newbidata.tmp > "$tmp_newbidata" [[ -s $tmp_newbidata ]] && ${cp} "$tmp_newbidata" "$BOSINST_DATA" return 0 } # Add secondary dump VG resource stanzas and vars #################################################### tsddupdate () { typeset ERROR='eval nosdd ; return 1' typeset LV= typeset VG= typeset SECDEV= typeset DISKLIST= typeset VGID= typeset LVCOUNT= NOPVID=0000000000000000 rm "$tmp_tdd" >/dev/null 2>&1 ${sed} '/^[a-z_]*:$/i\ ' $BOSINST_DATA | ${grep} -vp ^secondary_dumpvg_disk_data: > "$tmp_newbidata" # Check if there if is a LV as a secondary dump dev # that is on a vg other than rootvg SECDEV=$(LANG=C sysdumpdev -l | ${awk} '$1 == "secondary" {print $2}') [[ -z "$SECDEV" ]] && return 0 LV=$(${basename} $SECDEV) VG=$(LANG=C ${lslv} $LV 2>/dev/null | ${awk} '$0 ~ /VOLUME GROUP/ {print $6}') [[ -z "$VG" ]] && return 1 [[ "$VG" = "rootvg" ]] && return 0 # If we are here, the VG is not rootvg # Find the disks that make up that LV DISKLIST=$(LANG=C ${lslv} -l $LV 2>/dev/null | ${awk} '$1 ~ /^hdisk.*/ {print $1}') [[ -z "$DISKLIST" ]] && $ERROR # Get the VGID VGID=$(LANG=C ${lsvg} -L $VG 2>/dev/null | awk '$0 ~ /VG IDENTIFIER/ {print $6}') [[ -z $VGID ]] && $ERROR # Now check that the dump lv is the only LV on the VG LVCOUNT=$(lqueryvg -g $VGID -n 2>/dev/null) [[ "$LVCOUNT" != 1 ]] && $ERROR # Ok, we have VG, LV and DISKLIST # Populate the stanzas for disk in $DISKLIST do pvid= pvid=$( ${getlvodm} -p $disk 2>/dev/null ) pvid=${pvid:-"$NOPVID"} # # Do not add hot spare disks. # if [ "`lquerypv -p $pvid -N $disk -S`" = "0" ] then physical_location= conn= loc= size= echo >> "$tmp_tdd" echo "secondary_dumpvg_disk_data:" >> "$tmp_tdd" pvid=$( ${getlvodm} -p $disk 2>/dev/null ) pvid=${pvid:-"$NOPVID"} echo " PVID = "$pvid >> "$tmp_tdd" physical_location=$( ${lsdev} -Cc disk -F "physloc" -l $disk ) echo " PHYISICAL_LOCATION = "$physical_location >> "$tmp_tdd" conn=$( ${lsdev} -Cc disk -F "parent//connwhere" -l $disk ) conn=${conn:-"//"} echo " CONNECTION = "$conn >> "$tmp_tdd" loc=$( ${bootinfo} -o $disk ) echo " LOCATION = "$loc >> "$tmp_tdd" size=$( ${bootinfo} -s $disk ) echo " SIZE_MB = "$size >> "$tmp_tdd" echo " HDISKNAME = "$disk >> "$tmp_tdd" fi done # If there is anything to add, do it if [[ -s "$tmp_tdd" ]]; then ${cat} "$tmp_tdd" >> "$tmp_newbidata" fi ${cp} "$tmp_newbidata" "$BOSINST_DATA" # Set dump stanza ${sed} '/^[a-z_]*:$/i\ ' $BOSINST_DATA | ${grep} -p ^dump: | ${grep} '.' > "$tmp_newbidata" # If there is a dump stanza if [[ -s $tmp_newbidata ]]; then if grep -q '.*SECONDARY =.*' $tmp_newbidata ; then ${sed} -e "s/.*SECONDARY =.*/ SECONDARY = \/dev\/$LV/" $tmp_newbidata > "$tmp_newbidata.tmp" ${cp} $tmp_newbidata.tmp $tmp_newbidata else echo " SECONDARY = /dev/$LV " >> $tmp_newbidata fi if grep -q '.*SEC_VGNAME =.*' $tmp_newbidata ; then ${sed} -e "s/.*SEC_VGNAME =.*/ SEC_VGNAME = $VG/" $tmp_newbidata > "$tmp_newbidata.tmp" ${cp} $tmp_newbidata.tmp $tmp_newbidata else echo " SEC_VGNAME = $VG " >> $tmp_newbidata fi else echo >> "$tmp_newbidata" echo "dump:" >> "$tmp_newbidata" echo " SECONDARY = /dev/$LV" >> "$tmp_newbidata" echo " SEC_VGNAME = $VG" >> "$tmp_newbidata" fi # If there is anything to add, do it if [[ -s "$tmp_newbidata" ]]; then ${sed} '/^[a-z_]*:$/i\ ' $BOSINST_DATA | ${grep} -vp ^dump: > "$tmp_newbidata.tmp" ${cp} "$tmp_newbidata.tmp" "$BOSINST_DATA" ${cat} "$tmp_newbidata" >> "$BOSINST_DATA" fi return 0 } ######################################################### # Get_Rootvg_ISCSI_Targets: # Update the bosinst.data with target_iscsi_data stanzas # if any of the disks in rootvg is an iscsi disk # This function returns 0 unless there are # problems adding data to bosinst.data in which case # returns a non-zero value. ######################################################### Get_Rootvg_ISCSI_Targets () { typeset ERROR='eval return 1' typeset DISKLIST= typeset ISCSI_DISKS= typeset IS_ISCSI= typeset IS_SW= typeset IS_TOE= typeset SW_DISKS= typeset TOE_DISKS= typeset BUF=$tmp_tid typeset DISK_PARENT= typeset ADAPTER_PARENT= typeset disk= # SW Initiator Array vars typeset SW_ADAPTERS= typeset SW_GROUPS= typeset SW_TARGETS= typeset SW_INITIATORS= typeset SW_PORTS= typeset SW_HOSTS_IPS= # TOE Targets Array vars typeset TOE_ADAPTERS= typeset TOE_GROUPS= typeset TOE_TARGETS= typeset TOE_INITIATORS= typeset TOE_PORTS= typeset TOE_HOSTS_IP= typeset TOE_ADAPTERS_IP= typeset TOE_ADAPTERS_GW= typeset TOE_ADAPTERS_SNM= # Array search loop control typeset -i INDEX=0 typeset -i i=0 typeset FOUND=FALSE # bosinst.data fields for target_iscsi_data: typeset DISK_ADAPTER= typeset ISCSI_GROUP= typeset TARGET_NAME= typeset INITIATOR_NAME= typeset PORT= typeset IP= typeset SW_INITIATOR= # TOE specific typeset TOE_ADAPTER_IP= typeset TOE_ADAPTER_GW= typeset TOE_ADAPTER_SNM= #################### # Clear buffer file #################### ${rm} $BUF >/dev/null 2>&1 ###################### # Get the rootvg disks ###################### DISKLIST=$(${lsvg} -p rootvg | ${awk} '{if ($0 ~ /^hdisk.*/) print $1}') ########################################### # Loop through the list to find iSCSI disks # they have PdDvLn = "disk/iscsi/osdisk" ########################################### for disk in $DISKLIST do IS_ISCSI=FALSE IS_ISCSI=$(${odmget} -q name=$disk CuDv | \ ${awk} '$1 == "PdDvLn" && $3 ~ /iscsi/ {print "TRUE"}') if [[ "$IS_ISCSI" = "TRUE" ]]; then ISCSI_DISKS="$ISCSI_DISKS $disk" fi done ###################### # No disks, we're done ###################### [[ -z "$ISCSI_DISKS" ]] && return 0 ############################################ # We have iSCSI disks, make two lists, # one for SW and one for TOE # SW disks have PdDvLn = "driver/node/iscsi" # TOE disks have a grandparent with # PdDvLn = "adapter/xxxxx/xxxxx" ############################################ for disk in $ISCSI_DISKS do IS_SW=FALSE DISK_PARENT=$(${lsdev} -l $disk -F"parent" 2>/dev/null) if [[ -n $DISK_PARENT ]]; then IS_SW=$(${odmget} -q name=$DISK_PARENT CuDv | \ ${awk} '$1 == "PdDvLn" && $3 ~ "driver/node/iscsi" {print "TRUE"}') fi # If SW, add it to list if [[ "$IS_SW" = "TRUE" ]]; then SW_DISKS="$SW_DISKS $disk" continue fi # If we are here, the disk is not SW, # as a sanity check, verify it is really TOE IS_TOE=FALSE ADAPTER_PARENT=$(${lsdev} -l $DISK_PARENT -F"parent" 2>/dev/null) if [[ -n $ADAPTER_PARENT ]]; then IS_TOE=$(${odmget} -q name=$ADAPTER_PARENT CuDv | \ ${awk} '$1 == "PdDvLn" && $3 ~ /adapter/ {print "TRUE"}') fi # If TOE, add it to list if [[ "$IS_TOE" = "TRUE" ]]; then TOE_DISKS="$TOE_DISKS $disk" continue fi done ####################################### # If there are SW disks, create a file # with the target_iscsi_data stanzas ####################################### [[ -n "$SW_DISKS" ]] && Create_ISCSI_SW_Targets $SW_DISKS ####################################### # If there are TOE disks, create a file # with the target_iscsi_data stanzas ####################################### [[ -n "$TOE_DISKS" ]] && Create_ISCSI_TOE_Targets $TOE_DISKS ##################################################### # Remove existing target_iscsi_data stanzas # and save a temporary bosinst.data file without them ##################################################### ${sed} '/^[a-z_]*:$/i\ ' $BOSINST_DATA | ${grep} -vp ^target_iscsi_data: > "$tmp_newbidata" ################################## # Check for the targets files, # and concatenate if there are two # then add to the bosinst.data ################################## if [[ -s "$ISCSI_SW_TARGETS_FILE" ]]; then ${cp} $ISCSI_SW_TARGETS_FILE $BUF fi if [[ -s "$ISCSI_TOE_TARGETS_FILE" ]]; then [[ -s "$BUF" ]] && echo >> $BUF ${cat} $ISCSI_TOE_TARGETS_FILE >> $BUF fi # If there is anything to add, do it if [[ -s "$BUF" ]]; then ${cat} "$BUF" >> "$tmp_newbidata" fi # Error if the file is not good [[ ! -s "$tmp_newbidata" ]] && $ERROR ${cp} "$tmp_newbidata" "$BOSINST_DATA" || $ERROR return 0 } # Usage: Create_ISCSI_SW_Targets Create_ISCSI_SW_Targets() { typeset ERROR='eval return 1' typeset DISKLIST="$*" typeset BUF= # Hold current target values typeset CURR_TARGET= typeset CURR_PORT= typeset CURR_IP= typeset CURR_INITIATOR= typeset CURR_GROUP= typeset CURR_DISC_POLICY= typeset CURR_ADAPTER_IP= typeset CURR_ADAPTER_GW= typeset CURR_ADAPTER_SNM= # SW Initiator Array vars typeset SW_ADAPTERS= typeset SW_GROUPS= typeset SW_TARGETS= typeset SW_INITIATORS= typeset SW_PORTS= typeset SW_HOSTS_IPS= typeset SW_DISC_POLICY= typeset SW_ADAPTER_IPS= typeset SW_ADAPTER_GWS= typeset SW_ADAPTER_SNMS= # Array search loop control typeset -i INDEX=0 typeset -i i=0 typeset FOUND=FALSE # Loop to find disks with iscsi parent # adapters for both TOE or SW Initiator. # When found, if the target is not known # already collect the required information and # insert it in the bosinst.data file for disk in $DISKLIST do # Get the disk adapter DISK_ADAPTER=$($lsdev -l $disk -F"parent" 2>/dev/null) [[ -z "$DISK_ADAPTER" ]] && $ERROR # Get the target name, port and ip CURR_TARGET=$($lsattr -El $disk -F "attribute value" | \ ${awk} '$1 == "target_name" {print $2}') CURR_PORT=$($lsattr -El $disk -F "attribute value" | \ ${awk} '$1 == "port_num" {print $2}') CURR_IP=$($lsattr -El $disk -F "attribute value" | \ ${awk} '$1 == "host_addr" {print $2}') CURR_INITIATOR=$($lsattr -El $DISK_ADAPTER -F "attribute value" | \ ${awk} '$1 == "initiator_name" {print $2}') CURR_DISC_POLICY=$($lsattr -El $DISK_ADAPTER -F "attribute value" | \ ${awk} '$1 == "disc_policy" {print $2}') # The only supported discovery policy for # iscsi SW initiator is "odm" if [[ "$CURR_DISC_POLICY" = "odm" ]]; then CURR_GROUP="static" else # Don't record this target continue fi # Need to save ethernet IP settings to support # non-prompted mksysb restore from CD (NIM will ignore these fields) WORKDIR=`/usr/lib/instl/libinst_mkworkdir` || $ERROR LANG=C /usr/sbin/route -n get $CURR_IP > $WORKDIR/route.info || $ERROR ${egrep} "interface|gateway" $WORKDIR/route.info > $WORKDIR/route.grep || $ERROR IFS_SAVE=$IFS IFS=" " ${cat} $WORKDIR/route.grep | while read RT_LINE do set -- $RT_LINE if [[ $1 = gateway: ]] then CURR_ADAPTER_GW=$2 elif [[ $1 = interface: ]] then EN_IF=$2 fi done # Get ip address and netmask from ifconfig LANG=C /usr/sbin/ifconfig $EN_IF 2>/dev/null > $WORKDIR/ip.info || $ERROR ${grep} inet $WORKDIR/ip.info > $WORKDIR/ip.grep || $ERROR set -- `${cat} $WORKDIR/ip.grep` CURR_ADAPTER_IP=$2 CURR_ADAPTER_SNM=$4 ${rm} -rf $WORKDIR IFS=$IFS_SAVE # append ethernet interface to DISK_ADAPTER DISK_ADAPTER=$DISK_ADAPTER:$EN_IF # We now have all the values for the # current target, compare to the saved ones # if any of the values is different, save it, # if they are all the same, skip it. i=0 while [[ $i -lt $INDEX ]] do if [[ "$DISK_ADAPTER" = "${SW_ADAPTERS[i]}" ]] && \ [[ "$CURR_TARGET" = "${SW_TARGETS[i]}" ]] && \ [[ "$CURR_PORT" = "${SW_PORTS[i]}" ]] && \ [[ "$CURR_IP" = "${SW_HOSTS_IPS[i]}" ]] && \ [[ "$CURR_INITIATOR" = "${SW_INITIATORS[i]}" ]] && \ [[ "$CURR_DISC_POLICY" = "${SW_DISC_POLICY[i]}" ]] && \ [[ "$CURR_ADAPTER_IP" = "${SW_ADAPTER_IPS[i]}" ]] && \ [[ "$CURR_ADAPTER_GW" = "${SW_ADAPTER_GWS[i]}" ]] && \ [[ "$CURR_ADAPTER_SNM" = "${SW_ADAPTER_SNMS[i]}" ]] && \ [[ "$CURR_GROUP" = "${SW_GROUPS[i]}" ]]; then FOUND=TRUE break else FOUND=FALSE (( i = i + 1 )) fi done # If the adapter is found... # continue to the next adapter and skip # adding it to the file [[ "$FOUND" = "TRUE" ]] && continue # The adapter was not found, add to # the list and increase the index SW_ADAPTERS[$INDEX]=$DISK_ADAPTER SW_TARGETS[$INDEX]=$CURR_TARGET SW_PORTS[$INDEX]=$CURR_PORT SW_HOSTS_IPS[$INDEX]=$CURR_IP SW_INITIATORS[$INDEX]=$CURR_INITIATOR SW_DISC_POLICY[$INDEX]=$CURR_DISC_POLICY SW_GROUPS[$INDEX]=$CURR_GROUP SW_ADAPTER_IPS[$INDEX]=$CURR_ADAPTER_IP SW_ADAPTER_GWS[$INDEX]=$CURR_ADAPTER_GW SW_ADAPTER_SNMS[$INDEX]=$CURR_ADAPTER_SNM (( INDEX = INDEX + 1 )) done # If we are here, we are ready # to write the target_iscsi_stanzas i=0 BUF=$ISCSI_SW_TARGETS_FILE ${rm} $BUF 2>/dev/null while [[ $i -lt $INDEX ]] do if [[ -n ${SW_ADAPTERS[i]} ]]; then echo >> "$BUF" echo "target_iscsi_data:" >> "$BUF" echo " ADAPTER_NAME = "${SW_ADAPTERS[i]} >> "$BUF" echo " ISCSI_GROUP = "${SW_GROUPS[i]} >> "$BUF" echo " TARGET_NAME = "${SW_TARGETS[i]} >> "$BUF" echo " INITIATOR_NAME = "${SW_INITIATORS[i]} >> "$BUF" echo " PORT_NUMBER = "${SW_PORTS[i]} >> "$BUF" echo " IP_ADDRESS = "${SW_HOSTS_IPS[i]} >> "$BUF" echo " SW_INITIATOR = yes" >> "$BUF" echo " DISC_POLICY = "${SW_DISC_POLICY[i]} >> "$BUF" echo " ADAPTER_IP = "${SW_ADAPTER_IPS[i]} >> "$BUF" echo " ADAPTER_GW = "${SW_ADAPTER_GWS[i]} >> "$BUF" echo " ADAPTER_SNM = "${SW_ADAPTER_SNMS[i]} >> "$BUF" fi (( i = i + 1 )) done return 0 } # Usage: Create_ISCSI_TOE_Targets Create_ISCSI_TOE_Targets() { typeset ERROR='eval return 1' typeset DISKLIST="$*" typeset BUF= # Hold current target values typeset CURR_TARGET= typeset CURR_PORT= typeset CURR_IP= typeset CURR_INITIATOR= typeset CURR_GROUP= typeset CURR_DISC_POLICY= typeset CURR_ADAPTER_IP= typeset CURR_ADAPTER_GW= typeset CURR_ADAPTER_SNM= # TOE Array vars typeset TOE_ADAPTERS= typeset TOE_GROUPS= typeset TOE_TARGETS= typeset TOE_INITIATORS= typeset TOE_PORTS= typeset TOE_HOSTS_IPS= typeset TOE_DISC_POLICY= typeset TOE_ADAPTER_IPS= typeset TOE_ADAPTER_GWS= typeset TOE_ADAPTER_SNMS= # Array search loop control typeset -i INDEX=0 typeset -i i=0 typeset FOUND=FALSE # No disks...error [[ -z "$DISKLIST" ]] && $ERROR # Loop through the TOE attached disks to collect # information about the target. for disk in $DISKLIST do # Get the disk adapter DISK_ADAPTER=$($lsdev -l $disk -F"parent" 2>/dev/null) [[ -z "$DISK_ADAPTER" ]] && $ERROR ADAPTER_PARENT=$($lsdev -l $disk -F"parent" 2>/dev/null) [[ -z "$ADAPTER_PARENT" ]] && $ERROR DISK_ADAPTER=$ADAPTER_PARENT # Get the target name, port and ip CURR_TARGET=$($lsattr -El $disk -F "attribute value" | \ ${awk} '$1 == "target_name" {print $2}') CURR_PORT=$($lsattr -El $disk -F "attribute value" | \ ${awk} '$1 == "port_num" {print $2}') CURR_IP=$($lsattr -El $disk -F "attribute value" | \ ${awk} '$1 == "host_addr" {print $2}') CURR_INITIATOR=$($lsattr -El $DISK_ADAPTER -F "attribute value" | \ ${awk} '$1 == "initiator_name" {print $2}') CURR_DISC_POLICY=$($lsattr -El $DISK_ADAPTER -F "attribute value" | \ ${awk} '$1 == "disc_policy" {print $2}') CURR_ADAPTER_IP=$($lsattr -El $DISK_ADAPTER -F "attribute value" | \ ${awk} '$1 == "host_addr" {print $2}') CURR_ADAPTER_GW=$($lsattr -El $DISK_ADAPTER -F "attribute value" | \ ${awk} '$1 == "gateway_addr" {print $2}') CURR_ADAPTER_SNM=$($lsattr -El $DISK_ADAPTER -F "attribute value" | \ ${awk} '$1 == "subnet_mask" {print $2}') # TOE supports the following discovery policies # odm, slp. if [[ "$CURR_DISC_POLICY" = "odm" ]]; then CURR_GROUP="static" elif [[ "$CURR_DISC_POLICY" = "slp" ]]; then CURR_GROUP="auto" else # Don't record this target continue fi # We now have all the values for the # current target, compare to the saved ones # if any of the values is different, save it, # if they are all the same, skip it. i=0 while [[ $i -lt $INDEX ]] do if [[ "$DISK_ADAPTER" = "${TOE_ADAPTERS[i]}" ]] && \ [[ "$CURR_TARGET" = "${TOE_TARGETS[i]}" ]] && \ [[ "$CURR_PORT" = "${TOE_PORTS[i]}" ]] && \ [[ "$CURR_IP" = "${TOE_HOSTS_IPS[i]}" ]] && \ [[ "$CURR_INITIATOR" = "${TOE_INITIATORS[i]}" ]] && \ [[ "$CURR_GROUP" = "${TOE_GROUPS[i]}" ]] && \ [[ "$CURR_DISC_POLICY" = "${TOE_DISC_POLICY[i]}" ]] && \ [[ "$CURR_ADAPTER_IP" = "${TOE_ADAPTER_IPS[i]}" ]] && \ [[ "$CURR_ADAPTER_GW" = "${TOE_ADAPTER_GWS[i]}" ]] && \ [[ "$CURR_ADAPTER_SNM" = "${TOE_ADAPTER_SNMS[i]}" ]]; then FOUND=TRUE break else FOUND=FALSE (( i = i + 1 )) fi done # If the adapter is found... # continue to the next adapter and skip # adding it to the file [[ "$FOUND" = "TRUE" ]] && continue # The adapter was not found, add to # the list and increase the index TOE_ADAPTERS[$INDEX]=$DISK_ADAPTER TOE_TARGETS[$INDEX]=$CURR_TARGET TOE_PORTS[$INDEX]=$CURR_PORT TOE_HOSTS_IPS[$INDEX]=$CURR_IP TOE_INITIATORS[$INDEX]=$CURR_INITIATOR TOE_GROUPS[$INDEX]=$CURR_GROUP TOE_DISC_POLICY[$INDEX]=$CURR_DISC_POLICY TOE_ADAPTER_IP[$INDEX]=$CURR_ADAPTER_IP TOE_ADAPTER_GW[$INDEX]=$CURR_ADAPTER_GW TOE_ADAPTER_SNM[$INDEX]=$CURR_ADAPTER_SNM (( INDEX = INDEX + 1 )) done # If we are here, we are ready # to write the target_iscsi_stanzas i=0 BUF=$ISCSI_TOE_TARGETS_FILE ${rm} $BUF 2>/dev/null while [[ $i -lt $INDEX ]] do if [[ -n ${TOE_ADAPTERS[i]} ]]; then echo >> "$BUF" echo "target_iscsi_data:" >> "$BUF" echo " ADAPTER_NAME = "${TOE_ADAPTERS[i]} >> "$BUF" echo " ISCSI_GROUP = "${TOE_GROUPS[i]} >> "$BUF" if [[ "$ISCSI_GROUP" = "odm" ]]; then echo " TARGET_NAME = "${TOE_TARGETS[i]} >> "$BUF" echo " INITIATOR_NAME = "${TOE_INITIATORS[i]} >> "$BUF" echo " PORT_NUMBER = "${TOE_PORTS[i]} >> "$BUF" echo " IP_ADDRESS = "${TOE_HOSTS_IPS[i]} >> "$BUF" fi echo " SW_INITIATOR = no" >> "$BUF" echo " DISC_POLICY = "${TOE_DISC_POLICY[i]} >> "$BUF" if [[ -n "${TOE_ADAPTER_IP[i]}" ]]; then echo " ADAPTER_IP = "${TOE_ADAPTER_IP[i]} >> "$BUF" fi if [[ -n "${TOE_ADAPTER_GW[i]}" ]]; then echo " ADAPTER_GW = "${TOE_ADAPTER_IP[i]} >> "$BUF" fi if [[ -n "${TOE_ADAPTER_SNM[i]}" ]]; then echo " ADAPTER_SNM = "${TOE_ADAPTER_SNM[i]} >> "$BUF" fi fi (( i = i + 1 )) done return 0 } ############################# udfs_backup #################################### # # NAME: udfs_backup # # DESCRIPTION: Allows for creating volume group backups on media that support # creation of a UDFS file system to contain the backup. # # INPUT: None # # OUTPUT: 0 - success, 1 - failure # ############################################################################## udfs_backup() { typeset ERROR='eval ${rm} -f $FIFO;return 1' typeset FIFO=$mksysb_tmpdir/backup.fifo.$RANDOM typeset ERRTOKEN=$mksysb_tmpdir/errtoken.${RANDOM}.${RANDOM} typeset MBUF=$mksysb_tmpdir/backup.mbuf.$RANDOM typeset MOUNTP=$mksysb_tmpdir/_udfs.$$ # udfs mount point typeset OUTF="${MOUNTP}/usr/sys/inst.images" # Archive file typeset BPID # backup process ID typeset ALIVE=1 # is backup running typeset VOL_ID=1 # volume number typeset NEXT_VOL=0 typeset BUF_k # amount to write typeset MAXWAIT=360 typeset W=0 typeset BACKUP_SIZE # existing image size typeset BACK_NAME="savevg_image" # savevg or mksysb typeset SKIP_WRITTEN=0 # amount written typeset TIMESTAMP=`/usr/bin/date +"%y %m %d %H %M %S" | sed 's/ //g'` # Verify parameters ${mkdir} $MOUNTP while [[ $ALIVE -eq 1 || -s $FIFO ]] && [[ ! -s $ERRTOKEN ]] do # create udfs file system on media and mount /usr/sbin/udfcreate -d $DEVICE -s 2048 rc="$?" [ "$rc" -ne 0 ] && cleanup_m "$CMD_EC" \ "`${dspmsg} -s $MSGSET $MSGCAT 11 \ '0512-008 %s: The %s command failed with return code of %s. Backup canceled.' $NAME /usr/sbin/udfcreate $rc`" ${mount} -v udfs $DEVICE $MOUNTP rc="$?" [ "$rc" -ne 0 ] && cleanup_m "$CMD_EC" \ "`${dspmsg} -s $MSGSET $MSGCAT 11 \ '0512-008 %s: The %s command failed with return code of %s. Backup canceled.' $NAME $mount $rc`" if [[ "$VG" = "rootvg" ]] then # rootvg specific backup processing BACK_NAME="mksysb_image" echo "" ${dspmsg} -s $MSGSET $MSGCAT 86 'Populating the UDF file system...\n' # Populate media with install programs based on cd proto files populate_media_fs $MOUNTP /usr/lpp/bosinst/cdfs.required.list $OFF $NAME $BACKUPFILE if [ $? -ne 0 ]; then ${sleep} 10 ${umount} $MOUNTP /usr/bin/dspmsg -s 5 $MSGCAT 63 \ "0512-321 : Error populating the media file system\n\ using the /usr/lpp/bosinst/cdfs.required.list proto file.\n" cleanup_m "$CMD_EC" fi populate_media_fs $MOUNTP /usr/lpp/bosinst/cdfs.optional.list $ON $NAME $BACKUPFILE if [[ $VOL_ID -eq 1 ]] then # rootvg specific backup volume 1 processing ${mkdir} -p /${MOUNTP}/ppc/chrp # Existing mksysb image file specified. if [ -n "$BACKUPFILE" ] then olddir=`pwd` cd $MOUNTP sleep_countb=1 while :; do while [ "$sleep_countb" -le 30 ] do ${sleep} 10 echo ".\c" let "sleep_countb = sleep_countb + 1" done echo "" sleep_countb=1 done & SPID=$! # Restore image.data and bosinst.data from user supplied mksysb # and place in udfs file system /usr/sbin/restore -xdqf $BACKUPFILE ./bosinst.data ./image.data ./usr/lib/boot/bootinfo.txt ./tmp/vgdata/rootvg >/dev/null 2>$MSGBUF # Create boot image ${mkdir} -p /${MOUNTP}/ppc/chrp ${sed} 's/^.*<\/boot-script>$/boot \&device;:\\ppc\\chrp\\bootfile.exe<\/boot-script>/' \ ./usr/lib/boot/bootinfo.txt >$MOUNTP/ppc/bootinfo.txt ${rm} ./usr/lib/boot/bootinfo.txt [ -z "$TMPDIR" ] && TMPDIR=$MOUNTP /usr/sbin/bootpkg -m $BACKUPFILE -d cd -l $TMPDIR -O ${cp} $TMPDIR/cd.bi $MOUNTP/ppc/chrp/bootfile.exe cd $olddir # create OSLEVEL file oslevel=`get_stanza_data "image_data" "IMAGE_TYPE" "" "OSLEVEL" | \ head -n 1` echo "OSLEVEL=$oslevel" > \ $MOUNTP/OSLEVEL # Create a backup else # Copy /image.data and /bosinst.data to udfs file system ${cp} /image.data $MOUNTP ${cp} /bosinst.data $MOUNTP if [ -n "$MAPS" ] then # If mapping, then copy map files ${mkdir} -p ${MOUNTP}/tmp/vgdata/$VG ${cp} -p -R /tmp/vgdata/$VG/* ${MOUNTP}/tmp/vgdata/$VG fi if [[ "$NAME" = "mksysb" ]] then # Create boot image ${mkdir} -p /${MOUNTP}/ppc/chrp ${bosboot} -a -d cd -T chrp -b $MOUNTP/ppc/chrp/bootfile.exe \ -k /usr/lib/boot/unix_64 ${sed} 's/^.*<\/boot-script>$/boot \&device;:\\ppc\\chrp\\bootfile.exe<\/boot-script>/' \ /usr/lib/boot/bootinfo.txt >/$MOUNTP/ppc/bootinfo.txt fi # create OSLEVEL file oslevel=`get_stanza_data "image_data" "IMAGE_TYPE" "" "OSLEVEL" | \ head -n 1` echo "OSLEVEL=$oslevel" > \ $MOUNTP/OSLEVEL fi fi # end vol 1 fi # end rootvg specific processing ${mkdir} -p ${MOUNTP}/usr/sys/inst.images echo "" # Check how much space is available on the media INITSPACE=$(${df} -k $MOUNTP | ${tail} -1 | ${awk} '{print $3}') # Leave 0.5 percent free space (( BUF_k = $INITSPACE * 995 / 1000 )) # Set up beginning of backup if [[ $VOL_ID -eq 1 ]] then # volume 1 specific processing if [ -n "$BACKUPFILE" ] then # Keep track of how much there is left of the mksysb image to backup after each volume BACKUP_REMAIN=`${ls} -l $BACKUPFILE | ${awk} '{print$5}'` ## in bytes (( BACKUP_REMAIN = BACKUP_REMAIN - BUF_k * 1024 )) if [ $BACKUP_REMAIN -le 0 ] then # No more left to write ALIVE=0 fi BACKF=$BACKUPFILE else # Make a pipe echo "" ${dspmsg} -s $MSGSET $MSGCAT 34 'Backing up %s files' $TOTAL_FILES /usr/bin/mkfifo -m 700 $FIFO || $ERROR BACKF=$FIFO if [ -n "$VFLAG" ] then #Defect 998390 : Directing the stderr to the ERRTOKEN file which is used later #to check if the backup was successful (exec ${backup} -iq $VFLAG $PFLAG $AFLAG $EXFLAG $EXFLAG_EXPR -f $FIFO < $archive_lst 2>$ERRTOKEN) & else (exec ${backup} -iqv $PFLAG $AFLAG $EXFLAG $EXFLAG_EXPR -f $FIFO < $archive_lst > \ $mksysb_tmpdir/_mksysb.$$ 2>$ERRTOKEN) & fi # Get the background pid BPID="$!" # Reset error handlers ERROR='eval ${rm} -f $FIFO; kill -9 $BPID 2>/dev/null; return 1' eval 'trap "kill -9 $BPID 2>/dev/null" 1 2 3 11 15 EXIT' # Is the above PID still alive? ALIVE=$(is_pid_alive $BPID) || $ERROR while [[ ! -s $FIFO && $ALIVE -eq 1 ]]; do (( W = W + 1 )) [[ $W -gt $MAXWAIT ]] && $ERROR ALIVE=$(is_pid_alive $BPID) || $ERROR ${sleep} 1 done [[ $ALIVE -ne 1 || -s $ERRTOKEN ]] && $ERROR fi # Additional volumes processing elif [ -n "$BACKUPFILE" ] then # Not volume 1 and existing backup, track remaining amount to be # written to media (( BACKUP_REMAIN = BACKUP_REMAIN - BUF_k * 1024 )) ALIVE=0 if [ -n "$BACKUPFILE" ] then sleep_countb=1 while :; do while [ "$sleep_countb" -le 30 ] do ${sleep} 10 echo ".\c" let "sleep_countb = sleep_countb + 1" done echo "" sleep_countb=1 done & SPID=$! fi if [ $BACKUP_REMAIN -gt 0 ] then # Still more to write ALIVE=1 fi fi # when command is "savewpar" if [ "$NAME" = "savewpar" ] then BACK_NAME="savewpar_image" fi # Write out a chunk of backup. /usr/bin/touch $mksysb_tmpdir/writing if [ -n "$BACKUPFILE" ] then ${dspmsg} -s $MSGSET $MSGCAT 87 '\nCopying backup...\n' fi ${dd} count=$BUF_k skip=$SKIP_WRITTEN if=$BACKF ibs=1k obs=128k >> $OUTF/$BACK_NAME 2>$MBUF #defect 1027815 only check if dd was successful as we will need to create the #data file even if there were errors in ERRTOKEN if [[ $? -ne 0 ]]; then ${cat} $MBUF ${sleep} 10 ${umount} $MOUNTP $ERROR fi [ -n "$BACKUPFILE" ] && (( SKIP_WRITTEN = SKIP_WRITTEN + BUF_k )) ${rm} $mksysb_tmpdir/writing # writing has finished, possibly waiting for next volume if [ -n "$BACKUPFILE" ] then kill -9 $SPID 2>/dev/null else # backup of current volume group still running ALIVE=$(is_pid_alive $BPID) || $ERROR fi if [[ $ALIVE -eq 1 ]]; then # more volumes create_data_file $VOL_ID "$ON" $VG "$ON" $MOUNTP $TIMESTAMP ${sleep} 10 ALIVE=$(is_pid_alive $BPID) || $ERROR if [[ $ALIVE -eq 1 ]]; then ${umount} $MOUNTP (( NEXT_VOL = VOL_ID + 1 )) echo "" ${dspmsg} -s $MSGSET $MSGCAT 85 \ "The backup will require additional media.\n\ Replace the current writable media (volume $VOL_ID),\n\ with new writable media (volume $NEXT_VOL) in device $DEVICE.\n\ Press the 0 then we display #the error to the STDOUT and return 1 else return 0 if [[ -z "$BACKUPFILE" ]] then # Whew! made it. [[ -z "$BACKUPFILE" ]] && rm -f $FIFO $MBUF if [[ -s $ERRTOKEN ]] then ${cat} $ERRTOKEN return 1 else return 0 fi fi return 0 } ## end of udfs_backup ############################## verify_alt_boot ################################ # # NAME: verify_alt_boot() # # # DESCRIPTION: Verifies whether bos.alt_disk_install.boot_images is at a # level (6.1.2.0 or higher) that supports multibos mksysb # # INPUT: none # # # OUTPUT: # Rebased pathname # ########## verify_alt_boot () { alt_lev=`/usr/bin/lslpp -Lqc bos.alt_disk_install.boot_images | \ ${awk} -F: '{print $3}'` [[ -z "$alt_lev" ]] && cleanup_m "$INVALID_ALT" echo $alt_lev | /usr/bin/tr '.' ' ' | read ver rel mod fix (( ver > 6 )) && return (( ver < 6 )) && cleanup_m "$INVALID_ALT" (( rel < 1 )) && cleanup_m "$INVALID_ALT" (( mod < 2 )) && cleanup_m "$INVALID_ALT" } ############################## verify_boot_levels ################################ # # NAME: verify_boot_levels() # # # DESCRIPTION: Verifies whether bos.alt_disk_install.boot_images is at the same level # as the system. # # INPUT: none # # # OUTPUT: none # # ########## verify_boot_levels() { alt_lev=`/usr/bin/lslpp -Lqc bos.alt_disk_install.boot_images | \ ${awk} -F: '{print $3}'` echo $alt_lev | /usr/bin/tr '.' ' ' | read ver rel mod fix alt_lev=$ver$rel$mod sys_lev=`/usr/bin/lslpp -Lqc bos.mp64 | \ ${awk} -F: '{print $3}'` echo $sys_lev | /usr/bin/tr '.' ' ' | read ver rel mod fix sys_lev=$ver$rel$mod if [[ $alt_lev != $sys_lev ]]; then cleanup_m "$INVALID_ALT" fi return 0 } verify_image () { typeset mesg typeset img_type ############################################################# ## If the image is suppose to be a mksysb, then check the ## image for the existance of a bosinst.data. ############################################################# if [ `dd if=$BACKUPFILE bs=1k count=128 2>/dev/null \ | restbyname -TqdSf - 2>/dev/null \ | grep -cw '^\.\/bosinst\.data'` -eq 0 ]; then img_type=mksysb /usr/bin/dspmsg -s 5 mksysb.cat 109 \ "0512-325 $NAME: The user supplied $img_type image: $BACKUPFILE is not a valid $img_type image.\n" $NAME $img_type $BACKUPFILE $img_type exit 1 fi } ## end of verify_image start_rootvgwpar_if_defined () { if [[ "$ROOTVGWPAR" = "yes" ]] && [[ `${corralquery} -a $WPAR` -eq 0 ]]; then # Bringing up WPAR's rootvg disks ${dspmsg} -s 3 wpars.cat 51 \ "Bringing up WPAR's rootvg disks for backup. Please wait..." ${startwpar} -p -m $WPAR > /dev/null 2>&1 if [[ $? -ne 0 ]]; then cleanup_m "$?" \ "`${dspmsg} -s 1 wpars.cat 423 \ '%s: 0960-475 Failed to start workload partition %s.' $NAME $WPAR`" fi fi } stop_rootvgwpar_if_was_defined () { if [[ "$ROOTVGWPAR" = "yes" ]] && [[ $ROOTVGWPARSTATE_AT_BACKUPSTART = 'D' ]] && [[ `${corralquery} -a $WPAR` -eq 1 ]]; then # Revert back to the previous state of WPAR ${dspmsg} -s 3 wpars.cat 52 \ "Reverting back to the previous state of WPAR...\n" ${stopwpar} -F $WPAR > /dev/null 2>&1 if [[ $? -ne 0 ]]; then cleanup_m "$?" \ "`${dspmsg} -s 1 wpars.cat 445 \ '%s: 0960-501 Error stopping workload partition subsystem.' $NAME`" fi fi } post_process_map_data () { # Only to be called in rootvg wpar related OPs with map file option. typeset VDEV typeset RDEV # Translate wpar hdisk to global hdisk once to avoid excessive time and # translation for each line in each MAPFILE via rdev_for_vdev logic # Use the original image.data (IMAGE_DATA.save) from the post process of image.data set -A hdisktranslate VDEV=`cat $IMAGE_DATA.save | ${awk} ' { if( ($0 ~ "DISK_LIST") ) print $0;} '` echo "$VDEV" | read varname dlist # loop through the disk list and tranlate wpar disk to global disk for hd in $dlist do wpardisk_num=$(echo $hd | ${sed} -e "s/hdisk//") RDEV=$(rdev_for_vdev $hd) globaldisk_num=$(echo $RDEV | ${sed} -e "s/hdisk//") hdisktranslate[$wpardisk_num]=$globaldisk_num done # Modify hdisk in MAPFILE # mapfile makes use of savewpar symlink: # ln -sf /tmp/wpardata/ /wpars//.savewpar_dir while TMP_LINE=$(line) do VDEV=`echo $TMP_LINE | ${awk} ' { if( ($0 ~ "MAPFILE") ) print $0;} '` if [[ -n $VDEV ]] then echo "$VDEV" | read varname mapfile > $mapfile.mod # loop through a mapfile - translate wpar disk to global disk and modify mapfile while TMP_LINE=$(line) do echo $TMP_LINE | ${sed} -e "s/:/ /g" | read hd loc wpardisk_num=$(echo $hd | ${sed} -e "s/hdisk//") echo "hdisk${hdisktranslate[$wpardisk_num]}:$loc" >> $mapfile.mod done < $mapfile mv $mapfile $mapfile.save || return 1 mv $mapfile.mod $mapfile || return 1 fi done < $IMAGE_DATA.save return 0 } post_process_image_data () { # Only to be called in rootvg wpar related OPs. typeset VDEV typeset RDEV while TMP_LINE=$(line) do VDEV=`echo $TMP_LINE | ${awk} ' { if( ($0 ~ "DISK_LIST") || ($0 ~ "HDISKNAME") ) print $0;} '` if [[ -n $VDEV ]] then nlist="" echo "$VDEV" | read varname dlist # loop through the disk list for hd in $dlist do RDEV=$(rdev_for_vdev $hd) [[ -z $nlist ]] && nlist="$RDEV" || nlist="$nlist $RDEV" done echo " $varname $nlist" >> $DATA_DIR/image.data_diskmod else echo "$TMP_LINE" >> $DATA_DIR/image.data_diskmod fi done < $IMAGE_DATA mv $IMAGE_DATA $IMAGE_DATA.save || return 1 mv $DATA_DIR/image.data_diskmod $IMAGE_DATA || return 1 return 0 } rdev_for_vdev () { typeset VDEV=$1 wpar_lscorral_cache "$WPAR" "D" || return 1 typeset i=0 while [[ $i -lt $LSWPAR_D_COUNT ]] do if [[ "${LSWPAR_D_vdevname[$i]}" = "$VDEV" ]] then echo ${LSWPAR_D_devname[$i]} return 0 fi i=$((i+1)) done return 1 } ######################### snap_remove #################################### ## ## Name: snap_remove ## ## Function: The snap_remove function is responsible for unmounting ## and removing snapshots. ## ## Parameters: None ## ## Returns: None ## ## ######################################################################## snap_remove () { if [ -n "$snap_mount" ] then cd $ROOTDIR > /dev/null 2>&1 [ "$NAME" = "savevg" ] && umount $admin_mnt/tmp/vgdata > /dev/null 2>&1 sleep 10 for i in $snap_list do umount $admin_mnt${i} > /dev/null 2>&1 # File systems recommended to do umount -f twice to trigger the ultimate force unmount if [ $? -ne 0 ] then umount -f $admin_mnt${i} > /dev/null 2>&1 umount -f $admin_mnt${i} > /dev/null 2>&1 fi done for i in $snap_lv_list do snapshot -d $i > /dev/null 2>&1 done rm -fr $admin_mnt > /dev/null 2>&1 fi } ######################### snap_clean #################################### ## ## Name: snap_clean ## ## Function: The snap_clean function is responsible for unmounting ## and removing snapshots from a fail previous execution ## ## Parameters: None ## ## Returns: None ## ## ######################################################################## snap_clean () { trap '' 1 2 15 cd $ROOTDIR > /dev/null 2>&1 # Previous mksysb execution creates /admin/mksysb.[0-9]* # as mount point for snapshot, so find them, unmount them # and remove snapshot associated with them for i in `${ls} -d /admin/mksysb.[0-9]* 2>/dev/null` do temp_snaplv=`LANG=C ${df} $i 2>/dev/null | ${grep} $i | ${awk} '{print $1}'` ${umount} $i > /dev/null 2>&1 [[ -n $temp_snaplv ]] && /usr/sbin/snapshot -d $temp_snaplv > /dev/null 2>&1 ${rm} -fr $i > /dev/null 2>&1 done } #################### main ########################## # # set up environment # if [ "$MKSYSB_DEBUG" ]; then set -x for i in $(typeset +f); do typeset -ft $i done fi export PATH="/usr/bin:/usr/sbin:/etc:$PATH" export ODMDIR="/etc/objrepos" NAME=`/usr/bin/basename $0` BOOT_PLATFORM=`/usr/sbin/bootinfo -a` # Needed for IA64 (value 4) MSGCAT=mksysb.cat # message catalog name MSGSET=1 # message set number USAGE_MB=1 # mksysb usage err exit code USAGE_SV=2 # savevg usage err exit code USAGE_EC=$USAGE_MB # set mksysb usage error [ "$NAME" = "savevg" ] && USAGE_EC=$USAGE_SV # set savevg usage error CMD_EC=3 # exit code prior to mounting any file systems TRAP_EC=4 # exit code for trap NO_SPACE_EC=5 # exit code for NO SPACE INVALID_VG=6 # exit code for Invalid VG name for savevg INVALID_WPAR=7 # exit code for Invalid WPAR for savewpar USAGE_WPAR=8 # wpar usage err exit code LOCK_EC=9 # failure to acquire wpar lock exit code INSIDE_WPAR=10 # running command inside a workload partition INVALID_ALT=11 # Invalid bos.alt_disk_install.boot_images for # multibos support BOOT_FAIL=12 # bosboot failed building the custom boot image [ "$NAME" = "savewpar" ] && USAGE_EC=$USAGE_WPAR # set savewpar usage error BOOTABLE=0 # true if a bootable image is made TAPE_BOOTABLE=0 # true if system is tape bootable DEVICE= # initialize backup device to NULL TAPEBLKSZF=tapeblksz # file to save tape block size TAPEBLKSZ=/$TAPEBLKSZ # path to file to save tape block size BOPT="NONE" # # Blocks for the B option to backup BFLAG= oldblksize= tapedev= tapestate= # State of Tape device IMAGE= MAPS= EX= EXCLUDE= EXFLAG= EXFLAG_EXPR= RFLAG= VERIFYFLAG=no VFLAG= XXFLAG= PFLAG="-p" AFLAG="-U" GFLAG="" XFSFLAG= XFSLIST= MULTIFLAG="" NEWBOOT="" NAMEFSFLAG="y" METADATAONLY="n" NFSFLAG="" ZFLAG="-Z" NNFLAG="" SNAPFLAG= BKPID="" BACKUPFILE="" BACKUPLOG=/var/adm/ras/vgbackuplog BACKUPLOGSIZE=20480 # Limits log to roughly 256 lines BACKUPSIZE=0 BACKUPSHRINKSIZE=0 ON=1 OFF=0 DEVCLASS= MASS_STORAGE=0 quarterinch=no # Indicates use of 1/4 in tape drive tddupdateflag=yes # Indicates the target_disk_data stanzas in # bosinst.data should be updated. TMPDIR="" UDF="no" ROOTVGWPAR="" ROOTVGWPARSTATE_AT_BACKUPSTART="" WPAR_OSTYPE=0 # Versioned-WPARs have non-zero ostype values ## used for snapshot processing snap_mount= snap_list= snap_lv_list= ## Full-Path to commands used alog=/usr/bin/alog awk=/usr/bin/awk backup=/usr/sbin/backup basename=/usr/bin/basename bootinfo=/usr/sbin/bootinfo bosboot=/usr/sbin/bosboot cat=/usr/bin/cat chdev=/usr/sbin/chdev chroot=/usr/sbin/chroot chroot_cre=/usr/lib/wpars/chroot_cre cp=/usr/bin/cp cut=/usr/bin/cut date=/usr/bin/date dd=/usr/bin/dd df=/usr/bin/df dirname=/usr/bin/dirname dspmsg=/usr/bin/dspmsg du=/usr/bin/du egrep=/usr/bin/egrep expr=/usr/bin/expr find=/usr/bin/find getopt=/usr/bin/getopt grep=/usr/bin/grep head=/usr/bin/head lqueryvg=/usr/sbin/lqueryvg ln=/usr/bin/ln ls=/usr/bin/ls lsattr=/usr/sbin/lsattr lsjfs2=/usr/sbin/lsjfs2 lslv=/usr/sbin/lslv lsvg=/usr/sbin/lsvg lsvgfs=/usr/sbin/lsvgfs lswpar=/usr/sbin/lswpar mkinsttape=/usr/sbin/mkinsttape mkszfile=/usr/bin/mkszfile mkvgdata=/usr/bin/mkvgdata mkwpardata=/usr/bin/mkwpardata mount=/usr/sbin/mount umount=/usr/sbin/unmount odmget=/usr/bin/odmget oslevel=/usr/bin/oslevel rm=/usr/bin/rm sed=/usr/bin/sed sleep=/usr/bin/sleep sort=/usr/bin/sort sum=/usr/bin/sum tail=/usr/bin/tail tctl=/usr/bin/tctl wc=/usr/bin/wc ps=/usr/bin/ps fuser=/usr/sbin/fuser lsdev=/usr/sbin/lsdev mkdir=/usr/bin/mkdir rmdir=/usr/bin/rmdir lspv=/usr/sbin/lspv getlvodm=/usr/sbin/getlvodm startwpar=/usr/sbin/startwpar stopwpar=/usr/sbin/stopwpar mkwpar=/usr/sbin/mkwpar wparinstcmd=/usr/lib/wpars/wparinstcmd corralquery=/usr/lib/corrals/corralquery clogin=/usr/sbin/clogin if [ "$NAME" = "savewpar" ] then # Load WPAR and install shell utilities . /usr/lib/wpars/libcor_sh || return 1 init_baselib `basename $0` || return 1 cor_init_vars export GLOBALCMD="savewpar" # GLOBALCMD is used by wpar lock facility fi # Disallow this operation in a workload partition fail_if_wpar # Disallow this operation during an AIX live update fail_if_lvup ### Security hooks if [ -x /usr/bin/setB1priv ] && [ ! -f /etc/security/bestC2 ] then /usr/bin/setB1priv $$ 2 fi ### End Security hooks getoptions $* # Parse the commandline arguements ############################################################# ## Load cmdbsys_lib functions. ############################################################# . /usr/lpp/bosinst/cmdbsys_lib [ "$NNFLAG" = "y" ] && NNFLAG="yes" BOSINST_DATA=/bosinst.data # Bos Install Options Data file BOSINST_VARFL=/var/adm/ras/bosinst.data # Bos Install Data file BOSINST_TMPLT=/usr/lpp/bosinst/bosinst.template # Bos Install Template file if [ "$NAME" != "savewpar" ] then DATA_BASEDIR=/tmp/vgdata # VG data Directory DATA_DIR=$DATA_BASEDIR/$VG # vg data Directory if [ "$VG" = "rootvg" ] then IMAGE_DATA="/image.data" # rootvg Image.data file else IMAGE_DATA=$DATA_DIR/$VG.data # vg Image.data file FILE_LIST=$DATA_BASEDIR/vgdata.files$$ # file listing vg.data files in archive FS_LIST=$DATA_DIR/filesystems # A copy of /etc/filesystems BOSINST_DATA="" fi ROOTDIR=/ DATALNK= DLNKMADE= else # The *F versions of the definitions below exist so that savewpar # can access the file names directly through the working directory # symbolic link denoted by $DATALNKF DATA_BASEDIR=/tmp/wpardata # base working Directory DATA_DIR=$DATA_BASEDIR/$WPAR # data Directory IMAGE_DATAF=image.data # Image.data file IMAGE_DATA=$DATA_DIR/${IMAGE_DATAF} # FILE_LISTF=data.files$$ # file listing data files in archive FILE_LIST=$DATA_DIR/${FILE_LISTF} # FS_LISTF=filesystems # A copy of /etc/filesystems FS_LIST=$DATA_DIR/${FS_LISTF} # BOSINST_DATA="" WPAR_BASEDIR=`${lswpar} -qca directory $WPAR` SPEC_FILEF=wpar.spec # A copy of the spec file SPEC_FILE=$DATA_DIR/${SPEC_FILEF} ROOTDIR=$WPAR_BASEDIR DATALNKF=.savewpar_dir DATALNK=/${DATALNKF} DLNKMADE= namefs_list= check_root_link [[ $? -ne 0 ]] && cleanup_m "$CMD_EC" \ "`${dspmsg} -s $MSGSET $MSGCAT 76 \ '0512-066 %s: Could not create link to the working directory from %s\n' $NAME $WPAR_BASEDIR/${DATALNKF}`" fi # Call snap_clean the first time to clean up # any left over snaps. snap_clean BACKUP_DATAF=backup.data IMAGE_INFOF=image.info if [ "$VG" = "backup" ] then BACKUP_DATA=$DATA_DIR/vgdata/${BACKUP_DATAF} else BACKUP_DATA=$DATA_DIR/${BACKUP_DATAF} fi IMAGE_INFO=$DATA_DIR/${IMAGE_INFOF} if [ "$VG" = "rootvg" ] then # check if Hardware Dump File System and if so, add to list of files to exclude. hdexist=$(ODMDIR=/etc/objrepos ${odmget} -q attribute=fwdump_dev SWservAt | ${grep} value) if [[ -n $hdexist ]] then # the lv and fs are already removed from the image.data file by mkszfile changes # but we need to not backup the mount point for the file system hdfsname=$(ODMDIR=/etc/objrepos ${odmget} -q attribute=fwdump_dir SWservAt | ${grep} value | ${cut} -d"\"" -f2) [[ -n $hdfsname ]] && HWDUMPFSNAME=$(echo $hdfsname | sed 's/\./\\\./') fi fi if [ "$NAME" != "savewpar" ] then EXCLUDE_DATA=/etc/exclude.$VG # File containing list of files EXCLUDE_PACK_DATA=/etc/exclude_packing.$VG # File containing list of files else EXCLUDE_DATA=/etc/exclude.$WPAR # File containing list of files EXCLUDE_PACK_DATA=/etc/exclude_packing.$WPAR # File containing list of files fi [ ! -s "$EXCLUDE_DATA" ] && EX= # and/or directories to exclude [ ! -s "$EXCLUDE_PACK_DATA" ] && EXFLAG= # and/or directories to exclude # Setup list of files to be excluded from packing if [ "$EXFLAG" = "-e" ] then if [ "$PFLAG" != "-p" ] then ${dspmsg} -s $MSGSET $MSGCAT 92 '-p and -P flags are mutually exclusive.\n' cleanup_m "$USAGE_EC" fi cp $EXCLUDE_PACK_DATA /etc/exclude_packing EXFLAG_EXPR=`cat /etc/exclude_packing|tr -s '\n' '|'|sed -e 's/\|$//'` rm /etc/exclude_packing fi mksysb_tmpdir="/tmp/mksysb.$$" NEW_EXCLUDE_FILE=$mksysb_tmpdir/new_exclude tmp_file=".archive.list.$$" tmp_list=".MNT.list.$$" tmp_list_final=".MNT.finallist.$$" archive_lst="$mksysb_tmpdir/$tmp_file" BOSBOOT_LOG="$mksysb_tmpdir/bosboot.log" mounted_list="$mksysb_tmpdir/$tmp_list" mounted_list_final="$mksysb_tmpdir/$tmp_list_final" tmp_tdd="$mksysb_tmpdir/tmp_tdd.$$" tmp_tid="$mksysb_tmpdir/tmp_tid.$$" tmp_newbidata="$mksysb_tmpdir/tmp_newbidata.$$" ISCSI_SW_TARGETS_FILE="$mksysb_tmpdir/tmp_swtargets.$$" ISCSI_TOE_TARGETS_FILE="$mksysb_tmpdir/tmp_toetargets.$$" admin_mnt=/admin/mksysb.$$ snap_data="$mksysb_tmpdir/snapdata.$$" BAD_FIND=0 # # Trap on exit/interrupt/break to clean up # trap "cleanup_m $TRAP_EC \"`${dspmsg} -s $MSGSET $MSGCAT 4 '0512-007 %s: Abnormal program termination.' $NAME`"\" 1 2 15 # Create a temporary directory for temporary files oldumask=$(umask) umask 077 ${mkdir} $mksysb_tmpdir RC=$? if [[ $RC -ne 0 ]] then cleanup_m "$CMD_EC" \ "`${dspmsg} -s $MSGSET $MSGCAT 40 \ '0512-050 Could not create temporary directory %s\n' $mksysb_tmpdir`" fi umask $oldumask # # check prerequsites: # usage; # $IMAGE_DATA file exists or is created (-i flag); # $BOSINST_DATA file exists; # the absolute path was used in $device. # if [ "$VG" = "rootvg" ] then [ -s $BOSINST_DATA ] && [ -e /save_bosinst.data_file ] && tddupdateflag=no if [ ! -s $BOSINST_DATA ] then ${cp} $BOSINST_VARFL $BOSINST_DATA 2> /dev/null if [ -s $BOSINST_DATA ] then ${sed} -e "s/^[ ]*RECOVER_DEVICES[ ]*=[ ]*[a-zA-Z]*/ RECOVER_DEVICES = Default/" $BOSINST_DATA > $tmp_newbidata ${cp} "$tmp_newbidata" "$BOSINST_DATA" ${rm} "$tmp_newbidata" else ${cp} $BOSINST_TMPLT $BOSINST_DATA 2> /dev/null fi [ ! -s $BOSINST_DATA ] && cleanup_m "$CMD_EC" \ "`${dspmsg} -s $MSGSET $MSGCAT 1 \ '0512-004 %s: The %s file does not exist. Backup canceled.' $NAME $BOSINST_DATA`" fi # # call tddupdate function - # Update target_disk_data stanzas in bosinst.data unless # if [ "$tddupdateflag" = "yes" ] then check_edition tddupdate Get_Rootvg_ISCSI_Targets tsddupdate fi fi # # check if tape device, and if so, determine if usable # if [[ $DEVICE = /dev/* ]] then tapedev="`/usr/bin/basename $DEVICE | /usr/bin/cut -d . -f1`" if [[ $DEVCLASS = usbms ]] || [[ $DEVCLASS = cdrom ]] || [[ $MASS_STORAGE -eq 1 ]] then UDF="yes" if [ `/usr/sbin/lsdev -C -l $tapedev -S available | \ /usr/bin/wc -l` -ne 1 ] then cleanup_m "$CMD_EC" \ "`${dspmsg} -s 5 $MSGCAT 95 \ '0512-302 %s: Device %s is not Available.' $NAME $DEVICE `" fi else if [ `/usr/sbin/lsdev -C -c tape -l $tapedev -S available | /usr/bin/wc -l` -eq 1 ] then #Check to make sure we can write on the tape. 2>/dev/null >$DEVICE rc="$?" [ "$rc" -ne 0 ] && cleanup_m "$CMD_EC" \ "`${dspmsg} -s $MSGSET $MSGCAT 98 \ '0512-017 %s: Cannot write to the device %s.\n\t\t Either write protected, in use, or not ready.' $NAME $DEVICE `" ### Need to know if 1/4 in tape in use, due to problems after fsf ${lsdev} -C -l $tapedev | ${grep} -q "1/4" rc="$?" [ "$rc" -eq 0 ] && quarterinch=yes elif [ $tapedev != null ] then # Not a tape device, cannot backup to anything in /dev that is not # a tape device with the exception of /dev/null cleanup_m "$CMD_EC" \ "`${dspmsg} -s $MSGSET $MSGCAT 51 \ '0512-057 %s: Device %s is not in the available state or \n\t\t is not a tape device or valid file name.' $NAME $DEVICE `" fi fi fi ## Mounting unmounted filesystems for WPARS in the Defined State ## if [ "$NNFLAG" = "yes" ] then mount_fs_wpar fi ## if customer has requested a new boot image in ## /usr/lpp/bos.alt_disk_install/boot_images ## do it now before building image.data if [[ "$NEWBOOT" = "yes" ]] then if [[ -f /usr/ios/cli/ioscli ]] then BOOTSAVE=/usr/lpp/bos.alt_disk_install/boot_images/bosboot.disk.chrp.vios.$$ BOOTNEW=/usr/lpp/bos.alt_disk_install/boot_images/bosboot.disk.chrp.vios else BOOTSAVE=/usr/lpp/bos.alt_disk_install/boot_images/bosboot.disk.chrp.$$ BOOTNEW=/usr/lpp/bos.alt_disk_install/boot_images/bosboot.disk.chrp fi BOOTTMP=/tmp/boot_images/bosboot.disk.chrp.$$ TMP_LV="" FREETMPBLKS="" MUSTHAVE_TMP_BLKS="" KBYTES= REM= EXPAND_BLKS= ${mkdir} -p /tmp/boot_images if [[ $? != 0 ]] then cleanup_m "$CMD_EC" \ "`${dspmsg} -s $MSGSET $MSGCAT 40 \ '0512-050 Could not create temporary directory %s\n' /tmp/boot_images`" fi mv $BOOTNEW $BOOTSAVE # tmp space expansion added here 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}'` # Get space needed for bosboot BOOT_BLKS=`LC_ALL=C ${bosboot} -qab $BOOTTMP | ${grep} /tmp | ${awk} '{print $2 * 2}'` MUSTHAVE_TMP_BLKS="$BOOT_BLKS" ### 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 $MSGSET $MSGCAT 29 'Expanding /tmp.\n' /usr/sbin/chfs -a size=+$EXPAND_BLKS /tmp if [[ $? != 0 ]] then cleanup_m "$NO_SPACE_EC" \ "`dspmsg -s 2 $MSGCAT 26 \ '0512-041 %s: The /tmp file system could not be expanded.\n' $NAME`" fi else cleanup_m "$NO_SPACE_EC" \ "`${dspmsg} -s 2 $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 ${bosboot} -a -b $BOOTTMP if [[ $? != 0 ]] then cleanup_m "$BOOT_FAIL" fi # /usr space expansion USR_BOOT_BLKS= TMP_LV="" FREETMPBLKS="" MUSTHAVE_TMP_BLKS="" KBYTES= REM= EXPAND_BLKS= USR_LV=`LC_ALL=C ${df} /usr | ${tail} +2l | grep /dev | ${awk} '{gsub ("/dev/", "", $1); print $1}' ` FREEUSRBLKS=`LC_ALL=C ${df} /dev/$USR_LV | ${tail} +2l | ${awk} '{print $3}'` # Get space needed for bosboot USR_BOOT_BLKS=`ls -l $BOOTTMP | ${awk} '{print $5}'` ## convert to 512 blocks U_512=`${expr} $USR_BOOT_BLKS \/ 512 ` U_REM=`${expr} $BOOT_BLKS \% 512` [[ $U_REM -ne 0 ]] && U_512=`${expr} $U_512 \+ 1` MUSTHAVE_USR_BLKS="$U_512" ### CHECK IF ENOUGH FREE SPACE EXISTS IN /usr ###### if [ $FREEUSRBLKS -lt $MUSTHAVE_USR_BLKS ] then KBYTES=`${expr} $MUSTHAVE_USR_BLKS \/ 2 ` #Convert to KBytes REM=`${expr} $MUSTHAVE_USR_BLKS \% 2` [ "$REM" -ne 0 ] && KBYTES=`${expr} $KBYTES \+ 1` if [ -n "$XXFLAG" ] then ((EXPAND_BLKS = MUSTHAVE_USR_BLKS - FREEUSRBLKS)) dspmsg -s $MSGSET $MSGCAT 110 'Expanding /usr.\n' /usr/sbin/chfs -a size=+$EXPAND_BLKS /usr if [[ $? != 0 ]] then cleanup_m "$NO_SPACE_EC" \ "`dspmsg -s 1 $MSGCAT 111 \ '0512-078 %s: The use of the C flag requires that the /usr file system \n\ be expanded. The /usr file system could not be expanded.\n' $NAME`" fi else cleanup_m "$NO_SPACE_EC" \ "`${dspmsg} -s 1 $MSGCAT 112 \ '0512-079 %s: The new boot image could not be built because the %s KBytes of free work space in the /usr filesystem that are necessary were not found. To make backup, do one of the following: \t (1) Specify that the /usr filesystem can be expanded. \t (From the commandline, specify the -X option.) \t (2) Use the chfs command to extend the /usr filesystem. \t (3) Free up space to provide a total of %s Kbytes of free work space \t in the /usr filesystem.\n\n' $NAME $KBYTES $KBYTES`" fi fi ### End of usr space check # move the boot image from /tmp to /usr mv $BOOTTMP $BOOTNEW if [[ $? != 0 ]] then cleanup_m "$BOOT_FAIL" fi fi ### End if NEWBOOT if [ "$IMAGE" = "y" ] || [ ! -s $IMAGE_DATA ] then export MKSYSB_CALL=yes if [ "$NAME" = "mksysb" ] && [ "$BOOT_PLATFORM" -ne 4 ] then MKDATA_CMD="mkszfile" ${mkszfile} $MAPS "$GFLAG" "$XXFLAG" $XFSFLAG ## call mkszfile elif [ "$NAME" = "savewpar" ] then if [[ "$ROOTVGWPAR" = "yes" ]]; then ${wparinstcmd} -c "SAVEWPAR=1 ${mkszfile} $MAPS $XXFLAG" $WPAR if [[ $? != 0 ]] then cleanup_m "$CMD_EC" \ "`${dspmsg} -s $MSGSET $MSGCAT 5 \ '0512-008 %s: The %s command failed. Backup canceled.' $NAME $mkszfile`" fi # These are the special vars that will be used only in this condition. # This contains *.map image.info ROOTVGWPAR_INFO_DIR="$WPAR_BASEDIR/tmp/vgdata/rootvg" ROOTVGWPAR_IMAGE_DATA="$WPAR_BASEDIR/image.data" # Now mkszfile runs inside a rootvg wpar, so certain operations needs to be done in global. if [[ ! -d $DATA_DIR ]]; then ${mkdir} -p $DATA_DIR if [[ $? != 0 ]] then cleanup_m "$CMD_EC" \ "`${dspmsg} -s $MSGSET $MSGCAT 5 \ '0512-008 %s: The %s command failed. Backup canceled.' $NAME $mkdir`" fi fi ${mkwpar} -e $WPAR -W -w -o $DATA_DIR/wpar.spec if [[ $? != 0 ]] then cleanup_m "$CMD_EC" \ "`${dspmsg} -s $MSGSET $MSGCAT 5 \ '0512-008 %s: The %s command failed. Backup canceled.' $NAME $mkwpar`" fi ${cp} $ROOTVGWPAR_IMAGE_DATA $IMAGE_DATA ${cp} $ROOTVGWPAR_INFO_DIR/* $DATA_DIR # We need the global's /etc/filesystems as other wpar backups do. ${cp} /etc/filesystems $DATA_DIR # Due to device virtualization diskname might be different from diskname in global for somecases. # Thus, we re-map disk name in image.data so that backup's done correctly. post_process_image_data # Cleaning up files in the WPAR. ${rm} $ROOTVGWPAR_IMAGE_DATA ${rm} $ROOTVGWPAR_INFO_DIR/* if [ -n "$MAPS" ] then post_process_map_data fi else MKDATA_CMD="mkwpardata" ${mkwpardata} $MAPS "$XXFLAG" $WPAR ## call mkwpardata for non-rootvg WPAR. fi else MKDATA_CMD="mkvgdata" ${mkvgdata} $MAPS "$XXFLAG" $XFSFLAG $VG ## call mkvgdata fi if [[ $? != 0 ]] then cleanup_m "$CMD_EC" \ "`${dspmsg} -s $MSGSET $MSGCAT 5 \ '0512-008 %s: The %s command failed. Backup canceled.' $NAME $MKDATA_CMD`" fi elif [ $VG = "rootvg" -a $BOOT_PLATFORM -ne 4 ] # Check for /tmp space then 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}'` # Get space needed for bosboot, required at mksysb and bosinstall time BOOT_BLKS=`LC_ALL=C ${bosboot} -qad /dev/ipldevice | ${tail} +3l | ${awk} '{print $2 * 2}'` if [ "$NAME" = "mksysb" ] then TAPE_BLKS=`LC_ALL=C ${bosboot} -qad /dev/rmt0 2>/dev/null | ${tail} +3l | ${awk} '{print $2 * 2}'` [ "$TAPE_BLKS" -gt "$BOOT_BLKS" ] && BOOT_BLKS=$TAPE_BLKS fi MUSTHAVE_TMP_BLKS="$BOOT_BLKS" ############################################## # # ### 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 $MSGSET $MSGCAT 29 'Expanding /tmp.\n' /usr/sbin/chfs -a size=+$EXPAND_BLKS /tmp if [[ $? != 0 ]] then cleanup_m "$NO_SPACE_EC" \ "`dspmsg -s 2 $MSGCAT 26 \ '0512-041 %s: The /tmp file system could not be expanded.\n' $NAME`" fi else cleanup_m "$NO_SPACE_EC" \ "`${dspmsg} -s 2 $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 fi [ ! -s $IMAGE_DATA ] && cleanup_m "$CMD_EC" \ "`${dspmsg} -s $MSGSET $MSGCAT 1 \ '0512-004 %s: The %s file does not exist. Backup canceled.' $NAME $IMAGE_DATA`" # Force -B for RootVG WPAR if [ "$NAME" = "savewpar" ] && [ "$ROOTVGWPAR" = "yes" ] then NAMEFSFLAG="n" fi if [ "$NAME" = "savewpar" ] && [ "$NAMEFSFLAG" = "y" ] then get_writable_namefs_mounts fi if [ "$NAME" = "savewpar" ] && [ "$NFSFLAG" = "y" ] then get_writable_nfs_mounts fi make_backup_data if [ -r $DATA_DIR/*.map ] ## Gets any maps found then MAP_DATA=`${ls} -1 $DATA_DIR/*map | ${awk} '{print $1}'` fi case "$DEVICE" in # # Fix the block size if $DEVICE is a tape device # /dev/rmt[0-9]*) if [ "$VG" = "rootvg" ] then # set location of tapeblksz file for rootvg TAPEBLKSZ=/tapeblksz if [[ -n $ZFLAG ]] then # print warning if EFS Encrypted File Systems EFSVAR= EFSNAME= EFSVAR=`get_stanza_data "fs_data" "FS_JFS2_EFS" "yes" "FS_JFS2_EFS"` EFSNAME=`get_stanza_data "fs_data" "FS_JFS2_EFS" "yes" "FS_NAME"` if [[ -n $EFSVAR ]] then ${dspmsg} -s $MSGSET $MSGCAT 113 \ "ATTENTION: %s: An Encrypted File System (EFS) is in the rootvg:\n\ %s\n\ which will cause installation from the mksysb tape to fail\n\ when the EFS information is included in the backup.\n\ Please use the -Z flag to exclude the EFS information.\n" "$NAME" "$EFSNAME" fi fi elif [ "$NAME" = "savewpar" ] then # set location of tapeblksz file for user volume group TAPEBLKSZ=${DATA_DIR}/tapeblksz else # set location of tapeblksz file for user volume group TAPEBLKSZ=${DATA_BASEDIR}/$VG/tapeblksz fi # # strip /dev/ from device name and # get the base name (eg translate: # /dev/rmt0.2 to rmt0) # tapedev="`/usr/bin/basename $DEVICE | /usr/bin/cut -d . -f1`" # # set block size data in tapeblksz file # CMD="${lsattr} -E -O -a block_size" oldblksize=`LC_ALL=C $CMD -l $tapedev 2> /dev/null | ${grep} -v block_size` if [ "$?" -eq 0 ] then echo "$oldblksize $BOPT" > $TAPEBLKSZ fi if [ "$VG" = "rootvg" ] then # see if a low or high density tape device was specified # (eg rmt0.1) density="`${expr} $DEVICE : \ "/dev/rmt[0-9]*\.\([0-9]*\)"`" # # change device to 512 tape block size # [[ $oldblksize -ne 512 ]] && ${chdev} -l $tapedev -a block_size=512 >/dev/null 2>&1 # Force use of extended file marks CMD2="${lsattr} -E -O -a extfm" oldextfm=`LC_ALL=C $CMD2 -l $tapedev 2> /dev/null | ${grep} -v extfm` if [ "$?" -eq 0 ] then oldextfm=${oldextfm:-no} ${chdev} -l $tapedev -a extfm=yes >/dev/null 2>&1 else oldextfm= fi # # Use the same density device driver as # the user specified, but since we are now # making bootable tapes, the tape drive # must be no-rewind. Thus, rmt(n).1, rmt(n).2, # and rmt(n).3 will be mapped to rmt(n).1 and # rmt(n).4 and above map to rmt(n).5. # [ "${density:-1}" -lt 4 ] && density=1 || density=5 TDEVICE="/dev/${tapedev}.${density}" # Make first 3 images on tape (boot, bosinst, toc) make_bootape $TDEVICE verify_boot_image if [[ $oldblksize -eq 512 ]] && [[ -z "$oldextfm" ]] then ${tctl} -f $TDEVICE fsf 3 fi # Reset tape device to tape block size preset by user. if [[ $oldblksize -ne 512 ]] then ## for 4mm tape drives on J-series machines, need to ## rewind the tape before doing the chdev. # Rewind and reposition tape SUBCOMMAND=rewind ${tctl} -f $TDEVICE rewind # wait for tape to rewind rc="$?" [[ "$rc" -ne 0 ]] && cleanup_m "$CMD_EC" \ "`${dspmsg} -s $MSGSET $MSGCAT 36 \ '0512-044 %s: Cannot access device %s.\n\ttctl %s failed with return code %s.' $NAME $device $SUBCOMMAND $rc `" ${chdev} -l $tapedev -a block_size=$oldblksize > /dev/null 2>&1 # Rewind and reposition tape SUBCOMMAND=rewind ${tctl} -f $TDEVICE rewind # wait for tape to rewind rc="$?" [[ "$rc" -ne 0 ]] && cleanup_m "$CMD_EC" \ "`${dspmsg} -s $MSGSET $MSGCAT 36 \ '0512-044 %s: Cannot access device %s.\n\ttctl %s failed with return code %s.' $NAME $device $SUBCOMMAND $rc `" SUBCOMMAND="fsf" ${tctl} -f $TDEVICE fsf 3 rc="$?" [[ "$rc" -ne 0 ]] && cleanup_m "$CMD_EC" \ "`${dspmsg} -s $MSGSET $MSGCAT 36 \ '0512-044 %s: Cannot access device %s.\n\ttctl %s failed with return code %s.' $NAME $device $SUBCOMMAND $rc `" # tapedev set to null to indicate no cleanup_m neccessary if [[ -z "$oldextfm" ]] then tapedev= fi ## if 1/4 in tape in use, do tctl read, expecting errors, ## so that the next write will be successful. [ "$quarterinch" = "yes" ] && ${tctl} -f $TDEVICE read >/dev/null 2>&1 fi # Reset extfm to value preset by user if [[ -n "$oldextfm" ]] then ## for 4mm tape drives on J-series machines, need to ## rewind the tape before doing the chdev. # Rewind and reposition tape SUBCOMMAND=rewind ${tctl} -f $TDEVICE rewind # wait for tape to rewind rc="$?" [[ "$rc" -ne 0 ]] && cleanup_m "$CMD_EC" \ "`${dspmsg} -s $MSGSET $MSGCAT 36 \ '0512-044 %s: Cannot access device %s.\n\ttctl %s failed with return code %s.' $NAME $device $SUBCOMMAND $rc `" ${chdev} -l $tapedev -a extfm=$oldextfm >/dev/null 2>&1 # oldextfm set to null to indicate no cleanup_m necessary oldextfm= # Rewind and reposition tape SUBCOMMAND=rewind ${tctl} -f $TDEVICE rewind # wait for tape to rewind rc="$?" [[ "$rc" -ne 0 ]] && cleanup_m "$CMD_EC" \ "`${dspmsg} -s $MSGSET $MSGCAT 36 \ '0512-044 %s: Cannot access device %s.\n\ttctl %s failed with return code %s.' $NAME $device $SUBCOMMAND $rc `" SUBCOMMAND="fsf" ${tctl} -f $TDEVICE fsf 3 rc="$?" [[ "$rc" -ne 0 ]] && cleanup_m "$CMD_EC" \ "`${dspmsg} -s $MSGSET $MSGCAT 36 \ '0512-044 %s: Cannot access device %s.\n\ttctl %s failed with return code %s.' $NAME $device $SUBCOMMAND $rc `" # tapedev set to null to indicate no cleanup_m neccessary tapedev= ## if 1/4 in tape in use, do tctl read, expecting errors, ## so that the next write will be successful. [ "$quarterinch" = "yes" ] && ${tctl} -f $TDEVICE read >/dev/null 2>&1 fi ${rm} -f $TAPEBLKSZ else # tapedev set to null to indicate no cleanup_m neccessary tapedev= fi # end of test for rootvg Volume Group ;; # end of Tape Case *) ;; # all other cases esac if [ -n "$BACKUPFILE" ] then if [ "$UDF" = "no" ] then copy_backup else udfs_backup fi done_backup $rc cleanup_m "$rc" "" fi # # make a list of filesystems to be backed up # echo "" # As a progress indicator print dots every 10 seconds during # the creation of the list of files to backup while :; do ${sleep} 10 echo ".\c" done & PID=$! fs_list=$(/usr/bin/sed '/:$/i\ ' $IMAGE_DATA | awk '{if($0 !~ "VG_SOURCE_DISK_LIST" && $0 !~ "LV_SOURCE_DISK_LIST") {print $0}} ' | ${egrep} "^[ ]+"FS_NAME"[ ]*" | ${awk} 'BEGIN{FS="="} {print $2}' ) fs_list_sorted=$(echo "$fs_list"|${sort} -t " ") fs_list=$fs_list_sorted if [ "$MULTIFLAG" = "yes" ] then rvg_list="/ /usr /opt /var" else if [ "$SNAPFLAG" = "y" ] then ${dspmsg} -s 1 $MSGCAT 105 'Creating snapshots.' # Use snapshots ${mkdir} $admin_mnt RC=$? if [[ $RC -ne 0 ]] then cleanup_m "$CMD_EC" \ "`${dspmsg} -s $MSGSET $MSGCAT 40 \ '0512-050 Could not create temporary directory %s\n' $admin_mnt`" fi totminlv=0 totminlv8=0 totminlv15=0 { for j in $fs_list do # If there is a file system exclusion file, check to see if this # file system is in the list. If so, skip it. if [[ -n "$XFSLIST" ]] then ${grep} -q "^${j}$" $XFSLIST && continue fi # fs list is based on WPAR base, but need absolute path for looking # up file system characteristics if [ "$NAME" = "savewpar" ] then r_j=`rebase $j` else r_j=$j fi # Is file system JFS2, if so, get minimum size typefs=`get_stanza_data "lv_data" "MOUNT_POINT" $j "TYPE"` if [[ "$typefs" = "jfs2" ]] then lvmin=`get_stanza_data "lv_data" "MOUNT_POINT" $j "LV_MIN_LPS"` (( snaplp = $lvmin * 2 / 100 + 1 )) (( snaplp8 = $lvmin * 8 / 100 + 1 )) (( snaplp15 = $lvmin * 15 / 100 + 1 )) print "$j $snaplp $snaplp8 $snaplp15" (( totminlv = $snaplp + $totminlv )) (( totminlv8 = $snaplp8 + $totminlv8 )) (( totminlv15 = $snaplp15 + $totminlv15 )) fi done } > $snap_data # It is recommended that snapshot size be 2-15 percent of file system. # Will use either 2, 8, or 15 percent as long as it is less than half # the available free space. if [[ $totminlv15 -le $FREE_SP ]] then snapsz=15 elif [[ $totminlv8 -le $FREE_SP ]] then snapsz=8 elif [[ $totminlv -le $FREE_SP ]] then snapsz=2 else dspmsg -s 1 $MSGCAT 103 '0512-073 Failed creating snapshots.\n' if [[ "$CALLED_FROM_NIM" = "y" ]] then dspmsg -s 1 $MSGCAT 104 'Continuing backup without snapshots.\n' SNAPFLAG= else dspmsg -s 1 $MSGCAT 102 \ '0512-073 There is not enough available free space to use snaphsots.\nMake more space available or retry without snapshots (-T flag).\n' cleanup_m "$NO_SPACE_EC" "" fi fi fi for i in $fs_list do # If there is a file system exclusion file, check to see if this # file system is in the list. If so, skip it. if [[ -n "$XFSLIST" ]] then ${grep} -q "^${i}$" $XFSLIST && continue fi # fs list is based on WPAR base, but need absolute path for looking # up file system characteristics if [ "$NAME" = "savewpar" ] then r_i=`rebase $i` else r_i=$i fi #lsjfs2 query won't work for rootvg wpar filesystems since they do not exist in global. fs_attr=`LC_ALL=C ${lsjfs2} $r_i 2> /dev/null | ${tail} +2l` # Does file system have internal snapshots, if not create snapshot isnap=`echo $fs_attr | awk 'BEGIN{FS=":"} { print $22}'` if [[ "$ROOTVGWPAR" != "yes" ]] then if [ "$SNAPFLAG" = "y" ] then snaplv= if [ "$isnap" = "no" ] then if [ $snapsz = 15 ] then snaplvsz=`grep "^$i " $snap_data | awk '{print $4}'` elif [ $snapsz = 8 ] then snaplvsz=`grep "^$i " $snap_data | awk '{print $3}'` else snaplvsz=`grep "^$i " $snap_data | awk '{print $2}'` fi (( snaplvsz = $snaplvsz * $PPSZ )) snaplv=`LANG=C snapshot -o snapfrom=$r_i -o size=${snaplvsz}M` if [[ $? != 0 ]] then dspmsg -s 1 $MSGCAT 103 '0512-073 Failed creating snapshots.\n' if [[ "$CALLED_FROM_NIM" = "y" ]] then dspmsg -s 1 $MSGCAT 104 'Continuing backup without snapshots.\n' snap_remove SNAPFLAG= snap_mount= else cleanup_m "$NO_SPACE_EC" "" fi else snaplv=`echo $snaplv | awk '{print $8}'` fi fi # If snaplv created, then mount it, otherwise overmount file # system itself without snapshot if [ "$SNAPFLAG" = "y" ] then if [ -n "$snaplv" ] then [[ ! -d $admin_mnt${i} ]] && mkdir -p $admin_mnt${i} mount -v jfs2 -o snapshot $snaplv $admin_mnt${i} snap_mount=yes snap_list="$i $snap_list" # Does file system have multiple snapshots addsnap=`snapshot -q $r_i | wc -l` [[ $addsnap -eq 3 ]] && snap_lv_list="$snaplv $snap_lv_list" else [[ ! -d $admin_mnt${i} ]] && mkdir -p $admin_mnt${i} mount $r_i $admin_mnt${i} snap_list="$i $snap_list" fi fi fi dmapi=`echo $fs_attr | ${tail} +2l | ${awk} 'BEGIN{FS=":"} {print $19}'` if [ "$dmapi" != "yes" ] || [ "$DMAPIFLAG" = "y" ] then rvg_list="$i $rvg_list" else print -u2 "\nDMAPI enabled filesystem detected: $i \nUse -A to back up contents. Refer to /usr/lpp/bos.sysmgt/README.\n" fi else rvg_list="$i $rvg_list" fi done # If no snapshots were created, then unmount all the overmounts and create # backup using traditional method. # If snapshots were created and this is savevg, then we also need the # vgdata files from /tmp. if [ -z "$snap_mount" ] then for i in $snap_list do umount $admin_mnt${i} done elif [ $NAME = "savevg" ] then [[ ! -d $admin_mnt/tmp/vgdata ]] && mkdir -p $admin_mnt/tmp/vgdata mount /tmp/vgdata $admin_mnt/tmp/vgdata fi [ "$SNAPFLAG" = "y" ] && echo "" fi ${dspmsg} -s $MSGSET $MSGCAT 33 'Creating list of files to back up ' # For savewpar, the data directory is accessed through a symlink, so the # metadata files need to be backup up through that link, so the paths # need to be adjusted. if [ $NAME = "savewpar" ] then IMAGE_INFO=/$IMAGE_INFOF IMAGE_DATA=/$IMAGE_DATAF BACKUP_DATA=/$BACKUP_DATAF FS_LIST=/$FS_LISTF SPEC_FILE=/$SPEC_FILEF if [ -n "$MAP_DATA" ] then MAP_DATA=`echo $MAP_DATA | sed "s:${DATA_DIR}::g"` fi fi # If you using snapshots, change to snapshot staging area. if [ -z "$snap_mount" ] then cd / > /dev/null 2>&1 else cd $admin_mnt > /dev/null 2>&1 fi # Put the bosinst.data, image.data and Map files in front of tape if [ $VG != "rootvg" ] then { echo .${DATALNK}$IMAGE_INFO echo .${DATALNK}$IMAGE_DATA echo .${DATALNK}$BACKUP_DATA echo .${DATALNK}$FS_LIST if [ -f $TAPEBLKSZ ] then if [ "$NAME" = "savewpar" ] then echo .${DATALNK}/$TAPEBLKSZF else echo .$TAPEBLKSZ fi fi if [ "$NAME" = "savewpar" ] then echo .${DATALNK}$SPEC_FILE fi for m in $MAP_DATA do echo .${DATALNK}$m done } > "$FILE_LIST" fi # # make a list of files to backup using # the list of filesystems just created # # DO NOT remove the '.' on the '.$i' in the find command. The list # of files need to be relative to the current directory (/) # # # # Notify user that find command had problems where the archive list is incomplete. # # if [ "$RFLAG" != "y" ];then echo # # if [ "$NAME" = "savewpar" ] then cd $WPAR_BASEDIR fi remote_mnts1=`LC_CTYPE=C ${mount} | \ ${awk} '(NR>2){ if (/^ / && $3!="jfs" && $3!="jfs2"){print $2} if (!/^ / && $4!="jfs" && $4!="jfs2"){print $3}}'` mount_list=`LC_CTYPE=C ${mount}` curdir=`pwd` for i in $rvg_list do ${find} .$i ! -name "$tmp_file" ! -type s \( -fstype jfs -o -fstype jfs2 \) -xdev -print >/dev/null if [ $? -gt 0 ] then BAD_FIND=1 fi done # Now check NFS-mounted files if requested - savewpar only for n in $nfs_list do # find NFS files relative to base of WPAR i=$(canonical $n) ${find} .$i ! -name "$tmp_file" ! -type s \( -fstype nfs \) -xdev -print >/dev/null if [ $? -gt 0 ] then BAD_FIND=1 fi done # Get namefs-mounted files if applicable - savewpar only for n in $namefs_list do # find namefs-mounted files relative to base of WPAR i=$(canonical $n) ${find} .$i ! -name "$tmp_file" ! -type s -xdev -print >/dev/null if [ $? -gt 0 ] then BAD_FIND=1 fi done if [ "$NAME" = "savewpar" ] then cd - >/dev/null fi fi one_time_expand="yes" expand_tmp="yes" while [ "$expand_tmp" = "yes" ] do expected_size=`{ if [ $VG = "rootvg" ] then # Save bosinst.data file for rootvg echo .$BOSINST_DATA echo .${DATALNK}$IMAGE_INFO else # save other vg specific files for other vgs echo .${DATALNK}$IMAGE_INFO if [ "$NAME" != "savewpar" ] then echo .$FILE_LIST echo .${DATA_BASEDIR}/vgdata.files else echo .${DATALNK}/$FILE_LISTF echo .${DATALNK}/vgdata.files fi echo .${DATALNK}$FS_LIST if [ -f $TAPEBLKSZ ] then if [ "$NAME" = "savewpar" ] then echo .${DATALNK}/$TAPEBLKSZF else echo .$TAPEBLKSZ fi fi if [ "$NAME" = "savewpar" ] then echo .${DATALNK}$SPEC_FILE fi fi echo .${DATALNK}$IMAGE_DATA echo .${DATALNK}$BACKUP_DATA for m in $MAP_DATA do echo .${DATALNK}$m done EXCL_DEV_GREPST=$( echo $EXCL_DEV| sed 's/\./\\\./') BOSINST_DATA_GREPST=$( echo $BOSINST_DATA| sed 's/\./\\\./') IMAGE_DATA_GREPST=$( echo $IMAGE_DATA| sed 's/\./\\\./') SLP_GREPST="/var/tmp/slp_srvreg.lock|^./var/locks/slp_srvreg.lock" [ -n "$DATALNKF" ] && DATALNK_GREPST=$( echo $DATALNKF | sed 's/\./\\\./') # Check for the savevg metadata only flag (-r). # If this flag has been used, then the archive list is complete. # We don't care about the exclude file, or backing up any more # files. if [ "$RFLAG" != "y" ] then if [ -n "$EX" ] || [ -n "$GFLAG" ] then # Try and cleanup_m the exclude file, in case it's invalid. # First, remove all "tab" characters, then all leading spaces, # then all trailing spaces. Finally, delete all empty lines. if [ -n "$EX" ] then cat $EXCLUDE_DATA | sed 's/ //g;s/^ *//g;s/ *$//g;/^$/d' > $NEW_EXCLUDE_FILE else > $NEW_EXCLUDE_FILE fi # Exclude WPAR files? if [ -n "$GFLAG" ] then EX="yes" /usr/sbin/lswpar -qa directory 2>/dev/null | /usr/bin/sed 's/^/./' >> $NEW_EXCLUDE_FILE fi fi proto_list=$mksysb_tmpdir/proto_list temp_list=$mksysb_tmpdir/temp_list ${egrep} "^./" /usr/lib/bootpkg/bootpkg_list|sort -u |${awk} '{print $0}' > $proto_list ${awk} '{if(length($6) > 0 && substr($2, 1, 1) != "c" && substr($2, 1, 1) != "b" )print "."$6}' /usr/lib/boot/network/chrp.*.proto /usr/lib/boot/chrp.*.proto |sort -u >> $proto_list if [ "$NAME" != "savevg" ] then find ./etc/objrepos/Cu* ./etc/objrepos/Pd* ./sbin/helpers ./sbin/helpers/aufsmnthelp ./sbin/helpers/jfs2/* ./sbin/helpers/nfsmnthelp ./sbin/helpers/udfmnthelp ./sbin/helpers/v3fshelper >> $proto_list fi if [ "$NAME" = "savewpar" ] then cd $WPAR_BASEDIR fi for i in $rvg_list do if [ -n "$EX" ] then ## use exclude file if [ -n "$snap_mount" ] then # Look for jfs file systems and if found, cd to $ROOTDIR to get list. echo $remote_mnts1 | egrep "${admin_mnt}${i}$|${admin_mnt}${i} " >/dev/null 2>&1 [ $? = 0 ] && cd $ROOTDIR > /dev/null 2>&1 fi ${find} .$i ! -name "$tmp_file" ! -type s \( -fstype jfs -o -fstype jfs2 \) -xdev -print | \ ${egrep} -v "^.$IMAGE_DATA_GREPST\$|^.$HWDUMPFSNAME\$|^.$DATA_BASEDIR|^.$mksysb_tmpdir|^.$BOSINST_DATA_GREPST\$|^.$EXCL_DEV_GREPST\$|^\./\.savewpar_dir\$|^.$SLP_GREPST\$" | \ ${egrep} -v -f $NEW_EXCLUDE_FILE 2> /dev/null cd $curdir > /dev/null 2>&1 else if [ -n "$snap_mount" ] then # Look for jfs file systems and if found, cd to $ROOTDIR to get list. echo $remote_mnts1 | egrep "${admin_mnt}${i}$|${admin_mnt}${i} " >/dev/null 2>&1 [ $? = 0 ] && cd $ROOTDIR > /dev/null 2>&1 fi ${find} .$i ! -name "$tmp_file" ! -type s \( -fstype jfs -o -fstype jfs2 \) -xdev -print | \ ${egrep} -v "^.$IMAGE_DATA_GREPST\$|^.$HWDUMPFSNAME\$|^.$DATA_BASEDIR|^.$mksysb_tmpdir|^.$BOSINST_DATA_GREPST\$|^.$EXCL_DEV_GREPST\$|^\./\.savewpar_dir\$|^.$SLP_GREPST\$" 2> /dev/null cd $curdir > /dev/null 2>&1 fi done > $temp_list cd $ROOTDIR > /dev/null 2>&1 # put proto files first ${awk} 'NR==FNR{a[$0];next}($0 in a)' $proto_list $temp_list # put non proto files next ${awk} 'NR==FNR{a[$0];next}!($0 in a)' $proto_list $temp_list rm -f $proto_list $temp_list 2>/dev/null # Now get NFS-mounted files if requested - savewpar only for n in $nfs_list do # find NFS files relative to base of WPAR i=$(canonical $n) if [ -n "$EX" ] then ## use exclude file ${find} .$i ! -name "$tmp_file" ! -type s \( -fstype nfs \) -xdev -print | \ ${egrep} -v "^.$IMAGE_DATA_GREPST\$|^.$HWDUMPFSNAME\$|^.$DATA_BASEDIR|^.$mksysb_tmpdir|^.$BOSINST_DATA_GREPST\$|^.$EXCL_DEV_GREPST\$|^\./\.savewpar_dir\$|^.$SLP_GREPST\$" | \ ${egrep} -v -f $NEW_EXCLUDE_FILE 2> /dev/null else pwd ${find} .$i ! -name "$tmp_file" ! -type s \( -fstype nfs \) -xdev -print | \ ${egrep} -v "^.$IMAGE_DATA_GREPST\$|^.$HWDUMPFSNAME\$|^.$DATA_BASEDIR|^.$mksysb_tmpdir|^.$BOSINST_DATA_GREPST\$|^.$EXCL_DEV_GREPST\$|^\./\.savewpar_dir\$|^.$SLP_GREPST\$" 2> /dev/null fi done # Finally get namefs-mounted files if requested - savewpar only for n in $namefs_list do # find namefs files relative to base of WPAR i=$(canonical $n) if [ -n "$EX" ] then ## use exclude file ${find} .$i ! -name "$tmp_file" ! -type s -xdev -print | \ ${egrep} -v "^.$IMAGE_DATA_GREPST\$|^.$HWDUMPFSNAME\$|^.$DATA_BASEDIR|^.$mksysb_tmpdir|^.$BOSINST_DATA_GREPST\$|^.$EXCL_DEV_GREPST\$|^\./\.savewpar_dir\$|^.$SLP_GREPST\$" | \ ${egrep} -v -f $NEW_EXCLUDE_FILE 2> /dev/null else pwd ${find} .$i ! -name "$tmp_file" ! -type s -xdev -print | \ ${egrep} -v "^.$IMAGE_DATA_GREPST\$|^.$HWDUMPFSNAME\$|^.$DATA_BASEDIR|^.$mksysb_tmpdir|^.$BOSINST_DATA_GREPST\$|^.$EXCL_DEV_GREPST\$|^\./\.savewpar_dir\$|^.$SLP_GREPST\$" 2> /dev/null fi done cd - >/dev/null fi ; } | tee "$archive_lst" | LC_CTYPE=C wc -c` # Verify that archive list is complete by comparing the # size of archive_lst with the size sent to the list. # If the list is incomplete and expand flag is set, # then expand /tmp once and try again. actual_size=`LC_CTYPE=C wc -c $archive_lst | ${awk} '{print $1}'` if [ $actual_size -lt $expected_size ] then if [ -n "$XXFLAG" ] && [ "$one_time_expand" = "yes" ] then one_time_expand="no" ((expand_size = ( expected_size - actual_size ) / 1024 + 1)) dspmsg -s $MSGSET $MSGCAT 29 'Expanding /tmp.\n' rm -r $archive_lst chfs -a size=+$expand_size /tmp if [[ $? != 0 ]] then cleanup_m "$NO_SPACE_EC" \ "`dspmsg -s 2 $MSGCAT 26 \ '0512-041 %s: The /tmp file system could not be expanded.\n' $NAME`" fi else (( expected_size = expected_size / 1024 )) cleanup_m "$NO_SPACE_EC" \ "`${dspmsg} -s 2 $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 $expected_size $expected_size`" fi else expand_tmp="no" fi done # Add the remote file system mount points to the list. # if the node field is not blank then the "mounted over" is the third field # Do not add snapshots mount points. LC_CTYPE=C remote_mnts=`${mount} | \ ${awk} '(NR>2){ if (/^ / && $3!="jfs" && $3!="jfs2" && $2!~'$$'){print $2} if (!/^ / && $4!="jfs" && $4!="jfs2" && $3!~'$$'){print $3}}'` > "$mounted_list" for i in $remote_mnts do TEMPMNT=$(/usr/lib/instl/realpath $i) ${egrep} -x .`${dirname} $TEMPMNT` "$mounted_list" \ "$archive_lst" > /dev/null 2>&1 [ "$?" -eq 0 ] && [ ! -f "$TEMPMNT" ] && echo .$TEMPMNT >> "$mounted_list" done # Remove remote mounts from the mounted list if they are not in the vg specified if [[ "$SNAPFLAG" = "y" && "$NAME" != "savewpar" ]]; then mnts_to_remove=$mksysb_tmpdir/mnts_to_remove.$$ # Determine if a remote mount point does not reside in the vg specified for mnt in $remote_mnts; do # df will show the remote filesystem name of the remote mount. # Instead we'll look at the filesystem of the parent directory. parent_dir_fs=`${df} -P $(${dirname} $mnt) | ${awk} 'NR==2{print $6}'` # If the filesystem is not in the vg, add the mount point to removal list ${lsvgfs} $VG 2>/dev/null | ${egrep} -q "^${parent_dir_fs}$" if [[ $? -eq 1 ]]; then echo "^.$mnt$" >> $mnts_to_remove fi done # Now we can remove the mounts if mnts_to_remove size > 0 if [[ -s $mnts_to_remove ]]; then mounted_list_tmp=$mksysb_tmpdir/mounted_list_tmp.$$ ${cat} $mounted_list | ${egrep} -v -f $mnts_to_remove > $mounted_list_tmp mv $mounted_list_tmp $mounted_list fi rm -f $mnts_to_remove >/dev/null 2>&1 fi if [ -n "$EX" ] then ## use exclude file ${cat} $mounted_list | ${egrep} -v -f $NEW_EXCLUDE_FILE > $mounted_list_final else ${cp} $mounted_list $mounted_list_final fi # Add remote mount points to archive list. For savewpar, only add the # remote mount points from within a wpar. if [ "$NAME" = "savewpar" ] then if [ -s "$mounted_list_final" ] then cat $mounted_list_final | ${sed} 's:^\.::' | while read mount_point do # If the path to the mount point is within the # wpar, then add the canonical form to the archive list wparmnt=`canonical $mount_point` if [ "$wparmnt" != "$mount_point" ] && [ "$wparmnt" != "/usr" ] && [ "$wparmnt" != "/opt" ] then echo .$wparmnt >> "$archive_lst" fi done fi else [ -s "$mounted_list_final" ] && cat "$mounted_list_final" >> "$archive_lst" fi # # Backup the files in the list # # Kill dots from 'Creating list of files to back up ' message kill_pid "$PID" # If -R is given for savewpar. Back up only meta data. if [[ $METADATAONLY = "y" ]]; then archive_lst=$FILE_LIST fi TOTAL_FILES=`${cat} "$archive_lst" | LC_CTYPE=C ${wc} -l | ${awk} '{print $1}'` if [ "$VG" != "rootvg" ] then if [ "$NAME" = "savewpar" ] then cp $FILE_LIST ${DATA_DIR}/vgdata.files else cp $FILE_LIST ${DATA_BASEDIR}/vgdata.files fi fi # Doublecheck that symlink to / in wpar still points to the data directory if [ "$NAME" = "savewpar" ] then ${ls} -ld ${WPAR_BASEDIR}/${DATALNKF} | ${egrep} -q "^l.* $DATA_DIR" [[ $? -ne 0 ]] && cleanup_m "$CMD_EC" \ "`${dspmsg} -s $MSGSET $MSGCAT 77 \ '0512-068 %s: Link to the working directory from %s has an unexpected value\n' $NAME $WPAR_BASEDIR/${DATALNKF}`" fi ulimit -f unlimited if [ -n "$VFLAG" ] then if [ "$UDF" = "yes" ] then udfs_backup rc=$? else echo "" ${dspmsg} -s $MSGSET $MSGCAT 34 'Backing up %s files' $TOTAL_FILES # If you using snapshots, change to snapshot staging area. if [ -z "$snap_mount" ] then cd $ROOTDIR > /dev/null 2>&1 else cd $admin_mnt > /dev/null 2>&1 fi echo "" ((${cat} "$archive_lst" | LANG=C ${backup} -iq $VFLAG $ZFLAG $PFLAG $AFLAG $EXFLAG $EXFLAG_EXPR -f"$DEVICE" $BFLAG);echo $? >$mksysb_tmpdir/backbyname.rc.$$)|tee $mksysb_tmpdir/_mksysb.$$ rc=`cat $mksysb_tmpdir/backbyname.rc.$$` rm $mksysb_tmpdir/backbyname.rc.$$ fi else # Show progress by counting the number of files backed # up and giving a message to show percentage # 500 of 5000 files (10%) # Check and Stop showing progress if waiting for next tape volume. FILES_BACKED="0" sleep_count2=1 while :; do if [ -n "$FIRST_TIME" ] then FILES_BACKED=`${cat} $mksysb_tmpdir/_mksysb.$$ 2>/dev/null | ${grep} "\.\/" | LC_CTYPE=C ${wc} -l | ${awk} '{print $1}'` if [ "$FILES_BACKED" != "0" ] then # Start check if waiting for next tape BKPID=`LC_ALL=C ${ps} -df |${grep} backbyname |${grep} "$$" |${awk} '{print $2}'` if [ -n "$BKPID" ] then if [ "$UDF" = "no" ] then ${fuser} "$DEVICE" 2>/dev/null |${grep} "$BKPID" >/dev/null rc="$?" else # Still writing to UDF? [ -f $mksysb_tmpdir/writing ] && rc=0 || rc=1 ${sleep} 10 fi # Do not put status dots or messages on screen if tape # waiting for next volume as indicated by non-zero # return code. if [ "$rc" -eq 0 ] then if [ $FILES_BACKED -eq $TOTAL_FILES ] then (( FILES_BACKED = TOTAL_FILES - 1 )) fi let "PERCENT_BACKED = (FILES_BACKED * 100) / TOTAL_FILES" echo "" ${dspmsg} -s $MSGSET $MSGCAT 35 \ '%s of %s files backed up (%s%s)' $FILES_BACKED $TOTAL_FILES \ $PERCENT_BACKED "%" ${sleep} 10 sleep_count=1 rc=0 while [ "$sleep_count" -le 30 -a "$rc" -eq 0 ] do ${fuser} "$DEVICE" 2>/dev/null |${grep} "$BKPID" >/dev/null || break [ "$UDF" = "yes" -a ! -f $mksysb_tmpdir/writing ] && break ${sleep} 10 echo ".\c" let "sleep_count = sleep_count + 1" done else ${sleep} 10 fi # if BKPID is zero length, do not print messages because # backup is not currently occuring. fi elif [ "$UDF" = "yes" ] then # UDF needs a bit more time before checking if backup # is still running as it does not start as quickly # do to additional processing needed ${sleep} 10 echo ".\c" let "sleep_count2 = sleep_count2 + 1" if [ "$sleep_count2" -ge 30 ] then echo "\n" sleep_count2=1 fi fi else echo "" if [ "$UDF" = "no" ] then ${dspmsg} -s $MSGSET $MSGCAT 34 'Backing up %s files' $TOTAL_FILES fi sleep_count=1 while [ "$sleep_count" -le 30 ] do ${sleep} 10 echo ".\c" let "sleep_count = sleep_count + 1" done FIRST_TIME=yes fi done & PID=$! ulimit -f unlimited # If you using snapshots, change to snapshot staging area. if [ -z "$snap_mount" ] then cd $ROOTDIR > /dev/null 2>&1 else cd $admin_mnt > /dev/null 2>&1 fi if [ "$UDF" = "yes" ] then udfs_backup else LANG=C ${cat} "$archive_lst" | ${backup} -iqv $ZFLAG $PFLAG $AFLAG $EXFLAG $EXFLAG_EXPR -f"$DEVICE" $BFLAG > $mksysb_tmpdir/_mksysb.$$ fi rc=$? # Kill progress indicator 'x of y files (z%)' message kill_pid "$PID" echo "" # backup a success ? if [ "$rc" -eq 0 ] then FILES_BACKED=$TOTAL_FILES PERCENT_BACKED=100 echo "" ${dspmsg} -s $MSGSET $MSGCAT 35 \ '%s of %s files backed up (%s%s)' $FILES_BACKED $TOTAL_FILES \ $PERCENT_BACKED "%" fi fi echo "" done_backup $rc ##################################################### ## Write the information about the completed backup ## to the backup log in /var/adm/ras/vgbackuplog ##################################################### DATE=`${date}` OSLEVEL_R=`${oslevel} -r 2> /dev/null` OSLEVEL_S=`${oslevel} -s 2> /dev/null` COMMAND="`${basename} $0` ${@}" if [[ ! -f $BACKUPLOG ]]; then echo "#Device;Command;Date;Shrink Size;Full Size;Maintenance Level;ServicePack Level" | ${alog} -f $BACKUPLOG -s $BACKUPLOGSIZE 2>&1 > /dev/null fi echo "$DEVICE;\"$COMMAND\";$DATE;$BACKUPSHRINKSIZE;$BACKUPSIZE;$OSLEVEL_R;$OSLEVEL_S" | ${alog} -f $BACKUPLOG -s $BACKUPLOGSIZE 2>&1 > /dev/null [ -s $BOSBOOT_LOG ] && ${cat} $BOSBOOT_LOG >&2 cleanup_m "$rc" ""