| 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. 2000,2006 | 
|---|
| 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 | # @(#)16 1.43.1.1 src/avs/fs/mmfs/ts/admin/mmlsnsd.sh, mmfs, avs_rgpfs24, rgpfs24s008a 11/22/06 15:43:42 | 
|---|
| 17 | ############################################################################# | 
|---|
| 18 | # | 
|---|
| 19 | #  List information for the disks that belong to a GPFS cluster. | 
|---|
| 20 | # | 
|---|
| 21 | #  Usage: | 
|---|
| 22 | # | 
|---|
| 23 | #     mmlsnsd [ -a | -F | -f Device | -d "DiskName[;DiskName]" ] | 
|---|
| 24 | #             [ -L | -m | -M | -X ] [-v] | 
|---|
| 25 | # | 
|---|
| 26 | #  where | 
|---|
| 27 | # | 
|---|
| 28 | #     -a          list all disks.  This is the default. | 
|---|
| 29 | # | 
|---|
| 30 | #     -F          list all disks that do not belong to any file system. | 
|---|
| 31 | # | 
|---|
| 32 | #     -f Device   list all disks that belong to file system Device. | 
|---|
| 33 | # | 
|---|
| 34 | #     -d "DiskName[;DiskName]"  list the disks in the specified list | 
|---|
| 35 | #                 of ";"-separated disk names. | 
|---|
| 36 | # | 
|---|
| 37 | #     -L          display longer disk information. | 
|---|
| 38 | # | 
|---|
| 39 | #     -m          display the disk device name on the local node, | 
|---|
| 40 | #                 or, if applicable, the disk device names on the | 
|---|
| 41 | #                 primary and backup server nodes. | 
|---|
| 42 | # | 
|---|
| 43 | #     -M          display the disk device names on all nodes to which | 
|---|
| 44 | #                 the disk is attached.  Caution:  This is a slow operation! | 
|---|
| 45 | # | 
|---|
| 46 | #     -v          display additional error information where available. | 
|---|
| 47 | # | 
|---|
| 48 | #     -X          display eXtended disk information. | 
|---|
| 49 | # | 
|---|
| 50 | ############################################################################# | 
|---|
| 51 |  | 
|---|
| 52 | # Include global declarations and service routines. | 
|---|
| 53 | . /usr/lpp/mmfs/bin/mmglobfuncs | 
|---|
| 54 | . /usr/lpp/mmfs/bin/mmsdrfsdef | 
|---|
| 55 | . /usr/lpp/mmfs/bin/mmfsfuncs | 
|---|
| 56 |  | 
|---|
| 57 | sourceFile="mmlsnsd.sh" | 
|---|
| 58 | [[ -n $DEBUG || -n $DEBUGmmlsnsd ]] && set -x | 
|---|
| 59 | $mmTRACE_ENTER "$*" | 
|---|
| 60 |  | 
|---|
| 61 | # Local work files.  Names should be of the form: | 
|---|
| 62 | #   fn=${tmpDir}fn.${mmcmd}.$$ | 
|---|
| 63 |  | 
|---|
| 64 | disksToShow=${tmpDir}disksToShow.${mmcmd}.$$ | 
|---|
| 65 | collectedDiskData=${tmpDir}collectedDiskData.${mmcmd}.$$ | 
|---|
| 66 |  | 
|---|
| 67 | LOCAL_FILES=" $disksToShow $collectedDiskData " | 
|---|
| 68 |  | 
|---|
| 69 | # Local variables | 
|---|
| 70 | usageMsg=428 | 
|---|
| 71 | headerPrinted=no | 
|---|
| 72 | underline="----------------------------------------------------------" | 
|---|
| 73 | underline="${underline}----------------------------------------------" | 
|---|
| 74 | underline="${underline}----------------------------------------------" | 
|---|
| 75 |  | 
|---|
| 76 |  | 
|---|
| 77 | # Local functions | 
|---|
| 78 |  | 
|---|
| 79 |  | 
|---|
| 80 | ########################################################################## | 
|---|
| 81 | # | 
|---|
| 82 | # Display local nsd data for the desired disks. | 
|---|
| 83 | # This function prints the local device name on all nodes | 
|---|
| 84 | # for all disks that were specified by the user. | 
|---|
| 85 | # | 
|---|
| 86 | # Input:  $1  - file containing disk data collected from the nodes | 
|---|
| 87 | #         $2  - file containing disk data from the mmsdrfs file | 
|---|
| 88 | #         $3  - file containing a list of nodes to check | 
|---|
| 89 | # | 
|---|
| 90 | ########################################################################## | 
|---|
| 91 | function showLocalDeviceInfo  # <diskDataFile> <sdrfsDiskData> <nodefile> | 
|---|
| 92 | { | 
|---|
| 93 | typeset sourceFile="mmlsnsd.sh" | 
|---|
| 94 | [[ -n $DEBUG || -n $DEBUGshowLocalDeviceInfo ]] && set -x | 
|---|
| 95 | $mmTRACE_ENTER "$*" | 
|---|
| 96 | typeset diskDataFile=$1 | 
|---|
| 97 | typeset sdrfsDiskData=$2 | 
|---|
| 98 | typeset nodeFile=$3 | 
|---|
| 99 |  | 
|---|
| 100 | typeset diskLine diskFoundOnNode diskFoundOnPrimary diskFoundOnBackup | 
|---|
| 101 | typeset nodeName globalName pvid localDiskName diskdataLine | 
|---|
| 102 | typeset primaryServer backupServer nsdSubtype remarks xRemarks | 
|---|
| 103 |  | 
|---|
| 104 | # If this is a single node cluster, prepend the node name | 
|---|
| 105 | # to the front of each record in the diskDataFile, since | 
|---|
| 106 | # mmcommon onall does not use mmdsh for single node clusters. | 
|---|
| 107 | if [[ $MMMODE = single ]] | 
|---|
| 108 | then | 
|---|
| 109 | $sed "s/^/$ourNodeName: /" $diskDataFile > $tmpfile2 | 
|---|
| 110 | $mv $tmpfile2 $diskDataFile | 
|---|
| 111 | checkForErrors "mv $tmpfile2 $diskDataFile" $? | 
|---|
| 112 | fi  # end of if [[ $MMMODE = single ]] | 
|---|
| 113 |  | 
|---|
| 114 | # Separate the valid nsd data into one file, and any error messages | 
|---|
| 115 | # into another.  The error messages (if any) will be displayed later. | 
|---|
| 116 | $grep    getLocalNsdData $diskDataFile > $tmpfile | 
|---|
| 117 | $grep -v getLocalNsdData $diskDataFile > $errMsg | 
|---|
| 118 |  | 
|---|
| 119 | # Sort the collected nsd data by the NSD id (pvid). | 
|---|
| 120 | $sort -t : -k 3,3 $tmpfile -o $tmpfile2 | 
|---|
| 121 | checkForErrors "$mmcmd: sort of tmpfile" $? | 
|---|
| 122 |  | 
|---|
| 123 | # Sort the disk data from the mmsdrfs file based on the NSD id (pvid). | 
|---|
| 124 | $sort -t : -k 2,2 $sdrfsDiskData -o $sdrfsDiskData | 
|---|
| 125 | checkForErrors "$mmcmd: sort of sdrfsDiskData" $? | 
|---|
| 126 |  | 
|---|
| 127 | # Join the file containing the nsd data collected from the nodes | 
|---|
| 128 | # with the file containing the mmsdrfs data for the desired nsds; | 
|---|
| 129 | # the join is performed based on the NSD id (pvid) value. | 
|---|
| 130 | # The lines in the resulting file have the following fields: | 
|---|
| 131 | #   nodeName:diskName:pvid:localDiskName:primaryServer:backupServer:localNsdSubtype:nsdSubtype | 
|---|
| 132 | $join -1 2 -2 3 -t: -o 2.1,1.1,1.2,2.4,1.3,1.4,2.5,2.6 $sdrfsDiskData $tmpfile2 > $tmpfile | 
|---|
| 133 | checkForErrors "$mmcmd: join" $? | 
|---|
| 134 | $touch $tmpfile       # Make sure the file exists, even if it is empty. | 
|---|
| 135 |  | 
|---|
| 136 | # Sort the disk data file by disk name and the node file | 
|---|
| 137 | # by node name to ensure the output of the nested loops | 
|---|
| 138 | # below is in the order most easily read by the user. | 
|---|
| 139 | $sort -t : -k 1,1 $sdrfsDiskData -o $sdrfsDiskData | 
|---|
| 140 | checkForErrors "$mmcmd: second sort of sdrfsDiskData" $? | 
|---|
| 141 | $sort -t : -k 1,1 $nodefile -o $nodefile | 
|---|
| 142 | checkForErrors "$mmcmd: sort of nodefile" $? | 
|---|
| 143 |  | 
|---|
| 144 | # Loop through the disks from the mmsdrfs file to print their data. | 
|---|
| 145 | IFS=":"               # Change the field separator to ':'. | 
|---|
| 146 | exec 3<&- | 
|---|
| 147 | exec 3< $sdrfsDiskData | 
|---|
| 148 | while read -u3 diskLine | 
|---|
| 149 | do | 
|---|
| 150 | # Parse the line. | 
|---|
| 151 | set -f ; set -- $diskLine ; set +f | 
|---|
| 152 | globalName=$1 | 
|---|
| 153 | pvid=$2 | 
|---|
| 154 | primaryServer=$3 | 
|---|
| 155 | backupServer=$4 | 
|---|
| 156 | nsdSubtype=$5 | 
|---|
| 157 | IFS="$IFS_sv"       # Restore the default IFS settings. | 
|---|
| 158 |  | 
|---|
| 159 | diskFoundOnPrimary=false | 
|---|
| 160 | diskFoundOnBackup=false | 
|---|
| 161 |  | 
|---|
| 162 | # Get the lines from the joined file that match this disk. | 
|---|
| 163 | # The awk script takes into account that tspreparedisk treats | 
|---|
| 164 | # hdisk and generic as equivalent, and either nsd subtype could | 
|---|
| 165 | # be present if the cluster has both AIX and Linux nodes or the | 
|---|
| 166 | # filesystem was imported from one OS environment to the other. | 
|---|
| 167 | $rm -f $tmpfile2 | 
|---|
| 168 | $awk -F: '                                           \ | 
|---|
| 169 | $3=="'$pvid'" &&                                   \ | 
|---|
| 170 | ( $7=="'$nsdSubtype'"                         ||   \ | 
|---|
| 171 | ($7=="hdisk" && "'$nsdSubtype'"=="generic") ||   \ | 
|---|
| 172 | ($7=="generic" && "'$nsdSubtype'"=="hdisk") )    \ | 
|---|
| 173 | {print $1":"$4":"$7":"$8 >> "'$tmpfile2'"}       \ | 
|---|
| 174 | ' $tmpfile | 
|---|
| 175 | checkForErrors awk $? | 
|---|
| 176 |  | 
|---|
| 177 | # Process the lines that were found. | 
|---|
| 178 | if [[ -s $tmpfile2 ]] | 
|---|
| 179 | then | 
|---|
| 180 | # Print a line of output for each line extracted from the joined file. | 
|---|
| 181 | # For -M we report all nodes, while for -m and -X, we only report | 
|---|
| 182 | # the node running the command and any server nodes. | 
|---|
| 183 | IFS=":"               # Change the field separator to ':'. | 
|---|
| 184 | exec 4<&- | 
|---|
| 185 | exec 4< $tmpfile2 | 
|---|
| 186 | while read -u4 diskdataLine | 
|---|
| 187 | do | 
|---|
| 188 | # Parse the line. | 
|---|
| 189 | set -f ; set -- $diskdataLine ; set +f | 
|---|
| 190 | nodeName=$1 | 
|---|
| 191 | localDiskName=$2 | 
|---|
| 192 | devType=$3 | 
|---|
| 193 | extendedRemarks=$4 | 
|---|
| 194 | IFS="$IFS_sv"       # Restore the default IFS settings. | 
|---|
| 195 |  | 
|---|
| 196 | if [[ -n $Mflag || | 
|---|
| 197 | ( (-n $mflag || -n $Xflag) && ($nodeName = $ourNodeName   || | 
|---|
| 198 | $nodeName = $primaryServer || | 
|---|
| 199 | $nodeName = $backupServer   ) ) ]] | 
|---|
| 200 | then | 
|---|
| 201 | # Set the remarks field appropriately. | 
|---|
| 202 | if [[ $nodeName = $primaryServer ]] | 
|---|
| 203 | then | 
|---|
| 204 | diskFoundOnPrimary=true | 
|---|
| 205 | remarks="primary node" | 
|---|
| 206 | elif [[ $nodeName = $backupServer ]] | 
|---|
| 207 | then | 
|---|
| 208 | diskFoundOnBackup=true | 
|---|
| 209 | remarks="backup node" | 
|---|
| 210 | else | 
|---|
| 211 | remarks="directly attached" | 
|---|
| 212 | fi  # end of if [[ $nodeName = $primaryServer ]] | 
|---|
| 213 |  | 
|---|
| 214 | # Append extended remarks if there are any. | 
|---|
| 215 | [[ -n $extendedRemarks ]] && | 
|---|
| 216 | remarks="$remarks,$extendedRemarks" | 
|---|
| 217 |  | 
|---|
| 218 | # Print the line of output. | 
|---|
| 219 | if [[ -n $Xflag ]] | 
|---|
| 220 | then | 
|---|
| 221 | printf " %-12s %-18s %-14s %-8s %-24s %s\n" "$globalName"  \ | 
|---|
| 222 | "$pvid" "$localDiskName" "$devType" "$nodeName" "$remarks" | 
|---|
| 223 | else | 
|---|
| 224 | printf " %-12s %-18s %-14s %-24s %s\n" "$globalName"  \ | 
|---|
| 225 | "$pvid" "$localDiskName" "$nodeName" "$remarks" | 
|---|
| 226 | fi | 
|---|
| 227 | fi  # end of if [[ -n $Mflag || ... | 
|---|
| 228 |  | 
|---|
| 229 | IFS=":"  # Change the separator back to ":" for the next iteration. | 
|---|
| 230 |  | 
|---|
| 231 | done  # end of while read -u4 diskdataLine | 
|---|
| 232 |  | 
|---|
| 233 | fi  # end of if [[ -s $tmpfile2 ]] | 
|---|
| 234 |  | 
|---|
| 235 | # Check whether the disk is missing anywhere and report it if it is. | 
|---|
| 236 | if [[ -z $primaryServer ]] | 
|---|
| 237 | then | 
|---|
| 238 | # Report this directly-attached disk as missing on nodes on which | 
|---|
| 239 | # it was not found.  For -M we report all nodes, while for -m and -X, | 
|---|
| 240 | # we only report the node running the command. | 
|---|
| 241 | exec 4<&- | 
|---|
| 242 | exec 4< $nodefile | 
|---|
| 243 | while read -u4 nodeName | 
|---|
| 244 | do | 
|---|
| 245 | if [[ -n $Mflag || | 
|---|
| 246 | ( (-n $mflag || -n $Xflag) && $nodeName = $ourNodeName ) ]] | 
|---|
| 247 | then | 
|---|
| 248 | # Check whether the disk was found on this node. | 
|---|
| 249 | # The awk script takes into account that tspreparedisk treats | 
|---|
| 250 | # hdisk and generic as equivalent, and either nsd subtype could | 
|---|
| 251 | # be present if the cluster has both AIX and Linux nodes or the | 
|---|
| 252 | # filesystem was imported from one OS environment to the other. | 
|---|
| 253 | diskFoundOnNode=$($awk -F: '                         \ | 
|---|
| 254 | BEGIN { foundFlag = "false" }                      \ | 
|---|
| 255 | $1 == "'$nodeName'" && $3 == "'$pvid'" &&          \ | 
|---|
| 256 | ( $7=="'$nsdSubtype'"                         ||   \ | 
|---|
| 257 | ($7=="hdisk" && "'$nsdSubtype'"=="generic") ||   \ | 
|---|
| 258 | ($7=="generic" && "'$nsdSubtype'"=="hdisk") ) {  \ | 
|---|
| 259 | { foundFlag = "true" }                           \ | 
|---|
| 260 | { exit }                                         \ | 
|---|
| 261 | }                                                  \ | 
|---|
| 262 | END { print foundFlag }                            \ | 
|---|
| 263 | ' $tmpfile) | 
|---|
| 264 | checkForErrors "awk $tmpfile" $? | 
|---|
| 265 | if [[ $diskFoundOnNode = false ]] | 
|---|
| 266 | then | 
|---|
| 267 | localDiskName=$UNRESOLVED | 
|---|
| 268 | remarks="(not found) directly attached" | 
|---|
| 269 | if [[ -n $Xflag ]] | 
|---|
| 270 | then | 
|---|
| 271 | devType=$UNRESOLVED | 
|---|
| 272 | printf " %-12s %-18s %-14s %-8s %-24s %s\n" "$globalName"  \ | 
|---|
| 273 | "$pvid" "$localDiskName" "$devType" "$nodeName" "$remarks" | 
|---|
| 274 | else | 
|---|
| 275 | printf " %-12s %-18s %-14s %-24s %s\n" "$globalName"  \ | 
|---|
| 276 | "$pvid" "$localDiskName" "$nodeName" "$remarks" | 
|---|
| 277 | fi | 
|---|
| 278 | fi  # end of if [[ $diskFoundOnNode = false ]] | 
|---|
| 279 | fi  # end of if [[ -n $Mflag || ( (-n $mflag || -n $Xflag) && ... | 
|---|
| 280 | done  # end of while read -u4 nodeName | 
|---|
| 281 | else | 
|---|
| 282 | # Output a line for the primary or backup server | 
|---|
| 283 | # if either was specified but was not found. | 
|---|
| 284 | if [[ -n $primaryServer && $diskFoundOnPrimary = false ]] | 
|---|
| 285 | then | 
|---|
| 286 | localDiskName=$UNRESOLVED | 
|---|
| 287 | nodeName=$primaryServer | 
|---|
| 288 | remarks="(not found) primary node" | 
|---|
| 289 | if [[ -n $Xflag ]] | 
|---|
| 290 | then | 
|---|
| 291 | devType=$UNRESOLVED | 
|---|
| 292 | printf " %-12s %-18s %-14s %-8s %-24s %s\n" "$globalName"  \ | 
|---|
| 293 | "$pvid" "$localDiskName" "$devType" "$nodeName" "$remarks" | 
|---|
| 294 | else | 
|---|
| 295 | printf " %-12s %-18s %-14s %-24s %s\n" "$globalName"  \ | 
|---|
| 296 | "$pvid" "$localDiskName" "$nodeName" "$remarks" | 
|---|
| 297 | fi | 
|---|
| 298 | fi  # end of if [[ -n $primaryServer && $diskFoundOnPrimary = false ]] | 
|---|
| 299 | if [[ -n $backupServer && $diskFoundOnBackup = false ]] | 
|---|
| 300 | then | 
|---|
| 301 | localDiskName=$UNRESOLVED | 
|---|
| 302 | nodeName=$backupServer | 
|---|
| 303 | remarks="(not found) backup node" | 
|---|
| 304 | if [[ -n $Xflag ]] | 
|---|
| 305 | then | 
|---|
| 306 | devType=$UNRESOLVED | 
|---|
| 307 | printf " %-12s %-18s %-14s %-8s %-24s %s\n" "$globalName"  \ | 
|---|
| 308 | "$pvid" "$localDiskName" "$devType" "$nodeName" "$remarks" | 
|---|
| 309 | else | 
|---|
| 310 | printf " %-12s %-18s %-14s %-24s %s\n" "$globalName"  \ | 
|---|
| 311 | "$pvid" "$localDiskName" "$nodeName" "$remarks" | 
|---|
| 312 | fi | 
|---|
| 313 | fi  # end of if [[ -n $backupServer && $diskFoundOnBackup = false ]] | 
|---|
| 314 | fi  # end of if [[ -z $primaryServer ]] | 
|---|
| 315 |  | 
|---|
| 316 | IFS=":"  # Change the separator back to ":" for the next iteration. | 
|---|
| 317 |  | 
|---|
| 318 | done  # end of while read -u3 diskLine do | 
|---|
| 319 |  | 
|---|
| 320 | # If -v was specified, display any error messages | 
|---|
| 321 | # that were produced on the remote nodes. | 
|---|
| 322 | [[ -n $verboseOutput ]] && $cat $errMsg | 
|---|
| 323 | $rm -f $errMsg | 
|---|
| 324 |  | 
|---|
| 325 | return 0 | 
|---|
| 326 |  | 
|---|
| 327 | }  #----- end of function showLocalDeviceInfo ------------------ | 
|---|
| 328 |  | 
|---|
| 329 |  | 
|---|
| 330 |  | 
|---|
| 331 | ####################### | 
|---|
| 332 | # Mainline processing | 
|---|
| 333 | ####################### | 
|---|
| 334 |  | 
|---|
| 335 |  | 
|---|
| 336 | ################################# | 
|---|
| 337 | # Process the command arguments. | 
|---|
| 338 | ################################# | 
|---|
| 339 | [[ $arg1 = '-?' || $arg1 = '-h' || $arg1 = '--help' || $arg1 = '--' ]] &&  \ | 
|---|
| 340 | syntaxError "help" $usageMsg | 
|---|
| 341 |  | 
|---|
| 342 | while getopts :ad:Ff:LMmvX OPT | 
|---|
| 343 | do | 
|---|
| 344 | case $OPT in | 
|---|
| 345 |  | 
|---|
| 346 | a) [[ -n $aflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" | 
|---|
| 347 | aflag="-$OPT" | 
|---|
| 348 | [[ -n $dflag || -n $Fflag || -n $fflag ]] &&  \ | 
|---|
| 349 | syntaxError "invalidCombination" $usageMsg $aflag $dflag $Fflag $fflag | 
|---|
| 350 | ;; | 
|---|
| 351 |  | 
|---|
| 352 | d) [[ -n $dflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" | 
|---|
| 353 | dflag="-$OPT" | 
|---|
| 354 | [[ -n $aflag || -n $Fflag || -n $fflag ]] &&  \ | 
|---|
| 355 | syntaxError "invalidCombination" $usageMsg $dflag $aflag $Fflag $fflag | 
|---|
| 356 | darg="$OPTARG" | 
|---|
| 357 | [[ "$OPTARG" = *+([-:,${BLANKchar}${TABchar}])* ]] &&  \ | 
|---|
| 358 | syntaxError "badSeparator_notSemicolon" $noUsageMsg | 
|---|
| 359 | disksToDisplay=$(print -- "$OPTARG" | $sed 's/;/ /g') | 
|---|
| 360 | ;; | 
|---|
| 361 |  | 
|---|
| 362 | F) [[ -n $Fflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" | 
|---|
| 363 | Fflag="-$OPT" | 
|---|
| 364 | [[ -n $aflag || -n $dflag || -n $fflag ]] &&  \ | 
|---|
| 365 | syntaxError "invalidCombination" $usageMsg $Fflag $aflag $dflag $fflag | 
|---|
| 366 | ;; | 
|---|
| 367 |  | 
|---|
| 368 | f) [[ -n $fflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" | 
|---|
| 369 | fflag="-$OPT" | 
|---|
| 370 | [[ -n $aflag || -n $dflag || -n $Fflag ]] &&  \ | 
|---|
| 371 | syntaxError "invalidCombination" $usageMsg $fflag $aflag $dflag $Fflag | 
|---|
| 372 | farg="$OPTARG" | 
|---|
| 373 | ;; | 
|---|
| 374 |  | 
|---|
| 375 | L) [[ -n $Lflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" | 
|---|
| 376 | Lflag="-$OPT" | 
|---|
| 377 | [[ -n $Mflag || -n $mflag || -n $Xflag ]] &&  \ | 
|---|
| 378 | syntaxError "invalidCombination" $usageMsg $Lflag $Mflag $mflag $Xflag | 
|---|
| 379 | ;; | 
|---|
| 380 |  | 
|---|
| 381 | M) [[ -n $Mflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" | 
|---|
| 382 | Mflag="-$OPT" | 
|---|
| 383 | [[ -n $Lflag || -n $mflag || -n $Xflag ]] &&  \ | 
|---|
| 384 | syntaxError "invalidCombination" $usageMsg $Mflag $Lflag $mflag $Xflag | 
|---|
| 385 | ;; | 
|---|
| 386 |  | 
|---|
| 387 | m) [[ -n $mflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" | 
|---|
| 388 | mflag="-$OPT" | 
|---|
| 389 | [[ -n $Lflag || -n $Mflag || -n $Xflag ]] &&  \ | 
|---|
| 390 | syntaxError "invalidCombination" $usageMsg $mflag $Lflag $Mflag $Xflag | 
|---|
| 391 | ;; | 
|---|
| 392 |  | 
|---|
| 393 | v) [[ -n $vflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" | 
|---|
| 394 | vflag="-$OPT" | 
|---|
| 395 | verboseOutput=yes | 
|---|
| 396 | ;; | 
|---|
| 397 |  | 
|---|
| 398 | X) [[ -n $Xflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" | 
|---|
| 399 | Xflag="-$OPT" | 
|---|
| 400 | [[ -n $Lflag || -n $Mflag || -n $mflag ]] &&  \ | 
|---|
| 401 | syntaxError "invalidCombination" $usageMsg $Xflag $Lflag $Mflag $mflag | 
|---|
| 402 | ;; | 
|---|
| 403 |  | 
|---|
| 404 | :) syntaxError "missingValue" $usageMsg $OPTARG | 
|---|
| 405 | ;; | 
|---|
| 406 |  | 
|---|
| 407 | +[adFfLMmvX]) | 
|---|
| 408 | syntaxError "invalidOption" $usageMsg "$OPT" | 
|---|
| 409 | ;; | 
|---|
| 410 |  | 
|---|
| 411 | *) syntaxError "invalidOption" $usageMsg $OPTARG | 
|---|
| 412 | ;; | 
|---|
| 413 |  | 
|---|
| 414 | esac | 
|---|
| 415 | done  # end of while getopts :ad:Ff:LMmv OPT | 
|---|
| 416 |  | 
|---|
| 417 | shift OPTIND-1 | 
|---|
| 418 | [[ $# != 0 ]] && syntaxError "extraArg" $usageMsg $1 | 
|---|
| 419 |  | 
|---|
| 420 | # If no disk selection option was specified, default to -a. | 
|---|
| 421 | [[ -z $aflag && -z $dflag && -z $Fflag && -z $fflag ]] &&  \ | 
|---|
| 422 | aflag="-a" | 
|---|
| 423 |  | 
|---|
| 424 |  | 
|---|
| 425 | ###################################################################### | 
|---|
| 426 | # Set up trap exception handling and call the gpfsInit function. | 
|---|
| 427 | # It will ensure that the local copy of the mmsdrfs and the rest | 
|---|
| 428 | # of the GPFS system files are up-to-date.  No need to lock the sdr. | 
|---|
| 429 | ###################################################################### | 
|---|
| 430 | trap pretrap2 HUP INT QUIT KILL | 
|---|
| 431 | gpfsInitOutput=$(gpfsInit nolock) | 
|---|
| 432 | setGlobalVar $? $gpfsInitOutput | 
|---|
| 433 |  | 
|---|
| 434 | # In single mode environment -M does not make much sense. | 
|---|
| 435 | if [[ -n $Mflag && $MMMODE = single ]] | 
|---|
| 436 | then | 
|---|
| 437 | Mflag="" | 
|---|
| 438 | mflag="-m" | 
|---|
| 439 | fi | 
|---|
| 440 |  | 
|---|
| 441 |  | 
|---|
| 442 | ################################################################# | 
|---|
| 443 | # If a particular file system is requested, make sure it exists. | 
|---|
| 444 | ################################################################# | 
|---|
| 445 | if [[ -n $farg ]] | 
|---|
| 446 | then | 
|---|
| 447 | findFSoutput=$(findFS "$farg" $mmsdrfsFile) | 
|---|
| 448 | [[ -z $findFSoutput ]] && cleanupAndExit | 
|---|
| 449 |  | 
|---|
| 450 | # Parse the output from the findFS function. | 
|---|
| 451 | set -f ; set -- $findFSoutput ; set +f | 
|---|
| 452 | # fqfsDeviceName=$1 | 
|---|
| 453 | fsDeviceName=$2 | 
|---|
| 454 | fsHomeCluster=$3 | 
|---|
| 455 |  | 
|---|
| 456 | # Exit with a message if the command was invoked for a remote file system. | 
|---|
| 457 | if [[ $fsHomeCluster != $HOME_CLUSTER ]] | 
|---|
| 458 | then | 
|---|
| 459 | # Command is not allowed for remote file systems. | 
|---|
| 460 | printErrorMsg 106 $mmcmd $farg $fsHomeCluster | 
|---|
| 461 | cleanupAndExit 1 | 
|---|
| 462 | fi | 
|---|
| 463 | fi   # end of if [[ -n $farg ]] | 
|---|
| 464 |  | 
|---|
| 465 |  | 
|---|
| 466 | ############################### | 
|---|
| 467 | # Select the disks to display. | 
|---|
| 468 | ############################### | 
|---|
| 469 | $rm -f $disksToShow $nodefile $diskNamesFile | 
|---|
| 470 | IFS=":"         # Change the field separator to ':'. | 
|---|
| 471 | exec 3<&- | 
|---|
| 472 | exec 3< $mmsdrfsFile | 
|---|
| 473 | while read -u3 sdrfsLine | 
|---|
| 474 | do | 
|---|
| 475 | # Parse the line. | 
|---|
| 476 | set -f ; set -A v -- - $sdrfsLine ; set +f | 
|---|
| 477 | IFS="$IFS_sv" | 
|---|
| 478 | printLine=false      # assume line is not needed | 
|---|
| 479 |  | 
|---|
| 480 | if [[ ${v[$LINE_TYPE_Field]} = $SG_DISKS ]] | 
|---|
| 481 | then | 
|---|
| 482 | # This line describes a disk.  If it matches our selection | 
|---|
| 483 | # criteria, add the line to disksToShow.  Otherwise, skip the line. | 
|---|
| 484 | if [[ -n $aflag ]] | 
|---|
| 485 | then | 
|---|
| 486 | printLine=true | 
|---|
| 487 | elif [[ -n $Fflag && ${v[$NODESETID_Field]} = $FREE_DISK ]] | 
|---|
| 488 | then | 
|---|
| 489 | printLine=true | 
|---|
| 490 | elif [[ -n $fflag && ${v[$DEV_NAME_Field]} = $fsDeviceName ]] | 
|---|
| 491 | then | 
|---|
| 492 | printLine=true | 
|---|
| 493 | elif [[ -n $dflag ]] | 
|---|
| 494 | then | 
|---|
| 495 | # See if this disk is one of the disks to be displayed. | 
|---|
| 496 | tempList="" | 
|---|
| 497 | displayThisDisk=no | 
|---|
| 498 | for diskName in $disksToDisplay | 
|---|
| 499 | do | 
|---|
| 500 | if [[ ${v[$DISK_NAME_Field]} = $diskName ]] | 
|---|
| 501 | then | 
|---|
| 502 | # The disk represented by the current SG_DISKS line | 
|---|
| 503 | # is one of the disks that we want to display. | 
|---|
| 504 | if [[ $displayThisDisk = no ]] | 
|---|
| 505 | then | 
|---|
| 506 | # We are seeing this disk for the first time. | 
|---|
| 507 | printLine=true | 
|---|
| 508 | displayThisDisk=yes | 
|---|
| 509 | else | 
|---|
| 510 | # We have already seen this name during the current iteration. | 
|---|
| 511 | # It must be a duplicate entry in the command line list. | 
|---|
| 512 | : # ignore the duplicate - do not fail the command. | 
|---|
| 513 | fi | 
|---|
| 514 | else | 
|---|
| 515 | # diskName does not match the name of the disk in the current | 
|---|
| 516 | # SG_DISKS line.  Add diskName to the temporary list. | 
|---|
| 517 | tempList="$tempList $diskName" | 
|---|
| 518 | fi  # end of if [[ ${v[$DISK_NAME_Field]} = $diskName ]] | 
|---|
| 519 | done  # for diskName in $disksToDisplay | 
|---|
| 520 |  | 
|---|
| 521 | # If this disk will be displayed, its name does not appear in tempList. | 
|---|
| 522 | # In other words, tempList contains only the names of the disks that | 
|---|
| 523 | # are to be displayed but for which the corresponding SG_LINES have not | 
|---|
| 524 | # been encountered yet. | 
|---|
| 525 |  | 
|---|
| 526 | # Initialize the disksToDisplay list for the next iteration. | 
|---|
| 527 | disksToDisplay=$tempList | 
|---|
| 528 |  | 
|---|
| 529 | else | 
|---|
| 530 | # This is an SG_DISKS line that does not match our selection criteria. | 
|---|
| 531 | : # skip this line | 
|---|
| 532 | fi  # end of if [[ -n $aflag ]] | 
|---|
| 533 |  | 
|---|
| 534 | if [[ $printLine = true ]] | 
|---|
| 535 | then | 
|---|
| 536 | print_newLine >> $disksToShow | 
|---|
| 537 | checkForErrors "writing to file $disksToShow" $? | 
|---|
| 538 |  | 
|---|
| 539 | # If -m or -X was specified and the disk has primary or backup servers, | 
|---|
| 540 | # add the servers to the list of nodes to collect data from. | 
|---|
| 541 | if [[ -n $mflag || -n $Xflag ]] | 
|---|
| 542 | then | 
|---|
| 543 | [[ -n ${v[$NSD_PRIMARY_NODE_Field]} ]] &&  \ | 
|---|
| 544 | print ${v[$NSD_PRIMARY_NODE_Field]} >> $nodefile | 
|---|
| 545 | [[ -n ${v[$NSD_BACKUP_NODE_Field]} ]]  &&  \ | 
|---|
| 546 | print ${v[$NSD_BACKUP_NODE_Field]}  >> $nodefile | 
|---|
| 547 | fi | 
|---|
| 548 |  | 
|---|
| 549 | # If -m, -M, or -X was specified, add data for the disk | 
|---|
| 550 | # to a file that will be used later. | 
|---|
| 551 | [[ -n $mflag || -n $Mflag || -n $Xflag ]] &&  \ | 
|---|
| 552 | print ${v[$DISK_NAME_Field]}:${v[$PVID_Field]}:${v[$NSD_PRIMARY_NODE_Field]}:${v[$NSD_BACKUP_NODE_Field]}:${v[$NSD_SUBTYPE_Field]} >> $diskNamesFile | 
|---|
| 553 | fi  # end of if [[ $printLine = true ]] | 
|---|
| 554 |  | 
|---|
| 555 | elif [[ ${v[$LINE_TYPE_Field]} = $MEMBER_NODE && -n $Mflag ]] | 
|---|
| 556 | then | 
|---|
| 557 | # Generate a list of all nodes in the cluster. | 
|---|
| 558 | print ${v[$REL_HOSTNAME_Field]} >> $nodefile | 
|---|
| 559 |  | 
|---|
| 560 | else | 
|---|
| 561 | # This is not a line that we care about. | 
|---|
| 562 | :  # Skip this line. | 
|---|
| 563 | fi  # end of if [[ ${v[$LINE_TYPE_Field]} = $SG_DISKS ]] | 
|---|
| 564 |  | 
|---|
| 565 | IFS=":"  # Change the separator back to ":" for the next iteration. | 
|---|
| 566 |  | 
|---|
| 567 | done  # end while read -u3 sdrfsLine | 
|---|
| 568 |  | 
|---|
| 569 | IFS="$IFS_sv"  # Restore the default IFS settings. | 
|---|
| 570 |  | 
|---|
| 571 |  | 
|---|
| 572 | # If there are no disks matching the selection criteria, | 
|---|
| 573 | # put out a message and give up. | 
|---|
| 574 | if [[ ! -s $disksToShow ]] | 
|---|
| 575 | then | 
|---|
| 576 | # No disks were found. | 
|---|
| 577 | printErrorMsg 418 $mmcmd | 
|---|
| 578 | cleanupAndExit 0 | 
|---|
| 579 | fi | 
|---|
| 580 |  | 
|---|
| 581 | # If -d option was used and there are still entries in the | 
|---|
| 582 | # disksToDisplay list, tell the user that not all disks were found. | 
|---|
| 583 | if [[ -n $disksToDisplay ]] | 
|---|
| 584 | then | 
|---|
| 585 | # Some disks were not found. | 
|---|
| 586 | for diskName in $disksToDisplay | 
|---|
| 587 | do | 
|---|
| 588 | printErrorMsg 524 $mmcmd $diskName | 
|---|
| 589 | done | 
|---|
| 590 | fi | 
|---|
| 591 |  | 
|---|
| 592 | # Finish creating the node file if -m or -X was specified. | 
|---|
| 593 | if [[ -n $mflag || -n $Xflag ]] | 
|---|
| 594 | then | 
|---|
| 595 | # Add the node running the command to the list of nodes to check. | 
|---|
| 596 | print $ourNodeName >> $nodefile | 
|---|
| 597 |  | 
|---|
| 598 | # Sort the file for uniqueness so that we do not have any | 
|---|
| 599 | # nodes listed more than once. | 
|---|
| 600 | $sort -u $nodefile -o $nodefile | 
|---|
| 601 | fi | 
|---|
| 602 |  | 
|---|
| 603 | # Print the appropriate header line. | 
|---|
| 604 | # This depends on the specified formatting option. | 
|---|
| 605 | if [[ -n $Lflag ]] | 
|---|
| 606 | then | 
|---|
| 607 | # header "File system  Disk name  NSD volumeID  Primary node  Backup node" | 
|---|
| 608 | header=$(printInfoMsg 501) | 
|---|
| 609 | printf "\n%s\n%.${#header}s\n" "$header" "$underline" | 
|---|
| 610 |  | 
|---|
| 611 | elif [[ -n $Mflag || -n $mflag || -n $Xflag ]] | 
|---|
| 612 | then | 
|---|
| 613 | if [[ -n $Xflag ]] | 
|---|
| 614 | then | 
|---|
| 615 | # header "Disk name   NSD volumeID   Device   Devtype   Node name   Remarks" | 
|---|
| 616 | header=$(printInfoMsg 512) | 
|---|
| 617 | else | 
|---|
| 618 | # header "Disk name   NSD volumeID   Device   Node name   Remarks" | 
|---|
| 619 | header=$(printInfoMsg 502) | 
|---|
| 620 | fi | 
|---|
| 621 | printf "\n%s\n%.${#header}s\n" "$header" "$underline" | 
|---|
| 622 |  | 
|---|
| 623 | # Obtain the local nsd data from the nodes. | 
|---|
| 624 | $mmcommon onall $nodefile $unreachedNodes getLocalNsdData $Xflag >$collectedDiskData 2>&1 | 
|---|
| 625 |  | 
|---|
| 626 | else | 
|---|
| 627 | # header "File system   Disk name   Primary node   Backup node" | 
|---|
| 628 | header=$(printInfoMsg 503) | 
|---|
| 629 | printf "\n%s\n%.${#header}s\n" "$header" "$underline" | 
|---|
| 630 | fi  # end of if [[ -n $Lflag ]] | 
|---|
| 631 |  | 
|---|
| 632 | # If -m, -M, or -X was specified, sort the disk data file and call routine | 
|---|
| 633 | # to print the output for the desired disks on all of the pertinent nodes. | 
|---|
| 634 | if [[ -n $mflag || -n $Mflag || -n $Xflag ]] | 
|---|
| 635 | then | 
|---|
| 636 | # Invoke routine to display the disk data from the nodes. | 
|---|
| 637 | showLocalDeviceInfo $collectedDiskData $diskNamesFile $nodefile | 
|---|
| 638 |  | 
|---|
| 639 | else | 
|---|
| 640 | # For options other than -m, -M, or -X, loop through the selected | 
|---|
| 641 | # disks one by one and print the desired information. | 
|---|
| 642 | IFS=":" | 
|---|
| 643 | exec 3<&- | 
|---|
| 644 | exec 3< $disksToShow | 
|---|
| 645 | while read -u3 diskLine | 
|---|
| 646 | do | 
|---|
| 647 | # Parse the line. | 
|---|
| 648 | set -f ; set -A v -- - $diskLine ; set +f | 
|---|
| 649 | IFS="$IFS_sv" | 
|---|
| 650 |  | 
|---|
| 651 | # Check whether this is a free disk. | 
|---|
| 652 | [[ ${v[$NODESETID_Field]} = $FREE_DISK ]] &&  \ | 
|---|
| 653 | v[$DEV_NAME_Field]="(free disk)" | 
|---|
| 654 |  | 
|---|
| 655 | if [[ -n $Lflag ]] | 
|---|
| 656 | then                          # Extended disk information requested. | 
|---|
| 657 | # If no primary node, indicate the disk is directly-attached. | 
|---|
| 658 | [[ -z ${v[$NSD_PRIMARY_NODE_Field]} ]] &&  \ | 
|---|
| 659 | v[$NSD_PRIMARY_NODE_Field]="(directly attached)" | 
|---|
| 660 |  | 
|---|
| 661 | # Print the line of output for the disk. | 
|---|
| 662 | printf " %-13s %-12s %-18s %-24s %s\n"  \ | 
|---|
| 663 | "${v[$DEV_NAME_Field]}" "${v[$DISK_NAME_Field]}" "${v[$PVID_Field]}" \ | 
|---|
| 664 | "${v[$NSD_PRIMARY_NODE_Field]}" "${v[$NSD_BACKUP_NODE_Field]}" | 
|---|
| 665 |  | 
|---|
| 666 | else                          # Default disk information requested. | 
|---|
| 667 | # If no primary node, indicate the disk is directly-attached. | 
|---|
| 668 | [[ -z ${v[$NSD_PRIMARY_NODE_Field]} ]] &&  \ | 
|---|
| 669 | v[$NSD_PRIMARY_NODE_Field]="(directly attached)" | 
|---|
| 670 |  | 
|---|
| 671 | # Print the line of output for the disk. | 
|---|
| 672 | printf " %-13s %-12s %-24s %s\n"  \ | 
|---|
| 673 | "${v[$DEV_NAME_Field]}" "${v[$DISK_NAME_Field]}"  \ | 
|---|
| 674 | "${v[$NSD_PRIMARY_NODE_Field]}" "${v[$NSD_BACKUP_NODE_Field]}" | 
|---|
| 675 | fi  # end of if [[ -n $Lflag ]] | 
|---|
| 676 |  | 
|---|
| 677 | IFS=":"  # Change the separator back to ":" for the next iteration. | 
|---|
| 678 |  | 
|---|
| 679 | done  # end while read -u3 diskLine | 
|---|
| 680 |  | 
|---|
| 681 | fi  # end of if [[ -n $Mflag ]] | 
|---|
| 682 |  | 
|---|
| 683 | IFS="$IFS_sv"  # Restore the default IFS settings. | 
|---|
| 684 |  | 
|---|
| 685 | # Add a blank line for nicer formatting. | 
|---|
| 686 | print "" | 
|---|
| 687 |  | 
|---|
| 688 | # If any nodes could not be reached, tell the user which ones. | 
|---|
| 689 | if [[ -s $unreachedNodes ]] | 
|---|
| 690 | then | 
|---|
| 691 | # The following nodes could not be reached: . . . | 
|---|
| 692 | printErrorMsg 270 $mmcmd | 
|---|
| 693 | $cat $unreachedNodes 1>&2 | 
|---|
| 694 | fi | 
|---|
| 695 |  | 
|---|
| 696 | cleanupAndExit 0 | 
|---|
| 697 |  | 
|---|