#!/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 # @(#)45 1.9.1.2 src/avs/fs/mmfs/ts/admin/mmlsfileset.sh, mmfs, avs_rgpfs24, rgpfs24s005a 6/14/06 14:40:28 ################################################################################ # # Usage: # mmlsfileset Device [[FilesetNameList] [-J JunctionPathList]] | -F FileName] # [-L] [-d] [-i] # # where: # Device is the device name of the file system. # # FilesetNameList is a comma-separated list of fileset names. # # JunctionPathList is a comma-separated list of junction path names. # # FileName is the name of a file containing either fileset # names or junction path names. Each line must contain # a single entry. All junction path names must be fully # qualified path names. # # -L display extended information (fileset id, parent, etc.) # # -d display the number of blocks in use. # # -i display the number of i-nodes in use. # # Undocumented option: # -s display a list of snapshots for this fileset. # ################################################################################ # Include global declarations and service routines. . /usr/lpp/mmfs/bin/mmglobfuncs . /usr/lpp/mmfs/bin/mmsdrfsdef . /usr/lpp/mmfs/bin/mmfsfuncs sourceFile="mmlsfileset.sh" [[ -n $DEBUG || -n $DEBUGmmlsfileset ]] && set -x $mmTRACE_ENTER "$*" # Local work files. Names should be of the form: # fn=${tmpDir}fn.${mmcmd}.$$ filesetFile=${tmpDir}filesetFile.${mmcmd}.$$ LOCAL_FILES=" $filesetFile " # Local variables usageMsg=518 # Local functions ####################### # Mainline processing ####################### ####################################### # Process the command line arguments. ####################################### [[ $arg1 = '-?' || $arg1 = '-h' || $arg1 = '--help' || $arg1 = '--' ]] && \ syntaxError "help" $usageMsg [[ $argc -lt 1 ]] && \ syntaxError "missingArgs" $usageMsg # The first argument is always the file system name. device=$arg1 deviceName=${device##+(/)dev+(/)} # name stripped of /dev/ prefix fqDeviceName="/dev/$deviceName" # fully-qualified name (with /dev/ prefix) # The device name may be followed by a fileset name list # and a -J junction name list, or -F and a file name. if [[ -n $arg2 && $arg2 != "-"* ]] then # A fileset list was specified which may or # may not be followed by a junction list. filesetNameList=$arg2 if [[ $arg3 = "-J"* ]] then # The fileset list is followed by a junction list. junctionPathList=${arg3#-J} if [[ -z $junctionPathList ]] then [[ $argc -lt 4 ]] && syntaxError "missingArgs" $usageMsg junctionPathList=$arg4 shift 4 else shift 3 fi else # The fileset list is not followed by a junction list. shift 2 fi elif [[ $arg2 = "-J"* ]] then # Only a junction list is specified. junctionPathList=${arg2#-J} if [[ -z $junctionPathList ]] then [[ $argc -lt 3 ]] && syntaxError "missingArgs" $usageMsg junctionPathList=$arg3 shift 3 else shift 2 fi elif [[ $arg2 = "-F"* ]] then # A file name is specified; fileset and/or junction lists are not allowed. userFilesetFile=${arg2#-F} if [[ -z $userFilesetFile ]] then [[ $argc -lt 3 ]] && syntaxError "missingArgs" $usageMsg userFilesetFile=$arg3 shift 3 else shift 2 fi else # No file name and no fileset and/or junction lists are specified. shift 1 fi # Process the rest of the parameters. while getopts :diLs OPT do case $OPT in d) # Display number of blocks in use. [[ -n $dflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" dflag="-$OPT" ;; i) # Display number of inodes in use. [[ -n $iflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" iflag="-$OPT" ;; L) # Display extended information. [[ -n $Lflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" Lflag="-$OPT" ;; s) # Display the snapshots of the fileset. [[ -n $sflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" sflag="-$OPT" ;; +[diLs]) # Invalid option syntaxError "invalidOption" $usageMsg $OPT ;; :) # Missing argument syntaxError "missingValue" $usageMsg $OPTARG ;; *) # Invalid option syntaxError "invalidOption" $usageMsg $OPTARG ;; esac done # end of while getopts :diLs OPT do shift OPTIND-1 [[ $# != 0 ]] && syntaxError "extraArg" $usageMsg $1 # If a fileset list was specified, parse it and # put the names in a file. $rm -f $filesetFile if [[ -n $filesetNameList ]] then IFS=',' set -f for filesetName in $filesetNameList do print -- "$filesetName" >> $filesetFile checkForErrors "writing to $filesetFile" $? done set +f IFS="$IFS_sv" fi # end of if [[ -n $filesetNameList ]] # If a junction list was specified, parse it and # put the fully-qualified path names in a file. if [[ -n $junctionPathList ]] then IFS=',' set -f for junctionName in $junctionPathList do [[ $junctionName != /* ]] && junctionName="${PWD%/}/${junctionName}" print -- "$junctionName" >> $filesetFile checkForErrors "writing to $filesetFile" $? done set +f IFS="$IFS_sv" junctionsSpecified=yes fi # end of if [[ -n $junctionPathList ]] # If a file was specified, ensure the file exists and create our own copy. if [[ -n $userFilesetFile ]] then checkUserFile $userFilesetFile $filesetFile [[ $? -ne 0 ]] && cleanupAndExit # See if this file contains junction path names. $grep -q "^/" $filesetFile > /dev/null 2>&1 [[ $? -eq 0 ]] && junctionsSpecified=yes fi # end of if [[ -n $userFilesetFile ]] ##################################################################### # Set up trap exception handling and ensure that the local copy of # the mmsdrfs is up-to-date. There is no need to lock the mmsdrfs. ##################################################################### trap pretrap2 HUP INT QUIT KILL gpfsInitOutput=$(gpfsInit nolock) setGlobalVar $? $gpfsInitOutput ########################################################### # Make sure the specified file system exists and is local. ########################################################### 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 if the command was invoked for a remote file system. if [[ $fsHomeCluster != $HOME_CLUSTER ]] then # The command is not allowed for remote file systems. printErrorMsg 106 $mmcmd $device $fsHomeCluster cleanupAndExit fi ############################# # Verify the junction names. ############################# if [[ -n $junctionsSpecified ]] then # The file system must be mounted. mountPoint=$(findMountpoint $deviceName) if [[ -z $mountPoint ]] then # The file system is not mounted. printErrorMsg 552 $mmcmd $device cleanupAndExit fi # Find the device ID of the mounted GPFS file system. gpfsDeviceID=$($perl -e '($dev) = stat "'$mountPoint'"; printf "%u", $dev;') # Scan the entries in the file. If a junction path name is found, # ensure the junction is within the mounted file system. exec 3< $filesetFile while read -u3 name do # Skip empty lines. [[ $name = *([$BLANKchar$TABchar]) ]] && continue if [[ $name = /* ]] then # This is a junction path name. # Find the device ID and inode number of the junction. # The result is a colon-separated device and inode numbers. junctionDevAndIno=$($perl -e ' ($dev,$ino) = stat "'$name'"; if ($dev ne "") { printf "%u:%u", $dev,$ino }') # The junction must be within the mounted file system. if [[ $gpfsDeviceID != ${junctionDevAndIno%:*} ]] then printErrorMsg 550 $mmcmd $name $device fatalError=yes else # Things look OK. Create the extended junction path name. name="/GPFS:${junctionDevAndIno#*:}${name}" fi fi # end of if [[ $name = /* ]] # Put the verified name in a temp file. print -- "$name" >> $tmpfile checkForErrors "writing to $tmpfile" $? done # end while read -u3 name # Give up if there are errors. [[ -n $fatalError ]] && cleanupAndExit $mv $tmpfile $filesetFile checkForErrors "mv $tmpfile $filesetFile" $? fi # end of if [[ -n $junctionsSpecified ]] ######################################################################## # Invoke the tslsfileset command on the local node. # Display any error messages and exit if any of the following are true: # - the command completed successfully # - a junction path name is specified # - there is an unacceptable error # (anything other than daemon down or quorum wait) # - this is a single node cluster ######################################################################## if [[ -s $filesetFile ]] then $tslsfileset $fqDeviceName -F $filesetFile $Lflag $dflag $iflag $sflag 2>$errMsg rc=$(remapRC $?) else $tslsfileset $fqDeviceName $Lflag $dflag $iflag $sflag 2>$errMsg rc=$(remapRC $?) fi if [[ $rc -ne $MM_DaemonDown && $rc -ne $MM_QuorumWait || -n $junctionsSpecified || $MMMODE = single ]] then 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. [[ -s $errMsg ]] && $cat $errMsg 1>&2 # [[ $rc -ne 0 ]] && printErrorMsg 113 "$mmcmd" "tslsfileset" $rc fi # end of if [[ $rc -eq $MM_FsNotFound ]] cleanupAndExit $rc fi # end of if [[ ($rc -ne $MM_DaemonDown && ... ]] $rm -f $errMsg #################################################################### # We come here if the local GPFS daemon is not ready for commands. # Find an active node and send the command there. #################################################################### # Create a file with the reliable names of the nodes in the cluster. getNodeList $REL_HOSTNAME_Field $GLOBAL_ID $mmsdrfsFile > $nodefile preferredNode=$ourNodeName # Try the nodes one by one until you find a node that can execute the command. ################################## # Invoke the tslsfileset command. ################################## if [[ -s $filesetFile ]] then $mmcommon onactive $preferredNode $nodefile \ $filesetFile $NO_MOUNT_CHECK NULL $NO_LINK \ tslsfileset "$fqDeviceName -F $filesetFile $Lflag $dflag $iflag $sflag" rc=$? else $mmcommon onactive $preferredNode $nodefile \ $NO_FILE_COPY $NO_MOUNT_CHECK NULL $NO_LINK \ tslsfileset "$fqDeviceName $Lflag $dflag $iflag $sflag" rc=$? fi # end of if [[ -s $filesetFile ]] # if [[ $rc -ne 0 ]] # then # # tslsfileset failed. # printErrorMsg 104 $mmcmd tslsfileset # cleanupAndExit $rc # fi cleanupAndExit $rc