source: gpfs_3.1_ker2.6.20/lpp/mmfs/bin/mmremotefs

Last change on this file was 16, checked in by rock, 17 years ago
  • Property svn:executable set to *
File size: 35.6 KB
Line 
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,2007
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# @(#)46 1.55.1.2 src/avs/fs/mmfs/ts/admin/mmremotefs.sh, mmfs, avs_rgpfs24, rgpfs24s012a 5/2/07 15:29:30
17###############################################################################
18#
19#  Usage:
20#
21#    mmremotefs add device -f remoteDevice -C remoteClusterName
22#                     -T mountPoint [-o mountOptions] [-A yes|no|automount]
23#
24#    mmremotefs update device [-f remoteDevice] [-C remoteClusterName]
25#                    [-T mountPoint] [-o mountOptions] [-A yes|no|automount]
26#
27#    mmremotefs delete {device | all | -C remoteClusterName}
28#
29#    mmremotefs show   [device | all | -C remoteClusterName]
30#
31#  where
32#
33#    device        is the local name for the remote file system.
34#                  This name must be unique within the local cluster.
35#                  The actual name of the file system within its home cluster
36#                  may or may not be the same.  See the -f parameter.
37#
38#    -f remoteDevice   is the actual device name for the remote file system
39#                      within the file system's home cluster.
40#
41#    -C remoteClusterName   is the fully-qualified name for the remote
42#                           cluster that owns the file system.
43#
44#    -T mountPoint     is the mount point directory of the file system.
45#
46#    -o mountOptions   is a comma-separated list of mount options.
47#                      The default set of options is:  rw,nomtime,atime
48#
49#    -A yes|no|automount  controls the automount option.  If yes is specified,
50#                      the file system is mounted automatically when the GPFS
51#                      daemon is started.  If no is specified, the file system
52#                      can be mounted only with an explicit mount command.
53#                      If automount is specified, the mounting of the file
54#                      system is controlled by the system automount daemon.
55#                      The default setting is no.
56#
57###############################################################################
58
59# Include global declarations and service routines.
60. /usr/lpp/mmfs/bin/mmglobfuncs
61. /usr/lpp/mmfs/bin/mmsdrfsdef
62. /usr/lpp/mmfs/bin/mmfsfuncs
63
64sourceFile="mmremotefs.sh"
65[[ -n $DEBUG || -n $DEBUGmmremotefs ]] && set -x
66$mmTRACE_ENTER "$*"
67
68# Local work files.  Names should be of the form:
69#   fn=${tmpDir}fn.${mmcmd}.$$
70mountCheckList=${tmpDir}mountCheckList.${mmcmd}.$$
71
72LOCAL_FILES=" $mountCheckList "
73
74
75# Local variables
76usageMsg=385
77contactNodesCount=0
78
79
80# Local functions
81
82
83###########################################################################
84#
85# Function:  Process the specified mount options string.
86#            Provide default values for missing options.
87#
88# Input:     $1 - A comma-separated list of mount options.
89#
90# Output:    Colon-separated string containing the fields:
91#              rwOption:mtimeOption:atimeOption:quotaOptions:otherOptions:
92#
93# Returns:   0 - success
94#            1 - error encountered
95#
96###########################################################################
97function parseMountOptions   # <optionsString>
98{
99  typeset sourceFile="mmremotefs.sh"
100  [[ -n $DEBUG || -n $DEBUGparseMountOptions ]] && set -x
101  $mmTRACE_ENTER "$*"
102  typeset optionsString=$1
103
104  typeset rc=0
105  typeset rwOption="rw"
106  typeset mtimeOption=""
107  typeset atimeOption=""
108  typeset quotaOptions=""
109  typeset otherOptions=""
110
111  # Clear the string if DELETE or DEFAULT is specified.
112  [[ $optionsString = DEFAULT || $optionsString = DELETE ]] &&  \
113    optionsString=""
114
115  # Parse the options string looking for certain options.
116  # All other options are simply passed through.
117  IFS=","
118  for option in $optionsString
119  do
120    case $option in
121
122      rw | ro | rs )
123        [[ $option = rs ]] && option=ro
124        rwOption=$option
125        ;;
126
127      atime* | noatime )
128        if [[ $option = atime || $option = "atime=1" || $option = "atime=yes" ]]
129        then
130          atimeOption=atime
131        elif [[ $option = noatime || $option = "atime=0" || $option = "atime=no" ]]
132        then
133          atimeOption=noatime
134        else
135          print -u2 "$mmcmd:  Invalid mount option specified: $option."
136          return 1
137        fi
138        ;;
139
140      mtime* | nomtime )
141        if [[ $option = mtime || $option = "mtime=1" || $option = "mtime=yes" ]]
142        then
143          mtimeOption=mtime
144        elif [[ $option = nomtime || $option = "mtime=0" || $option = "mtime=no" ]]
145        then
146          mtimeOption=nomtime
147        else
148          print -u2 "$mmcmd:  Invalid mount option specified: $option."
149          return 1
150        fi
151        ;;
152
153      syncnfs* | nosyncnfs )
154        if [[ $option = syncnfs || $option = "syncnfs=1" || $option = "syncnfs=yes" ]]
155        then
156          otherOptions="${otherOptions},syncnfs"
157        elif [[ $option = nosyncnfs || $option = "syncnfs=0" || $option = "syncnfs=no" ]]
158        then
159          otherOptions="${otherOptions},nosyncnfs"
160        else
161          print -u2 "$mmcmd:  Invalid mount option specified: $option."
162          return 1
163        fi
164        ;;
165
166      *quota* )
167        :       # Do nothing; quotas should be controlled with mmchfs -Q.
168        ;;
169
170      *rootSquash* )
171        :       # Do nothing; root squash is controlled with mmauth grant.
172        ;;
173
174      * )
175        otherOptions="${otherOptions},$option"
176        ;;
177
178    esac  # end of case $option in
179  done  # end of for option in $optionsString do
180  IFS="$IFS_sv"
181
182  otherOptions="${otherOptions##+(,)}"   # Strip leading  commas, if any.
183  otherOptions="${otherOptions%%+(,)}"   # Strip trailing commas, if any.
184
185  # Put out the results and return.
186  print -- "$rwOption:$mtimeOption:$atimeOption:$quotaOptions:$otherOptions"
187
188  $mmTRACE_EXIT "rc=$rc"
189  return $rc
190
191}  #------ end of function parseMountOptions -----------------
192
193
194
195#######################
196# Mainline processing
197#######################
198
199
200#######################################
201# Process the command line arguments.
202#######################################
203[[ $arg1 = '-?' || $arg1 = '-h' || $arg1 = '--help' || $arg1 = '--' ]] &&  \
204  syntaxError "help" $usageMsg
205
206action=$arg1
207
208[[ -z $action ]] &&  \
209  syntaxError "missingArgs" $usageMsg
210
211# Allow "ls" to be used in place of "show".
212[[ $action = ls ]] && action=show
213
214# Process the positional parameters.
215case $action in
216  add )
217    [[ $argc -lt 5 ]] && syntaxError "missingArgs" $usageMsg
218    device=$arg2
219    ;;
220
221  update )
222    [[ $argc -lt 3 ]] && syntaxError "missingArgs" $usageMsg
223    device=$arg2
224    ;;
225
226  delete )
227    [[ $argc -lt 2 ]] && syntaxError "missingArgs" $usageMsg
228    if [[ $arg2 = "-C"* ]]
229    then
230      remoteClusterName=${arg2#-C}
231      if [[ -z $remoteClusterName ]]
232      then
233        remoteClusterName=$arg3
234        [[ -n $arg4 ]] && syntaxError "extraArg" $usageMsg $arg4
235      else
236        [[ -n $arg3 ]] && syntaxError "extraArg" $usageMsg $arg3
237      fi
238      [[ -z $remoteClusterName ]] && syntaxError "missingValue" $usageMsg "-C"
239    else
240      device=$arg2
241      [[ -n $arg3 ]] && syntaxError "extraArg" $usageMsg $arg3
242    fi
243    ;;
244
245  show )
246    if [[ -z $arg2 ]]
247    then
248      device=all
249    elif [[ $arg2 = "-C"* ]]
250    then
251      remoteClusterName=${arg2#-C}
252      if [[ -z $remoteClusterName ]]
253      then
254        remoteClusterName=$arg3
255        [[ -n $arg4 ]] && syntaxError "extraArg" $usageMsg $arg4
256      else
257        [[ -n $arg3 ]] && syntaxError "extraArg" $usageMsg $arg3
258      fi
259      [[ -z $remoteClusterName ]] && syntaxError "missingValue" $usageMsg "-C"
260    else
261      device=$arg2
262      [[ -n $arg3 ]] && syntaxError "extraArg" $usageMsg $arg3
263    fi
264    ;;
265
266  *) # Invalid action specified.
267    syntaxError "keyword" $usageMsg $action
268    ;;
269esac
270
271
272# Verify the device name.
273deviceName=${device##+(/)dev+(/)}  # name stripped of /dev/ prefix
274fqDeviceName="/dev/$deviceName"    # fully-qualified name (with /dev/ prefix)
275if [[ $deviceName = /* ]]
276then
277  printErrorMsg 169 $mmcmd $device
278  cleanupAndExit
279elif [[ $deviceName = */* ]]
280then
281  printErrorMsg 170 $mmcmd $device
282  cleanupAndExit
283else
284  checkName deviceName 255 "$deviceName"
285  [[ $? -ne 0 ]] && cleanupAndExit
286fi
287
288# If action is "add" or "update", there are more options to process.
289if [[ $action = add || $action = update ]]
290then
291  shift 2    # Move past the fs name in the parameter list.
292
293  # Process the individual arguments and the values associated with them.
294  while getopts :A:C:f:k:n:o:T: OPT
295  do
296    case $OPT in
297
298      A) [[ -n $Aflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT"
299         Aflag="-$OPT"; Aarg=$OPTARG;
300         [[ $Aarg != yes && $Aarg != no && $Aarg != automount ]] &&  \
301           syntaxError "invalidOption" $usageMsg "-$OPT $OPTARG"
302         if [[ $Aarg = yes ]]
303         then
304           Aarg=mmfs
305         elif [[ $Aarg = no ]]
306         then
307           Aarg=false
308         else
309           :  # It must be "automount".
310         fi
311         ;;
312
313      C) [[ -n $Cflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT"
314         Cflag="-$OPT"; Carg=$OPTARG;
315         ;;
316
317      f) [[ -n $fflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT"
318         fflag="-$OPT"; farg=$OPTARG;
319         ;;
320
321      o) [[ -n $oflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT"
322         oflag="-$OPT"; oarg=$OPTARG;
323         [[ -z $oarg ]] && oarg=DEFAULT
324         ;;
325
326      T) [[ -n $Tflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT"
327         Tflag="-$OPT"; Targ=$OPTARG;
328         checkName pathName 1023 "$Targ"
329         [[ $? -ne 0 ]] && cleanupAndExit
330         # Ensure the pathname starts with a slash.
331         [[ $Targ = ${Targ#/} ]] &&  \
332           syntaxError "absolutePath" $noUsageMsg $Targ
333         ;;
334
335      +[ACfknoT)  # Invalid option.
336         syntaxError "invalidOption" $usageMsg $OPT
337         ;;
338
339      :) # Missing argument.
340         syntaxError "missingValue" $usageMsg $OPTARG
341         ;;
342
343      *) # Invalid option.
344         syntaxError "invalidOption" $usageMsg $OPTARG
345         ;;
346    esac
347  done
348
349  shift OPTIND-1
350  [[ $# != 0 ]] && syntaxError "extraArg" $usageMsg $1
351
352  # Verify input parameters and assign default values as needed.
353  if [[ $action = add ]]
354  then
355    [[ -z $Carg ]] && syntaxError "missingArgs" $usageMsg
356    [[ -z $Targ ]] && syntaxError "missingArgs" $usageMsg
357    [[ -z $farg ]] && syntaxError "missingArgs" $usageMsg
358    [[ -z $Aarg ]] && Aarg=false
359    if [[ $device = all ]]
360    then
361      # The device name cannot be "all".
362      printErrorMsg 196 $mmcmd
363      cleanupAndExit
364    fi
365  else  # action = update
366    if [[ -z $Aarg && -z $Carg && -z $farg && -z $oarg && -z $Targ ]]
367    then
368      # No changes made.
369      printErrorMsg 323 $mmcmd
370      cleanupAndExit
371    fi
372  fi  # end of if [[ $action = add ]]
373
374  # Initialize local variables.
375  remoteDevice=${farg##+(/)dev+(/)}  # name stripped of /dev/ prefix
376  if [[ $remoteDevice = /* ]]
377  then
378    printErrorMsg 169 $mmcmd "$farg"
379    cleanupAndExit
380  elif [[ $remoteDevice = */* ]]
381  then
382    printErrorMsg 170 $mmcmd "$farg"
383    cleanupAndExit
384  else
385    checkName deviceName 255 "$remoteDevice"
386    [[ $? -ne 0 ]] && cleanupAndExit
387  fi
388  remoteClusterName=$Carg
389  mountPoint=$Targ
390  automountValue=$Aarg
391  mountOptions=$oarg
392
393  # Determine the values for the /etc/filesystems stanza lines.
394  sgVFS_Line_Value="mmfs"
395  sgTYPE_Line_Value="mmfs"
396  sgNODENAME_Line_Value="-"
397  sgACCOUNT_Line_Value="false"
398  sgMOUNT_Line_Value=$automountValue
399
400  # Parse the mount options.
401  parseMountOptionsOutput=$(parseMountOptions $mountOptions)
402  IFS=":"
403  set -f ; set -- $parseMountOptionsOutput ; set +f
404  sgRW_OPT_Value=$1
405  sgMTIME_OPT_Value=$2
406  sgATIME_OPT_Value=$3
407  sgQUOTA_OPT_Value=$4
408  sgOTHER_OPT_Value=$5
409  IFS="$IFS_sv"
410
411  # The mount point cannot be the same as the device name.
412  if [[ $fqDeviceName = $mountPoint ]]
413  then
414    printErrorMsg 305 $mmcmd $mountPoint
415    cleanupAndExit
416  fi
417fi  # end of if [[ $action = add || $action = update ]]
418
419
420#####################################################################
421# Set up trap exception handling and call the gpfsInit function.
422# It will ensure that the local copy of the mmsdrfs and the rest of
423# the GPFS system files are up-to-date and will obtain the sdr lock.
424#####################################################################
425if [[ $action = show ]]
426then
427  trap pretrap2 HUP INT QUIT KILL
428  gpfsInitOutput=$(gpfsInit nolock)
429  rc=$?
430else
431  trap pretrap HUP INT QUIT KILL
432  gpfsInitOutput=$(gpfsInit $lockId)
433  rc=$?
434fi
435setGlobalVar $rc $gpfsInitOutput
436
437# Determine the lookup order for resolving host names.
438[[ $osName != AIX ]] && resolveOrder=$(setHostResolveOrder)
439
440
441#############################################################################
442#
443# Go through the mmsdrfs file.
444#
445# If action is "add", extract needed information to ensure that we can
446# safely add the new remote file system.
447#
448# If action is "update", make the needed changes to the mmsdrfs file.
449#
450# If action is "delete", remove the appropriate lines from the mmsdrfs file.
451#
452# If action is "show", extract and display the relevant information.
453#
454#############################################################################
455$rm -f $newsdrfs $nodefile $mountCheckList
456deleteThisFileSystem=no
457IFS=":"
458exec 3<&-
459exec 3< $mmsdrfsFile
460while read -u3 sdrfsLine
461do
462  # Parse the line.
463  set -f ; set -A v -- - $sdrfsLine ; set +f
464
465  IFS="$IFS_sv"   # Restore the default IFS settings.
466  printLine=true  # Assume the line will be printed.
467
468  # Change some of the fields depending on the type of line.
469  case ${v[$LINE_TYPE_Field]} in
470
471    $VERSION_LINE )
472      # Increment the generation number.
473      newGenNumber=${v[$SDRFS_GENNUM_Field]}+1
474      v[$SDRFS_GENNUM_Field]=$newGenNumber
475
476      ourClusterName=${v[$CLUSTER_NAME_Field]}
477      ;;
478
479    $MEMBER_NODE )
480      # Add the reliable node name to nodefile.
481      print -- "${v[$REL_HOSTNAME_Field]}" >> $nodefile
482      checkForErrors "writing to file $nodefile" $?
483
484      # If this is the line for the node that is executing
485      # this command, set the preferredNode variable.
486      [[ ${v[$NODE_NUMBER_Field]} = $ourNodeNumber ]] &&  \
487        preferredNode=${v[$REL_HOSTNAME_Field]}
488      ;;
489
490    $SG_HEADR )
491      # Processing depends on the specified action:
492      case $action in
493        add )
494          # Make sure that the file system that we want to create
495          # does not already exist.
496          if [[ ${v[$DEV_NAME_Field]} = $deviceName ]]
497          then
498            printErrorMsg 107 $mmcmd $device
499            cleanupAndExit
500          fi
501          if [[ ${v[$REMOTE_DEV_NAME_Field]} = $remoteDevice &&
502                 ${v[$NODESETID_Field]} = $remoteClusterName ]]
503          then
504            # The file system on the remote cluster is already defined.
505            printErrorMsg 317 $mmcmd $remoteDevice $remoteClusterName
506            cleanupAndExit
507          fi
508
509          # Make a list of the used minor numbers.
510          existingMinorNumbers="$existingMinorNumbers ${v[$DEV_MINOR_Field]}"
511          ;;
512
513        update )
514          if [[ ${v[$DEV_NAME_Field]} = $deviceName ]]
515          then
516            # We are making changes to this remote file system.
517            fsFound=yes
518
519            # Generate the fully-qualified name for the file system.
520            fsFullName="${v[$NODESETID_Field]}:${v[$REMOTE_DEV_NAME_Field]}"
521
522            # Verify that this is indeed a remote file system.
523            if [[ ${v[$FS_TYPE_Field]} != $remotefs ]]
524            then
525              # The file system is not a remote file system known to GPFS.
526              printErrorMsg 252 $mmcmd $device
527              cleanupAndExit
528            fi
529
530            if [[ -n $remoteDevice ]]
531            then
532              # We are changing the actual name of the file system.
533              v[$REMOTE_DEV_NAME_Field]=$remoteDevice
534              fsMustNotBeMounted=yes
535            fi
536
537            if [[ -n $remoteClusterName ]]
538            then
539              # We are changing the home cluster name.
540              v[$NODESETID_Field]=$remoteClusterName
541              fsMustNotBeMounted=yes
542            fi
543          fi  # end of if [[ ${v[$DEV_NAME_Field]} = $deviceName ]]
544          ;;
545
546        delete )
547          if [[ (${v[$DEV_NAME_Field]} = $deviceName || $device = all ||
548                 ${v[$NODESETID_Field]} = $remoteClusterName) &&
549                 ${v[$FS_TYPE_Field]} = $remotefs ]]
550          then
551            # This file system is going away.
552            deleteThisFileSystem=yes
553            fsFound=yes
554
555            # Generate the fully-qualified name for the file system.
556            # Put it, together with the local device name, on the list
557            # of file systems that should not be mounted.
558            fsFullName="${v[$NODESETID_Field]}:${v[$REMOTE_DEV_NAME_Field]}"
559            print -- "$fsFullName $deviceName" >> $mountCheckList
560            checkForErrors "writing to file $mountCheckList" $?
561
562          else
563            # This file system will remain in place.
564            deleteThisFileSystem=""
565            if [[ ${v[$DEV_NAME_Field]} = $deviceName ]]
566            then
567              # The file system is not a remote file system known to GPFS.
568              printErrorMsg 252 $mmcmd $device
569              cleanupAndExit
570            fi
571          fi  # end of if [[ (${v[$DEV_NAME_Field]} = $deviceName ... ]]
572
573          [[ -n $deleteThisFileSystem ]] &&  \
574            printLine=false
575          ;;
576
577        show )
578          if [[ (${v[$DEV_NAME_Field]}  = $deviceName || $device = all ||
579                 ${v[$NODESETID_Field]} = $remoteClusterName) &&
580                 ${v[$FS_TYPE_Field]} = $remotefs ]]
581          then
582            fsFound=yes
583            displayThisFileSystem=yes
584            if [[ -z $headerOut ]]
585            then
586              # Output the header line.
587              header=$(printInfoMsg 490)
588              printf "%s\n" "$header"
589              headerOut=yes
590            fi
591
592            # Start outputting the individual fields.
593            printf "%-11s %-12s %-22s" "${v[$DEV_NAME_Field]}"  \
594                   "${v[$REMOTE_DEV_NAME_Field]}" "${v[$NODESETID_Field]}"
595          else
596            displayThisFileSystem=""
597            if [[ ${v[$DEV_NAME_Field]} = $deviceName ]]
598            then
599              # The file system is not a remote file system known to GPFS.
600              printErrorMsg 252 $mmcmd $device
601              cleanupAndExit
602            fi
603          fi  # end of if [[ (${v[$DEV_NAME_Field]}  = $deviceName ...
604          ;;
605
606        *) checkForErrors "unexpected action $action" 1
607          ;;
608      esac  # end case $action in
609      ;;
610
611    $SG_ETCFS )
612      # Processing depends on the specified action:
613      case $action in
614        add )
615          # Make sure that the new mount point is not already used
616          # by some other file system in the nodeset.
617          if [[ ${v[$LINE_NUMBER_Field]} = $MOUNT_POINT_Line &&
618                ${v[$ETCFS_TEXT_Field]}  = $mountPoint ]]
619          then
620            printErrorMsg 107 $mmcmd $mountPoint
621            cleanupAndExit
622          fi
623
624          # See if any of the existing file systems requires
625          # the system automounter.
626          if [[ ${v[$LINE_NUMBER_Field]} = $MOUNT_Line &&
627                ${v[$ETCFS_TEXT_Field]}  = *automount* ]]
628          then
629            automountMounts=yes
630          fi
631          ;;
632
633        update )
634          if [[ -n $mountPoint ]]
635          then
636            # We are changing the mount point.
637            if [[ ${v[$LINE_NUMBER_Field]} = $MOUNT_POINT_Line ]]
638            then
639              # This is a mount point line for some file system.
640              # If this is the mount point for our file system,
641              # set it to the new value.  Otherwise, add it to
642              # the list of existing mount points.
643              if [[ ${v[$DEV_NAME_Field]} = $deviceName ]]
644              then
645                oldMountPoint=${v[$ETCFS_TEXT_Field]}
646                v[$ETCFS_TEXT_Field]=$mountPoint
647                fsMustNotBeMounted=yes
648              else
649                existingMountPoints="$existingMountPoints ${v[$ETCFS_TEXT_Field]}"
650              fi
651            fi
652          fi  # end of if [[ -n $mountPoint ]]
653
654          if [[ -n $automountValue ]]
655          then
656            # We are changing the automount option.
657            if [[ ${v[$LINE_NUMBER_Field]} = $MOUNT_Line ]]
658            then
659              # This is a mount line for some file system, i.e.,
660              # the ' mount = ... ' line in etc/filesystems.
661
662              # See if any file system requires the system automounter.
663              [[ ${v[$ETCFS_TEXT_Field]}  = *automount* ]] &&  \
664                automountMounts=yes
665
666              # If this is the mount line for our file system,
667              # set the new value for the mount option.
668              if [[ ${v[$DEV_NAME_Field]} = $deviceName ]]
669              then
670                # If switching to or from automount,
671                # the file system must be unmounted.
672                [[ $automountValue = automount ||
673                   ${v[$ETCFS_TEXT_Field]} = *automount* ]] &&  \
674                  fsMustNotBeMounted=yes
675
676                # Set the new value for the mount option.
677                v[$ETCFS_TEXT_Field]="$MOUNT_Line_Prefix$automountValue"
678              fi  # end of if [[ ${v[$DEV_NAME_Field]} = $deviceName ]]
679
680            fi  # end of if [[ ${v[$LINE_NUMBER_Field]} = $MOUNT_Line ]]
681          fi  # end of if [[ -n $automountValue ]]
682
683          if [[ -n $remoteClusterName && ${v[$DEV_NAME_Field]} = $deviceName ]]
684          then
685            # We are changing the home cluster name.
686            v[$NODESETID_Field]=$remoteClusterName
687          fi
688          ;;
689
690        delete )
691          [[ -n $deleteThisFileSystem ]] &&  \
692            printLine=false
693          ;;
694
695        show )
696          if [[ -n $displayThisFileSystem ]]
697          then
698            # Output the mount point.
699            [[ ${v[$LINE_NUMBER_Field]} = $MOUNT_POINT_Line ]] &&  \
700              printf " %-20s" "${v[$ETCFS_TEXT_Field]}"
701
702            # Determine the automount value.  It will be displayed last.
703            if [[ ${v[$LINE_NUMBER_Field]} = $MOUNT_Line ]]
704            then
705              automountSetting=${v[$ETCFS_TEXT_Field]#$MOUNT_Line_Prefix}
706              if [[ $automountSetting = mmfs ]]
707              then
708                automountSetting=yes
709              elif [[ $automountSetting = false ]]
710              then
711                automountSetting=no
712              else
713                :  # Leave the value as is.
714              fi
715            fi  # end of if [[ ${v[$LINE_NUMBER_Field]} = $MOUNT_Line ]]
716          fi  # end of if [[ -n $displayThisFileSystem ]]
717          ;;
718
719        *) checkForErrors "unexpected action $action" 1
720          ;;
721
722      esac  # end case $action in
723      ;;
724
725    $SG_MOUNT )
726      # Processing depends on the specified action:
727      case $action in
728        add )
729          :  # There is nothing to do.
730          ;;
731
732        update )
733          if [[ -n $mountOptions && ${v[$DEV_NAME_Field]} = $deviceName ]]
734          then
735            # We are changing the mount options for this remote file system.
736            v[$RW_OPT_Field]=$sgRW_OPT_Value
737            v[$MTIME_OPT_Field]=$sgMTIME_OPT_Value
738            v[$ATIME_OPT_Field]=$sgATIME_OPT_Value
739            v[$QUOTA_OPT_Field]=$sgQUOTA_OPT_Value
740            v[$OTHER_OPT_Field]=$sgOTHER_OPT_Value
741          fi
742
743          if [[ -n $remoteClusterName && ${v[$DEV_NAME_Field]} = $deviceName ]]
744          then
745            # We are changing the home cluster name.
746            v[$NODESETID_Field]=$remoteClusterName
747          fi
748          ;;
749
750        delete )
751          [[ -n $deleteThisFileSystem ]] &&  \
752            printLine=false
753          ;;
754
755        show )
756          if [[ -n $displayThisFileSystem ]]
757          then
758            # Generate the mount options string.
759            optionsString="${v[$RW_OPT_Field]}"
760            [[ -n ${v[$MTIME_OPT_Field]} ]] &&  \
761              optionsString="${optionsString},${v[$MTIME_OPT_Field]}"
762            [[ -n ${v[$ATIME_OPT_Field]} ]] &&  \
763              optionsString="${optionsString},${v[$ATIME_OPT_Field]}"
764            [[ -n ${v[$OTHER_OPT_Field]} ]] &&  \
765              optionsString="${optionsString},${v[$OTHER_OPT_Field]}"
766            [[ -n ${v[$QUOTA_OPT_Field]} ]] &&  \
767              optionsString="${optionsString},quota=${v[$QUOTA_OPT_Field]}"
768
769            # Put out the last two values and finish the line.
770            printf " %-16s %s\n" "$optionsString" "$automountSetting"
771          fi  # end of if [[ -n $displayThisFileSystem ]]
772          ;;
773
774        *) checkForErrors "unexpected action $action" 1
775          ;;
776
777      esac  # end case $action in
778      ;;
779
780    $REM_CLUSTER )
781      [[ ${v[$NODESETID_Field]} = $remoteClusterName ]] &&  \
782        remoteClusterFound=yes
783      ;;
784
785    * )  # Pass all other lines without a change.
786      ;;
787
788  esac  # end of Change some of the fields
789
790  # Build and write the line to the new mmsdrfs file.
791  if [[ $printLine = true ]]
792  then
793    print_newLine >> $newsdrfs
794    checkForErrors "writing to file $newsdrfs" $?
795  fi
796
797  IFS=":"  # Change the separator back to ":" for the next iteration.
798
799done  # end while read -u3 mmsdrfsFile
800
801IFS="$IFS_sv"  # Restore the default IFS settings.
802
803
804if [[ -z $fsFound && $action != add ]]
805then
806  if [[ (-z $device || $device = all) && ($action = show || $action = delete) ]]
807  then
808    # There are no remote file systems.
809    printErrorMsg 193 $mmcmd
810  else
811    # Remote file system not found.
812    printErrorMsg 194 $mmcmd $device
813  fi
814  cleanupAndExit
815fi  # end of if [[ -z $clusterFound ]]
816
817
818#########################################
819# Additional action-specific processing.
820#########################################
821
822###############################
823# If action is "show", return.
824###############################
825if [[ $action = show ]]
826then
827  # Return; we are done.
828  cleanupAndExit $rc
829fi  # end of if [[ $action = show ]]
830
831
832#######################################################
833# If action is "update", perform final error checking.
834#######################################################
835if [[ $action = update ]]
836then
837  # If the mount point for a file system is being changed,
838  # ensure that the new mount point is not already in use.
839  if [[ -n $mountPoint ]]
840  then
841    for mpnt in $existingMountPoints
842    do
843      if [[ $mpnt = $mountPoint ]]
844      then
845        # There is already an existing filesystem using this mountpoint.
846        printErrorMsg 107 $mmcmd $mountPoint
847        cleanupAndExit
848      fi
849    done
850  fi  # end of if [[ -n $mountPoint ]]
851
852  # If the home cluster for a file system is being changed,
853  # ensure that the new cluster is already defined.
854  if [[ -n $remoteClusterName && -z $remoteClusterFound ]]
855  then
856    # The remote cluster is not defined.
857    printErrorMsg 263 $mmcmd $remoteClusterName
858    cleanupAndExit
859  fi
860
861  # If appropriate, put the file system on the list
862  # of file systems that should not be mounted.
863  if [[ -n $fsMustNotBeMounted ]]
864  then
865    print -- "$fsFullName $deviceName" >> $mountCheckList
866    checkForErrors "writing to file $mountCheckList" $?
867  fi
868fi  # end of if [[ $action = update ]]
869
870
871#############################################################################
872# If action is "add",  generate the needed information for the mmsdrfs file.
873#############################################################################
874if [[ $action = add ]]
875then
876  # Ensure the remote cluster that we need is already defined.
877  if [[ -z $remoteClusterFound ]]
878  then
879    # The remote cluster was not found.
880    printErrorMsg 188 $mmcmd $remoteClusterName
881    cleanupAndExit
882  fi  # end of if [[ -z $remoteClusterFound ]]
883
884  # Determine what the major number should be.
885  if [[ $osName = Linux ]]
886  then
887    checkVfsNumber
888    devMajor=$currentMajorNumber
889  fi
890  [[ -z $devMajor ]] && devMajor=$defaultMajorNumber
891
892  # Assign a minor number to the file system.
893  # Keep trying until we get a minor number that is not used by anybody.
894  rc=0
895  minor=""
896  while [[ -z $minor && $rc -eq 0 ]]
897  do
898    # Assign a minor number to the file system.
899    devMinor=$(assignDevMinor "$existingMinorNumbers")
900    rc=$?
901    if [[ $rc -eq 0 ]]
902    then
903      # Check whether the new device number is being used by somebody.
904      inuse=$($ls -lL /dev 2>/dev/null | $grep "^${fsDeviceType}.* $devMajor, *$devMinor ")
905      if [[ -z $inuse ]]
906      then
907        # The number seems to be free.
908        minor=$devMinor
909      fi
910
911      # Add the number to the list of existing minor numbers.
912      existingMinorNumbers="$existingMinorNumbers $devMinor"
913
914    fi  # end of if [[ $rc -eq 0 ]]
915  done  # end of while [[ -z $minor && $rc -eq 0 ]]
916
917  if [[ -z $minor ]]
918  then
919    print -u2 "$mmcmd:  Cannot assign a minor number for the file system."
920    cleanupAndExit
921  fi
922
923  # Build the SG-related lines for the new file system.
924  # Note: In order to preserve the tab characters in the /etc/filesystems lines,
925  #       we temporarily reset the value of the IFS variable to exclude the tab.
926  IFS=' '
927
928  newLine="$remoteClusterName:$SG_HEADR:$deviceName::$minor::$remotefs:$remoteDevice"
929  print -- "$newLine" >> $newsdrfs
930
931  newLine="$remoteClusterName:$SG_ETCFS:$deviceName:$MOUNT_POINT_Line:$mountPoint:"
932  print -- "$newLine" >> $newsdrfs
933
934  newLine="$remoteClusterName:$SG_ETCFS:$deviceName:$DEV_Line"
935  newLine="$newLine:$DEV_Line_Prefix$fqDeviceName"
936  print -- "$newLine" >> $newsdrfs
937
938  newLine="$remoteClusterName:$SG_ETCFS:$deviceName:$VFS_Line"
939  newLine="$newLine:$VFS_Line_Prefix$sgVFS_Line_Value"
940  print -- "$newLine" >> $newsdrfs
941
942  newLine="$remoteClusterName:$SG_ETCFS:$deviceName:$NODENAME_Line"
943  newLine="$newLine:$NODENAME_Line_Prefix$sgNODENAME_Line_Value"
944  print -- "$newLine" >> $newsdrfs
945
946  newLine="$remoteClusterName:$SG_ETCFS:$deviceName:$MOUNT_Line"
947  newLine="$newLine:$MOUNT_Line_Prefix$sgMOUNT_Line_Value"
948  print -- "$newLine" >> $newsdrfs
949
950  newLine="$remoteClusterName:$SG_ETCFS:$deviceName:$TYPE_Line"
951  newLine="$newLine:$TYPE_Line_Prefix$sgTYPE_Line_Value"
952  print -- "$newLine" >> $newsdrfs
953
954  newLine="$remoteClusterName:$SG_ETCFS:$deviceName:$ACCOUNT_Line"
955  newLine="$newLine:$ACCOUNT_Line_Prefix$sgACCOUNT_Line_Value"
956  print -- "$newLine" >> $newsdrfs
957
958  newLine="$remoteClusterName:$SG_MOUNT:$deviceName::$sgRW_OPT_Value"
959  newLine="$newLine:$sgMTIME_OPT_Value:$sgATIME_OPT_Value"
960  newLine="$newLine:$sgQUOTA_OPT_Value:$sgOTHER_OPT_Value:"
961  print -- "$newLine" >> $newsdrfs
962  checkForErrors "writing to file $newsdrfs" $?
963
964  IFS="$IFS_sv"
965
966fi  # end of if [[ $action = add ]]
967
968
969#########################################################
970# If this is the first automountable GPFS file system,
971# run the automount command on the nodes in the cluster.
972#########################################################
973if [[ $automountValue = "automount" && -z $automountMounts ]]
974then
975  # Determine the value of the automountDir parameter.
976  automountDir=$(showCfgValue automountDir)
977  [[ -z $automountDir ]] && automountDir=$defaultAutomountDir
978
979  # Run the automount command on the nodes on which GPFS is active.
980  # On nodes that do not have GPFS running right now, this will be
981  # done by the mmchecksubsys processing when the daemon is started.
982  $mmcommon onactive $preferredNode $nodefile        \
983      $NO_FILE_COPY $NO_MOUNT_CHECK NULL $NO_LINK    \
984      tsdsh $mmremote startAutomounter $automountDir >$tmpfile 2>&1
985  rc=$?
986
987  # Ignore errors but show messages from the nodes, if any.
988  if [[ $rc -ne 0 && $rc -ne $MM_DaemonDown && -s $tmpfile ]]
989  then
990    $awk '                             \
991      # Skip the lines with rc values. \
992      $2 == "rc" { next }              \
993      # Print everything else.         \
994      { print $0 }                     \
995    ' $tmpfile
996  fi  # end of if [[ -s $tmpfile ]]
997fi  # end of if [[ $automountValue = "automount" && -z $automountMounts ]]
998
999
1000############################################
1001# Sort the new version of the mmsdrfs file.
1002############################################
1003LC_ALL=C $SORT_MMSDRFS $newsdrfs -o $newsdrfs
1004checkForErrors "sorting $newsdrfs" $?
1005
1006
1007###################################################
1008# Lock the gpfs object to prevent any GPFS daemons
1009# from starting during the commit phase.
1010###################################################
1011[[ $getCredCalled = no ]] && getCred
1012setRunningCommand "$mmcmd" $primaryServer
1013checkForErrors setRunningCommand $?
1014gpfsLocked=yes
1015
1016
1017################################################################
1018# Make sure that file systems that should not be mounted
1019# are indeed not mounted.  Note that the scope of the mount
1020# restriction is our own cluster only.  It is OK for the file
1021# systems to be mounted elsewhere.
1022################################################################
1023if [[ -s $mountCheckList ]]
1024then
1025  exec 3<&-
1026  exec 3< $mountCheckList
1027  while read -u3 mountCheckLine
1028  do
1029    # Parse the line.
1030    set -f ; set -- $mountCheckLine ; set +f
1031    fsFullName=$1
1032    localDevName=$2
1033
1034    $mmcommon onactive $preferredNode $nodefile $NO_FILE_COPY   \
1035       $fsFullName $ourClusterName $NO_LINK $MOUNT_CHECK_ONLY ldev=$localDevName 2>$errMsg
1036    rc=$?
1037    if [[ $rc -eq $MM_FsMounted ]]
1038    then
1039      # The file system is still mounted (messages were issued by mmcommon).
1040      $rm -f $errMsg
1041      cleanupAndExit
1042    elif [[ $rc -eq $MM_FsNotFound || $rc -eq $MM_Remotefs ]]
1043    then
1044      # The file system was not found, so it cannot be mounted.
1045      rc=0
1046    elif [[ $rc -eq $MM_HostDown ||
1047            $rc -eq $MM_TimedOut ||
1048            $rc -eq $MM_UnknownCluster ||
1049            $rc -eq $MM_SecurityCfg ||
1050            $rc -eq $MM_AuthorizationFailed ]]
1051    then
1052      # We failed to connect to the remote cluster.
1053      rc=0
1054      if [[ $device != all ]]
1055      then
1056        # There is only one remote cluster, and we could not connect to it.
1057        # Exit the loop since none of its file systems can be mounted.
1058        break
1059      fi
1060    elif [[ $rc -eq $MM_DaemonDown ]]
1061    then
1062      # GPFS is down on all nodes in the local cluster.
1063      # There are no mounted file systems, so exit the loop.
1064      rc=0
1065      break
1066    elif [[ $rc -eq $MM_ConnectionReset ]]
1067    then
1068      # An internode connection was reset.
1069      printErrorMsg 257 $mmcmd
1070    elif [[ $rc -ne 0 ]]
1071    then
1072      if [[ -s $errMsg ]]
1073      then
1074        # Show the error messages from the daemon.
1075        $cat $errMsg 1>&2
1076      else
1077        # The mount check failed and there were no messages from the daemon.
1078        printErrorMsg 171 $mmcmd "mount check for $fsFullName" $rc
1079      fi
1080      # The command was unable to determine whether the file system is mounted.
1081      printErrorMsg 564 $mmcmd $localDevName
1082      cleanupAndExit
1083    fi  # end of if [[ $rc -eq $MM_FsMounted ]]
1084    $rm -f $errMsg
1085  done  # end of while read -u3 mountCheckLine
1086  $rm -f $errMsg
1087fi  # end of if [[ -s $mountCheckList ]]
1088
1089
1090############################################################
1091# Replace the mmsdrfs file in the sdr with the new version.
1092############################################################
1093trap "" HUP INT QUIT KILL
1094gpfsObjectInfo=$(commitChanges  \
1095   $nsId $nsId $gpfsObjectInfo $newGenNumber $newsdrfs $primaryServer)
1096rc=$?
1097if [[ $rc -ne 0 ]]
1098then
1099  # The commit step failed; we cannot replace the file in the sdr.
1100  printErrorMsg 381 $mmcmd
1101  cleanupAndExit
1102fi
1103
1104
1105#############################################################
1106# Unlock the sdr.
1107#############################################################
1108freeLockOnServer $primaryServer $ourNodeNumber >/dev/null
1109sdrLocked=no
1110trap posttrap HUP INT QUIT KILL
1111
1112
1113#########################################################################
1114# Make the new file system visible to the nodes.  This includes adding
1115# a stanza to /etc/filesystems and creating the mount point directory.
1116# If the mount point changed, remove the old mount point.
1117# This process is asynchronous.
1118#########################################################################
1119[[ -n $oldMountPoint && $mountPoint != $oldMountPoint ]] &&  \
1120  propagateOptions="rmdir$oldMountPoint"
1121
1122propagateSdrfsFile async $nodefile $newsdrfs $newGenNumber $propagateOptions
1123
1124cleanupAndExit 0
1125
Note: See TracBrowser for help on using the repository browser.