#!/bin/ksh # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # # # Licensed Materials - Property of IBM # # (C) COPYRIGHT International Business Machines Corp. 2002,2006 # 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 # @(#)65 1.25.1.2 src/avs/fs/mmfs/ts/admin/mmbackup.sh, mmfs, avs_rgpfs24, rgpfs24s005a 6/14/06 14:39:45 ############################################################################## # # Usage: # # mmbackup Device -n ControlFile [-t {full | incremental}] [-r IOrate] # [-s sortDir] [-T] # # or # # mmbackup Device -R [-r IOrate] [-s sortDir] [-T] # # where: # # -n ControlFile is a file containing information for controlling # the backup; this parameter is optional if mmbackup # was run previously, in which case the values from # the prior control file remain in effect if -n # is not specified # # -r IOrate an integer between 1 and 100 specifying how much # I/O bandwidth to allocate to the backup process # (the larger the number, the larger the allocated # bandwidth; default is 100) # # -t full | incremental type of backup; default is incremental # # -R resume backing up files which failed to be # backed up on the previous invocation of mmbackup # # -T enable tracing # # -s sortDir sort temporary directory name (default /tmp) # ############################################################################## # Include global declarations and service routines. . /usr/lpp/mmfs/bin/mmglobfuncs . /usr/lpp/mmfs/bin/mmsdrfsdef . /usr/lpp/mmfs/bin/mmfsfuncs sourceFile="mmbackup.sh" [[ -n $DEBUG || -n $DEBUGmmbackup ]] && set -x $mmTRACE_ENTER "$*" # Local work files. Names should be of the form: # fn=${tmpDir}fn.${mmcmd}.$$ tmpCtrlFile=${tmpDir}tmpCtrlFile.mmbackup.$$ LOCAL_FILES=" $tmpCtrlFile " # Local variables usageMsg=458 integer rc=0 integer nodeCount=0 integer n backupControlFile=".mmbuControl" typeset -i freeSpace # Local routines ########################################################################## # # Function: Get the amount of unused space in the specified file system. # # Input: $1 - file system dev name or name of a file or directory # # Output: the number of unused 1K blocks in the filesystem # # Returns: 0 # ########################################################################## function getFreeSpace # { | } { typeset sourceFile="mmbackup.sh" [[ -n $DEBUG || -n $DEBUGgetFreeSpace ]] && set -x $mmTRACE_ENTER "$*" typeset fileSystem=$1 typeset dfInfo typeset -i freeBlocks [[ -z $fileSystem ]] && \ checkForErrors "getFreeSpace: missing file system parameter" 1 # Issue the df command, requesting info in Posix format and 1K blocks. LC_ALL=C $df -P -k $fileSystem > $tmpfile # Read and discard the first line (the header). exec 3<&- exec 3< $tmpfile $rm -f $tmpfile read -u3 dfInfo # Read and extract the desired info from the second line. read -u3 dfInfo set -f ; set -- $dfInfo ; set +f freeBlocks=$4 # Return the result. print -- "$freeBlocks" return 0 } #--------- end of function getFreeSpace ------------------ ###################### # Mainline processing ###################### ################################# # Process the command arguments. ################################# [[ $arg1 = '-?' || $arg1 = '-h' || $arg1 = '--help' || $arg1 = '--' ]] && \ syntaxError "help" $usageMsg [[ $argc -lt 1 ]] && \ syntaxError "missingArgs" $usageMsg device=$arg1 # Save the file system name (always the first parameter). shift 1 # Drop the device name from the parameter list. while getopts :n:r:RTt:s: OPT do case $OPT in n) # input control file [[ -n $nflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" nflag="-$OPT"; narg=$OPTARG; [[ -n $Rflag ]] && \ syntaxError "invalidCombination" $usageMsg "-n" "-R" ;; r) [[ -n $rflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" rflag="-$OPT"; rarg=$OPTARG; # Ensure that rarg is an integer, and that its value is from 1 to 100. n=$(checkIntRange $rflag $rarg 1 100) [[ $? -ne 0 ]] && cleanupAndExit ;; s) [[ -n $sflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" sflag="-$OPT"; sarg=$OPTARG; ;; R) [[ -n $Rflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" Rflag="-$OPT"; [[ -n $nflag ]] && \ syntaxError "invalidCombination" $usageMsg "-n" "-R" [[ -n $tflag ]] && \ syntaxError "invalidCombination" $usageMsg "-t" "-R" ;; t) [[ -n $tflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" tflag="-$OPT"; targ=$OPTARG; [[ $targ != full && $targ != incremental ]] && \ syntaxError "invalidOption" $usageMsg "-$OPT $OPTARG" [[ -n $Rflag ]] && \ syntaxError "invalidCombination" $usageMsg "-t" "-R" ;; T) Tflag="-T"; ;; +[n,r,s,R,t]) # Invalid option syntaxError "invalidOption" $usageMsg $OPT ;; :) # Missing argument syntaxError "missingValue" $usageMsg $OPTARG ;; *) # Invalid option syntaxError "invalidOption" $usageMsg $OPTARG ;; esac done shift OPTIND-1 [[ $# != 0 ]] && syntaxError "extraArg" $usageMsg $1 # Complete the parameter checking and set defaults. [[ -z $nflag && -z $Rflag ]] && \ syntaxError "missingArgs" $usageMsg [[ -z $rarg ]] && rarg=100 rOption="-r $rarg" if [[ -z $targ ]] then if [[ -z $Rflag ]] then tOption="-t incremental" else tOption="" fi else tOption="-t $targ" fi sOption="" if [[ -n $sarg ]] then if [[ ! -d $sarg ]] then # The sort temp dir does not exist. Issue an error and quit. printErrorMsg 574 $mmcmd $sarg cleanupAndExit fi sOption="-s $sarg" fi ####################################################### # Make sure there is a reasonable amount of free space # in the /var/mmfs filesystem. This is needed so that # TSM can create error logs in /var/mmfs/mmbackup. ####################################################### freeSpace=$(getFreeSpace $mmbackupDir) if [[ $freeSpace -lt 100 ]] then # The filesystem is not mounted. Issue an error and quit. printErrorMsg 572 $mmcmd $mmbackupDir "100K" cleanupAndExit fi ######################################################################## # Set up trap exception handling and call the gpfsInit function. # It will ensure that the local copy of the mmsdrfs and the rest of the # GPFS system files are up-to-date. There is no need to lock the sdr. ######################################################################## trap pretrap2 HUP INT QUIT KILL gpfsInitOutput=$(gpfsInit nolock) setGlobalVar $? $gpfsInitOutput # Determine the lookup order for resolving host names. [[ $osName != AIX ]] && resolveOrder=$(setHostResolveOrder) ####################################################### # Make sure the file system exists, that it is part of # this node's cluster, and that it is mounted. ####################################################### findFSoutput=$(findFS "$device" $mmsdrfsFile) [[ -z $findFSoutput ]] && cleanupAndExit # Parse the output from the findFS function. set -f ; set -- $findFSoutput ; set +f fqDeviceName=$1 fsHomeCluster=$3 # Exit with a message if the command was invoked for a remote file system. if [[ $fsHomeCluster != $HOME_CLUSTER ]] then # Command is not allowed for remote file systems. printErrorMsg 106 $mmcmd $device $fsHomeCluster cleanupAndExit 1 fi # Obtain the name of the file system (i.e., the mount point). mountPoint=$(findMountpoint $fqDeviceName) if [[ $mountPoint = "" ]] then # The filesystem is not mounted. Issue an error and quit. printErrorMsg 563 $mmcmd $device $ourNodeName cleanupAndExit fi ########################################################## # Check that the control file, if specified, makes sense. ########################################################## if [[ -z $narg ]] then nOption="" else # Verify the existence of the user specified control file # and create our own copy. checkUserFile $narg $tmpCtrlFile [[ $? -ne 0 ]] && cleanupAndExit # Set nOption to pass the control file to tsbackup. nOption="-n $tmpCtrlFile" # Check whether the backup clients specified in the control file # belong to the cluster. foundError=false IFS_sv="$IFS" # Save the IFS variable. exec 3<&- exec 3< $tmpCtrlFile while read -u3 inputLine do IFS="=" set -f ; set -- $inputLine ; set +f lineType=$1 lineValue=$2 IFS="$IFS_sv" # Restore the IFS variable. if [[ $lineType = clientName ]] then # Find the IP address that corresponds to this node name. hostResult=$($host $lineValue) set -f ; set -- $hostResult ; set +f ipa=${3%%,*} # Exclude everything after the first comma. if [[ -z $ipa ]] then # An invalid node name was specified as a client. printErrorMsg 54 $mmcmd $lineValue foundError=true fi nodeName=$(getNodeInfo \ $REL_HOSTNAME_Field $IPA_Field $ipa $nsId $mmsdrfsFile) if [[ -z $nodeName ]] then # The specified client node is not a member of the GPFS cluster. printErrorMsg 290 $mmcmd $lineValue foundError=true fi fi done # end while read -u3 fileName # If an error was found, print a "command failed" message and exit. if [[ $foundError = true ]] then printErrorMsg 389 $mmcmd cleanupAndExit fi fi ################################################################ # If an incremental or a resume backup was specified, make sure # there is a readable backup control file from a prior backup. ################################################################ if [[ $targ = incremental || -n $Rflag ]] then myBackupCtrlFile="$mountPoint/$backupControlFile" if [[ ! -f $myBackupCtrlFile || ! -r $myBackupCtrlFile ]] then # Can't find or read the backup control file from a prior backup. printErrorMsg 565 $mmcmd $myBackupCtrlFile cleanupAndExit fi fi #################################### # Invoke tsbackup to do the backup. #################################### $tsbackup $fqDeviceName $mountPoint $nOption $rOption $tOption $Rflag $Tflag $sOption rc=$? if [[ $rc -ne 0 ]] then # The command failed. printErrorMsg 389 $mmcmd else # The command completed successfully. printInfoMsg 272 $mmcmd fi cleanupAndExit $rc