| 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. 2003,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 | # @(#)37 1.45.1.2 src/avs/fs/mmfs/ts/admin/mmimportfs.sh, mmfs, avs_rgpfs24, rgpfs24s002a 4/21/06 14:48:31 | 
|---|
| 17 | ############################################################################## | 
|---|
| 18 | # | 
|---|
| 19 | # Usage: | 
|---|
| 20 | #   mmimportfs {Device|all} -i ImportfsFile [-S ChangeSpecFile] [-R] | 
|---|
| 21 | # | 
|---|
| 22 | # where | 
|---|
| 23 | #   Device        is the file system to be imported. | 
|---|
| 24 | #                 If Device is "all", then all file systems in | 
|---|
| 25 | #                 the input file are imported.  Free disks, if any, | 
|---|
| 26 | #                 are imported as well. | 
|---|
| 27 | #                 Note:  To request a file system with the name "all", | 
|---|
| 28 | #                        specify "/dev/all" to distinguish from the | 
|---|
| 29 | #                        keyword "all" (import all file systems). | 
|---|
| 30 | # | 
|---|
| 31 | #   -i ImportfsFile   is the name of a file with the file system | 
|---|
| 32 | #                     information.  It must be created by mmexportfs. | 
|---|
| 33 | # | 
|---|
| 34 | #   -S ChangeSpecFile  a file containing a detailed description of changes | 
|---|
| 35 | #                 to be made to the file systems during the import step. | 
|---|
| 36 | # | 
|---|
| 37 | # Undocumented option: | 
|---|
| 38 | # | 
|---|
| 39 | #   -R            remove the specified file system from the mmsdrfs file | 
|---|
| 40 | #                 and replace it with the data from the import file. | 
|---|
| 41 | #                 If 'all' is specified, all file system and free disk | 
|---|
| 42 | #                 information that may currently exist is removed from | 
|---|
| 43 | #                 the mmsdrfs file and is replaced with the data from | 
|---|
| 44 | #                 the import file. | 
|---|
| 45 | # | 
|---|
| 46 | ############################################################################## | 
|---|
| 47 |  | 
|---|
| 48 | # Include global declarations and service routines. | 
|---|
| 49 | . /usr/lpp/mmfs/bin/mmglobfuncs | 
|---|
| 50 | . /usr/lpp/mmfs/bin/mmsdrfsdef | 
|---|
| 51 | . /usr/lpp/mmfs/bin/mmfsfuncs | 
|---|
| 52 |  | 
|---|
| 53 | sourceFile="mmimportfs.sh" | 
|---|
| 54 | [[ -n $DEBUG || -n $DEBUGmmimportfs ]] && set -x | 
|---|
| 55 | $mmTRACE_ENTER "$*" | 
|---|
| 56 |  | 
|---|
| 57 |  | 
|---|
| 58 | # Local work files.  Names should be of the form: | 
|---|
| 59 | #   fn=${tmpDir}fn.${mmcmd}.$$ | 
|---|
| 60 | existingDisks=${tmpDir}existingDisks.${mmcmd}.$$ | 
|---|
| 61 | recoveryFiles=${tmpDir}recoveryFiles.${mmcmd}.$$ | 
|---|
| 62 | importedFreeDisks=${tmpDir}importedFreeDisks.${mmcmd}.$$ | 
|---|
| 63 | resetFreeDisks=${tmpDir}resetFreeDisks.${mmcmd}.$$ | 
|---|
| 64 | disksToUnfence=${tmpDir}disksToUnfence.${mmcmd}.$$ | 
|---|
| 65 | aixNodes=${tmpDir}aixNodes.${mmcmd}.$$ | 
|---|
| 66 |  | 
|---|
| 67 | # The following declarations are the prefixes for the file names | 
|---|
| 68 | # that will contain information relevant to a specific file system. | 
|---|
| 69 | # The actual file names consist of the prefix followed by a device name. | 
|---|
| 70 | importFile=${tmpDir}importFile.${mmcmd}.$$ | 
|---|
| 71 | resetNSDs=${tmpDir}resetNSDs.${mmcmd}.$$ | 
|---|
| 72 | resetLVs=${tmpDir}resetLVs.${mmcmd}.$$ | 
|---|
| 73 |  | 
|---|
| 74 | LOCAL_FILES=" $existingDisks $recoveryFiles $importedFreeDisks $resetFreeDisks \ | 
|---|
| 75 |               $aixNodes $disksToUnfence $importFile.* $resetNSDs.* $resetLVs.* " | 
|---|
| 76 |  | 
|---|
| 77 | # Local variable declarations | 
|---|
| 78 | usageMsg=571 | 
|---|
| 79 | iflag="" | 
|---|
| 80 | Cflag="" | 
|---|
| 81 | Sflag="" | 
|---|
| 82 |  | 
|---|
| 83 | existingMountPoints="" | 
|---|
| 84 | maxDiskNumber=0 | 
|---|
| 85 |  | 
|---|
| 86 | # Local functions: | 
|---|
| 87 |  | 
|---|
| 88 |  | 
|---|
| 89 | ############################################################################## | 
|---|
| 90 | # | 
|---|
| 91 | # Function:  Given the source and target cluster types, determine whether | 
|---|
| 92 | #            the present version of mmimportfs can import the file system. | 
|---|
| 93 | # | 
|---|
| 94 | #            Note:  Not all possible cluster type combinations are supported. | 
|---|
| 95 | #                   In some cases, simplifying assumptions are made. | 
|---|
| 96 | # | 
|---|
| 97 | # Input:     $1 - source cluster type | 
|---|
| 98 | #            $2 - target cluster type | 
|---|
| 99 | # | 
|---|
| 100 | # Output:    None | 
|---|
| 101 | # | 
|---|
| 102 | # Returns:   0 - the two cluster types are compatible. | 
|---|
| 103 | #            1 - the two cluster types are not compatible. | 
|---|
| 104 | # | 
|---|
| 105 | ############################################################################## | 
|---|
| 106 | function checkClusterCompatibility  # <source> <target> | 
|---|
| 107 | { | 
|---|
| 108 |   sourceFile="mmimportfs.sh" | 
|---|
| 109 |   [[ -n $DEBUG || -n $DEBUGcheckClusterCompatibility ]] && set -x | 
|---|
| 110 |   $mmTRACE_ENTER "$*" | 
|---|
| 111 |  | 
|---|
| 112 |   typeset source=$1 | 
|---|
| 113 |   typeset target=$2 | 
|---|
| 114 |  | 
|---|
| 115 |   typeset rc | 
|---|
| 116 |  | 
|---|
| 117 |   case $source in | 
|---|
| 118 |     lc ) | 
|---|
| 119 |       [[ $target = lc     ]] && rc=0 | 
|---|
| 120 |       [[ $target = single ]] && rc=0 | 
|---|
| 121 |       ;; | 
|---|
| 122 |  | 
|---|
| 123 |     sp ) | 
|---|
| 124 |       [[ $target = lc     ]] && rc=0 | 
|---|
| 125 |       [[ $target = single ]] && rc=0 | 
|---|
| 126 |       ;; | 
|---|
| 127 |  | 
|---|
| 128 |     rpd ) | 
|---|
| 129 |       [[ $target = lc     ]] && rc=0 | 
|---|
| 130 |       [[ $target = single ]] && rc=0 | 
|---|
| 131 |       ;; | 
|---|
| 132 |  | 
|---|
| 133 |     hacmp ) | 
|---|
| 134 |       [[ $target = lc     ]] && rc=0 | 
|---|
| 135 |       [[ $target = single ]] && rc=0 | 
|---|
| 136 |       ;; | 
|---|
| 137 |  | 
|---|
| 138 |     single ) | 
|---|
| 139 |       [[ $target = lc     ]] && rc=0 | 
|---|
| 140 |       [[ $target = single ]] && rc=0 | 
|---|
| 141 |       ;; | 
|---|
| 142 |  | 
|---|
| 143 |      * ) | 
|---|
| 144 |       # Unknown source cluster type. | 
|---|
| 145 |       rc=1 | 
|---|
| 146 |       ;; | 
|---|
| 147 |   esac | 
|---|
| 148 |  | 
|---|
| 149 |   return $rc | 
|---|
| 150 |  | 
|---|
| 151 | }  #----- end of function checkClusterCompatibility ---------------- | 
|---|
| 152 |  | 
|---|
| 153 |  | 
|---|
| 154 | ########################################################################### | 
|---|
| 155 | # | 
|---|
| 156 | # Function:  See if there are any disks that will need to be recovered | 
|---|
| 157 | #            because of a previous failure of mmimportfs. | 
|---|
| 158 | # | 
|---|
| 159 | # Input:     $1 - source cluster type | 
|---|
| 160 | #            $2 - output file name | 
|---|
| 161 | # | 
|---|
| 162 | # Output:    File containing the disk names that may have failed a previous | 
|---|
| 163 | #            tspreparedisk -m call.  Each line has the following format: | 
|---|
| 164 | #              <diskName> <checksum> <timestamp> <server> <fullPathName> | 
|---|
| 165 | # | 
|---|
| 166 | # Returns:   0 - no errors | 
|---|
| 167 | #            1 - error encountered | 
|---|
| 168 | # | 
|---|
| 169 | ########################################################################### | 
|---|
| 170 | function getDiskRecoveryInformation  # <source> <outputFile> | 
|---|
| 171 | { | 
|---|
| 172 |   sourceFile="mmimportfs.sh" | 
|---|
| 173 |   [[ -n $DEBUG || -n $DEBUGgetDiskRecoveryInformation ]] && set -x | 
|---|
| 174 |   $mmTRACE_ENTER "$*" | 
|---|
| 175 |  | 
|---|
| 176 |   typeset source=$1 | 
|---|
| 177 |   typeset outputFile=$2 | 
|---|
| 178 |  | 
|---|
| 179 |   typeset server | 
|---|
| 180 |  | 
|---|
| 181 |   $rm -f $outputFile | 
|---|
| 182 |  | 
|---|
| 183 |   # If we are not creating NSDs, there is nothing to worry about. | 
|---|
| 184 |   [[ $source = lc || $source = single ]] &&  \ | 
|---|
| 185 |     return 0 | 
|---|
| 186 |  | 
|---|
| 187 |   # Create a list of all disk recovery files created by tspreparedisk. | 
|---|
| 188 |   # Such files, if any, will be stored in /var/mmfs/tmp/mmimportfs on | 
|---|
| 189 |   # the primary and backup server configuration nodes.  The file names | 
|---|
| 190 |   # have the following format: | 
|---|
| 191 |   #   tspreparedisk.diskDesc.<diskName>.<checksum>.<timestamp> | 
|---|
| 192 |   # | 
|---|
| 193 |   # Put the results in a file with the following format: | 
|---|
| 194 |   #   <diskName> <checksum> <timestamp> <server> <fullPathName> | 
|---|
| 195 |   # | 
|---|
| 196 |   for server in $(print -- $primaryServer $backupServer) | 
|---|
| 197 |   do | 
|---|
| 198 |     run onNode $server lsSGDescFile 2>/dev/null |  \ | 
|---|
| 199 |       $awk -F. ' | 
|---|
| 200 |         { print $3" "$4" "$5" '${server}' "$0 } | 
|---|
| 201 |       ' >> $outputFile | 
|---|
| 202 |   done | 
|---|
| 203 |  | 
|---|
| 204 |   # Sort the result so that if there is more than one recovery file | 
|---|
| 205 |   # for any given disk, the most recent version appears first. | 
|---|
| 206 |   $sort -k 1,1 -k 3,3nr -o $outputFile $outputFile | 
|---|
| 207 |   checkForErrors "sort $outputFile" $? | 
|---|
| 208 |  | 
|---|
| 209 |   return 0 | 
|---|
| 210 |  | 
|---|
| 211 | }  #----- end of function getDiskRecoveryInformation --------------- | 
|---|
| 212 |  | 
|---|
| 213 |  | 
|---|
| 214 | ######################################################################### | 
|---|
| 215 | # | 
|---|
| 216 | # Function:  Restore the disk and SG descriptors of the specified disk. | 
|---|
| 217 | # | 
|---|
| 218 | # Input:     $1 - diskName | 
|---|
| 219 | #            $2 - file created by function getDiskRecoveryInformation | 
|---|
| 220 | # | 
|---|
| 221 | # Output:    None. | 
|---|
| 222 | # | 
|---|
| 223 | # Returns:   0 - no errors | 
|---|
| 224 | #            1 - error encountered | 
|---|
| 225 | # | 
|---|
| 226 | ######################################################################### | 
|---|
| 227 | function recoverOldSGdescriptor  # <diskName> <recoveryInfoFile> | 
|---|
| 228 | { | 
|---|
| 229 |   sourceFile="mmimportfs.sh" | 
|---|
| 230 |   [[ -n $DEBUG || -n $DEBUGrecoverOldSGdescriptor ]] && set -x | 
|---|
| 231 |   $mmTRACE_ENTER "$*" | 
|---|
| 232 |  | 
|---|
| 233 |   typeset diskName=$1 | 
|---|
| 234 |   typeset recoveryInfoFile=$2 | 
|---|
| 235 |  | 
|---|
| 236 |   typeset recoveryInfo checksum serverNode fqName sumOutput newSum | 
|---|
| 237 |   typeset rc=0 | 
|---|
| 238 |  | 
|---|
| 239 |   # See if there is a recovery file for this disk. | 
|---|
| 240 |   recoveryInfo=$($grep -w $diskName $recoveryInfoFile) | 
|---|
| 241 |  | 
|---|
| 242 |   # Return if there is nothing to do. | 
|---|
| 243 |   [[ -z $recoveryInfo ]] &&  \ | 
|---|
| 244 |     return 0 | 
|---|
| 245 |  | 
|---|
| 246 |   print -u2 -- "$mmcmd: Recovering SG descriptor area of disk $diskName" | 
|---|
| 247 |  | 
|---|
| 248 |   # Parse the information from the recoveryInfoFile. | 
|---|
| 249 |   set -f ; set -- $recoveryInfo ; set +f | 
|---|
| 250 |   checksum=$2 | 
|---|
| 251 |   serverNode=$4 | 
|---|
| 252 |   fqName=$5 | 
|---|
| 253 |  | 
|---|
| 254 |   # Retrieve the file if it isn't already on our node. | 
|---|
| 255 |   if [[ ! -e $fqName ]] | 
|---|
| 256 |   then | 
|---|
| 257 |     # Ensure the target directory for rcp exists. | 
|---|
| 258 |     $mkdir -p ${fqName%/*} | 
|---|
| 259 |  | 
|---|
| 260 |     # Copy the file from the server node. | 
|---|
| 261 |     $rcp ${serverNode}:${fqName} $fqName | 
|---|
| 262 |     checkForErrors "rcp ${serverNode}:${fqName}" $? | 
|---|
| 263 |  | 
|---|
| 264 |     # Verify the checksum. | 
|---|
| 265 |     sumOutput=$($sum $fqName) | 
|---|
| 266 |     rc=$? | 
|---|
| 267 |     set -f ; set -- $sumOutput ; set +f | 
|---|
| 268 |     newSum=$1 | 
|---|
| 269 |     if [[ $checksum != $newSum ]] | 
|---|
| 270 |     then | 
|---|
| 271 |       printErrorMsg 379 $mmcmd $serverNode $ourNodeName | 
|---|
| 272 |       return 1 | 
|---|
| 273 |     fi | 
|---|
| 274 |   fi  # end of if [[ ! -e $fqName ]] | 
|---|
| 275 |  | 
|---|
| 276 |   # Restore the disk and SG descriptors of the disk. | 
|---|
| 277 |   $dd if=$fqName of=/dev/$diskName seek=1 2>$errMsg | 
|---|
| 278 |   rc=$? | 
|---|
| 279 |   if [[ $rc -ne 0 ]] | 
|---|
| 280 |   then | 
|---|
| 281 |     [[ -s $errMsg ]] && $cat $errMsg 1>&2 | 
|---|
| 282 |     $rm -f $errMsg | 
|---|
| 283 |     print -u2 "$mmcmd: dd if=$fqName of=/dev/$diskName seek=1 failed with rc $rc." | 
|---|
| 284 |     print -u2 "$mmcmd: Error recovering disk $diskName from a previous failure." | 
|---|
| 285 |     return $rc | 
|---|
| 286 |   fi | 
|---|
| 287 |   $rm -f $errMsg | 
|---|
| 288 |  | 
|---|
| 289 |   print -u2 -- "$mmcmd: Disk $diskName successfully recovered." | 
|---|
| 290 |  | 
|---|
| 291 |   # At this point the disk was successfully restored. | 
|---|
| 292 |   # Remove all SG descriptor files for this disk and return. | 
|---|
| 293 |   $rm -f ${fqName%/*}/tspreparedisk.diskDesc.${diskName}.* | 
|---|
| 294 |   for server in $(print -- $primaryServer $backupServer) | 
|---|
| 295 |   do | 
|---|
| 296 |     run onNode $server rmSGDescFile $diskName | 
|---|
| 297 |   done | 
|---|
| 298 |  | 
|---|
| 299 |   return 0 | 
|---|
| 300 |  | 
|---|
| 301 | }  #----- end of function recoverOldSGdescriptor ------------------- | 
|---|
| 302 |  | 
|---|
| 303 |  | 
|---|
| 304 | ############################################################################ | 
|---|
| 305 | # | 
|---|
| 306 | # Function:  Import a disk into cluster type single.  Depending on the | 
|---|
| 307 | #            source cluster types, this may also involve the conversion | 
|---|
| 308 | #            of the disk into an NSD. | 
|---|
| 309 | # | 
|---|
| 310 | #            Note:  The disk is assumed to be accessible on the local node. | 
|---|
| 311 | # | 
|---|
| 312 | # Input:     $1 - source cluster type | 
|---|
| 313 | #            $2 - current SG_DISKS line for the disk | 
|---|
| 314 | #            $3 - target nodesetId | 
|---|
| 315 | # | 
|---|
| 316 | # Output:    $1 - result: error, success. | 
|---|
| 317 | #            $2 - updated SG_DISKS line. | 
|---|
| 318 | # | 
|---|
| 319 | # Returns:   0 - everything worked OK | 
|---|
| 320 | #            1 - error encountered | 
|---|
| 321 | # | 
|---|
| 322 | ############################################################################ | 
|---|
| 323 | function importDisk_single  # <source> <diskLine> <targetNodeset> | 
|---|
| 324 | { | 
|---|
| 325 |   sourceFile="mmimportfs.sh" | 
|---|
| 326 |   [[ -n $DEBUG || -n $DEBUGimportDisk_single ]] && set -x | 
|---|
| 327 |   $mmTRACE_ENTER "$*" | 
|---|
| 328 |  | 
|---|
| 329 |   typeset sourceCluster=$1 | 
|---|
| 330 |   typeset currentDiskLine=$2 | 
|---|
| 331 |   typeset targetNodesetId=$3 | 
|---|
| 332 |  | 
|---|
| 333 |   typeset rc=0 | 
|---|
| 334 |   typeset result="success" | 
|---|
| 335 |   typeset invokingCommand="mmimportfs" | 
|---|
| 336 |   typeset updatedDiskLine createNsdOutput tspreparediskOutput | 
|---|
| 337 |   typeset diskName magicWord rc2 pvid nsdSubtype nsdSubtypeDiskname | 
|---|
| 338 |  | 
|---|
| 339 |   # Parse the current SG_DISKS line for the disk. | 
|---|
| 340 |   IFS=":" | 
|---|
| 341 |   set -f ; set -A v -- - $currentDiskLine ; set +f | 
|---|
| 342 |   IFS="$IFS_sv" | 
|---|
| 343 |   diskName=${v[$DISK_NAME_Field]} | 
|---|
| 344 |   [[ -z ${v[$NSD_SUBTYPE_Field]} ]] &&  \ | 
|---|
| 345 |     v[$NSD_SUBTYPE_Field]="generic" | 
|---|
| 346 |   nsdSubtype=${v[$NSD_SUBTYPE_Field]} | 
|---|
| 347 |   aixPvidValue=${v[$PVID_Field]} | 
|---|
| 348 |   [[ ${v[$NODESETID_Field]} = $FREE_DISK ]] &&  \ | 
|---|
| 349 |     invokingCommand="mmimportfs_freeDisk" | 
|---|
| 350 |   [[ ${v[$NODESETID_Field]} != $FREE_DISK ]] &&  \ | 
|---|
| 351 |     v[$NODESETID_Field]=$targetNodesetId | 
|---|
| 352 |  | 
|---|
| 353 |   if [[ $sourceCluster != lc && $sourceCluster != single ]] | 
|---|
| 354 |   then | 
|---|
| 355 |     # The source cluster type is sp, rpd, or hacmp. | 
|---|
| 356 |     # In all of these cases we may have to import | 
|---|
| 357 |     # the underlying logical volumes and, if applicable, | 
|---|
| 358 |     # recreate the VSDs. | 
|---|
| 359 |  | 
|---|
| 360 |     # For now, we assume that the disks are already in place. | 
|---|
| 361 |  | 
|---|
| 362 |     # See if this disk needs to be recovered from a previous | 
|---|
| 363 |     # partial SG descriptor migration. | 
|---|
| 364 |     if [[ -s $recoveryFiles ]] | 
|---|
| 365 |     then | 
|---|
| 366 |       recoverOldSGdescriptor $diskName $recoveryFiles | 
|---|
| 367 |       rc=$? | 
|---|
| 368 |       if [[ $rc -ne 0 ]] | 
|---|
| 369 |       then | 
|---|
| 370 |         print -- "error" | 
|---|
| 371 |         return $rc | 
|---|
| 372 |       fi | 
|---|
| 373 |     fi | 
|---|
| 374 |  | 
|---|
| 375 |     # Convert the disk into an NSD. | 
|---|
| 376 |     createNsdOutput=$(createNsd $diskName no $invokingCommand NULL) | 
|---|
| 377 |     rc=$? | 
|---|
| 378 |  | 
|---|
| 379 |     # The output of createNsd consists of a one-word NSD subtype value, | 
|---|
| 380 |     # followed by the output from tspreparedisk.  Separate the two parts. | 
|---|
| 381 |     nsdSubtype=${createNsdOutput%% *} | 
|---|
| 382 |     tspreparediskOutput=${createNsdOutput#* } | 
|---|
| 383 |  | 
|---|
| 384 |     # Set the value for the nsd subtype diskname if the nsd subtype | 
|---|
| 385 |     # is lv or vsd. | 
|---|
| 386 |     nsdSubtypeDiskname="" | 
|---|
| 387 |     [[ $nsdSubtype = lv || $nsdSubtype = vsd ]] && nsdSubtypeDiskname=$diskName | 
|---|
| 388 |  | 
|---|
| 389 |     # Parse the output from the tspreparedisk command. | 
|---|
| 390 |     IFS=":" | 
|---|
| 391 |     set -f ; set -- $tspreparediskOutput ; set +f | 
|---|
| 392 |     magicWord=$1 | 
|---|
| 393 |     rc2=$2 | 
|---|
| 394 |     pvid=$3 | 
|---|
| 395 |     IFS="$IFS_sv" | 
|---|
| 396 |  | 
|---|
| 397 |     if [[ $rc  -ne 0 || $nsdSubtype = error || | 
|---|
| 398 |           $rc2 -ne 0 || $magicWord != tspreparedisk ]] | 
|---|
| 399 |     then | 
|---|
| 400 |       # Try to make sense of the error. | 
|---|
| 401 |       if [[ $nsdSubtype = error ]] | 
|---|
| 402 |       then | 
|---|
| 403 |         : # determineNsdSubtype failed.  Messages were already issued. | 
|---|
| 404 |  | 
|---|
| 405 |       elif [[ $magicWord = tspreparedisk ]] | 
|---|
| 406 |       then | 
|---|
| 407 |         # tspreparedisk was executed but was not happy about something. | 
|---|
| 408 |         if [[ $rc2 = 1 ]]       # E_PERM | 
|---|
| 409 |         then | 
|---|
| 410 |           # Permission was denied for disk. | 
|---|
| 411 |           printErrorMsg 523 $mmcmd "/dev/$diskName" | 
|---|
| 412 |         elif [[ $rc2 = 2 ]]     # E_NOENT | 
|---|
| 413 |         then | 
|---|
| 414 |           # The disk was not found. | 
|---|
| 415 |           printErrorMsg 524 $mmcmd "/dev/$diskName" | 
|---|
| 416 |         elif [[ $rc2 = 5 ]]     # E_IO | 
|---|
| 417 |         then | 
|---|
| 418 |           # I/O error | 
|---|
| 419 |           printErrorMsg 525 $mmcmd "/dev/$diskName" | 
|---|
| 420 |         elif [[ $rc2 = $MM_DeviceNotFound ]]    # E_NODEV | 
|---|
| 421 |         then | 
|---|
| 422 |           # A return code of ENODEV was returned for the disk. | 
|---|
| 423 |           printErrorMsg 187 $mmcmd $ourNodeName "/dev/$diskName" | 
|---|
| 424 |         elif [[ $rc2 = 27 ]]    # E_FBIG | 
|---|
| 425 |         then | 
|---|
| 426 |           # The disk is too large. | 
|---|
| 427 |           printErrorMsg 508 $mmcmd "/dev/$diskName" | 
|---|
| 428 |         elif [[ $rc2 = 50 ]]    # E_NOCONNECT | 
|---|
| 429 |         then | 
|---|
| 430 |           # The disk is fenced out. | 
|---|
| 431 |           printErrorMsg 395 $mmcmd $ourNodeName "/dev/$diskName" | 
|---|
| 432 |         else | 
|---|
| 433 |           # Show the result from tspreparedisk. | 
|---|
| 434 |           print -u2 "$tspreparediskOutput" | 
|---|
| 435 |           # Unexpected error from tspreparedisk | 
|---|
| 436 |           printErrorMsg 171 "$mmcmd" "tspreparedisk $diskName" $rc2 | 
|---|
| 437 |         fi  # end if [[ $rc2 = 1 ]] | 
|---|
| 438 |       else | 
|---|
| 439 |         # Something is really wrong.  Output error information if any. | 
|---|
| 440 |         [[ -n $createNsdOutput ]] && print -u2 "$createNsdOutput" | 
|---|
| 441 |       fi  # end if [[ $nsdSubtype = error ]] | 
|---|
| 442 |  | 
|---|
| 443 |       # We failed to create an NSD from this disk. | 
|---|
| 444 |       printErrorMsg 47 $mmcmd $diskName | 
|---|
| 445 |       result="error" | 
|---|
| 446 |       rc=1 | 
|---|
| 447 |  | 
|---|
| 448 |     else | 
|---|
| 449 |       # At this point the disk was successfully defined as an NSD. | 
|---|
| 450 |       # Add the missing or updated information. | 
|---|
| 451 |       v[$PVID_Field]=$pvid | 
|---|
| 452 |       v[$NSD_SUBTYPE_Field]=$nsdSubtype | 
|---|
| 453 |       v[$NSD_SUBTYPE_DISKNAME_Field]=$nsdSubtypeDiskname | 
|---|
| 454 |       if [[ $nsdSubtype = lv ]] | 
|---|
| 455 |       then | 
|---|
| 456 |         v[$AIX_PVID_Field]=$aixPvidValue | 
|---|
| 457 |       else | 
|---|
| 458 |         v[$AIX_PVID_Field]="" | 
|---|
| 459 |       fi | 
|---|
| 460 |  | 
|---|
| 461 |       # Remove any leftover files from tspreparedisk -m. | 
|---|
| 462 |       $rm -f ${fqName%/*}/tspreparedisk.diskDesc.${diskName}.* | 
|---|
| 463 |     fi  # end if [[ $rc  -ne 0 || $nsdSubtype = error ||  ... | 
|---|
| 464 |   fi  # end of if [[ $sourceCluster != lc && $sourceCluster != single ]] | 
|---|
| 465 |  | 
|---|
| 466 |   # Ensure certain fields in the SG_DISKS line have | 
|---|
| 467 |   # appropriate values for cluster type single. | 
|---|
| 468 |   v[$NSD_PRIMARY_NODE_Field]="" | 
|---|
| 469 |   v[$NSD_BACKUP_NODE_Field]="" | 
|---|
| 470 |   v[$DAEMON_NSD_PRIMARY_Field]="" | 
|---|
| 471 |   v[$DAEMON_NSD_BACKUP_Field]="" | 
|---|
| 472 |   v[$DISK_TYPE_Field]="disk" | 
|---|
| 473 |   updatedDiskLine=$(print_newLine) | 
|---|
| 474 |  | 
|---|
| 475 |   # Return to the caller the updated SG_DISKS line. | 
|---|
| 476 |   print -- "$result" "$updatedDiskLine" | 
|---|
| 477 |   return $rc | 
|---|
| 478 |  | 
|---|
| 479 | }  #----- end of function importDisk_single ------------------------ | 
|---|
| 480 |  | 
|---|
| 481 |  | 
|---|
| 482 | ########################################################################### | 
|---|
| 483 | # | 
|---|
| 484 | # Function:  Import a disk into an lc cluster.  Depending on the source | 
|---|
| 485 | #            cluster types, this may involve one or more of the following | 
|---|
| 486 | #            operations to make the disk usable in the new cluster: | 
|---|
| 487 | #            import the base logical volume, make/redefine a VSD, | 
|---|
| 488 | #            make an NSD out of the disk, verify NSD servers belong | 
|---|
| 489 | #            to the right nodeset, etc. | 
|---|
| 490 | # | 
|---|
| 491 | # Input:     $1 - source cluster type | 
|---|
| 492 | #            $2 - current SG_DISKS line for the disk | 
|---|
| 493 | #            $3 - target nodesetId | 
|---|
| 494 | #            $4 - (optional) disk descriptor spec file | 
|---|
| 495 | # | 
|---|
| 496 | # Output:    $1 - result; error, success, successServersRemoved. | 
|---|
| 497 | #            $2 - updated SG_DISKS line. | 
|---|
| 498 | # | 
|---|
| 499 | # Returns:   0 - everything worked OK | 
|---|
| 500 | #            1 - error encountered | 
|---|
| 501 | # | 
|---|
| 502 | ########################################################################### | 
|---|
| 503 | function importDisk_lc  # <source> <diskLine> <targetNodeset> [<specFile>] | 
|---|
| 504 | { | 
|---|
| 505 |   sourceFile="mmimportfs.sh" | 
|---|
| 506 |   [[ -n $DEBUG || -n $DEBUGimportDisk_lc ]] && set -x | 
|---|
| 507 |   $mmTRACE_ENTER "$*" | 
|---|
| 508 |  | 
|---|
| 509 |   typeset sourceCluster=$1 | 
|---|
| 510 |   typeset currentDiskLine=$2 | 
|---|
| 511 |   typeset targetNodesetId=$3 | 
|---|
| 512 |   typeset specFile=$4 | 
|---|
| 513 |  | 
|---|
| 514 |   typeset rc=0 | 
|---|
| 515 |   typeset diskDesc="" | 
|---|
| 516 |   typeset result="success" | 
|---|
| 517 |   typeset invokingCommand="mmimportfs" | 
|---|
| 518 |   typeset diskName server backup nodesetId validateDescriptorOutput | 
|---|
| 519 |   typeset updatedDiskLine createNsdOutput tspreparediskOutput | 
|---|
| 520 |   typeset magicWord rc2 pvid nsdSubtype nsdSubtypeDiskname invokedNode | 
|---|
| 521 |  | 
|---|
| 522 |   # Parse the current SG_DISKS line for the disk. | 
|---|
| 523 |   IFS=":" | 
|---|
| 524 |   set -f ; set -A v -- - $currentDiskLine ; set +f | 
|---|
| 525 |   IFS="$IFS_sv" | 
|---|
| 526 |   diskName=${v[$DISK_NAME_Field]} | 
|---|
| 527 |   nsdSubtype=${v[$NSD_SUBTYPE_Field]} | 
|---|
| 528 |   aixPvidValue=${v[$PVID_Field]} | 
|---|
| 529 |   [[ -z $nsdSubtype ]] && nsdSubtype="generic" | 
|---|
| 530 |   [[ ${v[$NODESETID_Field]} = $FREE_DISK ]] &&  \ | 
|---|
| 531 |     invokingCommand="mmimportfs_freeDisk" | 
|---|
| 532 |   [[ ${v[$NODESETID_Field]} != $FREE_DISK ]] &&  \ | 
|---|
| 533 |     v[$NODESETID_Field]=$targetNodesetId | 
|---|
| 534 |   nodesetId=${v[$NODESETID_Field]} | 
|---|
| 535 |  | 
|---|
| 536 |   # If a change file is specified (-S option), | 
|---|
| 537 |   # see if it contains a descriptor for this disk. | 
|---|
| 538 |   [[ -s $specFile ]] &&  \ | 
|---|
| 539 |     diskDesc=$($grep -e "[$BLANKchar$TABchar]$diskName:"   \ | 
|---|
| 540 |                      -e "^$diskName:" $specFile 2>/dev/null) | 
|---|
| 541 |  | 
|---|
| 542 |   if [[ -n $diskDesc ]] | 
|---|
| 543 |   then | 
|---|
| 544 |     # If a disk descriptor was specified, | 
|---|
| 545 |     # parse it to get the server names. | 
|---|
| 546 |     IFS=':' | 
|---|
| 547 |     set -f ; set -- $diskDesc ; set +f | 
|---|
| 548 |     server=$2 | 
|---|
| 549 |     backup=$3 | 
|---|
| 550 |     IFS="$IFS_sv"  # Restore the default IFS setting. | 
|---|
| 551 |  | 
|---|
| 552 |     # If a primary server was specified, make sure that it is valid | 
|---|
| 553 |     # and convert it if necessary to an admin adapter name, since it | 
|---|
| 554 |     # may be needed for the subsequent createNsd call. | 
|---|
| 555 |     # We don't bother to check the backup server here, since it will | 
|---|
| 556 |     # be checked later by the validateAndConvertNsdDescriptor routine. | 
|---|
| 557 |     if [[ -n $server ]] | 
|---|
| 558 |     then | 
|---|
| 559 |       server=$(checkAndConvertNodeValue $server $REL_HOSTNAME_Field) | 
|---|
| 560 |       [[ $? -ne 0 ]] && cleanupAndExit | 
|---|
| 561 |     fi | 
|---|
| 562 | #   if [[ -n $backup ]] | 
|---|
| 563 | #   then | 
|---|
| 564 | #     backup=$(checkAndConvertNodeValue $backup $REL_HOSTNAME_Field) | 
|---|
| 565 | #     [[ $? -ne 0 ]] && cleanupAndExit | 
|---|
| 566 | #   fi | 
|---|
| 567 |  | 
|---|
| 568 |   else | 
|---|
| 569 |     # Otherwise, use the current NSD server names, if any. | 
|---|
| 570 |     if [[ $sourceCluster = lc ]] | 
|---|
| 571 |     then | 
|---|
| 572 |       server=${v[$NSD_PRIMARY_NODE_Field]} | 
|---|
| 573 |       backup=${v[$NSD_BACKUP_NODE_Field]} | 
|---|
| 574 |     else | 
|---|
| 575 |       server="" | 
|---|
| 576 |       backup="" | 
|---|
| 577 |     fi | 
|---|
| 578 |   fi  # end of if [[ -n $diskDesc ]] | 
|---|
| 579 |  | 
|---|
| 580 |   if [[ $sourceCluster != lc && $sourceCluster != single ]] | 
|---|
| 581 |   then | 
|---|
| 582 |     # The source cluster type is sp, rpd, or hacmp. | 
|---|
| 583 |     # In all of these cases we may have to import | 
|---|
| 584 |     # the underlying logical volumes and, if applicable, | 
|---|
| 585 |     # recreate the VSDs. | 
|---|
| 586 |  | 
|---|
| 587 |     :  # For now, we assume that the disks are already in place. | 
|---|
| 588 |  | 
|---|
| 589 |   fi  # end of if [[ $sourceCluster != lc && $sourceCluster != single ]] | 
|---|
| 590 |  | 
|---|
| 591 |   # If the user did not specify a new disk descriptor, | 
|---|
| 592 |   # generate one from the current SG_DISKS line. | 
|---|
| 593 |   [[ -z $diskDesc ]] &&  \ | 
|---|
| 594 |     diskDesc="$diskName:$server:$backup:" | 
|---|
| 595 |  | 
|---|
| 596 |   # If NSD server names were not specified by the user, | 
|---|
| 597 |   # or cannot be reasonably defaulted by us, the user | 
|---|
| 598 |   # will have to use mmchnsd to assign NSD servers. | 
|---|
| 599 |   [[ -z $server ]] &&  \ | 
|---|
| 600 |     result=successServersRemoved | 
|---|
| 601 |  | 
|---|
| 602 |   # Verify the correctness of the NSD server nodes. | 
|---|
| 603 |   validateDescriptorOutput=$(validateAndConvertNsdDescriptor "$diskDesc"  \ | 
|---|
| 604 |                    $currentDiskLine $CHANGE_NSD $nodesetId NULL oldDiskUsage) | 
|---|
| 605 |   rc=$? | 
|---|
| 606 |   if [[ $rc -eq 0 ]] | 
|---|
| 607 |   then | 
|---|
| 608 |     # If there are no problems, parse the result to get the new SG_DISKS line. | 
|---|
| 609 |     set -f ; set -- $validateDescriptorOutput ; set +f | 
|---|
| 610 |     updatedDiskLine="$1" | 
|---|
| 611 |  | 
|---|
| 612 |     # Parse the line that was returned by the validate function | 
|---|
| 613 |     # to pick up fields that may have been changed. | 
|---|
| 614 |     IFS=":" | 
|---|
| 615 |     set -f ; set -A v -- - $updatedDiskLine ; set +f | 
|---|
| 616 |     IFS="$IFS_sv" | 
|---|
| 617 |  | 
|---|
| 618 |   else | 
|---|
| 619 |     # Remove the NSD servers.  The user will have to run mmchnsd. | 
|---|
| 620 |     v[$NSD_PRIMARY_NODE_Field]="" | 
|---|
| 621 |     v[$NSD_BACKUP_NODE_Field]="" | 
|---|
| 622 |     v[$DAEMON_NSD_PRIMARY_Field]="" | 
|---|
| 623 |     v[$DAEMON_NSD_BACKUP_Field]="" | 
|---|
| 624 |     result=successServersRemoved | 
|---|
| 625 |     rc=0 | 
|---|
| 626 |   fi | 
|---|
| 627 |  | 
|---|
| 628 |   # Convert the disk into an NSD. | 
|---|
| 629 |   if [[ $sourceCluster != lc && $sourceCluster != single ]] | 
|---|
| 630 |   then | 
|---|
| 631 |     # See if this disk needs to be recovered from a previous | 
|---|
| 632 |     # partial SG descriptor migration. | 
|---|
| 633 |     if [[ -s $recoveryFiles ]] | 
|---|
| 634 |     then | 
|---|
| 635 |       recoverOldSGdescriptor $diskName $recoveryFiles | 
|---|
| 636 |       rc=$? | 
|---|
| 637 |       if [[ $rc -ne 0 ]] | 
|---|
| 638 |       then | 
|---|
| 639 |         print -- "error" | 
|---|
| 640 |         return $rc | 
|---|
| 641 |       fi | 
|---|
| 642 |     fi | 
|---|
| 643 |  | 
|---|
| 644 |     # Generate and write an unique NSD volume id on sector 2 of the disk. | 
|---|
| 645 |     # If an NSD server is specified, invoke the function on that node. | 
|---|
| 646 |     # This rule does not apply when the underlying disk is a VSD. | 
|---|
| 647 |     # For VSDs we should have access to the disk from the local node. | 
|---|
| 648 |     if [[ $sourceCluster = sp || -z $server || $server = $ourNodeName ]] | 
|---|
| 649 |     then | 
|---|
| 650 |       invokedNode=$ourNodeName | 
|---|
| 651 |       createNsdOutput=$(createNsd $diskName no $invokingCommand NULL) | 
|---|
| 652 |       rc=$? | 
|---|
| 653 |     else | 
|---|
| 654 |       invokedNode=$server | 
|---|
| 655 |       createNsdOutput=$(run on1 $server  \ | 
|---|
| 656 |                         createNsd $diskName no $invokingCommand NULL) | 
|---|
| 657 |       rc=$? | 
|---|
| 658 |     fi | 
|---|
| 659 |  | 
|---|
| 660 |     # The output of createNsd consists of a one-word NSD subtype value, | 
|---|
| 661 |     # followed by the output from tspreparedisk.  Separate the two parts. | 
|---|
| 662 |     nsdSubtype=${createNsdOutput%% *} | 
|---|
| 663 |     tspreparediskOutput=${createNsdOutput#* } | 
|---|
| 664 |  | 
|---|
| 665 |     # Set the value for the nsd subtype diskname if the nsd subtype | 
|---|
| 666 |     # is lv, vsd or file; this name is persistent across the nodes. | 
|---|
| 667 |     nsdSubtypeDiskname="" | 
|---|
| 668 |     [[ $nsdSubtype = lv || $nsdSubtype = vsd || $nsdSubtype = file ]] &&  \ | 
|---|
| 669 |       nsdSubtypeDiskname=$diskName | 
|---|
| 670 |  | 
|---|
| 671 |     # Parse the output from the tspreparedisk command. | 
|---|
| 672 |     IFS=":" | 
|---|
| 673 |     set -f ; set -- $tspreparediskOutput ; set +f | 
|---|
| 674 |     magicWord=$1 | 
|---|
| 675 |     rc2=$2 | 
|---|
| 676 |     pvid=$3 | 
|---|
| 677 |     IFS="$IFS_sv" | 
|---|
| 678 |  | 
|---|
| 679 |     if [[ $rc  -ne 0 || $nsdSubtype = error || | 
|---|
| 680 |           $rc2 -ne 0 || $magicWord != tspreparedisk ]] | 
|---|
| 681 |     then | 
|---|
| 682 |       # Try to make sense of the error. | 
|---|
| 683 |       if [[ $nsdSubtype = error ]] | 
|---|
| 684 |       then | 
|---|
| 685 |         :  # determineNsdSubtype failed.  Messages were already issued. | 
|---|
| 686 |  | 
|---|
| 687 |       elif [[ $magicWord = tspreparedisk ]] | 
|---|
| 688 |       then | 
|---|
| 689 |         # tspreparedisk was executed but was not happy about something. | 
|---|
| 690 |         if [[ $rc2 = 1 ]]       # E_PERM | 
|---|
| 691 |         then | 
|---|
| 692 |           # Permission was denied for disk. | 
|---|
| 693 |           printErrorMsg 523 $mmcmd "/dev/$diskName" | 
|---|
| 694 |         elif [[ $rc2 = 2 ]]     # E_NOENT | 
|---|
| 695 |         then | 
|---|
| 696 |           # The disk was not found. | 
|---|
| 697 |           printErrorMsg 524 $mmcmd "/dev/$diskName" | 
|---|
| 698 |         elif [[ $rc2 = 5 ]]     # E_IO | 
|---|
| 699 |         then | 
|---|
| 700 |           # I/O error | 
|---|
| 701 |           printErrorMsg 525 $mmcmd "/dev/$diskName" | 
|---|
| 702 |         elif [[ $rc2 = $MM_DeviceNotFound ]]    # E_NODEV | 
|---|
| 703 |         then | 
|---|
| 704 |           # A return code of ENODEV was returned for the disk. | 
|---|
| 705 |           printErrorMsg 187 $mmcmd $invokedNode "/dev/$diskName" | 
|---|
| 706 |         elif [[ $rc2 = 27 ]]    # E_FBIG | 
|---|
| 707 |         then | 
|---|
| 708 |           # The disk is too large. | 
|---|
| 709 |           printErrorMsg 508 $mmcmd "/dev/$diskName" | 
|---|
| 710 |         elif [[ $rc2 = 50 ]]    # E_NOCONNECT | 
|---|
| 711 |         then | 
|---|
| 712 |           # The disk is fenced out. | 
|---|
| 713 |           printErrorMsg 395 $mmcmd $invokedNode "/dev/$diskName" | 
|---|
| 714 |         else | 
|---|
| 715 |           # Show the result from tspreparedisk. | 
|---|
| 716 |           print -u2 "$tspreparediskOutput" | 
|---|
| 717 |           # Unexpected error from tspreparedisk. | 
|---|
| 718 |           printErrorMsg 171 "$mmcmd" "tspreparedisk $diskName" $rc2 | 
|---|
| 719 |         fi  # end if [[ $rc2 = 1 ]] | 
|---|
| 720 |       else | 
|---|
| 721 |         # Something is really wrong.  Output error information if any. | 
|---|
| 722 |         [[ -n $createNsdOutput ]] && print -u2 "$createNsdOutput" | 
|---|
| 723 |       fi  # end if [[ $nsdSubtype = error ]] | 
|---|
| 724 |  | 
|---|
| 725 |       # We failed to create an NSD from this disk. | 
|---|
| 726 |       printErrorMsg 47 $mmcmd $diskName | 
|---|
| 727 |       result="error" | 
|---|
| 728 |       rc=1 | 
|---|
| 729 |  | 
|---|
| 730 |     else | 
|---|
| 731 |       # At this point the disk was successfully defined as an NSD. | 
|---|
| 732 |       # Add missing or updated information. | 
|---|
| 733 |       v[$PVID_Field]=$pvid | 
|---|
| 734 |       v[$NSD_SUBTYPE_DISKNAME_Field]=$nsdSubtypeDiskname | 
|---|
| 735 |       if [[ $nsdSubtype = lv ]] | 
|---|
| 736 |       then | 
|---|
| 737 |         v[$AIX_PVID_Field]=$aixPvidValue | 
|---|
| 738 |       else | 
|---|
| 739 |         v[$AIX_PVID_Field]="" | 
|---|
| 740 |       fi | 
|---|
| 741 |  | 
|---|
| 742 |       # Remove any leftover files from tspreparedisk -m. | 
|---|
| 743 |       $rm -f ${fqName%/*}/tspreparedisk.diskDesc.${diskName}.* | 
|---|
| 744 |       for server in $(print -- $primaryServer $backupServer) | 
|---|
| 745 |       do | 
|---|
| 746 |         run onNode $server rmSGDescFile $diskName | 
|---|
| 747 |       done | 
|---|
| 748 |     fi  # end if [[ $rc  -ne 0 || $nsdSubtype = error || ... ]] | 
|---|
| 749 |  | 
|---|
| 750 |   fi  # end of if [[ $sourceCluster != lc && $sourceCluster != single ]] | 
|---|
| 751 |  | 
|---|
| 752 |   # Add the remaining missing or updated information and rebuild the line. | 
|---|
| 753 |   v[$DISK_TYPE_Field]=nsd | 
|---|
| 754 |   v[$NSD_SUBTYPE_Field]=$nsdSubtype | 
|---|
| 755 |   updatedDiskLine=$(print_newLine) | 
|---|
| 756 |  | 
|---|
| 757 |   # Return to the caller the updated SG_DISKS line. | 
|---|
| 758 |   print -- "$result" "$updatedDiskLine" | 
|---|
| 759 |   return $rc | 
|---|
| 760 |  | 
|---|
| 761 | }  #----- end of function importDisk_lc ---------------------------- | 
|---|
| 762 |  | 
|---|
| 763 |  | 
|---|
| 764 | ########################################################################### | 
|---|
| 765 | # | 
|---|
| 766 | # Function:  Unfence logical volumes and remove PR registrations. | 
|---|
| 767 | # | 
|---|
| 768 | # Input:     $1 - file with the nodes on which to unfence | 
|---|
| 769 | #            $2 - SG_DISKS lines for the disks to unfence | 
|---|
| 770 | # | 
|---|
| 771 | # Output:    None | 
|---|
| 772 | # | 
|---|
| 773 | # Returns:   0 - everything worked OK | 
|---|
| 774 | #            1 - error encountered | 
|---|
| 775 | # | 
|---|
| 776 | ########################################################################### | 
|---|
| 777 | function unfenceLogicalVolumes  # <nodeFile> <diskFile> | 
|---|
| 778 | { | 
|---|
| 779 |   sourceFile="mmimportfs.sh" | 
|---|
| 780 |   [[ -n $DEBUG || -n $DEBUGunfenceLogicalVolumes ]] && set -x | 
|---|
| 781 |   $mmTRACE_ENTER "$*" | 
|---|
| 782 |  | 
|---|
| 783 |   typeset nodefile=$1 | 
|---|
| 784 |   typeset diskLines=$2 | 
|---|
| 785 |  | 
|---|
| 786 |   typeset rc=0 | 
|---|
| 787 |   typeset unfenceDisksOutput outputLine nodeName magicWord rc2 | 
|---|
| 788 |   typeset failedNode errorFound | 
|---|
| 789 |  | 
|---|
| 790 |   # Give up if any of the input files is empty. | 
|---|
| 791 |   [[ ! -s $nodefile || ! -s $diskLines ]] &&  \ | 
|---|
| 792 |     return 0 | 
|---|
| 793 |  | 
|---|
| 794 |   $rm -f $tmpfile | 
|---|
| 795 |  | 
|---|
| 796 |   # Exclude the local host from the list of nodes. | 
|---|
| 797 |   $grep -v -w $ourNodeName $nodefile > ${nodefile}tmp | 
|---|
| 798 |  | 
|---|
| 799 |   # If there are remote nodes left in the file, | 
|---|
| 800 |   # unfence the disks on those nodes. | 
|---|
| 801 |   if [[ -s ${nodefile}tmp ]] | 
|---|
| 802 |   then | 
|---|
| 803 |     print -- "$mmcmd:  Attempting to unfence the disks.  This may take a while ... " | 
|---|
| 804 |  | 
|---|
| 805 |     # Create a copy of the file to propagate. | 
|---|
| 806 |     $cp $diskLines ${diskLines}tmp | 
|---|
| 807 |     checkForErrors "cp $diskLines ${diskLines}tmp" $? | 
|---|
| 808 |  | 
|---|
| 809 |     # Perform the tasks on all remote nodes. | 
|---|
| 810 |     $mmdsh -f 10 -vF ${nodefile}tmp -I ${diskLines}tmp  \ | 
|---|
| 811 |        $mmremote unfenceDisks ${diskLines}tmp >$tmpfile 2>&1 | 
|---|
| 812 |     rc=$? | 
|---|
| 813 |   fi | 
|---|
| 814 |  | 
|---|
| 815 |   # Unfence the disks on the local node. | 
|---|
| 816 |   # Append the result to the output from the remote nodes. | 
|---|
| 817 |   if [[ $osName = AIX ]] | 
|---|
| 818 |   then | 
|---|
| 819 |     unfenceDisksOutput=$(unfenceDisks $diskLines) | 
|---|
| 820 |     rc=$? | 
|---|
| 821 |  | 
|---|
| 822 |     # Append the output to the output from the remote nodes | 
|---|
| 823 |     # so that we can process the overall result. | 
|---|
| 824 |     print -- "$ourNodeName: $unfenceDisksOutput" >>$tmpfile | 
|---|
| 825 |   fi | 
|---|
| 826 |  | 
|---|
| 827 |   # Ignore the results and declare a success.  If we were not | 
|---|
| 828 |   # successful on some node, the mount will fail and the user | 
|---|
| 829 |   # will have to run mmremote unfenceDisks or fix the disks | 
|---|
| 830 |   # by himself.  Our problem is that we do not have a good | 
|---|
| 831 |   # way to tell whether the unfence process should work on | 
|---|
| 832 |   # any given node or not.  And we most definitely do not | 
|---|
| 833 |   # want to fail the mmimportfs command for such a reason. | 
|---|
| 834 |   $rm -f ${nodefile}tmp ${diskLines}tmp | 
|---|
| 835 |   return 0 | 
|---|
| 836 |  | 
|---|
| 837 | }  #----- end of function unfenceLogicalVolumes -------------------- | 
|---|
| 838 |  | 
|---|
| 839 |  | 
|---|
| 840 |  | 
|---|
| 841 | ####################### | 
|---|
| 842 | # Mainline processing | 
|---|
| 843 | ####################### | 
|---|
| 844 |  | 
|---|
| 845 | ################################# | 
|---|
| 846 | # Process the command arguments. | 
|---|
| 847 | ################################# | 
|---|
| 848 | [[ $arg1 = '-?' || $arg1 = '-h' || $arg1 = '--help' || $arg1 = '--' ]] &&  \ | 
|---|
| 849 |   syntaxError "help" $usageMsg | 
|---|
| 850 |  | 
|---|
| 851 | [[ $argc -lt 3 ]] &&  \ | 
|---|
| 852 |   syntaxError "missingArgs" $usageMsg | 
|---|
| 853 |  | 
|---|
| 854 | device=$arg1   # Save the stripe group device (always the first parameter). | 
|---|
| 855 | shift 1        # Drop the device name from the parameter list. | 
|---|
| 856 |  | 
|---|
| 857 | while getopts :C:i:RS: OPT | 
|---|
| 858 | do | 
|---|
| 859 |   case $OPT in | 
|---|
| 860 |     C) syntaxError "obsoleteOption" $usageMsg "-$OPT" | 
|---|
| 861 |        ;; | 
|---|
| 862 |  | 
|---|
| 863 |     i) # name of input file | 
|---|
| 864 |        [[ -n $iflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" | 
|---|
| 865 |        fsImportData=$OPTARG | 
|---|
| 866 |        ;; | 
|---|
| 867 |  | 
|---|
| 868 |     R) # replace existing file systems. | 
|---|
| 869 |        [[ -n $Rflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" | 
|---|
| 870 |        Rflag=yes | 
|---|
| 871 |        ;; | 
|---|
| 872 |  | 
|---|
| 873 |     S) # file with change specifications. | 
|---|
| 874 |        [[ -n $Sflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT" | 
|---|
| 875 |        Sflag=yes | 
|---|
| 876 |        changeSpecFile=$OPTARG | 
|---|
| 877 |        ;; | 
|---|
| 878 |  | 
|---|
| 879 |     :) syntaxError "missingValue" $usageMsg $OPTARG | 
|---|
| 880 |        ;; | 
|---|
| 881 |  | 
|---|
| 882 |     +[CiRS]) syntaxError "invalidOption" $usageMsg $OPT | 
|---|
| 883 |        ;; | 
|---|
| 884 |  | 
|---|
| 885 |     *) # invalid option specified | 
|---|
| 886 |        syntaxError "invalidOption" $usageMsg $OPTARG | 
|---|
| 887 |        ;; | 
|---|
| 888 |   esac | 
|---|
| 889 | done | 
|---|
| 890 |  | 
|---|
| 891 | shift OPTIND-1 | 
|---|
| 892 | [[ $# != 0 ]] && syntaxError "extraArg" $usageMsg $1 | 
|---|
| 893 |  | 
|---|
| 894 | # Check the input file parameters. | 
|---|
| 895 | if [[ ! -f $fsImportData || ! -r $fsImportData ]] | 
|---|
| 896 | then | 
|---|
| 897 |   # Can't read the input file. | 
|---|
| 898 |   printErrorMsg 43 $mmcmd $fsImportData | 
|---|
| 899 |   cleanupAndExit | 
|---|
| 900 | fi | 
|---|
| 901 | if [[ ! -s $fsImportData ]] | 
|---|
| 902 | then | 
|---|
| 903 |   # Input file is empty. | 
|---|
| 904 |   printErrorMsg 329 $mmcmd $fsImportData | 
|---|
| 905 |   cleanupAndExit | 
|---|
| 906 | fi | 
|---|
| 907 |  | 
|---|
| 908 | if [[ -n $Sflag && ( ! -f $changeSpecFile || ! -r $changeSpecFile ) ]] | 
|---|
| 909 | then | 
|---|
| 910 |   # Can't read the input file. | 
|---|
| 911 |   printErrorMsg 43 $mmcmd $changeSpecFile | 
|---|
| 912 |   cleanupAndExit | 
|---|
| 913 | fi | 
|---|
| 914 | if [[ -n $Sflag && ! -s $changeSpecFile ]] | 
|---|
| 915 | then | 
|---|
| 916 |   # Input file is empty. | 
|---|
| 917 |   printErrorMsg 329 $mmcmd $changeSpecFile | 
|---|
| 918 |   cleanupAndExit | 
|---|
| 919 | fi | 
|---|
| 920 |  | 
|---|
| 921 | # Process the input device name parameter. | 
|---|
| 922 | [[ $device = all ]] && importAll=true | 
|---|
| 923 | deviceName=${device#/dev+(/)}   # Strip /dev from the device name. | 
|---|
| 924 |  | 
|---|
| 925 |  | 
|---|
| 926 | ##################################################################### | 
|---|
| 927 | # Set up trap exception handling and call the gpfsInit function. | 
|---|
| 928 | # It will ensure that the local copy of the mmsdrfs and the rest of | 
|---|
| 929 | # the GPFS system files are up-to-date and will obtain the sdr lock. | 
|---|
| 930 | ##################################################################### | 
|---|
| 931 | trap pretrap HUP INT QUIT KILL | 
|---|
| 932 | gpfsInitOutput=$(gpfsInit $lockId) | 
|---|
| 933 | setGlobalVar $? $gpfsInitOutput | 
|---|
| 934 |  | 
|---|
| 935 | targetNodesetId=$nsId | 
|---|
| 936 |  | 
|---|
| 937 | # Determine the lookup order for resolving host names. | 
|---|
| 938 | [[ $osName != AIX ]] && resolveOrder=$(setHostResolveOrder) | 
|---|
| 939 |  | 
|---|
| 940 |  | 
|---|
| 941 | ###################################################################### | 
|---|
| 942 | # Create a new version of the mmsdrfs file that will receive the data | 
|---|
| 943 | # and collect information for the existing file systems, disks, etc. | 
|---|
| 944 | # If the -R option is specified, remove the affected lines from the | 
|---|
| 945 | # mmsdrfs file. | 
|---|
| 946 | ###################################################################### | 
|---|
| 947 | $rm -f $newsdrfs $existingDisks $allClusterNodes $aixNodes | 
|---|
| 948 | IFS=":" | 
|---|
| 949 | exec 3<&- | 
|---|
| 950 | exec 3< $mmsdrfsFile | 
|---|
| 951 | while read -u3 sdrfsLine | 
|---|
| 952 | do | 
|---|
| 953 |   # Parse the line. | 
|---|
| 954 |   set -f ; set -A v -- - $sdrfsLine ; set +f | 
|---|
| 955 |   IFS="$IFS_sv" | 
|---|
| 956 |   printLine=true | 
|---|
| 957 |  | 
|---|
| 958 |   # Change some of the fields depending on the type of line. | 
|---|
| 959 |   case ${v[$LINE_TYPE_Field]} in | 
|---|
| 960 |  | 
|---|
| 961 |     $VERSION_LINE )  # This is the global header line. | 
|---|
| 962 |        # Increment the generation number. | 
|---|
| 963 |        newGenNumber=${v[$SDRFS_GENNUM_Field]}+1 | 
|---|
| 964 |        v[$SDRFS_GENNUM_Field]=$newGenNumber | 
|---|
| 965 |  | 
|---|
| 966 |        targetCluster=${v[$CLUSTER_TYPE_Field]} | 
|---|
| 967 |        if [[ $MMMODE = lc ]] | 
|---|
| 968 |        then | 
|---|
| 969 |          [[ ${v[$HIGHEST_GPFS_DISK_NBR_Field]} -lt $initialDiskNumber ]] &&  \ | 
|---|
| 970 |            v[$HIGHEST_GPFS_DISK_NBR_Field]=$initialDiskNumber | 
|---|
| 971 |          prevMaxDiskNumber=${v[$HIGHEST_GPFS_DISK_NBR_Field]} | 
|---|
| 972 |        fi | 
|---|
| 973 |        ;; | 
|---|
| 974 |  | 
|---|
| 975 |     $MEMBER_NODE )  # This line describes a node that belongs to some nodeset. | 
|---|
| 976 |        # Create a file with the names of all nodes in the cluster. | 
|---|
| 977 |        print -- "${v[$REL_HOSTNAME_Field]}" >> $allClusterNodes | 
|---|
| 978 |        checkForErrors "writing to file $allClusterNodes" $? | 
|---|
| 979 |  | 
|---|
| 980 |        # Create separate files with the names of the AIX nodes. | 
|---|
| 981 |        if [[ ${v[$OS_NAME_Field]} = "AIX" ]] | 
|---|
| 982 |        then | 
|---|
| 983 |          print -- "${v[$REL_HOSTNAME_Field]}" >> $aixNodes | 
|---|
| 984 |          checkForErrors "writing to file $aixNodes" $? | 
|---|
| 985 |        fi | 
|---|
| 986 |        ;; | 
|---|
| 987 |  | 
|---|
| 988 |     $SG_HEADR )  # This is the header line for some file system. | 
|---|
| 989 |        # We are starting the processing of a new file system.  If the file | 
|---|
| 990 |        # system should be replaced, remove the line from the mmsdrfs file. | 
|---|
| 991 |        if [[ (${v[$DEV_NAME_Field]} = $deviceName || $device = all) && | 
|---|
| 992 |               -n $Rflag && ${v[$FS_TYPE_Field]} = $localfs ]] | 
|---|
| 993 |        then | 
|---|
| 994 |          # This file system should be replaced. | 
|---|
| 995 |          replaceThisFileSystem=true | 
|---|
| 996 |          printLine=false | 
|---|
| 997 |  | 
|---|
| 998 |        else | 
|---|
| 999 |          replaceThisFileSystem="" | 
|---|
| 1000 |  | 
|---|
| 1001 |          # Create a list of the already assigned minor numbers. | 
|---|
| 1002 |          existingMinorNumbers="$existingMinorNumbers ${v[$DEV_MINOR_Field]}" | 
|---|
| 1003 |  | 
|---|
| 1004 |          # If this file systems belongs to the nodeset on which we | 
|---|
| 1005 |          # are running, remember its name.  It will be needed shortly | 
|---|
| 1006 |          # to figure out the value of the GPFS device major number. | 
|---|
| 1007 |          [[ ${v[$NODESETID_Field]} = $nsId ]] &&  \ | 
|---|
| 1008 |            fqDeviceName="/dev/${v[$DEV_NAME_Field]}" | 
|---|
| 1009 |        fi  # end if [[ (${v[$DEV_NAME_Field]} = $deviceName || $device = all) ... | 
|---|
| 1010 |        ;; | 
|---|
| 1011 |  | 
|---|
| 1012 |     $SG_ETCFS )  # This line is a stanza line for one of the filesystems. | 
|---|
| 1013 |        if [[ -n $replaceThisFileSystem ]] | 
|---|
| 1014 |        then | 
|---|
| 1015 |          printLine=false | 
|---|
| 1016 |        else | 
|---|
| 1017 |          # If this is the first line in the stanza, | 
|---|
| 1018 |          # save the device name and mount point. | 
|---|
| 1019 |          if [[ ${v[$LINE_NUMBER_Field]} = $MOUNT_POINT_Line ]] | 
|---|
| 1020 |          then | 
|---|
| 1021 |            fsInfo="${v[$DEV_NAME_Field]}:${v[$ETCFS_TEXT_Field]}:${v[$NODESETID_Field]}" | 
|---|
| 1022 |            existingFsInfo="$fsInfo $existingFsInfo" | 
|---|
| 1023 |  | 
|---|
| 1024 |            # Note:  the trailing blanks in the following lists are important. | 
|---|
| 1025 |            existingFileSystems="$existingFileSystems ${v[$DEV_NAME_Field]} " | 
|---|
| 1026 |            existingMountPoints="$existingMountPoints ${v[$ETCFS_TEXT_Field]} " | 
|---|
| 1027 |          fi | 
|---|
| 1028 |        fi  # end if [[ -n $replaceThisFileSystem ]] | 
|---|
| 1029 |        ;; | 
|---|
| 1030 |  | 
|---|
| 1031 |     $SG_MOUNT ) | 
|---|
| 1032 |        [[ -n $replaceThisFileSystem ]] &&  \ | 
|---|
| 1033 |          printLine=false | 
|---|
| 1034 |        ;; | 
|---|
| 1035 |  | 
|---|
| 1036 |     $SG_DISKS )  # This line describes a disk. | 
|---|
| 1037 |        # Decide if this disk is to be replaced.  If the disk belongs to some | 
|---|
| 1038 |        # file system, the replaceThisFileSystem flag already has the correct | 
|---|
| 1039 |        # value.  If this is a free disk, it will be replaced only if all file | 
|---|
| 1040 |        # systems are being replaced.  Note that the replaceThisFileSystem flag | 
|---|
| 1041 |        # is used to control the replacing of disks that are part of some file | 
|---|
| 1042 |        # system as well as the replacing of free disks. | 
|---|
| 1043 |        if [[ ${v[$NODESETID_Field]} = $FREE_DISK ]] | 
|---|
| 1044 |        then | 
|---|
| 1045 |          if [[ $device != all ]] | 
|---|
| 1046 |          then | 
|---|
| 1047 |            replaceThisFileSystem="" | 
|---|
| 1048 |          else | 
|---|
| 1049 |            replaceThisFileSystem=true | 
|---|
| 1050 |          fi | 
|---|
| 1051 |        fi  # end if [[ ${v[$NODESETID_Field]} = $FREE_DISK ]] | 
|---|
| 1052 |  | 
|---|
| 1053 |        if [[ -n $replaceThisFileSystem ]] | 
|---|
| 1054 |        then | 
|---|
| 1055 |          printLine=false | 
|---|
| 1056 |        else | 
|---|
| 1057 |          # Create a file with the names of all existing disks. | 
|---|
| 1058 |          # It doesn't matter if the disks are free or not. | 
|---|
| 1059 |          print -- "${v[$DISK_NAME_Field]}" >> $existingDisks | 
|---|
| 1060 |          checkForErrors "writing to file $existingDisks" $? | 
|---|
| 1061 |  | 
|---|
| 1062 |          # Keep track of the highest NSD number assigned to a disk. | 
|---|
| 1063 |          if [[ ${v[$DISK_NAME_Field]} = gpfs+([0-9])nsd ]] | 
|---|
| 1064 |          then | 
|---|
| 1065 |            nsdName=${v[$DISK_NAME_Field]} | 
|---|
| 1066 |            nsdNumber=${nsdName#gpfs} | 
|---|
| 1067 |            nsdNumber=${nsdNumber%nsd} | 
|---|
| 1068 |            [[ $nsdNumber -gt $maxDiskNumber ]] && maxDiskNumber=$nsdNumber | 
|---|
| 1069 |          fi | 
|---|
| 1070 |        fi  # end if [[ -n $replaceThisFileSystem ]] | 
|---|
| 1071 |        ;; | 
|---|
| 1072 |  | 
|---|
| 1073 |     * )  # Pass all other lines without a change. | 
|---|
| 1074 |        ;; | 
|---|
| 1075 |  | 
|---|
| 1076 |   esac  # end Change some of the fields | 
|---|
| 1077 |  | 
|---|
| 1078 |   # Build and write the line to the new mmsdrfs file. | 
|---|
| 1079 |   if [[ $printLine = true ]] | 
|---|
| 1080 |   then | 
|---|
| 1081 |     print_newLine >> $newsdrfs | 
|---|
| 1082 |     checkForErrors "writing to file $newsdrfs" $? | 
|---|
| 1083 |   fi | 
|---|
| 1084 |  | 
|---|
| 1085 |   IFS=":"  # Change the separator back to ":" for the next iteration. | 
|---|
| 1086 |  | 
|---|
| 1087 | done  # end while read -u3 sdrfsLine | 
|---|
| 1088 |  | 
|---|
| 1089 | IFS="$IFS_sv"  # Restore the default IFS settings. | 
|---|
| 1090 |  | 
|---|
| 1091 |  | 
|---|
| 1092 | ########################################################################### | 
|---|
| 1093 | # Figure out what should the GPFS file systems device major number be. | 
|---|
| 1094 | ########################################################################### | 
|---|
| 1095 | if [[ $osName = Linux && -n $fqDeviceName ]] | 
|---|
| 1096 | then | 
|---|
| 1097 |   devMajor=$(LC_ALL=C $ls -l $fqDeviceName 2>/dev/null | $awk ' { print $5 } ') | 
|---|
| 1098 |   devMajor=${devMajor%,*} | 
|---|
| 1099 | fi | 
|---|
| 1100 | [[ -z $devMajor ]] && devMajor=$defaultMajorNumber | 
|---|
| 1101 |  | 
|---|
| 1102 |  | 
|---|
| 1103 | ########################################################################### | 
|---|
| 1104 | # If the source is hacmp or LV based rpd cluster, make an attempt | 
|---|
| 1105 | # to remove any PR settings and unfence the disks on all nodes in | 
|---|
| 1106 | # the new cluster.  This processing is by necessity time consuming. | 
|---|
| 1107 | # | 
|---|
| 1108 | # Notes:  The main loop is further down.  This is preliminary processing | 
|---|
| 1109 | #         and a necessary evil.  Some of the error checking is duplicated | 
|---|
| 1110 | #         here to allow us to get out faster if there is an obvious error. | 
|---|
| 1111 | ########################################################################### | 
|---|
| 1112 | $rm -f $disksToUnfence $resetLVs.* | 
|---|
| 1113 | IFS=":" | 
|---|
| 1114 | exec 3<&- | 
|---|
| 1115 | exec 3< $fsImportData | 
|---|
| 1116 | while read -u3 sdrfsLine | 
|---|
| 1117 | do | 
|---|
| 1118 |   # Parse the line. | 
|---|
| 1119 |   set -f ; set -A v -- - $sdrfsLine ; set +f | 
|---|
| 1120 |  | 
|---|
| 1121 |   IFS="$IFS_sv"    # Restore the default IFS settings. | 
|---|
| 1122 |   printLine=true   # Assume the line will be printed. | 
|---|
| 1123 |  | 
|---|
| 1124 |   case ${v[$LINE_TYPE_Field]} in | 
|---|
| 1125 |  | 
|---|
| 1126 |     $VERSION_LINE )  # This is the global header line. | 
|---|
| 1127 |        sourceCluster=${v[$CLUSTER_TYPE_Field]} | 
|---|
| 1128 |        [[ -z $sourceCluster ]] && sourceCluster=sp | 
|---|
| 1129 |        checkClusterCompatibility $sourceCluster $targetCluster | 
|---|
| 1130 |        rc=$? | 
|---|
| 1131 |        if [[ $rc -ne 0 ]] | 
|---|
| 1132 |        then | 
|---|
| 1133 |          # Incompatible cluster types. | 
|---|
| 1134 |          printErrorMsg 44 $mmcmd $sourceCluster $targetCluster | 
|---|
| 1135 |          cleanupAndExit | 
|---|
| 1136 |        fi | 
|---|
| 1137 |        getDiskRecoveryInformation $sourceCluster $recoveryFiles | 
|---|
| 1138 |  | 
|---|
| 1139 |        # Skip the preliminary processing if LVs are not possible. | 
|---|
| 1140 |        [[ $sourceCluster != rpd && $sourceCluster != hacmp ]] &&  \ | 
|---|
| 1141 |          break | 
|---|
| 1142 |  | 
|---|
| 1143 |        # Skip the preliminary processing if -R is specified. | 
|---|
| 1144 |        [[ -n $Rflag ]] &&  \ | 
|---|
| 1145 |          break | 
|---|
| 1146 |        ;; | 
|---|
| 1147 |  | 
|---|
| 1148 |     $SG_HEADR )  # This is the header line for some file system. | 
|---|
| 1149 |        # Starting the processing of a new file system. | 
|---|
| 1150 |        # See if the file system should be imported. | 
|---|
| 1151 |        if [[ ${v[$DEV_NAME_Field]} = $deviceName || -n $importAll ]] | 
|---|
| 1152 |        then | 
|---|
| 1153 |          importThisFileSystem=true | 
|---|
| 1154 |        else | 
|---|
| 1155 |          importThisFileSystem="" | 
|---|
| 1156 |        fi | 
|---|
| 1157 |  | 
|---|
| 1158 |        # Verify that the target cluster does not already | 
|---|
| 1159 |        # have a file system with the same name. | 
|---|
| 1160 |        if [[ -n $importThisFileSystem && | 
|---|
| 1161 |              $existingFileSystems = *" ${v[$DEV_NAME_Field]} "* ]] | 
|---|
| 1162 |        then | 
|---|
| 1163 |          importThisFileSystem="" | 
|---|
| 1164 |        fi | 
|---|
| 1165 |        ;; | 
|---|
| 1166 |  | 
|---|
| 1167 |     $SG_ETCFS )  # This line is a stanza line for one of the file systems. | 
|---|
| 1168 |        # If this is the first line in the stanza for a file system | 
|---|
| 1169 |        # being imported, verify that the mount point does not already | 
|---|
| 1170 |        # exist in the target cluster. | 
|---|
| 1171 |        if [[ ${v[$LINE_NUMBER_Field]} = $MOUNT_POINT_Line && | 
|---|
| 1172 |              -n $importThisFileSystem && | 
|---|
| 1173 |              $existingMountPoints = *" ${v[$ETCFS_TEXT_Field]} "* ]] | 
|---|
| 1174 |        then | 
|---|
| 1175 |          importThisFileSystem="" | 
|---|
| 1176 |        fi | 
|---|
| 1177 |        ;; | 
|---|
| 1178 |  | 
|---|
| 1179 |     $SG_DISKS )  # This line describes a disk. | 
|---|
| 1180 |        # Create the device suffix to be used for temp files. | 
|---|
| 1181 |        if [[ ${v[$DEV_NAME_Field]} = $NO_DEVICE ]] | 
|---|
| 1182 |        then | 
|---|
| 1183 |          # Avoid any name collision by using ":", a prohibited character. | 
|---|
| 1184 |          suffix=_FREEDISK:_ | 
|---|
| 1185 |        else | 
|---|
| 1186 |          suffix=${v[$DEV_NAME_Field]} | 
|---|
| 1187 |        fi | 
|---|
| 1188 |  | 
|---|
| 1189 |        # Decide if this disk is to be imported.  If the disk belongs to some | 
|---|
| 1190 |        # file system, the importThisFileSystem flag already has the correct | 
|---|
| 1191 |        # value.  If this is a free disk, it will be imported only if all file | 
|---|
| 1192 |        # systems are being imported.  Note that the importThisFileSystem flag | 
|---|
| 1193 |        # is used to control the importing of disks that are part of some file | 
|---|
| 1194 |        # system as well as the importing of free disks. | 
|---|
| 1195 |        if [[ ${v[$NODESETID_Field]} = $FREE_DISK ]] | 
|---|
| 1196 |        then | 
|---|
| 1197 |          if [[ -z $importAll ]] | 
|---|
| 1198 |          then | 
|---|
| 1199 |            importThisFileSystem="" | 
|---|
| 1200 |          else | 
|---|
| 1201 |            importThisFileSystem=true | 
|---|
| 1202 |          fi | 
|---|
| 1203 |        fi | 
|---|
| 1204 |  | 
|---|
| 1205 |        # If this disk belongs to a file system being imported, verify that | 
|---|
| 1206 |        # there are no name conflicts.  If there is a name conflict with a | 
|---|
| 1207 |        # disk that is part of a file system, that file system is dropped. | 
|---|
| 1208 |        # If the conflict is with a free disk, only that disk is dropped. | 
|---|
| 1209 |        if [[ -n $importThisFileSystem ]] | 
|---|
| 1210 |        then | 
|---|
| 1211 |          # Check the name. | 
|---|
| 1212 |          conflictingDisk=$($grep -w ${v[$DISK_NAME_Field]} $existingDisks 2>/dev/null) | 
|---|
| 1213 |          if [[ -n $conflictingDisk ]] | 
|---|
| 1214 |          then | 
|---|
| 1215 |            # There is already a disk with the same name. | 
|---|
| 1216 |            if [[ ${v[$DEV_NAME_Field]} != $NO_DEVICE ]] | 
|---|
| 1217 |            then | 
|---|
| 1218 |              $rm -f $resetLVs.$suffix | 
|---|
| 1219 |            fi | 
|---|
| 1220 |            importThisFileSystem="" | 
|---|
| 1221 |          fi  # end if [[ -n $conflictingDisk ]] | 
|---|
| 1222 |        fi  # end of if [[ -n $importThisFileSystem ]] | 
|---|
| 1223 |  | 
|---|
| 1224 |        # If this is a PR-capable logical volume, | 
|---|
| 1225 |        # add the line to the disks to be unfenced. | 
|---|
| 1226 |        if [[ -n $importThisFileSystem      && | 
|---|
| 1227 |              ${v[$DISK_TYPE_Field]} = "lv" && | 
|---|
| 1228 |              ${v[$DISK_SUBTYPE_Field]} != "other" ]] | 
|---|
| 1229 |        then | 
|---|
| 1230 |          print -- ${sdrfsLine} >> $resetLVs.$suffix | 
|---|
| 1231 |          checkForErrors "writing to file $resetLVs.$suffix" $? | 
|---|
| 1232 |        fi | 
|---|
| 1233 |        ;; | 
|---|
| 1234 |  | 
|---|
| 1235 |     * )  # Pass all other lines without a change. | 
|---|
| 1236 |        ;; | 
|---|
| 1237 |  | 
|---|
| 1238 |   esac  # end of case ${v[$LINE_TYPE_Field]} in | 
|---|
| 1239 |  | 
|---|
| 1240 |   IFS=":"  # Change the separator back to ":" for the next iteration. | 
|---|
| 1241 |  | 
|---|
| 1242 | done  # end while read -u3 sdrfsLine | 
|---|
| 1243 |  | 
|---|
| 1244 | IFS="$IFS_sv"  # Restore the default IFS settings. | 
|---|
| 1245 |  | 
|---|
| 1246 | # Combine all resetLVs files. | 
|---|
| 1247 | for fs in $($ls $resetLVs.* 2>/dev/null) | 
|---|
| 1248 | do | 
|---|
| 1249 |   $cat $fs >> $disksToUnfence | 
|---|
| 1250 |   checkForErrors "writing to file $disksToUnfence" $? | 
|---|
| 1251 | done | 
|---|
| 1252 |  | 
|---|
| 1253 | # If there are disks to unfence, do it now. | 
|---|
| 1254 | if [[ -s $disksToUnfence ]] | 
|---|
| 1255 | then | 
|---|
| 1256 |   unfenceLogicalVolumes $aixNodes $disksToUnfence | 
|---|
| 1257 |   rc=$? | 
|---|
| 1258 | fi | 
|---|
| 1259 |  | 
|---|
| 1260 |  | 
|---|
| 1261 | ########################################################################### | 
|---|
| 1262 | # Go through the input file with the exportfs information and extract | 
|---|
| 1263 | # in separate files the information for each individual file system | 
|---|
| 1264 | # that is to be imported.  Verify that there are no name conflicts and | 
|---|
| 1265 | # adjust the target nodeset id if necessary. | 
|---|
| 1266 | ########################################################################### | 
|---|
| 1267 | $rm -f $importFile.* $resetNSDs.* $importedFreeDisks $resetFreeDisks | 
|---|
| 1268 | IFS=":" | 
|---|
| 1269 | exec 3<&- | 
|---|
| 1270 | exec 3< $fsImportData | 
|---|
| 1271 | while read -u3 sdrfsLine | 
|---|
| 1272 | do | 
|---|
| 1273 |   # Parse the line. | 
|---|
| 1274 |   set -f ; set -A v -- - $sdrfsLine ; set +f | 
|---|
| 1275 |  | 
|---|
| 1276 |   IFS="$IFS_sv"    # Restore the default IFS settings. | 
|---|
| 1277 |   printLine=true   # Assume the line will be printed. | 
|---|
| 1278 |  | 
|---|
| 1279 |   case ${v[$LINE_TYPE_Field]} in | 
|---|
| 1280 |  | 
|---|
| 1281 |  # The version line has been processed in the preliminary pass. | 
|---|
| 1282 |  #  $VERSION_LINE )  # This is the global header line. | 
|---|
| 1283 |  #     sourceCluster=${v[$CLUSTER_TYPE_Field]} | 
|---|
| 1284 |  #     checkClusterCompatibility $sourceCluster $targetCluster | 
|---|
| 1285 |  #     rc=$? | 
|---|
| 1286 |  #     if [[ $rc -ne 0 ]] | 
|---|
| 1287 |  #     then | 
|---|
| 1288 |  #       # Incompatible cluster types. | 
|---|
| 1289 |  #       printErrorMsg 44 $mmcmd $sourceCluster $targetCluster | 
|---|
| 1290 |  #       cleanupAndExit | 
|---|
| 1291 |  #     fi | 
|---|
| 1292 |  #     getDiskRecoveryInformation $sourceCluster $recoveryFiles | 
|---|
| 1293 |  #     ;; | 
|---|
| 1294 |  | 
|---|
| 1295 |     $SG_HEADR )  # This is the header line for some file system. | 
|---|
| 1296 |        # Starting the processing of a new file system. | 
|---|
| 1297 |        # See if the file system should be imported. | 
|---|
| 1298 |        if [[ ${v[$DEV_NAME_Field]} = $deviceName || -n $importAll ]] | 
|---|
| 1299 |        then | 
|---|
| 1300 |          # This file system should be imported. | 
|---|
| 1301 |          importThisFileSystem=true | 
|---|
| 1302 |          if [[ -n $importAll ]] | 
|---|
| 1303 |          then | 
|---|
| 1304 |            someFsFound=true | 
|---|
| 1305 |          else | 
|---|
| 1306 |            specifiedFsFound=true | 
|---|
| 1307 |          fi | 
|---|
| 1308 |          # Put an informational message:  processing file system ... | 
|---|
| 1309 |          print -- ""  # Output a blank separator line. | 
|---|
| 1310 |          printInfoMsg 250 $mmcmd ${v[$DEV_NAME_Field]} | 
|---|
| 1311 |        else | 
|---|
| 1312 |          # This file system should not be imported. | 
|---|
| 1313 |          importThisFileSystem="" | 
|---|
| 1314 |        fi # end of if [[ ${v[$DEV_NAME_Field]} = $deviceName || -n $importAll ]] | 
|---|
| 1315 |  | 
|---|
| 1316 |        # Verify that the target cluster does not already | 
|---|
| 1317 |        # have a file system with the same name. | 
|---|
| 1318 |        if [[ -n $importThisFileSystem && | 
|---|
| 1319 |              $existingFileSystems = *" ${v[$DEV_NAME_Field]} "* ]] | 
|---|
| 1320 |        then | 
|---|
| 1321 |          # There is already a file system with the same name. | 
|---|
| 1322 |          printErrorMsg 48 $mmcmd ${v[$DEV_NAME_Field]} | 
|---|
| 1323 |          failedFileSystems="${failedFileSystems}\n\t${v[$DEV_NAME_Field]}" | 
|---|
| 1324 |          importThisFileSystem="" | 
|---|
| 1325 |        fi | 
|---|
| 1326 |  | 
|---|
| 1327 |        # If the file system will be imported and there are no problems so far, | 
|---|
| 1328 |        # start building temporary files with the file system information. | 
|---|
| 1329 |        if [[ -n $importThisFileSystem ]] | 
|---|
| 1330 |        then | 
|---|
| 1331 |          # First, figure out what the device minor number should be. | 
|---|
| 1332 |          # Keep trying until we get an unused minor number.  If this | 
|---|
| 1333 |          # does not work, we'll leave the device minor field null | 
|---|
| 1334 |          # hoping that mmfsmknod will take care of things later on. | 
|---|
| 1335 |          rc=0 | 
|---|
| 1336 |          newDevMinor="" | 
|---|
| 1337 |          while [[ -z $newDevMinor && rc -eq 0 ]] | 
|---|
| 1338 |          do | 
|---|
| 1339 |            # Assign a minor number to the file system. | 
|---|
| 1340 |            devMinor=$(assignDevMinor "$existingMinorNumbers") | 
|---|
| 1341 |            rc=$? | 
|---|
| 1342 |            if [[ $rc -eq 0 ]] | 
|---|
| 1343 |            then | 
|---|
| 1344 |              # See if the new device number is not being used by somebody on | 
|---|
| 1345 |              # the local node.  This is a crude check but better than nothing. | 
|---|
| 1346 |              # Going and checking all nodes in the nodeset is too expensive. | 
|---|
| 1347 |              inuse=$($ls -lL /dev 2>/dev/null |  \ | 
|---|
| 1348 |                    $grep "^${fsDeviceType}.* $devMajor, *$devMinor ") | 
|---|
| 1349 |  | 
|---|
| 1350 |              # The number seems to be free, use it. | 
|---|
| 1351 |              [[ -z $inuse ]] && newDevMinor=$devMinor | 
|---|
| 1352 |  | 
|---|
| 1353 |              # Add the number to the list of existing number. | 
|---|
| 1354 |              existingMinorNumbers="$existingMinorNumbers $devMinor" | 
|---|
| 1355 |  | 
|---|
| 1356 |            fi  # end of if [[ $rc -eq 0 ]] | 
|---|
| 1357 |          done # end of while [[ -z $newDevMinor && rc -eq 0 ]] | 
|---|
| 1358 |  | 
|---|
| 1359 |          # Change some of the fields as needed and put the line out. | 
|---|
| 1360 |          v[$NODESETID_Field]=$targetNodesetId | 
|---|
| 1361 |          v[$DEV_MINOR_Field]=$devMinor | 
|---|
| 1362 |          print_newLine >> $importFile.${v[$DEV_NAME_Field]} | 
|---|
| 1363 |          checkForErrors "writing to file $importFile.${v[$DEV_NAME_Field]}" $? | 
|---|
| 1364 |        fi | 
|---|
| 1365 |        ;; | 
|---|
| 1366 |  | 
|---|
| 1367 |     $SG_ETCFS )  # This line is a stanza line for one of the file systems. | 
|---|
| 1368 |        # If this is the first line in the stanza for a file system | 
|---|
| 1369 |        # being imported, verify that the mount point does not already | 
|---|
| 1370 |        # exist in the target cluster. | 
|---|
| 1371 |        if [[ ${v[$LINE_NUMBER_Field]} = $MOUNT_POINT_Line && | 
|---|
| 1372 |              -n $importThisFileSystem && | 
|---|
| 1373 |              $existingMountPoints = *" ${v[$ETCFS_TEXT_Field]} "* ]] | 
|---|
| 1374 |        then | 
|---|
| 1375 |          # There is already a file system with the same mount point. | 
|---|
| 1376 |          # Tell the guy to use mmchfs -T to change the existing mount point. | 
|---|
| 1377 |          printErrorMsg 49 $mmcmd ${v[$DEV_NAME_Field]} ${v[$ETCFS_TEXT_Field]} | 
|---|
| 1378 |          failedFileSystems="${failedFileSystems}\n\t${v[$DEV_NAME_Field]}" | 
|---|
| 1379 |          $rm -f $importFile.${v[$DEV_NAME_Field]} $resetNSDs.${v[$DEV_NAME_Field]} | 
|---|
| 1380 |          importThisFileSystem="" | 
|---|
| 1381 |        fi | 
|---|
| 1382 |  | 
|---|
| 1383 |        # If the file system will be imported and there are no problems so far, | 
|---|
| 1384 |        # add the lines to the temporary files with the file system information. | 
|---|
| 1385 |        if [[ -n $importThisFileSystem ]] | 
|---|
| 1386 |        then | 
|---|
| 1387 |          v[$NODESETID_Field]=$targetNodesetId | 
|---|
| 1388 |          print_newLine >> $importFile.${v[$DEV_NAME_Field]} | 
|---|
| 1389 |          checkForErrors "writing to file $importFile.${v[$DEV_NAME_Field]}" $? | 
|---|
| 1390 |        fi | 
|---|
| 1391 |        ;; | 
|---|
| 1392 |  | 
|---|
| 1393 |     $SG_MOUNT )  # This line has the mount options. | 
|---|
| 1394 |        # If the file system will be imported and there are no problems so far, | 
|---|
| 1395 |        # add the line to the temporary file with the file system information. | 
|---|
| 1396 |        if [[ -n $importThisFileSystem ]] | 
|---|
| 1397 |        then | 
|---|
| 1398 |          v[$NODESETID_Field]=$targetNodesetId | 
|---|
| 1399 |          print_newLine >> $importFile.${v[$DEV_NAME_Field]} | 
|---|
| 1400 |          checkForErrors "writing to file $importFile.${v[$DEV_NAME_Field]}" $? | 
|---|
| 1401 |        fi | 
|---|
| 1402 |        ;; | 
|---|
| 1403 |  | 
|---|
| 1404 |     $SG_DISKS )  # This line describes a disk. | 
|---|
| 1405 |        # Decide if this disk is to be imported.  If the disk belongs to some | 
|---|
| 1406 |        # file system, the importThisFileSystem flag already has the correct | 
|---|
| 1407 |        # value.  If this is a free disk, it will be imported only if all file | 
|---|
| 1408 |        # systems are being imported.  Note that the importThisFileSystem flag | 
|---|
| 1409 |        # is used to control the importing of disks that are part of some file | 
|---|
| 1410 |        # system as well as the importing of free disks. | 
|---|
| 1411 |        if [[ ${v[$NODESETID_Field]} = $FREE_DISK ]] | 
|---|
| 1412 |        then | 
|---|
| 1413 |          if [[ -z $importAll ]] | 
|---|
| 1414 |          then | 
|---|
| 1415 |            importThisFileSystem="" | 
|---|
| 1416 |          else | 
|---|
| 1417 |            importThisFileSystem=true | 
|---|
| 1418 |            # If not done already, put an informational message. | 
|---|
| 1419 |            if [[ -z $freeDiskStartMsg ]] | 
|---|
| 1420 |            then | 
|---|
| 1421 |              # Put an informational message:  processing free disks ... | 
|---|
| 1422 |              print -- ""  # Output a blank separator line. | 
|---|
| 1423 |              printInfoMsg 98 $mmcmd | 
|---|
| 1424 |              freeDiskStartMsg=issued | 
|---|
| 1425 |            fi | 
|---|
| 1426 |          fi  # end if [[ -z $importAll ]] | 
|---|
| 1427 |        fi  # end if [[ ${v[$NODESETID_Field]} = $FREE_DISK ]] | 
|---|
| 1428 |  | 
|---|
| 1429 |        # If this disk belongs to a file system being imported, verify that | 
|---|
| 1430 |        # there are no name conflicts.  If there is a name conflict with a | 
|---|
| 1431 |        # disk that is part of a file system, that file system is dropped. | 
|---|
| 1432 |        # If the conflict is with a free disk, only that disk is dropped. | 
|---|
| 1433 |        if [[ -n $importThisFileSystem ]] | 
|---|
| 1434 |        then | 
|---|
| 1435 |          # Put an informational message:  processing disk ... | 
|---|
| 1436 |          printInfoMsg 251 $mmcmd ${v[$DISK_NAME_Field]} | 
|---|
| 1437 |          # Check the name. | 
|---|
| 1438 |          conflictingDisk=$($grep -w ${v[$DISK_NAME_Field]} $existingDisks 2>/dev/null) | 
|---|
| 1439 |          if [[ -n $conflictingDisk ]] | 
|---|
| 1440 |          then | 
|---|
| 1441 |            # There is already a disk with the same name. | 
|---|
| 1442 |            printErrorMsg 51 $mmcmd ${v[$DISK_NAME_Field]} | 
|---|
| 1443 |            if [[ ${v[$DEV_NAME_Field]} != $NO_DEVICE ]] | 
|---|
| 1444 |            then | 
|---|
| 1445 |              failedFileSystems="${failedFileSystems}\n\t${v[$DEV_NAME_Field]}" | 
|---|
| 1446 |              $rm -f $importFile.${v[$DEV_NAME_Field]} $resetNSDs.${v[$DEV_NAME_Field]} | 
|---|
| 1447 |            fi | 
|---|
| 1448 |            importThisFileSystem="" | 
|---|
| 1449 |          fi  # end if [[ -n $conflictingDisk ]] | 
|---|
| 1450 |        fi  # end of if [[ -n $importThisFileSystem ]] | 
|---|
| 1451 |  | 
|---|
| 1452 |        # If the file system will be imported and there are no problems so far, | 
|---|
| 1453 |        # add the lines to the temporary files with the file system information. | 
|---|
| 1454 |        if [[ -n $importThisFileSystem ]] | 
|---|
| 1455 |        then | 
|---|
| 1456 |          # Ensure the disk is of the correct type for the cluster. | 
|---|
| 1457 |          importDiskOutput=$(importDisk_$targetCluster  \ | 
|---|
| 1458 |               $sourceCluster $sdrfsLine $targetNodesetId $changeSpecFile) | 
|---|
| 1459 |          rc=$? | 
|---|
| 1460 |  | 
|---|
| 1461 |          # The output of importDisk consists of a one word overall result, | 
|---|
| 1462 |          # followed by the updated SG_DISKS line.  Separate the two parts. | 
|---|
| 1463 |          importDiskResult=${importDiskOutput%% *} | 
|---|
| 1464 |          newDiskLine="${importDiskOutput#* }" | 
|---|
| 1465 |          if [[ $importDiskResult = success* ]] | 
|---|
| 1466 |          then | 
|---|
| 1467 |            if [[ ${v[$DEV_NAME_Field]} = $NO_DEVICE ]] | 
|---|
| 1468 |            then | 
|---|
| 1469 |              print -- ${newDiskLine} >> $importedFreeDisks | 
|---|
| 1470 |              checkForErrors "writing to file $importedFreeDisks" $? | 
|---|
| 1471 |            else | 
|---|
| 1472 |              print -- ${newDiskLine} >> $importFile.${v[$DEV_NAME_Field]} | 
|---|
| 1473 |              checkForErrors "writing to file $importFile.${v[$DEV_NAME_Field]}" $? | 
|---|
| 1474 |            fi | 
|---|
| 1475 |  | 
|---|
| 1476 |            if [[ $importDiskResult = successServersRemoved ]] | 
|---|
| 1477 |            then | 
|---|
| 1478 |              if [[ ${v[$DEV_NAME_Field]} = $NO_DEVICE ]] | 
|---|
| 1479 |              then | 
|---|
| 1480 |                print -- "\t${v[$DISK_NAME_Field]}" >> $resetFreeDisks | 
|---|
| 1481 |                checkForErrors "writing to file $resetFreeDisks" $? | 
|---|
| 1482 |              else | 
|---|
| 1483 |                print -- "\t${v[$DISK_NAME_Field]}" >> $resetNSDs.${v[$DEV_NAME_Field]} | 
|---|
| 1484 |                checkForErrors "writing to file $resetNSDs.${v[$DEV_NAME_Field]}" $? | 
|---|
| 1485 |              fi | 
|---|
| 1486 |            fi  # end if [[ $importDiskResult = successServersRemoved ]] | 
|---|
| 1487 |  | 
|---|
| 1488 |            # Keep track of the highest NSD number assigned to a disk. | 
|---|
| 1489 |            if [[ ${v[$DISK_NAME_Field]} = gpfs+([0-9])nsd ]] | 
|---|
| 1490 |            then | 
|---|
| 1491 |              nsdName=${v[$DISK_NAME_Field]} | 
|---|
| 1492 |              nsdNumber=${nsdName#gpfs} | 
|---|
| 1493 |              nsdNumber=${nsdNumber%nsd} | 
|---|
| 1494 |              [[ $nsdNumber -gt $maxDiskNumber ]] && maxDiskNumber=$nsdNumber | 
|---|
| 1495 |            fi | 
|---|
| 1496 |  | 
|---|
| 1497 |          else | 
|---|
| 1498 |            # There is a problem with this disk; | 
|---|
| 1499 |            # free disk errors are reported but ignored. | 
|---|
| 1500 |            printErrorMsg 50 $mmcmd ${v[$DISK_NAME_Field]} | 
|---|
| 1501 |            if [[ ${v[$DEV_NAME_Field]} != $NO_DEVICE ]] | 
|---|
| 1502 |            then | 
|---|
| 1503 |              failedFileSystems="${failedFileSystems}\n\t${v[$DEV_NAME_Field]}" | 
|---|
| 1504 |              $rm -f $importFile.${v[$DEV_NAME_Field]} $resetNSDs.${v[$DEV_NAME_Field]} | 
|---|
| 1505 |              importThisFileSystem="" | 
|---|
| 1506 |            fi | 
|---|
| 1507 |          fi  # end of if [[ $importDiskResult = success* ]] | 
|---|
| 1508 |        fi  # end of if [[ -n $importThisFileSystem ]] | 
|---|
| 1509 |        ;; | 
|---|
| 1510 |  | 
|---|
| 1511 |     * )  # Pass all other lines without a change. | 
|---|
| 1512 |        ;; | 
|---|
| 1513 |  | 
|---|
| 1514 |   esac  # end of case ${v[$LINE_TYPE_Field]} in | 
|---|
| 1515 |  | 
|---|
| 1516 |   IFS=":"  # Change the separator back to ":" for the next iteration. | 
|---|
| 1517 |  | 
|---|
| 1518 | done  # end while read -u3 sdrfsLine | 
|---|
| 1519 |  | 
|---|
| 1520 | IFS="$IFS_sv"  # Restore the default IFS settings. | 
|---|
| 1521 |  | 
|---|
| 1522 |  | 
|---|
| 1523 | ################################################################### | 
|---|
| 1524 | # Add to the new mmsdrfs file the information for all file systems | 
|---|
| 1525 | # that have not encountered any problems so far. | 
|---|
| 1526 | ################################################################### | 
|---|
| 1527 | for fs in $($ls $importFile.* 2>/dev/null) | 
|---|
| 1528 | do | 
|---|
| 1529 |   $cat $fs >> $newsdrfs | 
|---|
| 1530 |   checkForErrors "writing to file $newsdrfs" $? | 
|---|
| 1531 |   fsToImport="$fsToImport\n\t${fs#$importFile.}" | 
|---|
| 1532 | done | 
|---|
| 1533 |  | 
|---|
| 1534 | # Add the imported free disks, if any. | 
|---|
| 1535 | if [[ -s $importedFreeDisks ]] | 
|---|
| 1536 | then | 
|---|
| 1537 |   $cat $importedFreeDisks >> $newsdrfs | 
|---|
| 1538 |   checkForErrors "writing to file $newsdrfs" $? | 
|---|
| 1539 | fi | 
|---|
| 1540 |  | 
|---|
| 1541 | # If nothing was imported, there is no sense continuing. | 
|---|
| 1542 | if [[ -z $fsToImport && ! -s $importedFreeDisks ]] | 
|---|
| 1543 | then | 
|---|
| 1544 |   # There is nothing to do.  Issue appropriate messages. | 
|---|
| 1545 |   if [[ -n $importAll && -z $someFsFound ]] | 
|---|
| 1546 |   then | 
|---|
| 1547 |     # There is no file system information in the input file. | 
|---|
| 1548 |     printErrorMsg 273 $mmcmd $fsImportData | 
|---|
| 1549 |   elif [[ -z $importAll && -z $specifiedFsFound ]] | 
|---|
| 1550 |   then | 
|---|
| 1551 |     # The file system was not found in the input file. | 
|---|
| 1552 |     printErrorMsg 274 $mmcmd $device $fsImportData | 
|---|
| 1553 |   else | 
|---|
| 1554 |     :  # nothing here for now | 
|---|
| 1555 |   fi | 
|---|
| 1556 |  | 
|---|
| 1557 |   # Tell the user which file systems had problems. | 
|---|
| 1558 |   if [[ -n $failedFileSystems ]] | 
|---|
| 1559 |   then | 
|---|
| 1560 |     # Report the file systems that were not imported. | 
|---|
| 1561 |     print -- ""   # Output a blank separator line. | 
|---|
| 1562 |     printErrorMsg 275 $mmcmd "$failedFileSystems" | 
|---|
| 1563 |   fi | 
|---|
| 1564 |  | 
|---|
| 1565 |   # The command failed. | 
|---|
| 1566 |   printErrorMsg 389 $mmcmd | 
|---|
| 1567 |   cleanupAndExit | 
|---|
| 1568 | fi | 
|---|
| 1569 |  | 
|---|
| 1570 |  | 
|---|
| 1571 | ######################################################## | 
|---|
| 1572 | # Update the HIGHEST_GPFS_DISK_NBR_Field if necessary. | 
|---|
| 1573 | ######################################################## | 
|---|
| 1574 | $rm -f $tmpfile   # Make sure there is nothing in the file. | 
|---|
| 1575 | if [[ $maxDiskNumber -gt $prevMaxDiskNumber && $MMMODE = lc ]] | 
|---|
| 1576 | then | 
|---|
| 1577 |   $awk -F:  '                                                                 \ | 
|---|
| 1578 |      # If this is the global header line, change the max NSD number.          \ | 
|---|
| 1579 |      /^'$GLOBAL_ID:$VERSION_LINE:'/ {                                         \ | 
|---|
| 1580 |         { $'$HIGHEST_GPFS_DISK_NBR_Field' = "'$maxDiskNumber'" }              \ | 
|---|
| 1581 |         { print  $1":" $2":" $3":" $4":" $5":" $6":" $7":" $8":" $9":"$10":"  \ | 
|---|
| 1582 |                 $11":"$12":"$13":"$14":"$15":"$16":"$17":"$18":"$19":"$20":"  \ | 
|---|
| 1583 |                 $21":"$22":"$23":"$24":"$25":"$26":"$27":" >> "'$tmpfile'" }  \ | 
|---|
| 1584 |         { next }                                                              \ | 
|---|
| 1585 |      }                                                                        \ | 
|---|
| 1586 |      # All other lines are echoed without change.                             \ | 
|---|
| 1587 |      { print $0 >> "'$tmpfile'" }                                             \ | 
|---|
| 1588 |   ' $newsdrfs | 
|---|
| 1589 |   checkForErrors awk $? | 
|---|
| 1590 |  | 
|---|
| 1591 |   # The file was updated successfully. | 
|---|
| 1592 |   $mv $tmpfile $newsdrfs | 
|---|
| 1593 |   checkForErrors "mv $outfile $newsdrfs" $? | 
|---|
| 1594 | fi | 
|---|
| 1595 |  | 
|---|
| 1596 |  | 
|---|
| 1597 | ############################################ | 
|---|
| 1598 | # Sort the new version of the mmsdrfs file. | 
|---|
| 1599 | ############################################ | 
|---|
| 1600 | LC_ALL=C $SORT_MMSDRFS $newsdrfs -o $newsdrfs | 
|---|
| 1601 | checkForErrors "sorting $newsdrfs" $? | 
|---|
| 1602 |  | 
|---|
| 1603 |  | 
|---|
| 1604 | ############################################################ | 
|---|
| 1605 | # Replace the mmsdrfs file in the sdr with the new version. | 
|---|
| 1606 | ############################################################ | 
|---|
| 1607 | print -- ""   # Output a blank separator line. | 
|---|
| 1608 | print -- "$mmcmd: Committing the changes ..." | 
|---|
| 1609 |  | 
|---|
| 1610 | trap "" HUP INT QUIT KILL | 
|---|
| 1611 | gpfsObjectInfo=$(commitChanges  \ | 
|---|
| 1612 |    $nsId $nsId $gpfsObjectInfo $newGenNumber $newsdrfs $primaryServer) | 
|---|
| 1613 | rc=$? | 
|---|
| 1614 | if [[ $rc -ne 0 ]] | 
|---|
| 1615 | then | 
|---|
| 1616 |   # Cannot replace the file in the sdr. | 
|---|
| 1617 |   printErrorMsg 381 $mmcmd | 
|---|
| 1618 |   cleanupAndExit | 
|---|
| 1619 | fi | 
|---|
| 1620 |  | 
|---|
| 1621 |  | 
|---|
| 1622 | ################################################################### | 
|---|
| 1623 | # Unlock the sdr. | 
|---|
| 1624 | ################################################################### | 
|---|
| 1625 | freeLockOnServer $primaryServer $ourNodeNumber >/dev/null | 
|---|
| 1626 | sdrLocked=no | 
|---|
| 1627 | trap posttrap HUP INT QUIT KILL | 
|---|
| 1628 |  | 
|---|
| 1629 |  | 
|---|
| 1630 | ###################################################################### | 
|---|
| 1631 | # Issue messages summarizing the results and what remains to be done. | 
|---|
| 1632 | ###################################################################### | 
|---|
| 1633 | print -- ""   # Output a blank separator line. | 
|---|
| 1634 | # Tell the user which file systems were successfully imported. | 
|---|
| 1635 | [[ -n $fsToImport ]] &&  \ | 
|---|
| 1636 |   print -u2 "$mmcmd: The following file systems were successfully imported: $fsToImport" | 
|---|
| 1637 |  | 
|---|
| 1638 | # Tell the user which disks may need new server nodes. | 
|---|
| 1639 | for fs in $($ls $resetNSDs.* 2>/dev/null) | 
|---|
| 1640 | do | 
|---|
| 1641 |   print -u2 "$mmcmd: The NSD servers for the following disks from file system ${fs#$resetNSDs.} were reset or not defined:" | 
|---|
| 1642 |   $cat $fs 1>&2 | 
|---|
| 1643 |   mmchnsdMessageNeeded=true | 
|---|
| 1644 | done | 
|---|
| 1645 | # Add the imported free disks, if any. | 
|---|
| 1646 | if [[ -s $resetFreeDisks ]] | 
|---|
| 1647 | then | 
|---|
| 1648 |   print -u2 "$mmcmd: The NSD servers for the following free disks were reset or not defined:" | 
|---|
| 1649 |   $cat $resetFreeDisks 1>&2 | 
|---|
| 1650 |   mmchnsdMessageNeeded=true | 
|---|
| 1651 | fi | 
|---|
| 1652 | [[ -n $mmchnsdMessageNeeded ]] &&  \ | 
|---|
| 1653 |   print -u2 "$mmcmd: Use the mmchnsd command to assign NSD servers as needed." | 
|---|
| 1654 |  | 
|---|
| 1655 | # Tell the user which file systems were not imported. | 
|---|
| 1656 | [[ -n $failedFileSystems ]] &&  \ | 
|---|
| 1657 |   print -u2 "$mmcmd: The following file systems were not imported: $failedFileSystems" | 
|---|
| 1658 |  | 
|---|
| 1659 |  | 
|---|
| 1660 | ################################################################# | 
|---|
| 1661 | # Propagate the new mmsdrfs file.  This process is asynchronous. | 
|---|
| 1662 | ################################################################# | 
|---|
| 1663 | propagateSdrfsFile async $allClusterNodes $newsdrfs $newGenNumber rereadnsd | 
|---|
| 1664 |  | 
|---|
| 1665 | cleanupAndExit 0 | 
|---|
| 1666 |  | 
|---|