source: gpfs_3.1_ker2.6.20/lpp/mmfs/bin/mmlsdisk @ 223

Last change on this file since 223 was 16, checked in by rock, 17 years ago
  • Property svn:executable set to *
File size: 19.5 KB
Line 
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
54if [[ $ourUid -eq 0 ]]
55then
56  . /usr/lpp/mmfs/bin/mmsdrfsdef
57  . /usr/lpp/mmfs/bin/mmfsfuncs
58fi
59
60sourceFile="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
67tsnsdaccessResult=${tmpDir}tsnsdaccessResult.${mmcmd}.$$
68
69LOCAL_FILES=" $tsnsdaccessResult "
70
71
72# Local variables
73
74usageMsg=301
75integer rc=0
76integer nodeCount=0
77argList=""   # argList without quotes around disk list
78argListQ=""  # argList with quotes around disk list
79# underline="----------------------------------------------------------"
80# underline="${underline}----------------------------------------------"
81underline="------------  -----------------------  -----------------  ------------"
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###########################################################################
118function 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
350device=$arg1     # Save stripe group device (always the first parameter).
351shift 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.
358if [[ $argc -gt 1 ]]
359then
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
431fi  # end of if [[ $argc -gt 1 ]]
432
433
434###################################
435# Set up trap exception handling.
436###################################
437trap 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####################################################################
446if [[ $ourUid -eq 0 ]]
447then
448  gpfsInitOutput=$(gpfsInit nolock)
449  setGlobalVar $? $gpfsInitOutput
450
451elif [[ -n $Mflag ]]
452then
453  # This option requires root authority.
454  printErrorMsg 324 $mmcmd
455  cleanupAndExit
456fi  # 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.
465if [[ $device != *:* ]]
466then
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"
480else
481  fqDeviceName=$device
482  deviceName=${fqDeviceName##*:}
483  fsHomeCluster=${fqDeviceName%%:*}
484  remoteDevice=$deviceName
485fi  # end of if [[ $device != *:* ]]
486
487
488############################################
489# Process the -m and -M options separately.
490############################################
491if [[ -n $mflag || -n $Mflag ]]
492then
493  displayDiskAccessInfo $device $fqDeviceName $fsHomeCluster $Moption "$diskList"
494  cleanupAndExit $?
495fi  # 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
509rc=$(remapRC $?)
510if [[ ($rc -ne $MM_DaemonDown && $rc -ne $MM_QuorumWait) ||
511      $fsHomeCluster != $HOME_CLUSTER                    ||
512      $ourUid -ne 0                                      ||
513      $MMMODE = single ]]
514then
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
571fi  # 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.
581nodeCount=$(getNodeFile $REL_HOSTNAME_Field $fsHomeCluster $mmsdrfsFile $nodefile)
582if [[ $nodeCount -eq 0 ]]
583then
584  # The cluster is empty; there is nobody to run the command.
585  printErrorMsg 171 $mmcmd "getNodeFile (nodeCount=0)" 1
586  cleanupAndExit
587fi
588
589# Try the nodes one by one until you find a node that can execute the command.
590preferredNode=0     # We have no idea where to go first; let mmcommon decide.
591$mmcommon linkCommand $preferredNode $nodefile  \
592    mmlsdisk $fqDeviceName "$argListQ"
593rc=$?
594
595cleanupAndExit $rc
596
Note: See TracBrowser for help on using the repository browser.