source: gpfs_3.1_ker2.6.20/lpp/mmfs/bin/mmfsctl @ 16

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