#!/bin/ksh # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # # # Licensed Materials - Property of IBM # # (C) COPYRIGHT International Business Machines Corp. 1997,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 # @(#)18 1.109.1.5 src/avs/fs/mmfs/ts/admin/mmchfs.sh, mmfs, avs_rgpfs24, rgpfs24s006a 8/25/06 13:05:47 ################################################################################ # # Usage: # # mmchfs Device [-A {yes | no | automount}] [-D {posix | nfs4}] # [-E {yes | no}] [-F MaxNumInodes[:NumInodesToPreallocate]] # [-k {posix | nfs4 | all}] [-m DefaultMetadataReplicas] # [-o mountOptions] [-Q {yes | no}] [-r DefaultDataReplicas] # [-K {no | whenpossible | always}] # [-s {roundRobin | random | balancedRandom}] # [-S {yes | no}] [-T Mountpoint] [-V] [-z {yes | no}] # or # mmchfs Device [-W newDeviceName] # # where # # Device is the device name of the file system. # # -A {yes|no|automount} Set the automount option. # # -D {posix|nfs4} Indicates whether CIFS deny write locks block NFS writes # (nfs4) or not (posix) # # -E {yes|no} Enable or disable exact mtime # # -F MaxNumInodes[:NumInodesToPreallocate] # Specify the maximum number of files in the file system. # Optionally, specify how many inodes to preallocate. # # -k {posix|nfs4|all} Specify the ACL semantics (posix, nfs4, all) # # -K {no|whenpossible|always} Replica allocation behavior # # -m DefaultMetadataReplicas # is the default for the current number of replicas # for metadata. # # -o mountOptions is a comma-separated list of mount options. # # -Q {yes|no} Enable or disable the quota option. # # -r DefaultDataReplicas # is the default for the current number of replicas for data. # # -s StripeMethod is the stripe method. # # -S {yes|no} Enable or disable (suppress) atime. # # -T {mountpoint} Change the mount point to the specified value. # # -V Change the file system to the latest format version. # # -W newDeviceName is the desired new name of the file system. # # -z {yes|no} Enable or disable DMAPI. # # # Note: The -s option is undocumented. # # Note: The -C option is obsolete; use mmexportfs/mmimportfs instead. # ################################################################################ # Include global declarations and service routines. . /usr/lpp/mmfs/bin/mmglobfuncs . /usr/lpp/mmfs/bin/mmsdrfsdef . /usr/lpp/mmfs/bin/mmfsfuncs sourceFile="mmchfs.sh" [[ -n $DEBUG || -n $DEBUGmmchfs ]] && set -x $mmTRACE_ENTER "$*" # Local work files. Names should be of the form: # fn=${tmpDir}fn.${mmcmd}.$$ LOCAL_FILES=" " # Local variables integer n usageMsg=421 # Local functions ########################################################### # This function is called if there is an interrupt after # mmsdrfs changes are committed but before ts changes are. ########################################################### function localPosttrap { if [[ -n $mmsdrfsParms ]] then # Interrupt received: only -A, -Q, and -T changed. printErrorMsg 33 $mmcmd else # Interrupt received: no changes made. printErrorMsg 20 $mmcmd fi $mmTRACE_EXIT "rc=2" cleanupAndExit 2 } ########################################################################### # # Function: Process the specified mount options string. # Provide default values for missing options. # This function is called if the -o flag is specified. # # Input: $1 - A comma-separated list of mount options. # # Output: Colon-separated string containing the fields: # rwOption:mtimeOption:atimeOption:quotaOptions:otherOptions: # # Returns: 0 - success # 1 - error encountered # ########################################################################### function parseMountOptions # { typeset sourceFile="mmchfs.sh" [[ -n $DEBUG || -n $DEBUGparseMountOptions ]] && set -x $mmTRACE_ENTER "$*" typeset optionsString=$1 typeset rc=0 typeset rwOption="" typeset mtimeOption="" typeset atimeOption="" typeset quotaOptions="" typeset otherOptions="" # Parse the options string looking for certain options. # All other options are simply passed through. IFS="," for option in $optionsString do case $option in rw | ro | rs ) [[ $option = rs ]] && option=ro rwOption=$option ;; atime* | noatime ) if [[ $option = atime || $option = "atime=1" || $option = "atime=yes" ]] then atimeOption=atime elif [[ $option = noatime || $option = "atime=0" || $option = "atime=no" ]] then atimeOption=noatime else print -u2 "$mmcmd: Invalid mount option specified: $option." return 1 fi ;; mtime* | nomtime ) if [[ $option = mtime || $option = "mtime=1" || $option = "mtime=yes" ]] then mtimeOption=mtime elif [[ $option = nomtime || $option = "mtime=0" || $option = "mtime=no" ]] then mtimeOption=nomtime else print -u2 "$mmcmd: Invalid mount option specified: $option." return 1 fi ;; syncnfs* | nosyncnfs ) if [[ $option = syncnfs || $option = "syncnfs=1" || $option = "syncnfs=yes" ]] then otherOptions="${otherOptions},syncnfs" elif [[ $option = nosyncnfs || $option = "syncnfs=0" || $option = "syncnfs=no" ]] then otherOptions="${otherOptions},nosyncnfs" else print -u2 "$mmcmd: Invalid mount option specified: $option." return 1 fi ;; *quota* ) quotaOptions="${quotaOptions};$option" ;; *rootSquash* ) : # Do nothing; root squash is controlled with mmauth grant. ;; * ) otherOptions="${otherOptions},$option" ;; esac # end of case $option in done # end of for option in $optionsString do IFS="$IFS_sv" quotaOptions="${quotaOptions##+(;)}" # Strip leading semicolons, if any. quotaOptions="${quotaOptions%%+(;)}" # Strip trailing semicolons, if any. otherOptions="${otherOptions##+(,)}" # Strip leading commas, if any. otherOptions="${otherOptions%%+(,)}" # Strip trailing commas, if any. # Output the results and return. print -- "$rwOption:$mtimeOption:$atimeOption:$quotaOptions:$otherOptions:" $mmTRACE_EXIT "rc=$rc" return $rc } #------ end of function parseMountOptions ----------------- ###################### # Mainline processing ###################### ################################# # Process the command arguments. ################################# [[ $arg1 = '-?' || $arg1 = '-h' || $arg1 = '--help' || $arg1 = '--' ]] && \ syntaxError "help" $usageMsg [[ $argc -lt 2 ]] && \ syntaxError "missingArgs" $usageMsg # The first argument is always the file system name. device=$arg1 shift 1 # Drop the device name from the parameter list. # Process the individual arguments and the values associated with them. while getopts :A:C:D:E:F:k:K:m:o:Q:r:s:S:T:W:z:V OPT do case $OPT in A) [[ -n $Aflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" Aflag="-$OPT"; Aarg=$OPTARG; [[ $Aarg != yes && $Aarg != no && $Aarg != automount ]] && \ syntaxError "invalidOption" $usageMsg "-$OPT $OPTARG" if [[ $Aarg = yes ]] then Aarg=mmfs elif [[ $Aarg = no ]] then Aarg=false else : # It must be "automount". fi # Add -A to the list of parameters not handled by the daemon. if [[ -z $mmsdrfsParms ]] then mmsdrfsParms="-$OPT" else mmsdrfsParms="${mmsdrfsParms}, -$OPT" fi ;; C) syntaxError "obsoleteOption" $usageMsg "-$OPT" ;; D) [[ -n $Dflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" Dflag="-$OPT"; Darg=$OPTARG; [[ $Darg != nfs4 && $Darg != posix ]] && \ syntaxError "invalidOption" $usageMsg "-$OPT $OPTARG" # Add -D to the list of parameters handled by tschfs. tschfsParms="${tschfsParms} $Dflag $Darg" ;; E) [[ -n $Eflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" Eflag="-$OPT"; Earg=$OPTARG; [[ $Earg != yes && $Earg != no ]] && \ syntaxError "YesNoValue" $noUsageMsg "-$OPT" # Add -E to the list of parameters not handled by the daemon. if [[ -z $mmsdrfsParms ]] then mmsdrfsParms="-$OPT" else mmsdrfsParms="${mmsdrfsParms}, -$OPT" fi if [[ $Earg = yes ]] then Earg="mtime" else Earg="nomtime" fi callResetEFOptions=yes ;; F) [[ -n $Fflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" Fflag="-$OPT"; Farg=$OPTARG; ;; k) [[ -n $kflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" kflag="-$OPT"; karg=$OPTARG; [[ $karg != posix && $karg != nfs4 && $karg != all ]] && \ syntaxError "invalidOption" $usageMsg "-$OPT $OPTARG" # Add -k to the list of parameters handled by tschfs. tschfsParms="${tschfsParms} $kflag $karg" ;; K) [[ -n $Kflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" Kflag="-$OPT"; Karg=$OPTARG; [[ $Karg != no && $Karg != whenpossible && $Karg != always ]] && \ syntaxError "invalidOption" $usageMsg "-$OPT $OPTARG" # Add -K to the list of parameters handled by tschfs. tschfsParms="${tschfsParms} $Kflag $Karg" ;; m) [[ -n $mflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" mflag="-$OPT"; marg=$OPTARG; # Ensure that marg is an integer, and that its value is 1 or 2. n=$(checkIntRange $mflag $marg 1 2) [[ $? -ne 0 ]] && cleanupAndExit # Add -m to the list of parameters handled by tschfs. tschfsParms="${tschfsParms} $mflag $marg" ;; o) [[ -n $oflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" oflag="-$OPT"; oarg=$OPTARG; [[ -z $oarg ]] && oarg=DELETE # Add -o to the list of parameters not handled by the daemon. if [[ -z $mmsdrfsParms ]] then mmsdrfsParms="-$OPT" else mmsdrfsParms="${mmsdrfsParms}, -$OPT" fi callResetEFOptions=yes ;; Q) [[ -n $Qflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" Qflag="-$OPT"; Qarg=$OPTARG; [[ $Qarg != yes && $Qarg != no ]] && \ syntaxError "YesNoValue" $noUsageMsg "-$OPT" # Add -Q to the list of parameters not handled by the daemon. if [[ -z $mmsdrfsParms ]] then mmsdrfsParms="-$OPT" else mmsdrfsParms="${mmsdrfsParms}, -$OPT" fi if [[ $Qarg = yes ]] then Qarg=$QUOTA_ACTIVATED else Qarg=DELETE fi callResetEFOptions=yes ;; r) [[ -n $rflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" rflag="-$OPT"; rarg=$OPTARG; # Ensure that rarg is an integer, and that its value is 1 or 2. n=$(checkIntRange $rflag $rarg 1 2) [[ $? -ne 0 ]] && cleanupAndExit # Add -r to the list of parameters handled by tschfs. tschfsParms="${tschfsParms} $rflag $rarg" ;; s) [[ -n $sflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" sflag="-$OPT"; sarg=$OPTARG; # Let tschfs validate the argument. # Add -s to the list of parameters handled by tschfs. tschfsParms="${tschfsParms} $sflag $sarg" ;; S) [[ -n $Sflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" Sflag="-$OPT"; Sarg=$OPTARG; [[ $Sarg != yes && $Sarg != no ]] && \ syntaxError "YesNoValue" $noUsageMsg "-$OPT" # Add -S to the list of parameters not handled by the daemon. if [[ -z $mmsdrfsParms ]] then mmsdrfsParms="-$OPT" else mmsdrfsParms="${mmsdrfsParms}, -$OPT" fi if [[ $Sarg = yes ]] then Sarg="noatime" else Sarg="atime" fi callResetEFOptions=yes ;; T) [[ -n $Tflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" Tflag="-$OPT"; Targ=$OPTARG; # Ensure the pathname starts with a slash. [[ $Targ = ${Targ#/} ]] && \ syntaxError "absolutePath" $noUsageMsg $Targ # Add -T to the list of parameters not handled by the daemon. if [[ -z $mmsdrfsParms ]] then mmsdrfsParms="-$OPT" else mmsdrfsParms="${mmsdrfsParms}, -$OPT" fi callResetEFOptions=yes ;; V) [[ -n $Vflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" Vflag="-$OPT"; # Add -V to the list of parameters handled by tschfs. tschfsParms="${tschfsParms} $Vflag" ;; W) # If specified, W must be the only option. [[ $argc -gt 3 ]] && syntaxError "help" $usageMsg Wflag="-$OPT"; Warg=$OPTARG; checkName deviceName 255 "$Warg" [[ $? -ne 0 ]] && cleanupAndExit ;; z) [[ -n $zflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" zflag="-$OPT"; zarg=$OPTARG; [[ $zarg != yes && $zarg != no ]] && \ syntaxError "YesNoValue" $noUsageMsg "-$OPT" # Add -z to the list of parameters handled by tschfs. tschfsParms="${tschfsParms} $zflag $zarg" ;; +[ACDEFkKmoQrsSTVWz]) # 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 # Parse and process the -o value if it was specified. # This can result in prior values for Earg, Qarg, and Sarg # being overridden. if [[ $oarg = DEFAULT || $oarg = DELETE ]] then # Set the default mount options; leave the quota setting alone. sgRW_OPT_Value="rw" Earg="mtime" Sarg="atime" oarg=DELETE elif [[ -n $oarg ]] then # Parse the mount options and set variables to be used later. parseMountOptionsOutput=$(parseMountOptions $oarg) [[ $? -ne 0 ]] && cleanupAndExit IFS=":" set -f ; set -- $parseMountOptionsOutput ; set +f [[ -n $1 ]] && sgRW_OPT_Value=$1 [[ -n $2 ]] && Earg=$2 [[ -n $3 ]] && Sarg=$3 [[ -n $4 ]] && Qarg=$4 oarg=$5 IFS="$IFS_sv" fi # end of if [[ $oarg = DEFAULT || $oarg = DELETE ]] # Process the -F value. Verify it is of the form NumInodes[:NumInodesToPreallocate] if [[ -n $Farg ]] then IFS=":" set -f ; set -- $Farg ; set +f numInodes=$1 numInodesToPreallocate=$2 IFS="$IFS_sv" [[ -z $numInodes ]] && \ syntaxError "invalidOption" $usageMsg "$Fflag $Farg" n=$(checkIntRange $Fflag $numInodes) [[ $? -ne 0 ]] && cleanupAndExit Farg=$n if [[ -n $numInodesToPreallocate && $numInodesToPreallocate != 0 ]] then n=$(checkIntRange $Fflag $numInodesToPreallocate) [[ $? -ne 0 ]] && cleanupAndExit Farg="${Farg}:$n" fi # Add -F to the list of parameters handled by tschfs. tschfsParms="${tschfsParms} $Fflag $Farg" fi # end of if [[ -n $Farg ]] ########################################################### # If the request is to rename the file system (-W option), # invoke the mmmvfs script. ########################################################### if [[ -n $Wflag ]] then $mmmvfs $device $Wflag $Warg 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 and will obtain the sdr lock. ##################################################################### trap pretrap HUP INT QUIT KILL gpfsInitOutput=$(gpfsInit $lockId) 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 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 ############################################################################### # Go through the mmsdrfs file. If changing parameters that are kept in the file, # create a new version of the file. It will have a new generation number and # the appropriate parameters in the SG_ETCFS and/or SG_MOUNT lines will be # set to their new values. Simultaneously, create a file with the names of # the nodes that belong to the cluster. This file will be used later for # propagating the changes to the individual nodes and for finding a node # on which to execute the tschfs command if needed. ############################################################################### $rm -f $newsdrfs $nodefile $allQuorumNodes existingMountPoints="" IFS=":" # Change the field separator to ':'. exec 3<&- exec 3< $mmsdrfsFile while read -u3 sdrfsLine do # Parse the line. set -f ; set -A v -- - $sdrfsLine ; set +f IFS="$IFS_sv" # Restore the default IFS settings. # Change some of the fields depending on the type of line. case ${v[$LINE_TYPE_Field]} in $VERSION_LINE ) # This is the global header line. # Increment the generation number. newGenNumber=${v[$SDRFS_GENNUM_Field]}+1 v[$SDRFS_GENNUM_Field]=$newGenNumber ourClusterName=${v[$CLUSTER_NAME_Field]} ;; $NODESET_HDR ) # This is the header line for some cluster. # If this is our cluster, save the release level information. if [[ ${v[$NODESETID_Field]} = $fsHomeCluster ]] then lowestVersion=${v[$MIN_DAEMON_VERSION_Field]} highestVersion=${v[$MAX_DAEMON_VERSION_Field]} fi ;; $MEMBER_NODE ) # This line describes a node. # Add the reliable node name to nodefile. print -- "${v[$REL_HOSTNAME_Field]}" >> $nodefile checkForErrors "writing to file $nodefile" $? # Create a list of the quorum nodes. if [[ ${v[$CORE_QUORUM_Field]} = $quorumNode ]] then print -- "${v[$REL_HOSTNAME_Field]}" >> $allQuorumNodes checkForErrors "writing to file $allQuorumNodes" $? fi # If this is the line for the node that is executing # this command, set the preferredNode variable. [[ ${v[$NODE_NUMBER_Field]} = $ourNodeNumber ]] && \ preferredNode=${v[$REL_HOSTNAME_Field]} ;; $SG_ETCFS ) # This is an /etc/filesystem line. # The processing of the SG_ETCFS lines will depend # on the options that were specified on the mmchfs command. if [[ -n $Targ && ${v[$LINE_NUMBER_Field]} = $MOUNT_POINT_Line ]] then # We are changing the mount point and this # is a mount point line for some file system. # If this is the mount point for our file system, # set it to the new value. Otherwise, add it to # the list of existing mount points. if [[ ${v[$DEV_NAME_Field]} = $deviceName ]] then oldMountPoint=${v[$ETCFS_TEXT_Field]} v[$ETCFS_TEXT_Field]=$Targ fsMustNotBeMounted=yes [[ $mountCheckScope != $CHECK_ALL ]] && \ mountCheckScope=$ourClusterName else existingMountPoints="$existingMountPoints ${v[$ETCFS_TEXT_Field]}" fi fi # end if [[ -n $Targ && ${v[$LINE_NUMBER_Field]} = $MOUNT_POINT_Line ]] if [[ -n $Aarg && ${v[$LINE_NUMBER_Field]} = $MOUNT_Line ]] then # We are changing the automount option and # this is a mount line for some file system. # See if any file system requires the system automounter. [[ ${v[$ETCFS_TEXT_Field]} = *automount* ]] && \ automountMounts=true # If this is the mount line for our file system, # set the new value for the mount option. if [[ ${v[$DEV_NAME_Field]} = $deviceName ]] then # If switching to or from automount the file system must be unmounted. if [[ $Aarg = automount || ${v[$ETCFS_TEXT_Field]} = *automount* ]] then fsMustNotBeMounted=yes [[ $mountCheckScope != $CHECK_ALL ]] && \ mountCheckScope=$ourClusterName fi # Set the new value for the mount option. v[$ETCFS_TEXT_Field]="$MOUNT_Line_Prefix$Aarg" fi # end of if [[ ${v[$DEV_NAME_Field]} = $deviceName ]] fi # end if [[ -n $Aarg && ${v[$LINE_NUMBER_Field]} = $MOUNT_Line ]] ;; $SG_MOUNT ) # This line describes stripe group mount options. if [[ ${v[$DEV_NAME_Field]} = $deviceName ]] then # Change mount options for our file system. [[ -n $Earg ]] && v[$MTIME_OPT_Field]=$Earg if [[ -n $Qarg ]] then fsMustNotBeMounted=yes mountCheckScope=$CHECK_ALL if [[ $Qarg = DELETE ]] then v[$QUOTA_OPT_Field]=$QUOTA_DISACTIVATED else v[$QUOTA_OPT_Field]=$Qarg fi fi [[ -n $Sarg ]] && v[$ATIME_OPT_Field]=$Sarg if [[ -n $oarg ]] then if [[ $oarg = DELETE ]] then v[$OTHER_OPT_Field]="" else v[$OTHER_OPT_Field]=$oarg fi fi [[ -n $sgRW_OPT_Value ]] && v[$RW_OPT_Field]=$sgRW_OPT_Value fi # end of if [[ ${v[$DEV_NAME_Field]} = $deviceName ]] ;; * ) # Pass all other lines without a change. ;; esac # end Change some of the fields # Build and write the line to the new mmsdrfs file. print_newLine >> $newsdrfs checkForErrors "writing to file $newsdrfs" $? IFS=":" # Change the separator back to ":" for the next iteration. done # end while read -u3 sdrfsLine IFS="$IFS_sv" # Restore the default IFS settings. # If the mount point was changed, make sure that the new mount point # is not already used by some other file system and that the file system # is not mounted anywhere. if [[ -n $Targ ]] then for mpnt in $existingMountPoints do if [[ $mpnt = $Targ ]] then # There is already an existing filesystem using this mountpoint. printErrorMsg 107 $mmcmd $Targ cleanupAndExit fi done fi # end if [[ -n $Targ ]] # If necessary, ensure that the file system is not mounted. if [[ -n $fsMustNotBeMounted ]] then $mmcommon onactive $preferredNode $nodefile $NO_FILE_COPY \ $fqDeviceName $mountCheckScope $NO_LINK $MOUNT_CHECK_ONLY 2>$errMsg rc=$? if [[ $rc -eq $MM_FsMounted ]] then # File system is still mounted (messages were issued by mmcommon). cleanupAndExit $rc elif [[ $rc -eq $MM_DaemonDown ]] then # GPFS is down on all nodes that we care about. rc=0 elif [[ $rc -eq $MM_ConnectionReset ]] then # An internode connection was reset. printErrorMsg 257 $mmcmd cleanupAndExit $rc elif [[ $rc -ne 0 ]] then # An unexpected error occurred during the mount check. if [[ -s $errMsg ]] then # Show the error messages from the daemon. $cat $errMsg 1>&2 else # The mount check failed and there were no messages from the daemon. printErrorMsg 171 $mmcmd "mount check for $fqDeviceName" $rc fi # The command was unable to determine whether the file system is mounted. printErrorMsg 564 $mmcmd $fqDeviceName cleanupAndExit $rc fi # end if [[ $rc -eq $MM_FsMounted ]] $rm -f $errMsg fi # end if [[ -n $fsMustNotBeMounted ]] # If this is the first automountable GPFS file system, # run the automount command on the nodes in the cluster. if [[ $Aarg = "automount" && -z $automountMounts ]] then # Determine the value of the automountDir parameter. automountDir=$(showCfgValue automountDir) [[ -z $automountDir ]] && automountDir=$defaultAutomountDir # Run the automount command on the nodes on which GPFS is active. # On nodes that do not have GPFS running right now, this will be # done by the mmchecksubsys processing when the daemon is started. $mmcommon onactive $preferredNode $nodefile \ $NO_FILE_COPY $NO_MOUNT_CHECK NULL $NO_LINK \ tsdsh $mmremote startAutomounter $automountDir >$tmpfile 2>&1 rc=$? # Ignore errors but show messages from the nodes, if any. if [[ $rc -ne 0 && $rc -ne $MM_DaemonDown && -s $tmpfile ]] then $awk ' \ # Skip the lines with rc values. \ $2 == "rc" { next } \ # Print everything else. \ { print $0 } \ ' $tmpfile fi # end of if [[ -s $tmpfile ]] fi # end of if [[ $Aarg = "automount" && -z $automountMounts ]] # If changing the file system to the latest format version (-V), # verify that all nodes are running the same level of code. # if [[ -n $Vflag ]] # then # VflagAllowed=no # Assume the worst. # # # First look at the current information in the mmsdrfs file. # if [[ $lowestVersion -ne $highestVersion ]] # then # # -V requires all nodes to be at the same level. # printErrorMsg 583 $mmcmd # cleanupAndExit # fi # end if [[ $lowestVersion -ne $highestVersion ]] # # # According to the mmsdrfs file, all nodes are at the same level. # # Verify that this is indeed the case at least on the nodes # # on which the GPFS daemon is currently running. # getCodeRangeOutput=$($mmcommon onactive $preferredNode $nodefile \ # $NO_FILE_COPY $NO_MOUNT_CHECK NULL $NO_LINK mmremote getCodeRange) # rc=$? # if [[ -z $getCodeRangeOutput || $rc -ne 0 ]] # then # # Something went wrong with the mmcommon call. # [[ $rc -eq 0 ]] && rc=1 # if [[ -n $getCodeRangeOutput ]] # then # # If there was some output, assume it is an error message. # # Filter out the standard output strings, if any. # print -- "$getCodeRangeOutput" | $grep -v "getCodeRange:" 1>&2 # else # # Otherwise, output the generic unexpected error message. # printErrorMsg 171 "$mmcmd" "mmcommon onactive mmremote getCodeRange" $rc # fi # # else # # The mmcommon call seems to have worked. Parse the results. # IFS=":" # set -f ; set -- $getCodeRangeOutput ; set +f # kword=$1 # rc=$2 # status=$3 # maxDaemonVersion=$4 # minDaemonVersion=$5 # IFS="$IFS_sv" # # if [[ $kword = getCodeRange && $status = complete ]] # then # if [[ $minDaemonVersion = $maxDaemonVersion ]] # then # VflagAllowed=yes # else # # -V requires all nodes to be at the same level. # printErrorMsg 583 $mmcmd # fi # else # # Otherwise, output the generic unexpected error message. # printErrorMsg 171 "$mmcmd" "mmcommon onactive mmremote getCodeRange" $rc # fi # end if [[ $kword = getCodeRange && $status = complete ]] # fi # end if [[ -z $getCodeRangeOutput || $rc -ne 0 ]] # # # If we were not able to convince ourselves that it is OK # # to procede with the -V call, give up. # [[ $VflagAllowed = no ]] && cleanupAndExit # # fi # end if [[ -n $Vflag ]] ####################################################### # Change parameters that are kept in the mmsdrfs file. ####################################################### if [[ -n $mmsdrfsParms ]] then # Put the mmsdrfs file into the sdr. trap "" HUP INT QUIT KILL gpfsObjectInfo=$(commitChanges $fsHomeCluster $nsId \ $gpfsObjectInfo $newGenNumber $newsdrfs $primaryServer) rc=$? if [[ $rc -ne 0 ]] then # Cannot replace file in the sdr. printErrorMsg 381 $mmcmd cleanupAndExit fi # Unlock the sdr. [[ $sdrLocked = yes ]] && \ freeLockOnServer $primaryServer $ourNodeNumber >/dev/null sdrLocked=no trap localPosttrap HUP INT QUIT KILL # If necessary, tell the daemon to invalidate its currently-cached # mount options. if [[ -n $callResetEFOptions ]] then $mmcommon onactive $preferredNode $allQuorumNodes \ $NO_FILE_COPY $NO_MOUNT_CHECK NULL $NO_LINK \ tsctl resetEFOptions $fqDeviceName > $errMsg 2>&1 rc=$? [[ $rc = $MM_DaemonDown ]] && rc=0 [[ $rc -ne 0 && -s $errMsg ]] && cat $errMsg 2>&1 $rm -f $errMsg fi # If the mount point changed, remove the old mount point. [[ -n $oldMountPoint && $Targ != $oldMountPoint ]] && \ propagateOptions="rmdir$oldMountPoint" # Make the changes visible to the affected nodes. Note that when # changing the mount point or mount options, there is a window during # which different nodes may see different mount points and/or options. propagateSdrfsFile async $nodefile $newsdrfs $newGenNumber $propagateOptions fi # end if [[ -n $mmsdrfsParms ]] ############################################################ # If changes are requested that need to be handled by GPFS, # run the tschfs command on an active daemon. ############################################################ if [[ -n $tschfsParms && $tschfsParms != +( ) ]] then $mmcommon onactive $preferredNode $nodefile \ $NO_FILE_COPY $NO_MOUNT_CHECK NULL $NO_LINK \ tschfs $fqDeviceName $tschfsParms rc=$? if [[ $rc -ne 0 ]] then if [[ -n $mmsdrfsParms ]] then # The tschfs step failed. Some parameters changed. printErrorMsg 318 $mmcmd tschfs "$mmsdrfsParms" else # The tschfs step failed. printErrorMsg 104 $mmcmd tschfs fi cleanupAndExit fi fi # end of if [[ -n $tschfsParms && $tschfsParms != +( ) ]] ################################################### # If installed, invoke the syncfsconfig user exit. ################################################### if [[ -x $syncfsconfig && -n $mmsdrfsParms ]] then print -- "$mmcmd: Starting $syncfsconfig ..." $syncfsconfig print -- "$mmcmd: $syncfsconfig finished." fi $mmTRACE_EXIT "rc=0" cleanupAndExit 0