#!/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 # @(#)41 1.9.1.1 src/avs/fs/mmfs/ts/admin/mmchfileset.sh, mmfs, avs_rgpfs24, rgpfs24s007a 10/18/06 12:02:51 ################################################################################ # # Usage: # mmchfileset Device {FilesetName | -J JunctionPath} # {[-j NewFileSetName] [-t Comment]} # # where: # Device is the device name of the file system. # FilesetName is the fileset name. # JunctionPath is the fileset junction path name. # NewFilesetName is the new fileset name to be given to an existing fileset. # Comment is a user-provided description of the fileset. # The total length cannot exceed 255 characters. # ################################################################################ # Include global declarations and service routines. . /usr/lpp/mmfs/bin/mmglobfuncs . /usr/lpp/mmfs/bin/mmsdrfsdef . /usr/lpp/mmfs/bin/mmfsfuncs sourceFile="mmchfileset.sh" [[ -n $DEBUG || -n $DEBUGmmchfileset ]] && set -x $mmTRACE_ENTER "$*" # Local work files. Names should be of the form: # fn=${tmpDir}fn.${mmcmd}.$$ LOCAL_FILES=" " # Local variables usageMsg=514 # Local functions ####################### # Mainline processing ####################### ####################################### # Process the command line arguments. ####################################### [[ $arg1 = '-?' || $arg1 = '-h' || $arg1 = '--help' || $arg1 = '--' ]] && \ syntaxError "help" $usageMsg [[ $argc -lt 3 ]] && \ 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 must be followed by a fileset name or -J and a junction path. if [[ $arg2 = "-J"* ]] then junctionName=${arg2#-J} if [[ -z $junctionName ]] then junctionName=$arg3 shift 3 else shift 2 fi else filesetName=$arg2 checkName filesetName 255 "$filesetName" [[ $? -ne 0 ]] && cleanupAndExit [[ $arg3 = "-J"* ]] && \ syntaxError "invalidCombination" $usageMsg "-J" "FilesetName" shift 2 fi # Process the rest of the parameters. while getopts :j:t: OPT do case $OPT in j) # New fileset name [[ -n $jflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" jflag="-$OPT"; jarg="$OPTARG" newFilesetName=$jarg checkName filesetName 255 "$newFilesetName" [[ $? -ne 0 ]] && cleanupAndExit ;; t) # New comment string [[ -n $tflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" tflag="-$OPT"; targ="$OPTARG" userComments="$targ" checkName lengthCheckOnly 255 "$userComments" [[ $? -ne 0 ]] && cleanupAndExit ;; +[jt]) # Invalid option syntaxError "invalidOption" $usageMsg $OPT ;; :) # Missing argument syntaxError "missingValue" $usageMsg $OPTARG ;; *) # Invalid option syntaxError "invalidOption" $usageMsg $OPTARG ;; esac done # end of while getopts :j:t: OPT do shift OPTIND-1 [[ $# != 0 ]] && syntaxError "extraArg" $usageMsg $1 ###################################################################### # Set up trap exception handling and ensure that the local copy of # the mmsdrfs file is up-to-date. There is no need to lock the file. ###################################################################### 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 # Command is not allowed for remote file systems. printErrorMsg 106 $mmcmd $device $fsHomeCluster cleanupAndExit fi ############################# # Verify the junction name. ############################# if [[ -n $junctionName ]] then # The file system must be mounted. mountPoint=$(findMountpoint $deviceName) if [[ -z $mountPoint ]] then # 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;') # Ensure the junction path name is fully qualified. [[ $junctionName != /* ]] && junctionName="${PWD%/}/${junctionName}" junctionName=${junctionName%%/} # Strip any trailing slashes. # 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 "'$junctionName'"; if ($dev ne "") { printf "%u:%u", $dev,$ino }') # The junction must be within the mounted file system. if [[ $gpfsDeviceID != ${junctionDevAndIno%:*} ]] then printErrorMsg 550 $mmcmd "$junctionName" $device cleanupAndExit fi # Create the extended junction path name. junctionName="-J /GPFS:${junctionDevAndIno#*:}${junctionName}" fi # end of if [[ -n $junctionName ]] ########################################################################## # Invoke the tschfileset 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) # - the user comment string contains blanks or tabs # (the existing infrastructure cannot deal with imbedded blanks) # - the fileset name (old or new) contains path name expansion triggers # - this is a single node cluster ########################################################################## [[ -n $newFilesetName ]] && newFilesetName="-j $newFilesetName" set -f if [[ -n $userComments ]] then $tschfileset $fqDeviceName \ $filesetName $junctionName $newFilesetName -t "$userComments" 2>$errMsg rc=$(remapRC $?) else $tschfileset $fqDeviceName \ $filesetName $junctionName $newFilesetName 2>$errMsg rc=$(remapRC $?) fi set +f if [[ $rc -ne $MM_DaemonDown && $rc -ne $MM_QuorumWait || "$userComments" = *+([;$BLANKchar$TABchar])* || -n $junctionName || $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" "tschfileset" $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. if [[ -n $userComments ]] then $mmcommon onactive $preferredNode $nodefile \ $NO_FILE_COPY $NO_MOUNT_CHECK NULL $NO_LINK \ tschfileset $fqDeviceName $filesetName $newFilesetName -t "$userComments" rc=$? else $mmcommon onactive $preferredNode $nodefile \ $NO_FILE_COPY $NO_MOUNT_CHECK NULL $NO_LINK \ tschfileset $fqDeviceName $filesetName $newFilesetName rc=$? fi # if [[ $rc -ne 0 ]] # then # # tschfileset failed. # printErrorMsg 104 $mmcmd tschfileset # cleanupAndExit $rc # fi cleanupAndExit $rc