| 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. 2004,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 | # @(#)76 1.2.3.2 src/avs/fs/mmfs/ts/admin/mmfsctl.sh, mmfs, avs_rgpfs24, rgpfs24s005a 6/14/06 14:40:21 | 
|---|
| 17 | ################################################################################ | 
|---|
| 18 | # | 
|---|
| 19 | # Usage: | 
|---|
| 20 | # | 
|---|
| 21 | #   mmfsctl Device {suspend | resume} | 
|---|
| 22 | #     or | 
|---|
| 23 | #   mmfsctl Device {exclude | include} | 
|---|
| 24 | #                  {-d DiskList | -F DiskFile | -G FailureGroup} | 
|---|
| 25 | #     or | 
|---|
| 26 | #   mmfsctl Device syncFSconfig | 
|---|
| 27 | #                  {-n RemoteNodes | -C RemoteCluster} [-S SpecFile] | 
|---|
| 28 | # | 
|---|
| 29 | # where | 
|---|
| 30 | # | 
|---|
| 31 | #   Device            The device name of the affected GPFS file system. | 
|---|
| 32 | # | 
|---|
| 33 | #   suspend           Suspend the execution of all new I/O requests coming | 
|---|
| 34 | #                     from user applications, flush all pending requests | 
|---|
| 35 | #                     on all nodes, bring the file system to a consistent | 
|---|
| 36 | #                     state on disk. | 
|---|
| 37 | # | 
|---|
| 38 | #   resume            Resume normal processing of I/O requests on all nodes. | 
|---|
| 39 | # | 
|---|
| 40 | #   exclude           Exclude the specified disks when determining the | 
|---|
| 41 | #                     most recent file system control data structures. | 
|---|
| 42 | #                     This has the effect of overriding the normal GPFS | 
|---|
| 43 | #                     quorum requirements for on-disk file system data | 
|---|
| 44 | #                     and stops the disks from participating into normal | 
|---|
| 45 | #                     file systems operations. | 
|---|
| 46 | # | 
|---|
| 47 | #   include           Restore the specified disks for normal file system | 
|---|
| 48 | #                     operations. | 
|---|
| 49 | # | 
|---|
| 50 | #   -d DiskList       The names of the disks to be excluded or included. | 
|---|
| 51 | #                     If there is more than one disk, delimit each name with | 
|---|
| 52 | #                     a semicolon (;) and enclose the list in quotation marks. | 
|---|
| 53 | # | 
|---|
| 54 | #   -F DiskFile       A file that contains, one per line, the names of the | 
|---|
| 55 | #                     disks to be excluded or included. | 
|---|
| 56 | # | 
|---|
| 57 | #   -G FailureGroup   Exclude or include all disks that belong to the | 
|---|
| 58 | #                     specified failure group. | 
|---|
| 59 | # | 
|---|
| 60 | #   syncFSconfig      Synchronize the file system configuration information | 
|---|
| 61 | #                     in a remote cluster with the file system information | 
|---|
| 62 | #                     in the local cluster. | 
|---|
| 63 | # | 
|---|
| 64 | #   -C RemoteCluster  The name of the remote cluster where the file system | 
|---|
| 65 | #                     information is to be imported.  The cluster must | 
|---|
| 66 | #                     already be registered with the mmremotecluster command. | 
|---|
| 67 | # | 
|---|
| 68 | #   -n RemoteNodes    The path name to a file containing, one per line, | 
|---|
| 69 | #                     hostnames or IP addresses of nodes that belong to | 
|---|
| 70 | #                     the remote cluster. | 
|---|
| 71 | # | 
|---|
| 72 | #   -S SpecFile       The path name to a file with the NSD server designations | 
|---|
| 73 | #                     in the remote cluster for all affected disks.  The file | 
|---|
| 74 | #                     format is the same as for the -S parameter of mmimportfs. | 
|---|
| 75 | #                     Note that SpecFile refers to a file in the remote cluster | 
|---|
| 76 | #                     and must exist on all nodes in the contact node list. | 
|---|
| 77 | # | 
|---|
| 78 | ################################################################################ | 
|---|
| 79 |  | 
|---|
| 80 | # Include global declarations and service routines. | 
|---|
| 81 | . /usr/lpp/mmfs/bin/mmglobfuncs | 
|---|
| 82 | . /usr/lpp/mmfs/bin/mmsdrfsdef | 
|---|
| 83 | . /usr/lpp/mmfs/bin/mmfsfuncs | 
|---|
| 84 |  | 
|---|
| 85 | sourceFile="mmfsctl.sh" | 
|---|
| 86 | [[ -n $DEBUG || -n $DEBUGmmfsctl ]] && set -x | 
|---|
| 87 | $mmTRACE_ENTER "$*" | 
|---|
| 88 |  | 
|---|
| 89 | # Local work files.  Names should be of the form: | 
|---|
| 90 | #   fn=${tmpDir}fn.${mmcmd}.$$ | 
|---|
| 91 |  | 
|---|
| 92 | tmpDiskFile=${tmpDir}tmpDiskFile.${mmcmd}.$$ | 
|---|
| 93 |  | 
|---|
| 94 | LOCAL_FILES=" $tmpDiskFile " | 
|---|
| 95 |  | 
|---|
| 96 |  | 
|---|
| 97 | # Local variables | 
|---|
| 98 | usageMsg=484 | 
|---|
| 99 | typeset -l action | 
|---|
| 100 |  | 
|---|
| 101 |  | 
|---|
| 102 | # Local functions | 
|---|
| 103 |  | 
|---|
| 104 |  | 
|---|
| 105 | ##################################################################### | 
|---|
| 106 | # | 
|---|
| 107 | # Function:  Depending on the specified action, either suspend | 
|---|
| 108 | #            or resume I/O activity for a given file system. | 
|---|
| 109 | # | 
|---|
| 110 | # Input:     $1 - file system device name | 
|---|
| 111 | #            $2 - action:  suspend, suspendandflush, or resume | 
|---|
| 112 | # | 
|---|
| 113 | # Output:    None. | 
|---|
| 114 | # | 
|---|
| 115 | # Returns:   0 - no errors encountered | 
|---|
| 116 | #            1 - unexpected error | 
|---|
| 117 | # | 
|---|
| 118 | ##################################################################### | 
|---|
| 119 | function fsSuspendOrResume   # <device> <action> | 
|---|
| 120 | { | 
|---|
| 121 |   typeset sourceFile="mmfsctl.sh" | 
|---|
| 122 |   [[ -n $DEBUG || -n $DEBUGfsSuspendOrResume ]] && set -x | 
|---|
| 123 |   $mmTRACE_ENTER "$*" | 
|---|
| 124 |  | 
|---|
| 125 |   typeset device=$1 | 
|---|
| 126 |   typeset action=$2 | 
|---|
| 127 |  | 
|---|
| 128 |   typeset gpfsInitOutput findFSoutput fqDeviceName fsHomeCluster | 
|---|
| 129 |   typeset nodeCount preferredNode | 
|---|
| 130 |   typeset rc=0 | 
|---|
| 131 |  | 
|---|
| 132 |   [[ $action = suspend ]] && action=suspendandflush | 
|---|
| 133 |  | 
|---|
| 134 |  | 
|---|
| 135 |   ##################################################################### | 
|---|
| 136 |   # Set up trap exception handling and ensure that the local copy of | 
|---|
| 137 |   # the mmsdrfs is up-to-date.  There is no need to lock mmsdrfs file. | 
|---|
| 138 |   ##################################################################### | 
|---|
| 139 |   trap pretrap2 HUP INT QUIT KILL | 
|---|
| 140 |   gpfsInitOutput=$(gpfsInit nolock) | 
|---|
| 141 |   setGlobalVar $? $gpfsInitOutput | 
|---|
| 142 |  | 
|---|
| 143 |  | 
|---|
| 144 |   ########################################################### | 
|---|
| 145 |   # Make sure the specified file system exists and is local. | 
|---|
| 146 |   ########################################################### | 
|---|
| 147 |   findFSoutput=$(findFS "$device" $mmsdrfsFile) | 
|---|
| 148 |   [[ -z $findFSoutput ]] && cleanupAndExit | 
|---|
| 149 |  | 
|---|
| 150 |   # Parse the output from the findFS function. | 
|---|
| 151 |   set -f ; set -- $findFSoutput ; set +f | 
|---|
| 152 |   fqDeviceName=$1 | 
|---|
| 153 |   fsHomeCluster=$3 | 
|---|
| 154 |  | 
|---|
| 155 |   # Exit with a message if the command was invoked for a remote file system. | 
|---|
| 156 |   if [[ $fsHomeCluster != $HOME_CLUSTER ]] | 
|---|
| 157 |   then | 
|---|
| 158 |     # Command is not allowed for remote file systems. | 
|---|
| 159 |     printErrorMsg 106 $mmcmd $device $fsHomeCluster | 
|---|
| 160 |     cleanupAndExit 1 | 
|---|
| 161 |   fi | 
|---|
| 162 |  | 
|---|
| 163 |  | 
|---|
| 164 |   ################################################## | 
|---|
| 165 |   # First try to run the command on the local node. | 
|---|
| 166 |   ################################################## | 
|---|
| 167 |   ${mmcmdDir}/${links}/mmfsctl $fqDeviceName $action | 
|---|
| 168 |   rc=$(remapRC $?) | 
|---|
| 169 |  | 
|---|
| 170 |   # If acceptable error (daemon not running, waiting for quorum), | 
|---|
| 171 |   # try some other node.  Otherwise, get out; the command either | 
|---|
| 172 |   # worked or the errors are not acceptable. | 
|---|
| 173 |   [[ $rc -ne $MM_DaemonDown && | 
|---|
| 174 |      $rc -ne $MM_QuorumWait || | 
|---|
| 175 |      $MMMODE = single       ]] &&  \ | 
|---|
| 176 |     return $rc | 
|---|
| 177 |  | 
|---|
| 178 |  | 
|---|
| 179 |   ############################################################################ | 
|---|
| 180 |   # If the local daemon is not available, send the command to an active node. | 
|---|
| 181 |   ############################################################################ | 
|---|
| 182 |  | 
|---|
| 183 |   # Create a file with the reliable names of the nodes in the cluster. | 
|---|
| 184 |   nodeCount=$(getNodeFile $REL_HOSTNAME_Field $GLOBAL_ID $mmsdrfsFile $nodefile) | 
|---|
| 185 |   [[ $nodeCount = 0 ]] &&  \ | 
|---|
| 186 |     checkForErrors "$mmcmd:  No nodes found in the cluster." 1 | 
|---|
| 187 |  | 
|---|
| 188 |   # Try the nodes one by one until you find a node that can execute the command. | 
|---|
| 189 |   preferredNode=0     # We have no idea where to go first; let mmcommon decide. | 
|---|
| 190 |   $mmcommon linkCommand $preferredNode $nodefile mmfsctl $fqDeviceName $action | 
|---|
| 191 |   rc=$? | 
|---|
| 192 |  | 
|---|
| 193 |   return $rc | 
|---|
| 194 |  | 
|---|
| 195 | }  #-------- end of function fsSuspendOrResume ---------------------- | 
|---|
| 196 |  | 
|---|
| 197 |  | 
|---|
| 198 | ##################################################################### | 
|---|
| 199 | # | 
|---|
| 200 | # Function:  Mark the specified disks as excluded from stripe | 
|---|
| 201 | #            group descriptor operations. | 
|---|
| 202 | # | 
|---|
| 203 | # Input:     None explicit.  This function uses the global variables | 
|---|
| 204 | #            device, diskList, diskFile, and failureGroup. | 
|---|
| 205 | # | 
|---|
| 206 | # Output:    None. | 
|---|
| 207 | # | 
|---|
| 208 | # Returns:   0 - no errors encountered | 
|---|
| 209 | #            1 - unexpected error | 
|---|
| 210 | # | 
|---|
| 211 | ##################################################################### | 
|---|
| 212 | function fsExcludeDisks  # (parms passed via global variables) | 
|---|
| 213 | { | 
|---|
| 214 |   typeset sourceFile="mmfsctl.sh" | 
|---|
| 215 |   [[ -n $DEBUG || -n $DEBUGfsExcludeDisks ]] && set -x | 
|---|
| 216 |   $mmTRACE_ENTER "$*" | 
|---|
| 217 |  | 
|---|
| 218 |   typeset gpfsInitOutput findFSoutput fqDeviceName fsHomeCluster deviceName | 
|---|
| 219 |   typeset diskName disksToExclude sdrfsLine preferredNode tempList | 
|---|
| 220 |   typeset excludeThisDisk | 
|---|
| 221 |   typeset includedDisksFound="" | 
|---|
| 222 |   typeset rc=0 | 
|---|
| 223 |  | 
|---|
| 224 |  | 
|---|
| 225 |   ############################################################# | 
|---|
| 226 |   # Create a blank-separated list of the disks to be excluded. | 
|---|
| 227 |   ############################################################# | 
|---|
| 228 |   if [[ -n $diskList ]] | 
|---|
| 229 |   then | 
|---|
| 230 |     # The input is specified in the form of a list of disk names. | 
|---|
| 231 |     IFS=';' | 
|---|
| 232 |     for diskName in $diskList | 
|---|
| 233 |     do | 
|---|
| 234 |       disksToExclude="${disksToExclude}${diskName}${BLANKchar}" | 
|---|
| 235 |     done | 
|---|
| 236 |     IFS="$IFS_sv" | 
|---|
| 237 |     disksToExclude="${disksToExclude% }" | 
|---|
| 238 |  | 
|---|
| 239 |   elif [[ -n $diskFile ]] | 
|---|
| 240 |   then | 
|---|
| 241 |     # The disks are specified in a file. | 
|---|
| 242 |     exec 3< $diskFile | 
|---|
| 243 |     while read -u3 diskName | 
|---|
| 244 |     do | 
|---|
| 245 |       # Skip empty and comment lines. | 
|---|
| 246 |       [[ $diskName = *([$BLANKchar$TABchar])   ]] && continue | 
|---|
| 247 |       [[ $diskName = *([$BLANKchar$TABchar])#* ]] && continue | 
|---|
| 248 |  | 
|---|
| 249 |       # Put the disk name in the list. | 
|---|
| 250 |       disksToExclude="${disksToExclude}${diskName}${BLANKchar}" | 
|---|
| 251 |     done  # end while read -u3 diskDesc | 
|---|
| 252 |     disksToExclude="${disksToExclude% }" | 
|---|
| 253 |  | 
|---|
| 254 |   elif [[ -n $failureGroup ]] | 
|---|
| 255 |   then | 
|---|
| 256 |     : # The input must be a failure group; nothing to do for now. | 
|---|
| 257 |  | 
|---|
| 258 |   else | 
|---|
| 259 |     # Something is very wrong. | 
|---|
| 260 |     checkForErrors "fsExcludeDisks: Missing input parameters" 1 | 
|---|
| 261 |   fi  # end if [[ -n $diskList ]] | 
|---|
| 262 |  | 
|---|
| 263 |   # Is there anything to do? | 
|---|
| 264 |   if [[ -z $disksToExclude && -z $failureGroup ]] | 
|---|
| 265 |   then | 
|---|
| 266 |     # No disks were specified. | 
|---|
| 267 |     printErrorMsg 264 $mmcmd | 
|---|
| 268 |     cleanupAndExit | 
|---|
| 269 |   fi | 
|---|
| 270 |  | 
|---|
| 271 |  | 
|---|
| 272 |   ####################################################################### | 
|---|
| 273 |   # Set up trap exception handling and call the gpfsInit function. | 
|---|
| 274 |   # It will ensure that the local copy of the mmsdrfs and the rest of | 
|---|
| 275 |   # the GPFS system files are up-to-date and will obtain the sdr lock. | 
|---|
| 276 |   ####################################################################### | 
|---|
| 277 |   trap pretrap HUP INT QUIT KILL | 
|---|
| 278 |   gpfsInitOutput=$(gpfsInit $lockId) | 
|---|
| 279 |   setGlobalVar $? $gpfsInitOutput | 
|---|
| 280 |  | 
|---|
| 281 |   # Determine the lookup order for resolving host names. | 
|---|
| 282 |   [[ $osName != AIX ]] && resolveOrder=$(setHostResolveOrder) | 
|---|
| 283 |  | 
|---|
| 284 |  | 
|---|
| 285 |   ########################################################### | 
|---|
| 286 |   # Make sure the specified file system exists and is local. | 
|---|
| 287 |   ########################################################### | 
|---|
| 288 |   findFSoutput=$(findFS "$device" $mmsdrfsFile) | 
|---|
| 289 |   [[ -z $findFSoutput ]] && cleanupAndExit | 
|---|
| 290 |  | 
|---|
| 291 |   # Parse the output from the findFS function. | 
|---|
| 292 |   set -f ; set -- $findFSoutput ; set +f | 
|---|
| 293 |   fqDeviceName=$1 | 
|---|
| 294 |   deviceName=$2 | 
|---|
| 295 |   fsHomeCluster=$3 | 
|---|
| 296 |  | 
|---|
| 297 |   # Exit with a message if the command was invoked for a remote file system. | 
|---|
| 298 |   if [[ $fsHomeCluster != $HOME_CLUSTER ]] | 
|---|
| 299 |   then | 
|---|
| 300 |     # Command is not allowed for remote file systems. | 
|---|
| 301 |     printErrorMsg 106 $mmcmd $device $fsHomeCluster | 
|---|
| 302 |     cleanupAndExit 1 | 
|---|
| 303 |   fi | 
|---|
| 304 |  | 
|---|
| 305 |  | 
|---|
| 306 |   ############################################## | 
|---|
| 307 |   # Create the new version of the mmsdrfs file. | 
|---|
| 308 |   ############################################## | 
|---|
| 309 |   $rm -f $newsdrfs $nodefile | 
|---|
| 310 |   IFS=":" | 
|---|
| 311 |   exec 3<&- | 
|---|
| 312 |   exec 3< $mmsdrfsFile | 
|---|
| 313 |   while read -u3 sdrfsLine | 
|---|
| 314 |   do | 
|---|
| 315 |     # Parse the line. | 
|---|
| 316 |     set -f ; set -A v -- - $sdrfsLine ; set +f | 
|---|
| 317 |  | 
|---|
| 318 |     IFS="$IFS_sv"   # Restore the default IFS settings. | 
|---|
| 319 |  | 
|---|
| 320 |     # Change some of the fields depending on the type of line. | 
|---|
| 321 |     case ${v[$LINE_TYPE_Field]} in | 
|---|
| 322 |  | 
|---|
| 323 |       $VERSION_LINE )  # This is the global header line. | 
|---|
| 324 |         # Increment the generation number. | 
|---|
| 325 |         newGenNumber=${v[$SDRFS_GENNUM_Field]}+1 | 
|---|
| 326 |         v[$SDRFS_GENNUM_Field]=$newGenNumber | 
|---|
| 327 |         ;; | 
|---|
| 328 |  | 
|---|
| 329 |       $MEMBER_NODE ) | 
|---|
| 330 |         # Add the reliable node name to nodefile. | 
|---|
| 331 |         print -- "${v[$REL_HOSTNAME_Field]}" >> $nodefile | 
|---|
| 332 |         checkForErrors "writing to file $nodefile" $? | 
|---|
| 333 |  | 
|---|
| 334 |         # If this is the line for the node that is executing | 
|---|
| 335 |         # this command, set the preferredNode variable. | 
|---|
| 336 |         [[ ${v[$NODE_NUMBER_Field]} = $ourNodeNumber ]] &&  \ | 
|---|
| 337 |           preferredNode=${v[$REL_HOSTNAME_Field]} | 
|---|
| 338 |         ;; | 
|---|
| 339 |  | 
|---|
| 340 |       $SG_DISKS ) | 
|---|
| 341 |  | 
|---|
| 342 |         if [[ ${v[$DEV_NAME_Field]} = $deviceName ]] | 
|---|
| 343 |         then | 
|---|
| 344 |           # This is an SG_DISKS line that belongs to our filesystem. | 
|---|
| 345 |           # See if this disk is one of the disks to be excluded. | 
|---|
| 346 |           if [[ -n $failureGroup ]] | 
|---|
| 347 |           then | 
|---|
| 348 |             # Disks are to be excluded based on failure group. | 
|---|
| 349 |             [[ ${v[$FAILURE_GROUP_Field]} = $failureGroup ]] &&  \ | 
|---|
| 350 |               v[$EXCLUDE_Field]=$excludedDisk | 
|---|
| 351 |  | 
|---|
| 352 |           else | 
|---|
| 353 |             # The disks to be excluded are specified in the disksToExclude list. | 
|---|
| 354 |             tempList="" | 
|---|
| 355 |             excludeThisDisk=no | 
|---|
| 356 |             for diskName in $disksToExclude | 
|---|
| 357 |             do | 
|---|
| 358 |               if [[ $diskName = ${v[$DISK_NAME_Field]} ]] | 
|---|
| 359 |               then | 
|---|
| 360 |                 # The disk represented by the current SG_DISKS line | 
|---|
| 361 |                 # is one of the disks that must be excluded. | 
|---|
| 362 |                 if [[ $excludeThisDisk = no ]] | 
|---|
| 363 |                 then | 
|---|
| 364 |                   # Mark the disk as excluded. | 
|---|
| 365 |                   v[$EXCLUDE_Field]=$excludedDisk | 
|---|
| 366 |                   excludeThisDisk=yes | 
|---|
| 367 |                 else | 
|---|
| 368 |                   # We have already seen this name during the current iteration. | 
|---|
| 369 |                   # It must be a duplicate entry in the command line list. | 
|---|
| 370 |                   printErrorMsg 88 $mmcmd $diskName | 
|---|
| 371 |                   cleanupAndExit | 
|---|
| 372 |                 fi  # end of if [[ $excludeThisDisk = no ]] | 
|---|
| 373 |  | 
|---|
| 374 |               else | 
|---|
| 375 |                 # diskName does not match the name of the disk in the current | 
|---|
| 376 |                 # SG_DISKS line.  Add diskName to the temporary list. | 
|---|
| 377 |                 tempList="$tempList $diskName" | 
|---|
| 378 |               fi  # end of if [[ $diskName = ${v[$DISK_NAME_Field]} ]] | 
|---|
| 379 |             done  # end of for diskName in $disksToExclude | 
|---|
| 380 |  | 
|---|
| 381 |             # If this disk will be excluded, its name does not appear in | 
|---|
| 382 |             # tempList.  In other words, tempList contains only the names of | 
|---|
| 383 |             # the disks that are to be excluded but for which the corresponding | 
|---|
| 384 |             # SG_LINES have not been encountered yet.  Initialize the list | 
|---|
| 385 |             # for the next iteration. | 
|---|
| 386 |             disksToExclude=$tempList | 
|---|
| 387 |  | 
|---|
| 388 |           fi  # end of if [[ -n $failureGroup ]] | 
|---|
| 389 |  | 
|---|
| 390 |           # Keep an overall track of the EXCLUDE field to prevent | 
|---|
| 391 |           # marking all disks as excluded. | 
|---|
| 392 |           [[ ${v[$EXCLUDE_Field]} = $includedDisk ]] && | 
|---|
| 393 |             includedDisksFound=yes | 
|---|
| 394 |  | 
|---|
| 395 |         fi  # end of if [[ ${v[$DEV_NAME_Field]} = $deviceName ]] | 
|---|
| 396 |         ;; | 
|---|
| 397 |  | 
|---|
| 398 |       * )  # Pass all other lines without a change. | 
|---|
| 399 |         ;; | 
|---|
| 400 |  | 
|---|
| 401 |     esac  # end of "Change some of the fields . . . " | 
|---|
| 402 |  | 
|---|
| 403 |     # Build and write the line to the new mmsdrfs file. | 
|---|
| 404 |     print_newLine >> $newsdrfs | 
|---|
| 405 |     checkForErrors "writing to file $newsdrfs" $? | 
|---|
| 406 |  | 
|---|
| 407 |     IFS=":"  # Change the separator back to ":" for the next iteration. | 
|---|
| 408 |  | 
|---|
| 409 |   done  # end while read -u3 sdrfsLine | 
|---|
| 410 |  | 
|---|
| 411 |   IFS="$IFS_sv"  # Restore the default IFS settings. | 
|---|
| 412 |  | 
|---|
| 413 |   # If there are still entries left in the disksToExclude list, this means | 
|---|
| 414 |   # that the user-specified disks that do not belong to the file system. | 
|---|
| 415 |   if [[ -n $disksToExclude ]] | 
|---|
| 416 |   then | 
|---|
| 417 |     for diskName in $disksToExclude | 
|---|
| 418 |     do | 
|---|
| 419 |       printErrorMsg 315 $mmcmd $diskName $device | 
|---|
| 420 |     done | 
|---|
| 421 |     cleanupAndExit | 
|---|
| 422 |   fi | 
|---|
| 423 |  | 
|---|
| 424 |   # Make sure that at least one disk will remain included. | 
|---|
| 425 |   if [[ -z $includedDisksFound ]] | 
|---|
| 426 |   then | 
|---|
| 427 |     # All of the disks cannot be excluded. | 
|---|
| 428 |     print -u2 "$mmcmd: You cannot exclude all of the disks in a file system." | 
|---|
| 429 |     cleanupAndExit | 
|---|
| 430 |   fi | 
|---|
| 431 |  | 
|---|
| 432 |   # Make sure the file system is not mounted on any of the nodes. | 
|---|
| 433 |   $mmcommon onactive $preferredNode $nodefile  \ | 
|---|
| 434 |      $NO_FILE_COPY $fqDeviceName $CHECK_ALL $NO_LINK $MOUNT_CHECK_ONLY 2>$errMsg | 
|---|
| 435 |   rc=$? | 
|---|
| 436 |   if [[ $rc -eq $MM_FsMounted ]] | 
|---|
| 437 |   then | 
|---|
| 438 |     # The file system is still mounted; messages were issued by mmcommon. | 
|---|
| 439 |     cleanupAndExit | 
|---|
| 440 |   elif [[ $rc -eq $MM_DaemonDown ]] | 
|---|
| 441 |   then | 
|---|
| 442 |     # GPFS is down on all nodes that we care about; that's just fine. | 
|---|
| 443 |     rc=0 | 
|---|
| 444 |   elif [[ $rc -eq $MM_ConnectionReset ]] | 
|---|
| 445 |   then | 
|---|
| 446 |     # An internode connection was reset. | 
|---|
| 447 |     printErrorMsg 257 $mmcmd | 
|---|
| 448 |     cleanupAndExit $rc | 
|---|
| 449 |   elif [[ $rc -ne 0 ]] | 
|---|
| 450 |   then | 
|---|
| 451 |     # An unexpected error occurred during the mount check. | 
|---|
| 452 |     if [[ -s $errMsg ]] | 
|---|
| 453 |     then | 
|---|
| 454 |       # Show the error messages from the daemon. | 
|---|
| 455 |       $cat $errMsg 1>&2 | 
|---|
| 456 |     else | 
|---|
| 457 |       # The mount check failed and there were no messages from the daemon. | 
|---|
| 458 |       printErrorMsg 171 $mmcmd "mount check for $fqDeviceName" $rc | 
|---|
| 459 |     fi | 
|---|
| 460 |     # The command was unable to determine whether the file system is mounted. | 
|---|
| 461 |     printErrorMsg 564 $mmcmd $fqDeviceName | 
|---|
| 462 |     # The command failed. | 
|---|
| 463 |     printErrorMsg 389 $mmcmd | 
|---|
| 464 |     cleanupAndExit $rc | 
|---|
| 465 |   fi | 
|---|
| 466 |   $rm -f $errMsg | 
|---|
| 467 |  | 
|---|
| 468 |  | 
|---|
| 469 |   ############################### | 
|---|
| 470 |   # Commit the new mmsdrfs file. | 
|---|
| 471 |   ############################### | 
|---|
| 472 |   trap "" HUP INT QUIT KILL | 
|---|
| 473 |   gpfsObjectInfo=$(commitChanges  \ | 
|---|
| 474 |      $nodesetId $nsId $gpfsObjectInfo $newGenNumber $newsdrfs $primaryServer) | 
|---|
| 475 |   rc=$? | 
|---|
| 476 |   if [[ $rc -ne 0 ]] | 
|---|
| 477 |   then | 
|---|
| 478 |     # We were unable to replace the file in the sdr. | 
|---|
| 479 |     printErrorMsg 381 $mmcmd | 
|---|
| 480 |     cleanupAndExit | 
|---|
| 481 |   fi | 
|---|
| 482 |  | 
|---|
| 483 |  | 
|---|
| 484 |   ################## | 
|---|
| 485 |   # Unlock the sdr. | 
|---|
| 486 |   ################## | 
|---|
| 487 |   [[ $sdrLocked = yes ]] &&  \ | 
|---|
| 488 |     freeLockOnServer $primaryServer $ourNodeNumber >/dev/null | 
|---|
| 489 |   sdrLocked=no | 
|---|
| 490 |   trap localPosttrap HUP INT QUIT KILL | 
|---|
| 491 |  | 
|---|
| 492 |  | 
|---|
| 493 |   ################################################################## | 
|---|
| 494 |   # Propagate the new mmsdrfs file.  This process is asynchronous. | 
|---|
| 495 |   ################################################################## | 
|---|
| 496 |   propagateSdrfsFile async $nodefile $newsdrfs $newGenNumber | 
|---|
| 497 |  | 
|---|
| 498 |   return $rc | 
|---|
| 499 |  | 
|---|
| 500 | }  #-------- end of function fsExcludeDisks ---------------------- | 
|---|
| 501 |  | 
|---|
| 502 |  | 
|---|
| 503 | ##################################################################### | 
|---|
| 504 | # | 
|---|
| 505 | # Function:  Mark the specified disks as included for stripe group | 
|---|
| 506 | #            descriptor operations. | 
|---|
| 507 | # | 
|---|
| 508 | # Input:     None explicit.  This function uses the global variables | 
|---|
| 509 | #            device, diskList, diskFile, and failureGroup. | 
|---|
| 510 | # | 
|---|
| 511 | # Output:    None. | 
|---|
| 512 | # | 
|---|
| 513 | # Returns:   0 - no errors encountered | 
|---|
| 514 | #            1 - unexpected error | 
|---|
| 515 | # | 
|---|
| 516 | ##################################################################### | 
|---|
| 517 | function fsIncludeDisks  # (parms passed via global variables) | 
|---|
| 518 | { | 
|---|
| 519 |   typeset sourceFile="mmfsctl.sh" | 
|---|
| 520 |   [[ -n $DEBUG || -n $DEBUGfsIncludeDisks ]] && set -x | 
|---|
| 521 |   $mmTRACE_ENTER "$*" | 
|---|
| 522 |  | 
|---|
| 523 |   typeset gpfsInitOutput findFSoutput fqDeviceName fsHomeCluster deviceName | 
|---|
| 524 |   typeset diskName disksToInclude sdrfsLine preferredNode tempList | 
|---|
| 525 |   typeset includeThisDisk | 
|---|
| 526 |   typeset rc=0 | 
|---|
| 527 |  | 
|---|
| 528 |   tsDiskFile=${tmpDir}tsDiskFile.${mmcmd}.$$ | 
|---|
| 529 |   LOCAL_FILES="$LOCAL_FILES $tsDiskFile" | 
|---|
| 530 |  | 
|---|
| 531 |  | 
|---|
| 532 |   ############################################################# | 
|---|
| 533 |   # Create a blank-separated list of the disks to be included. | 
|---|
| 534 |   ############################################################# | 
|---|
| 535 |   if [[ -n $diskList ]] | 
|---|
| 536 |   then | 
|---|
| 537 |     # The input is specified in the form of a list of disk names. | 
|---|
| 538 |     IFS=';' | 
|---|
| 539 |     for diskName in $diskList | 
|---|
| 540 |     do | 
|---|
| 541 |       disksToInclude="${disksToInclude}${diskName}${BLANKchar}" | 
|---|
| 542 |     done | 
|---|
| 543 |     IFS="$IFS_sv" | 
|---|
| 544 |     disksToInclude="${disksToInclude% }" | 
|---|
| 545 |  | 
|---|
| 546 |   elif [[ -n $diskFile ]] | 
|---|
| 547 |   then | 
|---|
| 548 |     # The disks are specified in a file. | 
|---|
| 549 |     exec 3< $diskFile | 
|---|
| 550 |     while read -u3 diskName | 
|---|
| 551 |     do | 
|---|
| 552 |       # Skip empty and comment lines. | 
|---|
| 553 |       [[ $diskName = *([$BLANKchar$TABchar])   ]] && continue | 
|---|
| 554 |       [[ $diskName = *([$BLANKchar$TABchar])#* ]] && continue | 
|---|
| 555 |  | 
|---|
| 556 |       # Put the disk name in the list. | 
|---|
| 557 |       disksToInclude="${disksToInclude}${diskName}${BLANKchar}" | 
|---|
| 558 |     done  # end while read -u3 diskDesc | 
|---|
| 559 |     disksToInclude="${disksToInclude% }" | 
|---|
| 560 |  | 
|---|
| 561 |   elif [[ -n $failureGroup ]] | 
|---|
| 562 |   then | 
|---|
| 563 |     : # The input must be a failure group; nothing to do for now. | 
|---|
| 564 |  | 
|---|
| 565 |   else | 
|---|
| 566 |     # Something is very wrong. | 
|---|
| 567 |     checkForErrors "fsIncludeDisks: Missing input parameters" 1 | 
|---|
| 568 |   fi  # end if [[ -n $diskList ]] | 
|---|
| 569 |  | 
|---|
| 570 |   # Is there anything to do? | 
|---|
| 571 |   if [[ -z $disksToInclude && -z $failureGroup ]] | 
|---|
| 572 |   then | 
|---|
| 573 |     # No disks were specified. | 
|---|
| 574 |     printErrorMsg 264 $mmcmd | 
|---|
| 575 |     cleanupAndExit | 
|---|
| 576 |   fi | 
|---|
| 577 |  | 
|---|
| 578 |  | 
|---|
| 579 |   ####################################################################### | 
|---|
| 580 |   # Set up trap exception handling and call the gpfsInit function. | 
|---|
| 581 |   # It will ensure that the local copy of the mmsdrfs and the rest of | 
|---|
| 582 |   # the GPFS system files are up-to-date and will obtain the sdr lock. | 
|---|
| 583 |   ####################################################################### | 
|---|
| 584 |   trap pretrap HUP INT QUIT KILL | 
|---|
| 585 |   gpfsInitOutput=$(gpfsInit $lockId) | 
|---|
| 586 |   setGlobalVar $? $gpfsInitOutput | 
|---|
| 587 |  | 
|---|
| 588 |   # Determine the lookup order for resolving host names. | 
|---|
| 589 |   [[ $osName != AIX ]] && resolveOrder=$(setHostResolveOrder) | 
|---|
| 590 |  | 
|---|
| 591 |  | 
|---|
| 592 |   ########################################################### | 
|---|
| 593 |   # Make sure the specified file system exists and is local. | 
|---|
| 594 |   ########################################################### | 
|---|
| 595 |   findFSoutput=$(findFS "$device" $mmsdrfsFile) | 
|---|
| 596 |   [[ -z $findFSoutput ]] && cleanupAndExit | 
|---|
| 597 |  | 
|---|
| 598 |   # Parse the output from the findFS function. | 
|---|
| 599 |   set -f ; set -- $findFSoutput ; set +f | 
|---|
| 600 |   fqDeviceName=$1 | 
|---|
| 601 |   deviceName=$2 | 
|---|
| 602 |   fsHomeCluster=$3 | 
|---|
| 603 |  | 
|---|
| 604 |   # Exit with a message if the command was invoked for a remote file system. | 
|---|
| 605 |   if [[ $fsHomeCluster != $HOME_CLUSTER ]] | 
|---|
| 606 |   then | 
|---|
| 607 |     # Command is not allowed for remote file systems. | 
|---|
| 608 |     printErrorMsg 106 $mmcmd $device $fsHomeCluster | 
|---|
| 609 |     cleanupAndExit 1 | 
|---|
| 610 |   fi | 
|---|
| 611 |  | 
|---|
| 612 |  | 
|---|
| 613 |   ############################################## | 
|---|
| 614 |   # Create the new version of the mmsdrfs file. | 
|---|
| 615 |   ############################################## | 
|---|
| 616 |   $rm -f $newsdrfs $nodefile $tsDiskFile | 
|---|
| 617 |   IFS=":" | 
|---|
| 618 |   exec 3<&- | 
|---|
| 619 |   exec 3< $mmsdrfsFile | 
|---|
| 620 |   while read -u3 sdrfsLine | 
|---|
| 621 |   do | 
|---|
| 622 |     # Parse the line. | 
|---|
| 623 |     set -f ; set -A v -- - $sdrfsLine ; set +f | 
|---|
| 624 |  | 
|---|
| 625 |     IFS="$IFS_sv"   # Restore the default IFS settings. | 
|---|
| 626 |  | 
|---|
| 627 |     # Change some of the fields depending on the type of line. | 
|---|
| 628 |     case ${v[$LINE_TYPE_Field]} in | 
|---|
| 629 |  | 
|---|
| 630 |       $VERSION_LINE )  # This is the global header line. | 
|---|
| 631 |         # Increment the generation number. | 
|---|
| 632 |         newGenNumber=${v[$SDRFS_GENNUM_Field]}+1 | 
|---|
| 633 |         v[$SDRFS_GENNUM_Field]=$newGenNumber | 
|---|
| 634 |         ;; | 
|---|
| 635 |  | 
|---|
| 636 |       $MEMBER_NODE ) | 
|---|
| 637 |         # Add the reliable node name to nodefile. | 
|---|
| 638 |         print -- "${v[$REL_HOSTNAME_Field]}" >> $nodefile | 
|---|
| 639 |         checkForErrors "writing to file $nodefile" $? | 
|---|
| 640 |  | 
|---|
| 641 |         # If this is the line for the node that is executing | 
|---|
| 642 |         # this command, set the preferredNode variable. | 
|---|
| 643 |         [[ ${v[$NODE_NUMBER_Field]} = $ourNodeNumber ]] &&  \ | 
|---|
| 644 |           preferredNode=${v[$REL_HOSTNAME_Field]} | 
|---|
| 645 |         ;; | 
|---|
| 646 |  | 
|---|
| 647 |       $SG_DISKS ) | 
|---|
| 648 |  | 
|---|
| 649 |         if [[ ${v[$DEV_NAME_Field]} = $deviceName ]] | 
|---|
| 650 |         then | 
|---|
| 651 |           # This is an SG_DISKS line that belongs to our filesystem. | 
|---|
| 652 |           # See if this disk is one of the disks to be included. | 
|---|
| 653 |           if [[ -n $failureGroup ]] | 
|---|
| 654 |           then | 
|---|
| 655 |             # Disks are to be included based on failure group. | 
|---|
| 656 |             if [[ ${v[$FAILURE_GROUP_Field]} = $failureGroup ]] | 
|---|
| 657 |             then | 
|---|
| 658 |               # Mark the disk as included. | 
|---|
| 659 |               v[$EXCLUDE_Field]=$includedDisk | 
|---|
| 660 |  | 
|---|
| 661 |               # Add the disk to the list of disks for tsfsctl. | 
|---|
| 662 |               print -- "${v[$DISK_NAME_Field]}" >> $tsDiskFile | 
|---|
| 663 |               checkForErrors "writing to file $tsDiskFile" $? | 
|---|
| 664 |             fi  # end if [[ ${v[$FAILURE_GROUP_Field]} = $failureGroup ]] | 
|---|
| 665 |  | 
|---|
| 666 |           else | 
|---|
| 667 |             # The disks to be included are specified in the disksToInclude list. | 
|---|
| 668 |             tempList="" | 
|---|
| 669 |             includeThisDisk=no | 
|---|
| 670 |             for diskName in $disksToInclude | 
|---|
| 671 |             do | 
|---|
| 672 |               if [[ $diskName = ${v[$DISK_NAME_Field]} ]] | 
|---|
| 673 |               then | 
|---|
| 674 |                 # The disk represented by the current SG_DISKS line | 
|---|
| 675 |                 # is one of the disks that must be included. | 
|---|
| 676 |                 if [[ $includeThisDisk = no ]] | 
|---|
| 677 |                 then | 
|---|
| 678 |                   # Mark the disk as included. | 
|---|
| 679 |                   v[$EXCLUDE_Field]=$includedDisk | 
|---|
| 680 |                   includeThisDisk=yes | 
|---|
| 681 |  | 
|---|
| 682 |                   # Add the disk to the list of disks for tsfsctl. | 
|---|
| 683 |                   print -- "${v[$DISK_NAME_Field]}" >> $tsDiskFile | 
|---|
| 684 |                   checkForErrors "writing to file $tsDiskFile" $? | 
|---|
| 685 |                 else | 
|---|
| 686 |                   # We have already seen this name during the current iteration. | 
|---|
| 687 |                   # It must be a duplicate entry in the command line list. | 
|---|
| 688 |                   printErrorMsg 88 $mmcmd $diskName | 
|---|
| 689 |                   cleanupAndExit | 
|---|
| 690 |                 fi  # end of if [[ $includeThisDisk = no ]] | 
|---|
| 691 |  | 
|---|
| 692 |               else | 
|---|
| 693 |                 # diskName does not match the name of the disk in the current | 
|---|
| 694 |                 # SG_DISKS line.  Add diskName to the temporary list. | 
|---|
| 695 |                 tempList="$tempList $diskName" | 
|---|
| 696 |               fi  # end of if [[ $diskName = ${v[$DISK_NAME_Field]} ]] | 
|---|
| 697 |             done  # end of for diskName in $disksToInclude | 
|---|
| 698 |  | 
|---|
| 699 |             # If this disk will be included, its name does not appear in | 
|---|
| 700 |             # tempList.  In other words, tempList contains only the names of | 
|---|
| 701 |             # the disks that are to be included but for which the corresponding | 
|---|
| 702 |             # SG_LINES have not been encountered yet.  Initialize the list | 
|---|
| 703 |             # for the next iteration. | 
|---|
| 704 |             disksToInclude=$tempList | 
|---|
| 705 |  | 
|---|
| 706 |           fi  # end of if [[ -n $failureGroup ]] | 
|---|
| 707 |  | 
|---|
| 708 |         fi  # end of if [[ ${v[$DEV_NAME_Field]} = $deviceName ]] | 
|---|
| 709 |         ;; | 
|---|
| 710 |  | 
|---|
| 711 |       * )  # Pass all other lines without a change. | 
|---|
| 712 |         ;; | 
|---|
| 713 |  | 
|---|
| 714 |     esac  # end of "Change some of the fields . . . " | 
|---|
| 715 |  | 
|---|
| 716 |     # Build and write the line to the new mmsdrfs file. | 
|---|
| 717 |     print_newLine >> $newsdrfs | 
|---|
| 718 |     checkForErrors "writing to file $newsdrfs" $? | 
|---|
| 719 |  | 
|---|
| 720 |     IFS=":"  # Change the separator back to ":" for the next iteration. | 
|---|
| 721 |  | 
|---|
| 722 |   done  # end while read -u3 sdrfsLine | 
|---|
| 723 |  | 
|---|
| 724 |   IFS="$IFS_sv"  # Restore the default IFS settings. | 
|---|
| 725 |  | 
|---|
| 726 |   # If there are still entries left in the disksToInclude list, this means | 
|---|
| 727 |   # that the user-specified disks that do not belong to the file system. | 
|---|
| 728 |   if [[ -n $disksToInclude ]] | 
|---|
| 729 |   then | 
|---|
| 730 |     for diskName in $disksToInclude | 
|---|
| 731 |     do | 
|---|
| 732 |       printErrorMsg 315 $mmcmd $diskName $device | 
|---|
| 733 |     done | 
|---|
| 734 |     cleanupAndExit | 
|---|
| 735 |   fi | 
|---|
| 736 |  | 
|---|
| 737 |  | 
|---|
| 738 |   ############################## | 
|---|
| 739 |   # Invoke the tsfsctl command. | 
|---|
| 740 |   ############################## | 
|---|
| 741 |   $mmcommon onactive $preferredNode $nodefile                       \ | 
|---|
| 742 |                      $tsDiskFile $NO_MOUNT_CHECK NULL $NO_LINK      \ | 
|---|
| 743 |                      tsfsctl "$fqDeviceName include -F $tsDiskFile" | 
|---|
| 744 |   rc=$? | 
|---|
| 745 |   if [[ $rc -ne 0 ]] | 
|---|
| 746 |   then | 
|---|
| 747 |     # tsfsctl failed. | 
|---|
| 748 |     printErrorMsg 104 "$mmcmd" "tsfsctl include" | 
|---|
| 749 |     cleanupAndExit $rc | 
|---|
| 750 |   fi | 
|---|
| 751 |  | 
|---|
| 752 |  | 
|---|
| 753 |   ############################### | 
|---|
| 754 |   # Commit the new mmsdrfs file. | 
|---|
| 755 |   ############################### | 
|---|
| 756 |   trap "" HUP INT QUIT KILL | 
|---|
| 757 |   gpfsObjectInfo=$(commitChanges  \ | 
|---|
| 758 |      $nodesetId $nsId $gpfsObjectInfo $newGenNumber $newsdrfs $primaryServer) | 
|---|
| 759 |   rc=$? | 
|---|
| 760 |   if [[ $rc -ne 0 ]] | 
|---|
| 761 |   then | 
|---|
| 762 |     # We were unable to replace the file in the sdr. | 
|---|
| 763 |     printErrorMsg 381 $mmcmd | 
|---|
| 764 |     cleanupAndExit | 
|---|
| 765 |   fi | 
|---|
| 766 |  | 
|---|
| 767 |  | 
|---|
| 768 |   ################## | 
|---|
| 769 |   # Unlock the sdr. | 
|---|
| 770 |   ################## | 
|---|
| 771 |   [[ $sdrLocked = yes ]] &&  \ | 
|---|
| 772 |     freeLockOnServer $primaryServer $ourNodeNumber >/dev/null | 
|---|
| 773 |   sdrLocked=no | 
|---|
| 774 |   trap localPosttrap HUP INT QUIT KILL | 
|---|
| 775 |  | 
|---|
| 776 |  | 
|---|
| 777 |   ################################################################## | 
|---|
| 778 |   # Propagate the new mmsdrfs file.  This process is asynchronous. | 
|---|
| 779 |   ################################################################## | 
|---|
| 780 |   propagateSdrfsFile async $nodefile $newsdrfs $newGenNumber | 
|---|
| 781 |  | 
|---|
| 782 |   return $rc | 
|---|
| 783 |  | 
|---|
| 784 | }  #-------- end of function fsIncludeDisks ---------------------- | 
|---|
| 785 |  | 
|---|
| 786 |  | 
|---|
| 787 | ########################################################################### | 
|---|
| 788 | # | 
|---|
| 789 | # Function:  Synchronize the file system configuration information | 
|---|
| 790 | #            in the target cluster with the file system config data | 
|---|
| 791 | #            in the local cluster. | 
|---|
| 792 | # | 
|---|
| 793 | # Input:     None explicit.  This function uses the global variables | 
|---|
| 794 | #            remoteNodes, remoteCluster, and Sflag. | 
|---|
| 795 | # | 
|---|
| 796 | # Output:    None. | 
|---|
| 797 | # | 
|---|
| 798 | # Returns:   0 - no errors encountered | 
|---|
| 799 | #            1 - unexpected error | 
|---|
| 800 | # | 
|---|
| 801 | ########################################################################### | 
|---|
| 802 | function syncFSconfig  # (parms passed via global variables) | 
|---|
| 803 | { | 
|---|
| 804 |   typeset sourceFile="mmfsctl.sh" | 
|---|
| 805 |   [[ -n $DEBUG || -n $DEBUGsyncFSconfig ]] && set -x | 
|---|
| 806 |   $mmTRACE_ENTER "$*" | 
|---|
| 807 |  | 
|---|
| 808 |   typeset contactNodes nodeName | 
|---|
| 809 |   typeset rc=0 | 
|---|
| 810 |   typeset activeNodeFound="" | 
|---|
| 811 |  | 
|---|
| 812 |   fsExportData=${tmpDir}fsExportData.${mmcmd}.$$ | 
|---|
| 813 |   LOCAL_FILES="$LOCAL_FILES $fsExportData" | 
|---|
| 814 |  | 
|---|
| 815 |   # Determine where to send the data. | 
|---|
| 816 |   if [[ -n $remoteCluster ]] | 
|---|
| 817 |   then | 
|---|
| 818 |     # If a cluster name was specified, get the contact nodes | 
|---|
| 819 |     # from the mmsdrfs file. | 
|---|
| 820 |     contactNodes=$($mmcommon getContactNodes $remoteCluster) | 
|---|
| 821 |     $rm -f $nodefile | 
|---|
| 822 |     IFS="," | 
|---|
| 823 |     for nodeName in $contactNodes | 
|---|
| 824 |     do | 
|---|
| 825 |       [[ $nodeName != tcpPort* ]] &&  \ | 
|---|
| 826 |         print -- "$nodeName" >> $nodefile | 
|---|
| 827 |     done | 
|---|
| 828 |     IFS="$IFS_sv"  # Restore the default IFS settings. | 
|---|
| 829 |  | 
|---|
| 830 |     if [[ ! -s $nodefile ]] | 
|---|
| 831 |     then | 
|---|
| 832 |       # No contact nodes were provided for the cluster. | 
|---|
| 833 |       printErrorMsg 177 $mmcmd $remoteCluster | 
|---|
| 834 |       cleanupAndExit | 
|---|
| 835 |     fi | 
|---|
| 836 |   else | 
|---|
| 837 |     : # The contact nodes are in $nodefile (created by checkUserFile). | 
|---|
| 838 |   fi  # end if [[ -n $remoteCluster ]] | 
|---|
| 839 |  | 
|---|
| 840 |   # Extract the requested file system information from the local cluster. | 
|---|
| 841 |   # Collect the output in a file and show it only if there is an error. | 
|---|
| 842 | # printInfoMsg xyz $mmcmd | 
|---|
| 843 |   print -u2 "$mmcmd:  Exporting file system information from the source cluster . . ." | 
|---|
| 844 |   $mmexportfs $device -o $fsExportData -P | 
|---|
| 845 |   rc=$? | 
|---|
| 846 |   if [[ $rc -ne 0 ]] | 
|---|
| 847 |   then | 
|---|
| 848 |     printErrorMsg 389 "$mmcmd: mmexportfs" | 
|---|
| 849 |     cleanupAndExit | 
|---|
| 850 |   fi | 
|---|
| 851 |  | 
|---|
| 852 |   # Import the file system information into the remote cluster. | 
|---|
| 853 |   # Collect the output in a file and show it only if there is an error. | 
|---|
| 854 |   exec 3<&- | 
|---|
| 855 |   exec 3< $nodefile | 
|---|
| 856 |   while read -u3 nodeName | 
|---|
| 857 |   do | 
|---|
| 858 |     isNodeReachable $nodeName | 
|---|
| 859 |     [[ $? -ne 0 ]] && continue | 
|---|
| 860 |  | 
|---|
| 861 |     activeNodeFound=yes | 
|---|
| 862 | #   printInfoMsg wxy $mmcmd | 
|---|
| 863 |     print -u2 "$mmcmd:  Importing file system information into the target cluster on node $nodeName . . ." | 
|---|
| 864 |     $mmdsh -svL $nodeName -I $fsExportData  \ | 
|---|
| 865 |        "$mmimportfs $device -i $fsExportData $Sflag -R ; $rm -f $fsExportData" | 
|---|
| 866 |     rc=$? | 
|---|
| 867 |     [[ $rc -eq 0 ]] && break | 
|---|
| 868 |   done  # end of while read -u3 nodeName do | 
|---|
| 869 |  | 
|---|
| 870 |   # Did we fail to run mmimportfs succesfully anywhere? | 
|---|
| 871 |   if [[ $rc -ne 0 ]] | 
|---|
| 872 |   then | 
|---|
| 873 |     # The command failed.  Examine prior error messages. | 
|---|
| 874 |     printErrorMsg 389 "syncFSconfig: mmimportfs" | 
|---|
| 875 |     cleanupAndExit | 
|---|
| 876 |   fi | 
|---|
| 877 |  | 
|---|
| 878 |   if [[ -z $activeNodeFound ]] | 
|---|
| 879 |   then | 
|---|
| 880 |     if [[ -n $remoteCluster ]] | 
|---|
| 881 |     then | 
|---|
| 882 |       # None of the contact nodes in the cluster can be reached. | 
|---|
| 883 |       printErrorMsg 178 $mmcmd $remoteCluster | 
|---|
| 884 |     else | 
|---|
| 885 |       print -u2 "$mmcmd:  None of the nodes in the peer cluster can be reached." | 
|---|
| 886 |     fi | 
|---|
| 887 |     cleanupAndExit | 
|---|
| 888 |   fi | 
|---|
| 889 |  | 
|---|
| 890 |   return $rc | 
|---|
| 891 |  | 
|---|
| 892 | }  #------ end of function syncFSconfig --------------------- | 
|---|
| 893 |  | 
|---|
| 894 |  | 
|---|
| 895 |  | 
|---|
| 896 | ####################### | 
|---|
| 897 | # Mainline processing | 
|---|
| 898 | ####################### | 
|---|
| 899 |  | 
|---|
| 900 |  | 
|---|
| 901 | ###################################### | 
|---|
| 902 | # Process the command line arguments. | 
|---|
| 903 | ###################################### | 
|---|
| 904 | [[ $arg1 = '-?' || $arg1 = '-h' || $arg1 = '--help' || $arg1 = '--' ]] &&  \ | 
|---|
| 905 |   syntaxError "help" $usageMsg | 
|---|
| 906 |  | 
|---|
| 907 | # Process the positional parameters. | 
|---|
| 908 | device=$arg1 | 
|---|
| 909 | kword=$arg2 | 
|---|
| 910 | action=$arg2   # action keyword in lower case only | 
|---|
| 911 |  | 
|---|
| 912 | [[ -z $action ]] && syntaxError "missingArgs" $usageMsg | 
|---|
| 913 | shift 2    # Move past the fs name and action parameters. | 
|---|
| 914 |  | 
|---|
| 915 |  | 
|---|
| 916 | # Process the rest of the parameters. | 
|---|
| 917 | if [[ $action = suspend || $action = suspendandflush || $action = resume ]] | 
|---|
| 918 | then | 
|---|
| 919 |   [[ $# != 0 ]] && syntaxError "extraArg" $usageMsg $1 | 
|---|
| 920 |  | 
|---|
| 921 | elif [[ $action = exclude || $action = include ]] | 
|---|
| 922 | then | 
|---|
| 923 |   while getopts :d:F:G: OPT | 
|---|
| 924 |   do | 
|---|
| 925 |     case $OPT in | 
|---|
| 926 |  | 
|---|
| 927 |       d) [[ -n $dflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" | 
|---|
| 928 |          dflag="-$OPT" | 
|---|
| 929 |          [[ -n $Fflag || -n $Gflag ]] &&  \ | 
|---|
| 930 |            syntaxError "invalidCombination" $usageMsg $dflag $Fflag $Gflag | 
|---|
| 931 |          diskList="$OPTARG" | 
|---|
| 932 |          ;; | 
|---|
| 933 |  | 
|---|
| 934 |       F) [[ -n $Fflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" | 
|---|
| 935 |          Fflag="-$OPT" | 
|---|
| 936 |          [[ -n $dflag || -n $Gflag ]] &&  \ | 
|---|
| 937 |            syntaxError "invalidCombination" $usageMsg $dflag $Fflag $Gflag | 
|---|
| 938 |          Farg="$OPTARG" | 
|---|
| 939 |          ;; | 
|---|
| 940 |  | 
|---|
| 941 |       G) [[ -n $Gflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" | 
|---|
| 942 |          Gflag="-$OPT" | 
|---|
| 943 |          [[ -n $dflag || -n $Fflag ]] &&  \ | 
|---|
| 944 |            syntaxError "invalidCombination" $usageMsg $dflag $Fflag $Gflag | 
|---|
| 945 |          failureGroup=$(checkIntRange "-G" "$OPTARG") | 
|---|
| 946 |          [[ $? -ne 0 ]] && cleanupAndExit | 
|---|
| 947 |          ;; | 
|---|
| 948 |  | 
|---|
| 949 |        +[dfG]) # Invalid option. | 
|---|
| 950 |           syntaxError "invalidOption" $usageMsg $OPT | 
|---|
| 951 |           ;; | 
|---|
| 952 |  | 
|---|
| 953 |        :) # Missing argument. | 
|---|
| 954 |           syntaxError "missingValue" $usageMsg $OPTARG | 
|---|
| 955 |           ;; | 
|---|
| 956 |  | 
|---|
| 957 |        *) # Invalid option. | 
|---|
| 958 |           syntaxError "invalidOption" $usageMsg $OPTARG | 
|---|
| 959 |           ;; | 
|---|
| 960 |      esac | 
|---|
| 961 |   done | 
|---|
| 962 |   shift OPTIND-1 | 
|---|
| 963 |  | 
|---|
| 964 |   [[ -z $dflag && -z $Fflag && -z $Gflag ]] &&  \ | 
|---|
| 965 |     syntaxError "missingArgs" $usageMsg | 
|---|
| 966 |   [[ $# != 0 ]] && syntaxError "extraArg" $usageMsg $1 | 
|---|
| 967 |  | 
|---|
| 968 |   # If -F was specified, ensure the disk names file exists and is not empty. | 
|---|
| 969 |   if [[ -n $Fflag ]] | 
|---|
| 970 |   then | 
|---|
| 971 |     checkUserFile $Farg $tmpDiskFile | 
|---|
| 972 |     [[ $? -ne 0 ]] && cleanupAndExit | 
|---|
| 973 |     diskFile=$tmpDiskFile | 
|---|
| 974 |   fi  # end of if [[ -n $Fflag ]] | 
|---|
| 975 |  | 
|---|
| 976 | elif [[ $action = syncfsconfig ]] | 
|---|
| 977 | then | 
|---|
| 978 |   while getopts :C:n:S: OPT | 
|---|
| 979 |   do | 
|---|
| 980 |     case $OPT in | 
|---|
| 981 |       C) # Name of the target cluster. | 
|---|
| 982 |          [[ -n $Cflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" | 
|---|
| 983 |          remoteCluster=$OPTARG | 
|---|
| 984 |          Cflag=yes | 
|---|
| 985 |          ;; | 
|---|
| 986 |  | 
|---|
| 987 |       n) # Name of contact nodes file. | 
|---|
| 988 |          [[ -n $nflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" | 
|---|
| 989 |          narg=$OPTARG | 
|---|
| 990 |          nflag=yes | 
|---|
| 991 |          ;; | 
|---|
| 992 |  | 
|---|
| 993 |       S) # Name of disk specifications file. | 
|---|
| 994 |          [[ -n $Sflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" | 
|---|
| 995 |          Sflag="-S $OPTARG" | 
|---|
| 996 |          ;; | 
|---|
| 997 |  | 
|---|
| 998 |       :) syntaxError "missingValue" $usageMsg $OPTARG | 
|---|
| 999 |          ;; | 
|---|
| 1000 |  | 
|---|
| 1001 |       +[CnS]) syntaxError "invalidOption" $usageMsg $OPT | 
|---|
| 1002 |          ;; | 
|---|
| 1003 |  | 
|---|
| 1004 |       *) # Invalid option specified. | 
|---|
| 1005 |          syntaxError "invalidOption" $usageMsg $OPTARG | 
|---|
| 1006 |          ;; | 
|---|
| 1007 |     esac | 
|---|
| 1008 |   done | 
|---|
| 1009 |   shift OPTIND-1 | 
|---|
| 1010 |  | 
|---|
| 1011 |   [[ -n $Cflag && -n $nflag ]] &&  \ | 
|---|
| 1012 |     syntaxError "invalidCombination"  $usageMsg "-C" "-n" | 
|---|
| 1013 |   [[ -z $Cflag && -z $nflag ]] &&  \ | 
|---|
| 1014 |     syntaxError "missingArgs" $usageMsg | 
|---|
| 1015 |   [[ $# != 0 ]] && syntaxError "extraArg" $usageMsg $1 | 
|---|
| 1016 |  | 
|---|
| 1017 |   # If -n was specified, ensure the contact nodes file exist and is not empty. | 
|---|
| 1018 |   # This will also copy the names into $nodefile (needed by function syncfsconfig). | 
|---|
| 1019 |   if [[ -n $nflag ]] | 
|---|
| 1020 |   then | 
|---|
| 1021 |     checkUserFile $narg $nodefile | 
|---|
| 1022 |     [[ $? -ne 0 ]] && cleanupAndExit | 
|---|
| 1023 |   fi  # end of if [[ -n $nflag ]] | 
|---|
| 1024 |  | 
|---|
| 1025 | else | 
|---|
| 1026 |   syntaxError "keyword" $usageMsg $kword | 
|---|
| 1027 |  | 
|---|
| 1028 | fi  # end if [[ $action = suspend || $action = suspendandflush || $action = resume ]] | 
|---|
| 1029 |  | 
|---|
| 1030 |  | 
|---|
| 1031 | ################################################## | 
|---|
| 1032 | # Invoke the appropriate function to do the work. | 
|---|
| 1033 | ################################################## | 
|---|
| 1034 |  | 
|---|
| 1035 | case $action in | 
|---|
| 1036 |   suspend | suspendandflush | resume ) | 
|---|
| 1037 |     fsSuspendOrResume $device $action | 
|---|
| 1038 |     rc=$? | 
|---|
| 1039 |     ;; | 
|---|
| 1040 |  | 
|---|
| 1041 |   exclude ) | 
|---|
| 1042 |     fsExcludeDisks  # Parms are passed via global variables. | 
|---|
| 1043 |     rc=$? | 
|---|
| 1044 |     ;; | 
|---|
| 1045 |  | 
|---|
| 1046 |   include ) | 
|---|
| 1047 |     fsIncludeDisks  # Parms are passed via global variables. | 
|---|
| 1048 |     rc=$? | 
|---|
| 1049 |     ;; | 
|---|
| 1050 |  | 
|---|
| 1051 |   syncfsconfig ) | 
|---|
| 1052 |     syncFSconfig    # Parms are passed via global variables. | 
|---|
| 1053 |     rc=$? | 
|---|
| 1054 |     ;; | 
|---|
| 1055 |  | 
|---|
| 1056 |   *) syntaxError "keyword" $usageMsg $kword | 
|---|
| 1057 |     ;; | 
|---|
| 1058 | esac  # end case $action in | 
|---|
| 1059 |  | 
|---|
| 1060 | cleanupAndExit $rc | 
|---|
| 1061 |  | 
|---|