#!/bin/ksh # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # # # Licensed Materials - Property of IBM # # (C) COPYRIGHT International Business Machines Corp. 2005,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 # @(#)93 1.10 src/avs/fs/mmfs/ts/admin/mmapplypolicy.sh, mmfs, avs_rgpfs24, rgpfs240610b 2/17/06 16:50:52 ################################################################################ # # Usage: # mmapplypolicy {Device|Directory} [-P PolicyFile] [-I {yes|defer|test}] # [-L n] [-D yyyy-mm-dd[@hh:mm[:ss]]] [-s WorkDirectory] # # where: # Device The device name of the file system from which files # are to be deleted or migrated. # # Directory The fully-qualified path name of a GPFS file system # subtree form which files are to be deleted or migrated. # # -P PolicyFilename The name of the file containing the policy rules to be # applied. If not specified, the policy rules currently # in effect for the file system will be used. # # -I yes|defer|test Determines what actions mmapplypolicy will take on files: # # If -I yes is specified, all applicable MIGRATE and DELETE # policy rules will be executed, and the data movement # between pools is done during the execution of the # mmapplypolicy command. This is the default action. # # If -I defer is specified, all applicable MIGRATE and # DELETE policy rules will be executed, but the actual # data movement between pools is deferred until the next # mmrestripefs command. # # If -I test is specified, all policy rules are evaluated, # but the mmapplypolicy command only displays the actions # that would be executed had -I defer or -I yes been # specified. This option is intended for testing the # effects of particular policy rules; there is no actual # deletion of files or data movement between pools. # # -L n Controls the level of information displayed by the command. # n should be one of the following values: # 0 - Only display serious errors. # 1 - Display some information as the command executes, # but not for each file. This is the default. # 2 - Display each chosen file and the scheduled migration # or deletion action. # 3 - And display each candidate file and the applicable # rule. # 4 - And display each explicitly EXCLUDEd file and the # applicable rule. # 5 - And display the attributes of candidate and EXCLUDEd # files. # 6 - And display non-candidate files and their attributes. # # -D yyyy-mm-dd[@hh:mm[:ss]] Specifies the date and (UTC) time to be used # by the mmapplypolicy command when evaluating the policy # rules. The default is the current date and time. # If only a date is specified, the time will default to # 00:00:00. # # -s WorkDirectory The directory to be used for temporary storage during # command processing. The default directory is /tmp. # ################################################################################ # Include global declarations and service routines. . /usr/lpp/mmfs/bin/mmglobfuncs . /usr/lpp/mmfs/bin/mmsdrfsdef . /usr/lpp/mmfs/bin/mmfsfuncs sourceFile="mmapplypolicy.sh" [[ -n $DEBUG || -n $DEBUGmmapplypolicy ]] && set -x $mmTRACE_ENTER "$*" # Local work files. Names should be of the form: # fn=${tmpDir}fn.${mmcmd}.$$ tspolicyFile=${tmpDir}tspolicyFile.${mmcmd}.$$ LOCAL_FILES=" $tspolicyFile " # Local variables usageMsg=457 # Local functions ########################################################################## # # Function: Verifies the correctness of the input date-time string. # # Input: $1 - input date-time string # # Output: The verified string: yyyy-mm-dd@hh:mm:ss # # Returns: 0 - no errors encountered # 1 - invalid date-time string # ########################################################################## function parseDateTime # { typeset sourceFile="mmapplypolicy.sh" [[ -n $DEBUG || -n $DEBUGparseDateTime ]] && set -x typeset dt=$1 typeset dateTimeString if [[ $dt = [0-9][0-9][0-9][0-9]-0[1-9]-[0-3][0-9] ]] then dateTimeString="${dt}@00:00:00" elif [[ $dt = [0-9][0-9][0-9][0-9]-1[012]-[0-3][0-9] ]] then dateTimeString="${dt}@00:00:00" elif [[ $dt = [0-9][0-9][0-9][0-9]-0[1-9]-[0-3][0-9]@[012][0-9]:[0-5][0-9] ]] then dateTimeString="${dt}:00" elif [[ $dt = [0-9][0-9][0-9][0-9]-1[012]-[0-3][0-9]@[012][0-9]:[0-5][0-9] ]] then dateTimeString="${dt}:00" elif [[ $dt = [0-9][0-9][0-9][0-9]-0[1-9]-[0-3][0-9]@[012][0-9]:[0-5][0-9]:[0-5][0-9] ]] then dateTimeString="$dt" elif [[ $dt = [0-9][0-9][0-9][0-9]-1[012]-[0-3][0-9]@[012][0-9]:[0-5][0-9]:[0-5][0-9] ]] then dateTimeString="$dt" else # Unexpected date-time string. return 1 fi # Return the result. print -- "$dateTimeString" return 0 } #----- end of function parseDateTime ---------------------- ####################### # Mainline processing ####################### ################################# # Process the command arguments. ################################# [[ $arg1 = '-?' || $arg1 = '-h' || $arg1 = '--help' || $arg1 = '--' ]] && \ syntaxError "help" $usageMsg [[ $argc -lt 1 ]] && \ syntaxError "missingArgs" $usageMsg # Determine what was specified on the command line. if [[ $arg1 = /* && $arg1 != +(/)dev+(/)* ]] then # If the first argument starts with a "/" but not "/dev/", # it is assumed to be a fully-qualified directory name. directory=$arg1 else # Otherwise, the argument is assumed to be a file system device name. device=$arg1 deviceName=${device##+(/)dev+(/)} # Name stripped of /dev/ prefix. fi # end of if [[ $arg1 = "/"* && $arg1 != +(/)dev+(/)* ]] # Move past the required parameters. shift 1 # Process the rest of the options. while getopts :D:I:L:P:s: OPT do case $OPT in D) [[ -n $Dflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" Dflag="-$OPT"; Darg=$OPTARG; dateTimeString=$(parseDateTime "$Darg") [[ -z $dateTimeString ]] && \ syntaxError "invalidOption" $usageMsg "-$OPT $OPTARG" ;; I) [[ -n $Iflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" Iflag="-$OPT"; Iarg=$OPTARG; [[ $Iarg != yes && $Iarg != defer && $Iarg != test ]] && \ syntaxError "invalidOption" $usageMsg "-$OPT $OPTARG" ;; L) [[ -n $Lflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" Lflag="-$OPT"; Larg=$OPTARG; listingLevel=$(checkIntRange $Lflag $Larg 0 6) [[ $? -ne 0 ]] && cleanupAndExit ;; P) [[ -n $Pflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" Pflag="-$OPT"; Parg=$OPTARG; policyFile="$Parg" ;; s) [[ -n $sflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" sflag="-$OPT"; sarg=$OPTARG; workDirectory="$sarg" ;; +[DILPs]) # Invalid option. syntaxError "invalidOption" $usageMsg $OPT ;; :) # Missing argument. syntaxError "missingValue" $usageMsg $OPTARG ;; *) # Invalid option. syntaxError "invalidOption" $usageMsg $OPTARG ;; esac done # end of while getopts :t: OPT do shift OPTIND-1 [[ $# != 0 ]] && syntaxError "extraArg" $usageMsg $1 # Check the policy file input parameter. if [[ -n $policyFile && $policyFile != DEFAULT ]] then if [[ ! -f "$policyFile" ]] then # Can't read the input file. printErrorMsg 43 $mmcmd "$policyFile" cleanupAndExit fi if [[ ! -s "$policyFile" ]] then # Input file is empty. printErrorMsg 329 $mmcmd "$policyFile" cleanupAndExit fi fi # Check the working directory input parameter. if [[ -n $workDirectory && $workDirectory != DEFAULT ]] then if [[ ! -d "$workDirectory" ]] then # Directory does not exist. printErrorMsg 574 $mmcmd "$workDirectory" cleanupAndExit fi else workDirectory="/tmp" fi # Assign a default value for -I. [[ -z $Iarg ]] && Iarg=yes # Assign a listing level if the user did not specify one. [[ -z $listingLevel ]] && listingLevel=1 ##################################################################### # Set up trap exception handling and ensure that the local copy of # the mmsdrfs is up-to-date. There is no need to lock mmsdrfs file. ##################################################################### trap pretrap2 HUP INT QUIT KILL gpfsInitOutput=$(gpfsInit nolock) setGlobalVar $? $gpfsInitOutput ########################################################### # If the target of mmapplypolicy is a directory sub-tree, # find the file system to which this directory belongs. ########################################################### if [[ -n $directory ]] then if [[ ! -d "$directory" ]] then # Directory does not exist. printErrorMsg 574 $mmcmd "$directory" cleanupAndExit fi device=$(findDeviceName "$directory") [[ $? -ne 0 ]] && cleanupAndExit fi ###################################################### # Ensure the file system exists, that it belongs to # this cluster, and that it is mounted on this node. ###################################################### findFSoutput=$(findFS "$device" $mmsdrfsFile) [[ -z $findFSoutput ]] && cleanupAndExit # Parse the output from the findFS function. set -f ; set -- $findFSoutput ; set +f fqDeviceName=$1 deviceName=$2 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 fi # Verify that the file system is mounted. mountPoint=$(findMountpoint "$fqDeviceName") if [[ -z $mountPoint ]] then # The filesystem is not mounted. Issue an error and quit. printErrorMsg 563 $mmcmd "$device" "$ourNodeName" cleanupAndExit fi ############################################### # If a policy file was not specified, retrieve # the current policy file for the file system. ############################################### if [[ -z $policyFile ]] then # Invoke the tslspolicy command. $tslspolicy "$fqDeviceName" -L >$tspolicyFile rc=$(remapRC $?) if [[ $rc -eq $MM_DaemonDown ]] then # GPFS is down on this node. printErrorMsg 109 $mmcmd elif [[ $rc -eq $MM_QuorumWait ]] then # GPFS is not ready for commands. printErrorMsg 110 $mmcmd elif [[ $rc -eq $MM_ConnectionReset ]] then # An internode connection was reset. printErrorMsg 257 $mmcmd else # Either the command worked, or it is an unexpected error. : # [[ $rc -ne 0 ]] && printErrorMsg 113 "$mmcmd" "tslspolicy" $rc fi # end of if [[ $rc -eq $MM_DaemonDown ]] if [[ $rc -ne 0 || ! -s $tspolicyFile ]] then # The policy file cannot be determined. printErrorMsg 456 $mmcmd [[ $rc -eq 0 ]] && rc=1 cleanupAndExit $rc else # The command must have worked. policyFile=$tspolicyFile fi # end of if [[ $rc -ne 0 || ! -s $tspolicyFile ]] fi # end of if [[ -z $policyFile ]] #################################################################### # Determine the argument list for the tsmigrate command invocation. #################################################################### if [[ -n $directory ]] then argList="$directory -P $policyFile -I $Iarg -L $listingLevel -s $workDirectory" else argList="$fqDeviceName -P $policyFile -I $Iarg -L $listingLevel -s $workDirectory" fi [[ -n $dateTimeString ]] && argList="${argList} -D $dateTimeString" ################################################## # Invoke the tsmigrate command on the local node. ################################################## $tsmigrate $argList rc=$(remapRC $?) if [[ $rc -eq $MM_DaemonDown ]] then # GPFS is down on this node. printErrorMsg 109 $mmcmd elif [[ $rc -eq $MM_QuorumWait ]] then # GPFS is not ready for commands. printErrorMsg 110 $mmcmd elif [[ $rc -eq $MM_ConnectionReset ]] then # An internode connection was reset. printErrorMsg 257 $mmcmd else # Either the command worked, or it is an unexpected error. : # [[ $rc -ne 0 ]] && printErrorMsg 113 "$mmcmd" "tsmigrate" $rc fi # end of if [[ $rc -eq $MM_FsNotFound ]] # if [[ $rc -ne 0 ]] # then # # tsmigrate failed. # printErrorMsg 104 $mmcmd tsmigrate # cleanupAndExit $rc # fi cleanupAndExit $rc