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 | |
---|