| 1 | #!/bin/ksh | 
|---|
| 2 | # IBM_PROLOG_BEGIN_TAG | 
|---|
| 3 | # This is an automatically generated prolog. | 
|---|
| 4 | # | 
|---|
| 5 | # | 
|---|
| 6 | # | 
|---|
| 7 | # Licensed Materials - Property of IBM | 
|---|
| 8 | # | 
|---|
| 9 | # (C) COPYRIGHT International Business Machines Corp. 1999,2005 | 
|---|
| 10 | # All Rights Reserved | 
|---|
| 11 | # | 
|---|
| 12 | # US Government Users Restricted Rights - Use, duplication or | 
|---|
| 13 | # disclosure restricted by GSA ADP Schedule Contract with IBM Corp. | 
|---|
| 14 | # | 
|---|
| 15 | # IBM_PROLOG_END_TAG | 
|---|
| 16 | # @(#)85 1.46 src/avs/fs/mmfs/ts/admin/mmlsdisk.sh, mmfs, avs_rgpfs24, rgpfs240610b 10/6/05 10:56:32 | 
|---|
| 17 | ######################################################################### | 
|---|
| 18 | # | 
|---|
| 19 | # Usage: | 
|---|
| 20 | # | 
|---|
| 21 | #   mmlsdisk Device [-d "DiskName[;DiskName]"] [-e] [-L] | 
|---|
| 22 | # | 
|---|
| 23 | #   mmlsdisk Device [-d "DiskName[;DiskName]"] {-m | -M} | 
|---|
| 24 | # | 
|---|
| 25 | # where | 
|---|
| 26 | # | 
|---|
| 27 | #   -e    Display all of the disks that do not have an availability | 
|---|
| 28 | #         of up and a status of ready. | 
|---|
| 29 | # | 
|---|
| 30 | #   -L    Display an extended list of the disk parameters, including | 
|---|
| 31 | #         the disk id field and the remarks field.  The remarks column | 
|---|
| 32 | #         shows the current file system descriptor quorum assignments, | 
|---|
| 33 | #         and displays the excluded disks. | 
|---|
| 34 | # | 
|---|
| 35 | #   -m    Display whether I/O requests to the disk are satisfied on | 
|---|
| 36 | #         the local node or via an NSD server.  The scope of this | 
|---|
| 37 | #         option is the node on which the mmlsdisk command is issued. | 
|---|
| 38 | # | 
|---|
| 39 | #   -M    Display whether I/O requests to the disk are satisfied on | 
|---|
| 40 | #         the local node or via an NSD server.  If the I/O is done | 
|---|
| 41 | #         via an NSD server, show the NSD server name and the actual | 
|---|
| 42 | #         underlying disk name on that server node. | 
|---|
| 43 | #         Caution:  This is a slow operation! | 
|---|
| 44 | # | 
|---|
| 45 | # | 
|---|
| 46 | # Undocumented options: | 
|---|
| 47 | # | 
|---|
| 48 | #   -i    Display the disk id values for each of the disks. | 
|---|
| 49 | # | 
|---|
| 50 | ######################################################################### | 
|---|
| 51 |  | 
|---|
| 52 | # Include global declarations and service routines. | 
|---|
| 53 | . /usr/lpp/mmfs/bin/mmglobfuncs | 
|---|
| 54 | if [[ $ourUid -eq 0 ]] | 
|---|
| 55 | then | 
|---|
| 56 | . /usr/lpp/mmfs/bin/mmsdrfsdef | 
|---|
| 57 | . /usr/lpp/mmfs/bin/mmfsfuncs | 
|---|
| 58 | fi | 
|---|
| 59 |  | 
|---|
| 60 | sourceFile="mmlsdisk.sh" | 
|---|
| 61 | [[ -n $DEBUG || -n $DEBUGmmlsdisk ]] && set -x | 
|---|
| 62 | $mmTRACE_ENTER "$*" | 
|---|
| 63 |  | 
|---|
| 64 | # Local work files.  Names should be of the form: | 
|---|
| 65 | #   fn=${tmpDir}fn.${mmcmd}.$$ | 
|---|
| 66 |  | 
|---|
| 67 | tsnsdaccessResult=${tmpDir}tsnsdaccessResult.${mmcmd}.$$ | 
|---|
| 68 |  | 
|---|
| 69 | LOCAL_FILES=" $tsnsdaccessResult " | 
|---|
| 70 |  | 
|---|
| 71 |  | 
|---|
| 72 | # Local variables | 
|---|
| 73 |  | 
|---|
| 74 | usageMsg=301 | 
|---|
| 75 | integer rc=0 | 
|---|
| 76 | integer nodeCount=0 | 
|---|
| 77 | argList=""   # argList without quotes around disk list | 
|---|
| 78 | argListQ=""  # argList with quotes around disk list | 
|---|
| 79 | # underline="----------------------------------------------------------" | 
|---|
| 80 | # underline="${underline}----------------------------------------------" | 
|---|
| 81 | underline="------------  -----------------------  -----------------  ------------" | 
|---|
| 82 |  | 
|---|
| 83 |  | 
|---|
| 84 | # Local functions | 
|---|
| 85 |  | 
|---|
| 86 |  | 
|---|
| 87 | ########################################################################### | 
|---|
| 88 | # | 
|---|
| 89 | # Function:  Show whether disk I/O takes place on this node or | 
|---|
| 90 | #            over an NSD server.  If requested, try to determine | 
|---|
| 91 | #            the actual disk names to which the I/O is directed. | 
|---|
| 92 | # | 
|---|
| 93 | #            Notes: | 
|---|
| 94 | # | 
|---|
| 95 | #            - The file system must be mounted on this node. | 
|---|
| 96 | #              The scope of the command is the current node only. | 
|---|
| 97 | # | 
|---|
| 98 | #            - If the file system is owned by some other cluster, | 
|---|
| 99 | #              the underlying disk names cannot be determined; | 
|---|
| 100 | #              we cannot run commands on nodes that do not belong | 
|---|
| 101 | #              to this cluster. | 
|---|
| 102 | # | 
|---|
| 103 | # Input:     $1 - device name as provided by the user | 
|---|
| 104 | #            $2 - fully qualified file system device name | 
|---|
| 105 | #            $3 - file system home cluster name | 
|---|
| 106 | #            $4 - disk name mapping indicator:  yes or no | 
|---|
| 107 | #            $5 - disk name list (optional); if not specified, | 
|---|
| 108 | #                 all disks in the file system are assumed | 
|---|
| 109 | # | 
|---|
| 110 | # Output:    Formatted disk access information | 
|---|
| 111 | # | 
|---|
| 112 | # Returns:   0 - no errors encountered | 
|---|
| 113 | #            19 (ENODEV) - options line not found | 
|---|
| 114 | #            22 (EINVAL) - device name is not valid | 
|---|
| 115 | #            1 - some other unexpected error | 
|---|
| 116 | # | 
|---|
| 117 | ########################################################################### | 
|---|
| 118 | function displayDiskAccessInfo  # device fqDeviceName fsHomeCluster | 
|---|
| 119 | #   Moption [diskList] | 
|---|
| 120 | { | 
|---|
| 121 | typeset sourceFile="mmlsdisk.sh" | 
|---|
| 122 | [[ -n $DEBUG || -n $DEBUGdisplayDiskAccessInfo ]] && set -x | 
|---|
| 123 | $mmTRACE_ENTER "$*" | 
|---|
| 124 | typeset device=$1 | 
|---|
| 125 | typeset fqDeviceName=$2 | 
|---|
| 126 | typeset fsHomeCluster=$3 | 
|---|
| 127 | typeset Moption=$4 | 
|---|
| 128 | typeset diskList="$5" | 
|---|
| 129 |  | 
|---|
| 130 | typeset rc=0 | 
|---|
| 131 | typeset displayAll="" | 
|---|
| 132 |  | 
|---|
| 133 | typeset disksToDisplay diskName diskLine tsnsdaccessLine | 
|---|
| 134 | typeset magicWord nodeIPaddr localDiskName nodeName | 
|---|
| 135 | typeset hostResult availability nodeBelongsToTheCluster | 
|---|
| 136 | typeset diskInfo nsdId nsdSubtype getLocalDiskNameOutput | 
|---|
| 137 |  | 
|---|
| 138 | [[ $Moption != M ]] && Moption="" | 
|---|
| 139 |  | 
|---|
| 140 | # If disk list is specified, replace the ';' with blanks. | 
|---|
| 141 | if [[ -n $diskList ]] | 
|---|
| 142 | then | 
|---|
| 143 | disksToDisplay=$(print -- "$diskList" | $sed 's/;/ /g') | 
|---|
| 144 | else | 
|---|
| 145 | displayAll=yes | 
|---|
| 146 | fi | 
|---|
| 147 |  | 
|---|
| 148 | # Call tsnsdaccess to get the information for all disks in the file system. | 
|---|
| 149 | $tsnsdaccess $fqDeviceName > $tsnsdaccessResult 2> $errMsg | 
|---|
| 150 | rc=$(remapRC $?) | 
|---|
| 151 |  | 
|---|
| 152 | # Issue an appropriate message if tsnsdaccess failed. | 
|---|
| 153 | if [[ $rc -eq $MM_DaemonDown ]] | 
|---|
| 154 | then | 
|---|
| 155 | # GPFS is down on this node. | 
|---|
| 156 | printErrorMsg 109 $mmcmd | 
|---|
| 157 | elif [[ $rc -eq $MM_QuorumWait ]] | 
|---|
| 158 | then | 
|---|
| 159 | # GPFS is not ready for commands. | 
|---|
| 160 | printErrorMsg 110 $mmcmd | 
|---|
| 161 | elif [[ $rc -eq $MM_FsNotFound || $rc -eq $MM_RemoteNotFound ]] | 
|---|
| 162 | then | 
|---|
| 163 | # The file system is not mounted on this node. | 
|---|
| 164 | printErrorMsg 563 $mmcmd $device $ourNodeName | 
|---|
| 165 | elif [[ $rc -eq $MM_Remotefs && $fsHomeCluster != $HOME_CLUSTER ]] | 
|---|
| 166 | then | 
|---|
| 167 | # The file system is not owned by the remote cluster. | 
|---|
| 168 | [[ $device != *:* ]] &&  \ | 
|---|
| 169 | printErrorMsg 111 $mmcmd $device $remoteDevice $fsHomeCluster | 
|---|
| 170 | printErrorMsg 112 $mmcmd $remoteDevice $fsHomeCluster | 
|---|
| 171 | elif [[ ($rc -eq $MM_HostDown    || | 
|---|
| 172 | $rc -eq $MM_TimedOut    || | 
|---|
| 173 | $rc -eq $MM_SecurityCfg || | 
|---|
| 174 | $rc -eq $MM_AuthorizationFailed || | 
|---|
| 175 | $rc -eq $MM_UnknownCluster)    && | 
|---|
| 176 | $fsHomeCluster != $HOME_CLUSTER ]] | 
|---|
| 177 | then | 
|---|
| 178 | # Failed to connect to the remote cluster. | 
|---|
| 179 | [[ $rc -eq $MM_SecurityCfg ]] &&  \ | 
|---|
| 180 | printErrorMsg 150 $mmcmd | 
|---|
| 181 | [[ $rc -eq $MM_AuthorizationFailed ]] &&  \ | 
|---|
| 182 | printErrorMsg 151 $mmcmd | 
|---|
| 183 | printErrorMsg 105 $mmcmd $fsHomeCluster | 
|---|
| 184 | elif [[ $rc -eq $MM_ConnectionReset ]] | 
|---|
| 185 | then | 
|---|
| 186 | # An internode connection was reset. | 
|---|
| 187 | printErrorMsg 257 $mmcmd | 
|---|
| 188 | elif [[ $rc -ne 0 ]] | 
|---|
| 189 | then | 
|---|
| 190 | # tsnsdaccess failed. | 
|---|
| 191 | [[ -s $errMsg ]] && $cat $errMsg 1>&2 | 
|---|
| 192 | printErrorMsg 104 "$mmcmd" "tsnsdaccess $fqDeviceName" | 
|---|
| 193 | else | 
|---|
| 194 | :  # The command must have worked. | 
|---|
| 195 | fi  # end of if [[ $rc -eq $MM_DaemonDown ]] | 
|---|
| 196 | $rm -f $errMsg | 
|---|
| 197 |  | 
|---|
| 198 | # Give up if tsnsdaccess failed. | 
|---|
| 199 | [[ $rc -ne 0 ]] &&  \ | 
|---|
| 200 | return $rc | 
|---|
| 201 |  | 
|---|
| 202 | # Extract from the tsnsdaccess output the information for the disks | 
|---|
| 203 | # that we are interested in.  Store the result in a separate file. | 
|---|
| 204 | if [[ -n $displayAll ]] | 
|---|
| 205 | then | 
|---|
| 206 | $grep -e "tsnsdaccess:" -e "tsnsdaccess64:" $tsnsdaccessResult > $tmpfile | 
|---|
| 207 | else | 
|---|
| 208 | $rm -rf $tmpfile | 
|---|
| 209 | for diskName in $disksToDisplay | 
|---|
| 210 | do | 
|---|
| 211 | diskLine=$($grep -e "tsnsdaccess:$diskName:" -e "tsnsdaccess64:$diskName:" $tsnsdaccessResult) | 
|---|
| 212 | if [[ -z $diskLine ]] | 
|---|
| 213 | then | 
|---|
| 214 | printErrorMsg 315 $mmcmd $diskName $device | 
|---|
| 215 | return 1 | 
|---|
| 216 | else | 
|---|
| 217 | print -- "$diskLine" >> $tmpfile | 
|---|
| 218 | checkForErrors "writing to file $tmpfile" $? | 
|---|
| 219 | fi | 
|---|
| 220 | done  # end for diskName in $disksToDisplay | 
|---|
| 221 | fi  # end of if [[ -n $displayAll ]] | 
|---|
| 222 |  | 
|---|
| 223 | if [[ ! -s $tmpfile ]] | 
|---|
| 224 | then | 
|---|
| 225 | # Unexpected error.  This should not happen at this point. | 
|---|
| 226 | print -u2 "$mmcmd:  There is no disk information to display." | 
|---|
| 227 | return 1 | 
|---|
| 228 | fi | 
|---|
| 229 |  | 
|---|
| 230 | # Print the header line: | 
|---|
| 231 | #   "Disk name   IO performed on node   Device   Availability" | 
|---|
| 232 | header=$(printInfoMsg 506) | 
|---|
| 233 | printf "\n%s\n%.${#header}s\n" "$header" "$underline" | 
|---|
| 234 |  | 
|---|
| 235 | # Process the information from the tsnsdaccess call and print the results. | 
|---|
| 236 | exec 3<&- | 
|---|
| 237 | exec 3< $tmpfile | 
|---|
| 238 | while read -u3 tsnsdaccessLine | 
|---|
| 239 | do | 
|---|
| 240 | # Parse the line. | 
|---|
| 241 | IFS=":" | 
|---|
| 242 | set -f ; set -- $tsnsdaccessLine ; set +f | 
|---|
| 243 | IFS="$IFS_sv" | 
|---|
| 244 | magicWord=$1 | 
|---|
| 245 | diskName=$2 | 
|---|
| 246 | localDiskName=$3 | 
|---|
| 247 | nodeIPaddr=$4 | 
|---|
| 248 | nsdSubtype=$5 | 
|---|
| 249 | nsdId=$6 | 
|---|
| 250 |  | 
|---|
| 251 | # Determine the node name, local device name, and availability values. | 
|---|
| 252 | if [[ $localDiskName = "unused" ]] | 
|---|
| 253 | then | 
|---|
| 254 | # The disk is not being used on any of the nodes.  The only | 
|---|
| 255 | # thing that we know is that (most likely) the disk is down. | 
|---|
| 256 | availability="down" | 
|---|
| 257 | nodeName=$UNRESOLVED | 
|---|
| 258 | localDiskName=$UNRESOLVED | 
|---|
| 259 |  | 
|---|
| 260 | elif [[ $localDiskName = "unknown" ]] | 
|---|
| 261 | then | 
|---|
| 262 | # The disk is active but not on this node.  The IP address refers | 
|---|
| 263 | # to the NSD server for the disk.  That server may or may not be | 
|---|
| 264 | # part of our cluster.  If it is not, we will attempt to get its | 
|---|
| 265 | # name using the host command. | 
|---|
| 266 | availability="up" | 
|---|
| 267 |  | 
|---|
| 268 | nodeName=$(getNodeInfo  \ | 
|---|
| 269 | $REL_HOSTNAME_Field $IPA_Field $nodeIPaddr $HOME_CLUSTER $mmsdrfsFile) | 
|---|
| 270 |  | 
|---|
| 271 | if [[ -n $nodeName ]] | 
|---|
| 272 | then | 
|---|
| 273 | nodeBelongsToTheCluster=yes | 
|---|
| 274 | else | 
|---|
| 275 | hostResult=$($host $nodeIPaddr 2>/dev/null) | 
|---|
| 276 | set -f ; set -- $hostResult ; set +f | 
|---|
| 277 | nodeName=$1 | 
|---|
| 278 | nodeBelongsToTheCluster="" | 
|---|
| 279 | fi | 
|---|
| 280 | [[ -z $nodeName ]] && nodeName=$nodeIPaddr | 
|---|
| 281 |  | 
|---|
| 282 | if [[ -n $Moption && -n $nodeBelongsToTheCluster ]] | 
|---|
| 283 | then | 
|---|
| 284 | # -M is specified and the NSD server is a member of the cluster. | 
|---|
| 285 | # Find the local device name for the disk on the NSD server node. | 
|---|
| 286 | getLocalDiskNameOutput=$($mmcommon on1 $nodeName  \ | 
|---|
| 287 | getLocalDiskName $nsdId $nsdSubtype 2>$errMsg) | 
|---|
| 288 | rc=$? | 
|---|
| 289 |  | 
|---|
| 290 | # Parse the output from the getLocalDiskName function. | 
|---|
| 291 | IFS=":" | 
|---|
| 292 | set -f ; set -- $getLocalDiskNameOutput ; set +f | 
|---|
| 293 | magicWord=$1 | 
|---|
| 294 | localDiskName=$2 | 
|---|
| 295 | IFS="$IFS_sv" | 
|---|
| 296 |  | 
|---|
| 297 | if [[ -z $localDiskName || $magicWord != getLocalDiskName ]] | 
|---|
| 298 | then | 
|---|
| 299 | localDiskName=$UNRESOLVED | 
|---|
| 300 | fi | 
|---|
| 301 | $rm -f $errMsg | 
|---|
| 302 |  | 
|---|
| 303 | else | 
|---|
| 304 | # -M is not specified, or the NSD server is not a member | 
|---|
| 305 | # of our cluster;  we do not know the name of the disk. | 
|---|
| 306 | localDiskName=$UNRESOLVED | 
|---|
| 307 |  | 
|---|
| 308 | fi  # end of if [[ -n $Moption && -n $nodeBelongsToTheCluster ]] | 
|---|
| 309 |  | 
|---|
| 310 | else | 
|---|
| 311 | # The I/O takes place on the local node. | 
|---|
| 312 | availability="up" | 
|---|
| 313 | nodeName="localhost" | 
|---|
| 314 |  | 
|---|
| 315 | # If this is an AIX environment, replace the /dev/r prefix with /dev/. | 
|---|
| 316 | if [[ $osName = AIX && $localDiskName = +(/)dev+(/)r* ]] | 
|---|
| 317 | then | 
|---|
| 318 | localDiskName=${localDiskName##+(/)dev+(/)r} | 
|---|
| 319 | localDiskName=/dev/$localDiskName | 
|---|
| 320 | fi | 
|---|
| 321 |  | 
|---|
| 322 | fi  # end of if [[ $localDiskName = "unused" ]] | 
|---|
| 323 |  | 
|---|
| 324 | # Put out the results. | 
|---|
| 325 | printf "%-13s %-24s %-18s %s\n" \ | 
|---|
| 326 | "$diskName" "$nodeName" "$localDiskName" "$availability" | 
|---|
| 327 |  | 
|---|
| 328 | done  # end of while read -u3 tsnsdaccessLine | 
|---|
| 329 |  | 
|---|
| 330 | return $rc | 
|---|
| 331 |  | 
|---|
| 332 | }  #----- end of function displayDiskAccessInfo  ---------------- | 
|---|
| 333 |  | 
|---|
| 334 |  | 
|---|
| 335 |  | 
|---|
| 336 | ####################### | 
|---|
| 337 | # Mainline processing | 
|---|
| 338 | ####################### | 
|---|
| 339 |  | 
|---|
| 340 |  | 
|---|
| 341 | ##################################################################### | 
|---|
| 342 | # Process the command arguments. | 
|---|
| 343 | ##################################################################### | 
|---|
| 344 | [[ $arg1 = '-?' || $arg1 = '-h' || $arg1 = '--help' || $arg1 = '--' ]] &&  \ | 
|---|
| 345 | syntaxError "help" $usageMsg | 
|---|
| 346 |  | 
|---|
| 347 | [[ $argc -lt 1  ]] &&  \ | 
|---|
| 348 | syntaxError "missingArgs" $usageMsg | 
|---|
| 349 |  | 
|---|
| 350 | device=$arg1     # Save stripe group device (always the first parameter). | 
|---|
| 351 | shift 1          # Drop the device name from the parameter list. | 
|---|
| 352 |  | 
|---|
| 353 | # Parse the optional parameters.  Since the disk names in the -d option | 
|---|
| 354 | # are separated with ';', special care must be taken when creating argList. | 
|---|
| 355 | # For invocations via mmcommon, the disk list must be enclosed in quotes. | 
|---|
| 356 | # For direct (local) invocations of tslsdisk, the disk list must not have | 
|---|
| 357 | # surrounding quotes. | 
|---|
| 358 | if [[ $argc -gt 1 ]] | 
|---|
| 359 | then | 
|---|
| 360 | while getopts :eiLmMd: OPT | 
|---|
| 361 | do | 
|---|
| 362 | case $OPT in | 
|---|
| 363 | e) # Display all disks that are not up and ready. | 
|---|
| 364 | [[ -n $eflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" | 
|---|
| 365 | eflag="-$OPT" | 
|---|
| 366 | [[ -n $mflag || -n $Mflag ]] &&  \ | 
|---|
| 367 | syntaxError "invalidCombination" $usageMsg $eflag $mflag $Mflag | 
|---|
| 368 | argList="$argList -$OPT" | 
|---|
| 369 | argListQ="$argListQ -$OPT" | 
|---|
| 370 | ;; | 
|---|
| 371 |  | 
|---|
| 372 | i) # Display disk ids. | 
|---|
| 373 | [[ -n $iflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" | 
|---|
| 374 | iflag="-$OPT" | 
|---|
| 375 | [[ -n $mflag || -n $Mflag ]] &&  \ | 
|---|
| 376 | syntaxError "invalidCombination" $usageMsg $iflag $mflag $Mflag | 
|---|
| 377 | argList="$argList -$OPT" | 
|---|
| 378 | argListQ="$argListQ -$OPT" | 
|---|
| 379 | ;; | 
|---|
| 380 |  | 
|---|
| 381 | d) # Display information for the specified disks. | 
|---|
| 382 | [[ -n $dflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" | 
|---|
| 383 | diskList="$OPTARG" | 
|---|
| 384 | dflag="-$OPT" | 
|---|
| 385 | [[ "$diskList" = *+([-:,${BLANKchar}${TABchar}])* ]] &&  \ | 
|---|
| 386 | syntaxError "badSeparator_notSemicolon" $noUsageMsg | 
|---|
| 387 | argList="$argList -$OPT $OPTARG " | 
|---|
| 388 | argListQ="$argListQ -$OPT \"$OPTARG\" " | 
|---|
| 389 | ;; | 
|---|
| 390 |  | 
|---|
| 391 | L) # Display disk ids and other information. | 
|---|
| 392 | [[ -n $Lflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" | 
|---|
| 393 | Lflag="-$OPT" | 
|---|
| 394 | [[ -n $mflag || -n $Mflag ]] &&  \ | 
|---|
| 395 | syntaxError "invalidCombination" $usageMsg $Lflag $mflag $Mflag | 
|---|
| 396 | argList="$argList -$OPT" | 
|---|
| 397 | argListQ="$argListQ -$OPT" | 
|---|
| 398 | ;; | 
|---|
| 399 |  | 
|---|
| 400 | m) # Display disk I/O path (localhost vs. NSD server). | 
|---|
| 401 | [[ -n $mflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" | 
|---|
| 402 | mflag="-$OPT" | 
|---|
| 403 | Moption="$OPT" | 
|---|
| 404 | [[ -n $Mflag || -n $eflag || -n $iflag || -n $Lflag ]] &&  \ | 
|---|
| 405 | syntaxError "invalidCombination" $usageMsg $mflag $Mflag $eflag $iflag $Lflag | 
|---|
| 406 | ;; | 
|---|
| 407 |  | 
|---|
| 408 | M) # Display disk I/O path (localhost vs. NSD server) and hdisk name. | 
|---|
| 409 | [[ -n $Mflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" | 
|---|
| 410 | Mflag="-$OPT" | 
|---|
| 411 | Moption="$OPT" | 
|---|
| 412 | [[ -n $mflag || -n $eflag || -n $iflag || -n $Lflag ]] &&  \ | 
|---|
| 413 | syntaxError "invalidCombination" $usageMsg $Mflag $mflag $eflag $iflag $Lflag | 
|---|
| 414 | ;; | 
|---|
| 415 |  | 
|---|
| 416 | +[eidLmM]) # invalid option specified | 
|---|
| 417 | syntaxError "invalidOption" $usageMsg $OPT | 
|---|
| 418 | ;; | 
|---|
| 419 |  | 
|---|
| 420 | :) # missing required value after an option | 
|---|
| 421 | syntaxError "missingValue" $usageMsg $OPTARG | 
|---|
| 422 | ;; | 
|---|
| 423 |  | 
|---|
| 424 | *) # invalid option specified | 
|---|
| 425 | syntaxError "invalidOption" $usageMsg $OPTARG | 
|---|
| 426 | ;; | 
|---|
| 427 | esac | 
|---|
| 428 | done  # end of while getopts :eiLmMd: OPT | 
|---|
| 429 | shift OPTIND-1 | 
|---|
| 430 | [[ $# != 0 ]] && syntaxError "extraArg" $usageMsg $1 | 
|---|
| 431 | fi  # end of if [[ $argc -gt 1 ]] | 
|---|
| 432 |  | 
|---|
| 433 |  | 
|---|
| 434 | ################################### | 
|---|
| 435 | # Set up trap exception handling. | 
|---|
| 436 | ################################### | 
|---|
| 437 | trap pretrap2 HUP INT QUIT KILL | 
|---|
| 438 |  | 
|---|
| 439 |  | 
|---|
| 440 | #################################################################### | 
|---|
| 441 | # If invoked by a root user, call the gpfsInit function to ensure | 
|---|
| 442 | # that the local copy of the mmsdrfs file and the rest of the GPFS | 
|---|
| 443 | # system files are up-to-date.  There is no need to lock the sdr. | 
|---|
| 444 | # Non-root users are not allowed to invoke commands on other nodes. | 
|---|
| 445 | #################################################################### | 
|---|
| 446 | if [[ $ourUid -eq 0 ]] | 
|---|
| 447 | then | 
|---|
| 448 | gpfsInitOutput=$(gpfsInit nolock) | 
|---|
| 449 | setGlobalVar $? $gpfsInitOutput | 
|---|
| 450 |  | 
|---|
| 451 | elif [[ -n $Mflag ]] | 
|---|
| 452 | then | 
|---|
| 453 | # This option requires root authority. | 
|---|
| 454 | printErrorMsg 324 $mmcmd | 
|---|
| 455 | cleanupAndExit | 
|---|
| 456 | fi  # end of if [[ $ourUid -eq 0 ]] | 
|---|
| 457 |  | 
|---|
| 458 |  | 
|---|
| 459 | #################################### | 
|---|
| 460 | # Make sure the file system exists. | 
|---|
| 461 | #################################### | 
|---|
| 462 |  | 
|---|
| 463 | # If the invocation is not for an explicitly-remote device, obtain the | 
|---|
| 464 | # needed information about the filesystem from the mmsdrfs file. | 
|---|
| 465 | if [[ $device != *:* ]] | 
|---|
| 466 | then | 
|---|
| 467 | findFSoutput=$(findFS "$device" $mmsdrfsFile) | 
|---|
| 468 | [[ -z $findFSoutput ]] && cleanupAndExit | 
|---|
| 469 |  | 
|---|
| 470 | # Parse the output from the findFS function. | 
|---|
| 471 | set -f ; set -- $findFSoutput ; set +f | 
|---|
| 472 | fqDeviceName=$1 | 
|---|
| 473 | deviceName=$2 | 
|---|
| 474 | fsHomeCluster=$3 | 
|---|
| 475 | remoteDevice=$4 | 
|---|
| 476 |  | 
|---|
| 477 | # If this is a remote file system, set fqDeviceName appropriately. | 
|---|
| 478 | [[ $fsHomeCluster != $HOME_CLUSTER ]] &&  \ | 
|---|
| 479 | fqDeviceName="$fsHomeCluster:/dev/$remoteDevice" | 
|---|
| 480 | else | 
|---|
| 481 | fqDeviceName=$device | 
|---|
| 482 | deviceName=${fqDeviceName##*:} | 
|---|
| 483 | fsHomeCluster=${fqDeviceName%%:*} | 
|---|
| 484 | remoteDevice=$deviceName | 
|---|
| 485 | fi  # end of if [[ $device != *:* ]] | 
|---|
| 486 |  | 
|---|
| 487 |  | 
|---|
| 488 | ############################################ | 
|---|
| 489 | # Process the -m and -M options separately. | 
|---|
| 490 | ############################################ | 
|---|
| 491 | if [[ -n $mflag || -n $Mflag ]] | 
|---|
| 492 | then | 
|---|
| 493 | displayDiskAccessInfo $device $fqDeviceName $fsHomeCluster $Moption "$diskList" | 
|---|
| 494 | cleanupAndExit $? | 
|---|
| 495 | fi  # end of if [[ -n $mflag || -n $Mflag ]] | 
|---|
| 496 |  | 
|---|
| 497 |  | 
|---|
| 498 | ######################################################################## | 
|---|
| 499 | # Invoke the command on the local node. | 
|---|
| 500 | # Display any error messages and exit if any of the following are true: | 
|---|
| 501 | #   - the command completed successfully | 
|---|
| 502 | #   - there is an unacceptable error | 
|---|
| 503 | #       (anything other than daemon down or quorum wait) | 
|---|
| 504 | #   - the file system is remote | 
|---|
| 505 | #   - we are not running as UID 0 | 
|---|
| 506 | #   - this is a single node cluster | 
|---|
| 507 | ######################################################################## | 
|---|
| 508 | ${mmcmdDir}/${links}/mmlsdisk $fqDeviceName $argList 2>$errMsg | 
|---|
| 509 | rc=$(remapRC $?) | 
|---|
| 510 | if [[ ($rc -ne $MM_DaemonDown && $rc -ne $MM_QuorumWait) || | 
|---|
| 511 | $fsHomeCluster != $HOME_CLUSTER                    || | 
|---|
| 512 | $ourUid -ne 0                                      || | 
|---|
| 513 | $MMMODE = single ]] | 
|---|
| 514 | then | 
|---|
| 515 | if [[ $rc -eq $MM_FsNotFound ]] | 
|---|
| 516 | then | 
|---|
| 517 | if [[ $fsHomeCluster != $HOME_CLUSTER ]] | 
|---|
| 518 | then | 
|---|
| 519 | # The remote cluster does not know anything about this file system. | 
|---|
| 520 | printErrorMsg 108 $mmcmd $remoteDevice $fsHomeCluster | 
|---|
| 521 | else | 
|---|
| 522 | # Unexpected error. | 
|---|
| 523 | printErrorMsg 171 $mmcmd "file system $deviceName not found" $rc | 
|---|
| 524 | fi | 
|---|
| 525 | elif [[ ($rc -eq $MM_HostDown    || | 
|---|
| 526 | $rc -eq $MM_TimedOut    || | 
|---|
| 527 | $rc -eq $MM_SecurityCfg || | 
|---|
| 528 | $rc -eq $MM_AuthorizationFailed || | 
|---|
| 529 | $rc -eq $MM_UnknownCluster)    && | 
|---|
| 530 | $fsHomeCluster != $HOME_CLUSTER ]] | 
|---|
| 531 | then | 
|---|
| 532 | # Failed to connect to the remote cluster. | 
|---|
| 533 | [[ $rc -eq $MM_SecurityCfg ]] &&  \ | 
|---|
| 534 | printErrorMsg 150 $mmcmd | 
|---|
| 535 | [[ $rc -eq $MM_AuthorizationFailed ]] &&  \ | 
|---|
| 536 | printErrorMsg 151 $mmcmd | 
|---|
| 537 | printErrorMsg 105 $mmcmd $fsHomeCluster | 
|---|
| 538 | elif [[ $rc -eq $MM_Remotefs && $fsHomeCluster != $HOME_CLUSTER ]] | 
|---|
| 539 | then | 
|---|
| 540 | # The file system is not owned by the remote cluster. | 
|---|
| 541 | [[ $device != *:* ]] &&  \ | 
|---|
| 542 | printErrorMsg 111 $mmcmd $device $remoteDevice $fsHomeCluster | 
|---|
| 543 | printErrorMsg 112 $mmcmd $remoteDevice $fsHomeCluster | 
|---|
| 544 | elif [[ $rc -eq $MM_DaemonDown ]] | 
|---|
| 545 | then | 
|---|
| 546 | # GPFS is down on this node. | 
|---|
| 547 | printErrorMsg 109 $mmcmd | 
|---|
| 548 | elif [[ $rc -eq $MM_QuorumWait ]] | 
|---|
| 549 | then | 
|---|
| 550 | # GPFS is not ready for commands. | 
|---|
| 551 | printErrorMsg 110 $mmcmd | 
|---|
| 552 | elif [[ $rc -eq $MM_ConnectionReset ]] | 
|---|
| 553 | then | 
|---|
| 554 | # An internode connection was reset. | 
|---|
| 555 | printErrorMsg 257 $mmcmd | 
|---|
| 556 | else | 
|---|
| 557 | # Either the command worked, or it is an unexpected error. | 
|---|
| 558 | if [[ -s $errMsg ]] | 
|---|
| 559 | then | 
|---|
| 560 | # Show the error messages from the daemon. | 
|---|
| 561 | $cat $errMsg 1>&2 | 
|---|
| 562 | elif [[ $rc -ne 0 ]] | 
|---|
| 563 | then | 
|---|
| 564 | # tslsdisk failed. | 
|---|
| 565 | printErrorMsg 104 "$mmcmd" "tslsdisk $fqDeviceName" | 
|---|
| 566 | else | 
|---|
| 567 | :  # The command must have worked. | 
|---|
| 568 | fi  # end of if [[ -s $errMsg ]] | 
|---|
| 569 | fi  # end of if [[ $rc -eq $MM_FsNotFound ]] | 
|---|
| 570 | cleanupAndExit $rc | 
|---|
| 571 | fi  # end of if [[ ($rc -ne $MM_DaemonDown && ... ]] | 
|---|
| 572 | $rm -f $errMsg | 
|---|
| 573 |  | 
|---|
| 574 |  | 
|---|
| 575 | ######################################################################### | 
|---|
| 576 | # We come here if the command was invoked for a local file system but | 
|---|
| 577 | # the local daemon is not available; send the command to an active node. | 
|---|
| 578 | ######################################################################### | 
|---|
| 579 |  | 
|---|
| 580 | # Create a file with the reliable names of the nodes in the cluster. | 
|---|
| 581 | nodeCount=$(getNodeFile $REL_HOSTNAME_Field $fsHomeCluster $mmsdrfsFile $nodefile) | 
|---|
| 582 | if [[ $nodeCount -eq 0 ]] | 
|---|
| 583 | then | 
|---|
| 584 | # The cluster is empty; there is nobody to run the command. | 
|---|
| 585 | printErrorMsg 171 $mmcmd "getNodeFile (nodeCount=0)" 1 | 
|---|
| 586 | cleanupAndExit | 
|---|
| 587 | fi | 
|---|
| 588 |  | 
|---|
| 589 | # Try the nodes one by one until you find a node that can execute the command. | 
|---|
| 590 | preferredNode=0     # We have no idea where to go first; let mmcommon decide. | 
|---|
| 591 | $mmcommon linkCommand $preferredNode $nodefile  \ | 
|---|
| 592 | mmlsdisk $fqDeviceName "$argListQ" | 
|---|
| 593 | rc=$? | 
|---|
| 594 |  | 
|---|
| 595 | cleanupAndExit $rc | 
|---|
| 596 |  | 
|---|