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

Last change on this file since 16 was 16, checked in by rock, 16 years ago
  • Property svn:executable set to *
File size: 49.5 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. 2000,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# @(#)99 1.131.1.9 src/avs/fs/mmfs/ts/admin/mmcrcluster.sh, mmfs, avs_rgpfs24, rgpfs24s012a 4/2/07 12:58:08
17###############################################################################
18#
19# Usage:
20#   mmcrcluster -N {NodeDesc[,NodeDesc...] | NodeFile}
21#               -p PrimaryServer [-s SecondaryServer]
22#               [-r remoteShellCommand] [-R remoteFileCopyCommand]
23#               [-C ClusterName] [-U DomainName] [-A] [-c ConfigFile]
24#
25# where:
26#
27#   -N NodeDesc,NodeDesc,...  specifies a comma-separated list of node
28#                             descriptors that detail the node interfaces
29#                             to be added to the cluster.  The nodes must not
30#                             presently belong to the cluster.
31#
32#   -N NodeFile         specifies a file of node descriptors that detail
33#                       the node interfaces to be added to the cluster.
34#                       The nodes must not presently belong to the cluster.
35#
36#   -p PrimaryServer    specifies the node to be used as the primary server
37#                       of the GPFS sdrfs data for this cluster
38#
39#   -s SecondaryServer  specifies the node to be used as the secondary server
40#                       of the GPFS sdrfs data for this cluster (optional)
41#
42#   -r remoteShellCommand    specifies the fully-qualified pathname for
43#                       the remote shell program to be used by GPFS.
44#                       The default is /usr/bin/rsh.
45#
46#   -R remoteFileCopyCommand  specifies the fully-qualified pathname for
47#                       the remote file copy program to be used by GPFS.
48#                       The default is /usr/bin/rcp.
49#
50#   -C ClusterName      user-specified name for the cluster.  If the name
51#                       contains dots it is assumed to be a fully-qualified
52#                       domain name.  Otherwise, the domain will default
53#                       to the domain of the primary configuration server.
54#                       If not specified, or if single dot is specified,
55#                       ClusterName will default to the fully-qualified name
56#                       of the primary config server (-p parameter).
57#
58#   -U DomainName       UID domain name
59#
60#   -A                  specifies automatic bringing up of mmfs daemons at
61#                       boot time.  Default is no autoload.
62#
63#   -c ConfigFile       file with mmfs.cfg parameters; see mmfs.cfg.sample
64#                       in /usr/lpp/mmfs/samples
65#
66#
67# Obsolete but still supported options:
68#
69#   -n NodeFile         specifies a file of node descriptors that detail the
70#                       node interfaces making up the GPFS cluster
71#
72# Each node descriptor has the format:
73#
74#   nodeName:nodeRoles:adminNodeName:
75#
76# where:
77#
78#   nodeName        is either a short or fully-qualified hostname,
79#                   or an IP address for the primary GPFS network
80#                   to be used for daemon to daemon communications
81#
82#   nodeRoles       is a '-' separated list of node roles.  Unless changed
83#                   on the mmconfig or mmaddnode commands, these roles will
84#                   be associated with the node when it becomes a member of
85#                   a nodeset.
86#
87#   adminNodeName   is either a short or fully-qualified hostname, or an IP
88#                   address to be used by the admin scripts to communicate
89#                   between nodes.  This is an optional parameter; if it
90#                   is not specified, the nodeName value is used.
91#
92# Undocumented options:
93#
94#   -t ClusterType  specifies the cluster type for this cluster
95#                   (supported values are "lc" and "single").
96#                   See note below for additional information.
97#
98#     The format of the -t parameter is ClusterType[/EnvironmentType]
99#     where "ClusterType" is the GPFS cluster type as defined above.
100#     The optional "EnvironmentType" designates the environment within
101#     which the GPFS cluster is being created.  The following table
102#     shows the allowed values.
103#
104#       ClusterType  EnvironmentType  Remarks
105#
106#          lc           lc2           true loose cluster; no RSCT
107#
108#          lc           lc            old style Linux only loose cluster;
109#                                     RSCT subsystem is controlled by GPFS;
110#                                     this combination is no longer allowed
111#
112#          single       single        single node environment
113#
114# Notes:
115#
116#   - Nodes are designated as quorum or non-quorum nodes when they
117#     are added to the cluster (mmcrcluster, mmaddnode).
118#
119#   - The quorum designation can be changed with mmchconfig.
120#
121#   - It is not allowed to change (or delete from the cluster)
122#     the last quorum node.
123#
124#   - If VSD-based disks will be used, all AIX nodes must belong to
125#     an RSCT peer domain.  VSD disks will not be visible to nodes
126#     that do not belong to the RSCT peer domain.  This rule cannot
127#     be enforced by mmcrcluster or mmaddnode.
128#
129###############################################################################
130
131# Include global declarations and service routines.
132. /usr/lpp/mmfs/bin/mmglobfuncs
133. /usr/lpp/mmfs/bin/mmsdrfsdef
134
135sourceFile="mmcrcluster.sh"
136[[ -n $DEBUG || -n $DEBUGmmcrcluster ]] && set -x
137$mmTRACE_ENTER "$*"
138
139# Local work files.  Names should be of the form:
140#   fn=${tmpDir}fn.${mmcmd}.$$
141inputNodes=${tmpDir}inputNodes.${mmcmd}.$$
142processedNodes=${tmpDir}processedNodes.${mmcmd}.$$
143goodnodes=${tmpDir}goodnodes.${mmcmd}.$$
144singleNode=${tmpDir}singleNode.${mmcmd}.$$
145
146LOCAL_FILES=" $inputNodes $processedNodes $goodnodes $singleNode "
147
148
149# Local declarations
150usageMsg=343
151backupServer=""
152rshPath=""
153rcpPath=""
154nodesetId=$HOME_CLUSTER
155integer nodeNumber=0
156integer nodeCount=0
157integer totalNodeCount=0
158integer quorumNodeCount=0
159rc=0
160fatalError=""
161primaryInCluster=""
162backupInCluster=""
163lowestVersion=100000
164highestVersion=0
165osEnvironment=$osName
166commProtocol=TCP
167tcpPort=$defaultTcpPort
168newKeyGenNumber=0
169committedKeyGenNumber=0
170secLevel=0
171keyfileFormatLevel=0
172quorumDefault=$nonQuorumNode
173eventsPort=""
174mmsdrservPort=""
175lapiWindow=$noWindow       # obsolete
176switchNumber=$noSwitch     # obsolete
177
178Aarg=no
179carg=""
180Carg=""
181narg=""
182Narg=""
183parg=""
184rarg=""
185Rarg=""
186sarg=""
187Uarg=""
188typeset -l targ=""
189typeset -l role
190
191
192# Local routines
193
194
195#####################################################################
196#
197# Function:  Verifies that a command executed successfully.  If the
198#            return code from the command is not zero, the function
199#            issues a message and sets a failure flag.  It returns
200#            with the same return code that was specified on input.
201#
202# Input:     $1 - name of the command to check
203#            $2 - return code from the execution of the command
204#
205#####################################################################
206function checkForErrorsAndReturn
207{
208  if [ $2 != "0" ]
209  then
210    fatalError=yes
211    # Unexpected error
212    printErrorMsg 171 "$mmcmd" "$1" $2
213  fi
214  return $2
215
216}  #---------- end of function checkForErrorsAndReturn -----------
217
218
219########################################################################
220#
221# Function:  Verifies the user provided file with mmfs.cfg parameters
222#            and filters out all blank and comment lines.  Lines with
223#            configuration parameters that are invalid, or require
224#            additional processing, or have already been established
225#            by the mmcrcluster processing, are filtered out as well.
226#
227# Input:     $1 - name of file with the user-specified mmfs.cfg values.
228#            $2 - name of output file with verified mmfs.cfg values.
229#
230# Output:    None explicit.
231#
232# Returns:   Always zero.
233#
234########################################################################
235function processUserConfigFile  # <cfgFile> <verifiedFile>
236{
237  typeset sourceFile="mmcrcluster.sh"
238  [[ -n $DEBUG || -n $DEBUGprocessUserConfigFile ]] && set -x
239  $mmTRACE_ENTER "$*"
240  typeset cfgFile=$1
241  typeset verifiedCfgFile=$2
242
243  typeset -l cfgParm_lc
244  typeset cfgLine cfgParm errCode parmOut
245  typeset nodeOverrideInEffect=false
246
247  # Issue a progress message (processing user config data . . . ).
248  printInfoMsg 143 "$(date)" $mmcmd $cfgFile
249
250  $rm -f $verifiedCfgFile
251  exec 4<&-
252  exec 4< $cfgFile
253  while read -u4 cfgLine
254  do
255    # Skip empty and comment lines.
256    [[ $cfgLine = *([$BLANKchar$TABchar])   ]] && continue
257    [[ $cfgLine = *([$BLANKchar$TABchar])#* ]] && continue
258
259    # Parse the input line.
260    #
261    #  Each line is expected to consist of a config parameter and
262    #  a corresponding configuration value.  If a line contains a
263    #  node name, or a list of comma separated names, enclosed in
264    #  square brackets, the line introduces a node-override section.
265    #  A node-override section is terminated by a "[common]" line.
266
267    set -f ; set -- $cfgLine ; set +f
268    cfgParm=$1
269
270    # Convert the parameter to lower case characters only.
271    cfgParm_lc="$cfgParm"
272
273    # See if this is a node-override delimiter line.
274    if [[ $cfgParm = "[common]" ]]
275    then
276      # This is the terminating line of a node-override section.
277      nodeOverrideInEffect=false
278      errCode=0
279
280    elif [[ $cfgParm = \[* ]]
281    then
282      # This is the begining of a node-override section.
283      nodeOverrideInEffect=true
284      errCode=0
285
286    else
287      # This is a line with a config paramter/value pair.
288      # Examine the parameter to see if it should be suppressed.
289
290      case $cfgParm_lc in
291
292        # The following parameters are always set by mmcrcluster.
293        autoload                )  errCode=1 ;;
294        clusterid               )  errCode=1 ;;
295        clustername             )  errCode=1 ;;
296        clustertype             )  errCode=1 ;;
297        maxfeaturelevelallowed  )  errCode=1 ;;
298        usedisklease            )  errCode=1 ;;
299        uiddomain               )  [[ -n $Uarg ]]  && errCode=1 ;;
300
301        # The following parameters must always be set with mmchconfig.
302        cipherlist              )  errCode=2 ;;
303        eventsexportertcpport   )  errCode=2 ;;
304        gpfseventsport          )  errCode=2 ;;
305        mmsdrservport           )  errCode=2 ;;
306        mmsdrservtcpport        )  errCode=2 ;;
307        tcpport                 )  errCode=2 ;;
308        tiebreakerdisk          )  errCode=2 ;;
309        tsctcpport              )  errCode=2 ;;
310
311        # The following parameters are obsolete.
312        comm_protocol           )  errCode=3 ;;
313        corequorum              )  errCode=3 ;;
314        diskquorum              )  errCode=3 ;;
315        dynmemsize              )  errCode=3 ;;
316        gpfsobjectport          )  errCode=3 ;;
317        group                   )  errCode=3 ;;
318        importancefactor        )  errCode=3 ;;
319        locktableversion        )  errCode=3 ;;
320        logdir                  )  errCode=3 ;;
321        mallocsize              )  errCode=3 ;;
322        maxpagepool             )  errCode=3 ;;
323        memrebalanceinterval    )  errCode=3 ;;
324        mmgetobjdport           )  errCode=3 ;;
325        minpagepool             )  errCode=3 ;;
326        multinode               )  errCode=3 ;;
327        nodelist                )  errCode=3 ;;
328        nodeprefs               )  errCode=3 ;;
329        recgroup                )  errCode=3 ;;
330        singlenodequorum        )  errCode=3 ;;
331        spsecworkerthreads      )  errCode=3 ;;
332        useauthentication       )  errCode=3 ;;
333        usesinglenodequorum     )  errCode=3 ;;
334        usespsecurity           )  errCode=3 ;;
335        worker2threads          )  errCode=3 ;;
336
337        # Everything else looks acceptable for now.
338        * )  errCode=0 ;;
339
340      esac  # end of case $cfgParm_lc in
341
342
343      # If no error was detected so far, see if the parameter
344      # is allowed to appear in a node-override section.
345      if [[ $errCode -eq 0 && $nodeOverrideInEffect = true ]]
346      then
347
348        case $cfgParm_lc in
349          # The following parameters cannot appear in a node-override section.
350          allowdummyconnections   )  errCode=4 ;;
351          allowremoteconnections  )  errCode=4 ;;
352          automountdir            )  errCode=4 ;;
353          distributedtokenserver  )  errCode=4 ;;
354          leasedmstimeout         )  errCode=4 ;;
355          leaseduration           )  errCode=4 ;;
356          leaserecoverywait       )  errCode=4 ;;
357          listenonallinterfaces   )  errCode=4 ;;
358          maxmissedpingtimeout    )  errCode=4 ;;
359          maxtokenservers         )  errCode=4 ;;
360          minmissedpingtimeout    )  errCode=4 ;;
361          minquorumnodes          )  errCode=4 ;;
362          multitmmountthreshold   )  errCode=4 ;;
363          pindaemon               )  errCode=4 ;;
364          pingperiod              )  errCode=4 ;;
365          res                     )  errCode=4 ;;
366          setctimeonattrchange    )  errCode=4 ;;
367          totalpingtimeout        )  errCode=4 ;;
368          tscprimary              )  errCode=4 ;;
369          uiddomain               )  errCode=4 ;;
370          writealldescreplicas    )  errCode=4 ;;
371
372          # Everything else is acceptable.
373          * )  errCode=0 ;;
374
375        esac  # end of case $cfgParm_lc in
376
377      fi  # end of if [[ -z $errCode && -n $nodeOverrideInEffect ]]
378
379    fi  # end of if [[ $cfgParm = "[common]" ]]
380
381
382    # If an error was detected, issue an appropriate message and
383    # skip the line.  Otherwise, add the line to the verified file.
384    if [[ $errCode -eq 1 ]]
385    then
386      # Parameter is set by mmcrcluster.
387      printErrorMsg 144 $mmcmd $cfgParm "$cfgLine"
388
389    elif [[ $errCode -eq 2 ]]
390    then
391      # Parameter must be set using mmchconfig.
392      printErrorMsg 145 $mmcmd $cfgParm mmchconfig "$cfgLine"
393
394    elif [[ $errCode -eq 3 ]]
395    then
396      # Parameter is obsolete.
397      printErrorMsg 146 $mmcmd $cfgParm "$cfgLine"
398
399    elif [[ $errCode -eq 4 ]]
400    then
401      # Parameter cannot appear in a node-override section.
402      printErrorMsg 147 $mmcmd $cfgParm "$cfgLine"
403
404    else
405      # The line looks OK.  Ensure the parameter is spelled correctly.
406      # Print the line to the verified file.
407      case $cfgParm_lc in
408
409        allowdeleteaclonchmod             ) parmOut=allowDeleteAclOnChmod ;;
410        allowdummyconnections             ) parmOut=allowDummyConnections ;;
411        allowremoteconnections            ) parmOut=allowRemoteConnections ;;
412        allowsynchronousfcntlretries      ) parmOut=allowSynchronousFcntlRetries ;;
413        assertonstructureerror            ) parmOut=assertOnStructureError ;;
414        asyncsocketnotify                 ) parmOut=asyncSocketNotify ;;
415        automountdir                      ) parmOut=automountDir ;;
416        autosgloadbalance                 ) parmOut=autoSgLoadBalance ;;
417        crashdump                         ) parmOut=crashdump ;;
418        datastructuredump                 ) parmOut=dataStructureDump ;;
419        datastructuredumponsgpanic        ) parmOut=dataStructureDumpOnSGPanic ;;
420        distributedtokenserver            ) parmOut=distributedTokenServer ;;
421        dmapienable                       ) parmOut=dmapiEnable ;;
422        dmapieventbuffers                 ) parmOut=dmapiEventBuffers ;;
423        dmapieventtimeout                 ) parmOut=dmapiEventTimeout ;;
424        dmapimounttimeout                 ) parmOut=dmapiMountTimeout ;;
425        dmapisessionfailuretimeout        ) parmOut=dmapiSessionFailureTimeout ;;
426        dmapiworkerthreads                ) parmOut=dmapiWorkerThreads ;;
427        eewatchdoghungthreadcutoff        ) parmOut=eeWatchDogHungThreadCutoff ;;
428        eewatchdoginterval                ) parmOut=eeWatchDogInterval ;;
429        enablenfscluster                  ) parmOut=enableNFSCluster ;;
430        enableuidremap                    ) parmOut=enableUIDremap ;;
431        enablestatuidremap                ) parmOut=enableStatUIDremap ;;
432        enabletreebasedquotas             ) parmOut=enableTreeBasedQuotas ;;
433        envvar                            ) parmOut=envVar ;;
434        flusheddatatarget                 ) parmOut=flushedDataTarget ;;
435        flushedinodetarget                ) parmOut=flushedInodeTarget ;;
436        healthcheckinterval               ) parmOut=healthCheckInterval ;;
437        hotlistpct                        ) parmOut=hotlistPct ;;
438        ignorereplicaspaceonstat          ) parmOut=IgnoreReplicaSpaceOnStat ;;
439        iohistorysize                     ) parmOut=ioHistorySize ;;
440        leasedmstimeout                   ) parmOut=leaseDMSTimeout ;;
441        leaseduration                     ) parmOut=leaseDuration ;;
442        leaserecoverywait                 ) parmOut=leaseRecoveryWait ;;
443        license                           ) parmOut=LICENSE ;;
444        listenonallinterfaces             ) parmOut=listenOnAllInterfaces ;;
445        mmapkprocs                        ) parmOut=mmapKprocs ;;
446        maxallocpcttocache                ) parmOut=maxAllocPctToCache ;;
447        maxbackgrounddeletionthreads      ) parmOut=maxBackgroundDeletionThreads ;;
448        maxblocksize                      ) parmOut=maxblocksize ;;
449        maxbufferdescs                    ) parmOut=maxBufferDescs ;;
450        maxdatashippoolsize               ) parmOut=maxDataShipPoolSize ;;
451        maxdiskaddrbuffs                  ) parmOut=maxDiskAddrBuffs ;;
452        maxfcntlrangesperfile             ) parmOut=maxFcntlRangesPerFile ;;
453        maxfilecleaners                   ) parmOut=maxFileCleaners ;;
454        maxfilestocache                   ) parmOut=maxFilesToCache ;;
455        maxinodedeallochistory            ) parmOut=maxInodeDeallocHistory ;;
456        maxinodedeallocprefetch           ) parmOut=maxInodeDeallocPrefetch ;;
457        maxmbps                           ) parmOut=maxMBpS ;;
458        maxmissedpingtimeout              ) parmOut=maxMissedPingTimeout ;;
459        maxnfsdelegationtimeout           ) parmOut=maxNFSDelegationTimeout ;;
460        maxreceiverthreads                ) parmOut=maxReceiverThreads ;;
461        maxsgdesciobufsize                ) parmOut=maxSGDescIOBufSize ;;
462        maxstatcache                      ) parmOut=maxStatCache ;;
463        maxtokenservers                   ) parmOut=maxTokenServers ;;
464        minmissedpingtimeout              ) parmOut=minMissedPingTimeout ;;
465        minquorumnodes                    ) parmOut=minQuorumNodes ;;
466        mmsdrservtimeout                  ) parmOut=mmsdrservTimeout ;;
467        mmsdrservworkerpool               ) parmOut=mmsdrservWorkerPool ;;
468        multitmmountthreshold             ) parmOut=multiTMMountThreshold ;;
469        nfsprefetchstrategy               ) parmOut=nfsPrefetchStrategy ;;
470        nsdbufspace                       ) parmOut=nsdbufspace ;;
471        nsdmaxworkerthreads               ) parmOut=nsdMaxWorkerThreads ;;
472        nsdminworkerthreads               ) parmOut=nsdMinWorkerThreads ;;
473        nsdservercheckingintervalformount ) parmOut=nsdServerCheckingIntervalForMount ;;
474        nsdserverwaitconfig               ) parmOut=nsdServerWaitConfig ;;
475        nsdserverwaittimeformount         ) parmOut=nsdServerWaitTimeForMount ;;
476        nsdserverwaittimewindowonmount    ) parmOut=nsdServerWaitTimeWindowOnMount ;;
477        nsdthreadsperdisk                 ) parmOut=nsdThreadsPerDisk ;;
478        openssllibname                    ) parmOut=openssllibname ;;
479        pagepool                          ) parmOut=pagepool ;;
480        panicondiskfail                   ) parmOut=unmountOnDiskFail ;;
481        pcttokenmgrstorageuse             ) parmOut=pctTokenMgrStorageUse ;;
482        pindaemon                         ) parmOut=pindaemon ;;
483        pingperiod                        ) parmOut=pingPeriod ;;
484        pinmaster                         ) parmOut=pinmaster ;;
485        prefetchpct                       ) parmOut=prefetchPct ;;
486        prefetchthreads                   ) parmOut=prefetchThreads ;;
487        prefetchtimeout                   ) parmOut=prefetchTimeout ;;
488        priority                          ) parmOut=priority ;;
489        readreplicapolicy                 ) parmOut=readReplicaPolicy ;;
490        res                               ) parmOut=res ;;
491        retryfcntltokenthreshold          ) parmOut=retryFcntlTokenThreshold ;;
492        seqdiscardthreshhold              ) parmOut=seqDiscardThreshhold ;;
493        setctimeonattrchange              ) parmOut=setCtimeOnAttrChange ;;
494        sharedmemlimit                    ) parmOut=sharedMemLimit ;;
495        socketrcvbuffersize               ) parmOut=socketRcvBufferSize ;;
496        socketsndbuffersize               ) parmOut=socketSndBufferSize ;;
497        statcachedirpct                   ) parmOut=statCacheDirPct ;;
498        subnets                           ) parmOut=subnets ;;
499        syncinterval                      ) parmOut=syncInterval ;;
500        takeovertimeout                   ) parmOut=takeovertimeout ;;
501        tokenmemlimit                     ) parmOut=tokenMemLimit ;;
502        totalpingtimeout                  ) parmOut=totalPingTimeout ;;
503        trace                             ) parmOut=trace ;;
504        tscprimary                        ) parmOut=tscPrimary ;;
505        tscworkerpool                     ) parmOut=tscWorkerPool ;;
506        uiddomain                         ) parmOut=uidDomain ;;
507        uidexpiration                     ) parmOut=uidExpiration ;;
508        unmountondiskfail                 ) parmOut=unmountOnDiskFail ;;
509        wait4rvsd                         ) parmOut=wait4RVSD ;;
510        waitforvsd                        ) parmOut=wait4RVSD ;;
511        watchdogtimeout                   ) parmOut=watchdogtimeout ;;
512        worker1threads                    ) parmOut=worker1Threads ;;
513        worker3threads                    ) parmOut=worker3Threads ;;
514        writealldescreplicas              ) parmOut=writeAllDescReplicas ;;
515        writebehindthreshhold             ) parmOut=writebehindThreshhold ;;
516        \[*                               ) parmOut="" ;;
517        *                                 ) parmOut="$cfgParm" ;;
518      esac  # end of case $cfgParm_lc in
519
520      # Print the line to the verified file.
521      print -- "$parmOut${cfgLine#$cfgParm}" >> $verifiedCfgFile
522      checkForErrors "writing to file $verifiedCfgFile" $?
523    fi
524
525  done  # end of while read -u4 cfgLine
526
527  return 0
528
529}  #---------- end of function processUserConfigFile -----------
530
531
532
533######################
534# Mainline processing
535######################
536
537
538#################################
539# Process the command arguments.
540#################################
541[[ $arg1 = '-?' || $arg1 = '-h' || $arg1 = '--help' || $arg1 = '--' ]] &&  \
542  syntaxError "help" $usageMsg
543
544while getopts :Ac:C:n:N:p:r:R:s:t:U: OPT
545do
546  case $OPT in
547
548    A) # autoload option
549       [[ $Aarg = yes ]] && syntaxError "multiple" $noUsageMsg "-$OPT"
550       Aarg=yes
551       ;;
552
553    c) # config file name
554       [[ -n $carg ]] && syntaxError "multiple" $noUsageMsg "-$OPT"
555       carg=$OPTARG
556       ;;
557
558    C) # cluster name
559       [[ -n $Carg ]] && syntaxError "multiple" $noUsageMsg "-$OPT"
560       Carg=$OPTARG
561       checkName clusterName 255 "$Carg"
562       [[ $? -ne 0 ]] && cleanupAndExit
563       ;;
564
565    n) # node descriptors file
566       [[ -n $narg ]] && syntaxError "multiple" $noUsageMsg "-$OPT"
567       narg=$OPTARG
568       ;;
569
570    N) # node descriptors list or file
571       [[ -n $Narg ]] && syntaxError "multiple" $noUsageMsg "-$OPT"
572       Narg=$OPTARG
573       ;;
574
575    p) # primary server
576       [[ -n $parg ]] && syntaxError "multiple" $noUsageMsg "-$OPT"
577       parg=$OPTARG
578       ;;
579
580    r) # remote shell command
581       [[ -n $rarg ]] && syntaxError "multiple" $noUsageMsg "-$OPT"
582       rarg=$OPTARG
583       [[ $rarg = ${rarg#/} ]] &&  \
584         syntaxError "absolutePath_2" $noUsageMsg "-$OPT" "$rarg"
585       ;;
586
587    R) # remote file copy command
588       [[ -n $Rarg ]] && syntaxError "multiple" $noUsageMsg "-$OPT"
589       Rarg=$OPTARG
590       [[ $Rarg = ${Rarg#/} ]] &&  \
591         syntaxError "absolutePath_2" $noUsageMsg "-$OPT" "$Rarg"
592       ;;
593
594    s) # secondary server
595       [[ -n $sarg ]] && syntaxError "multiple" $noUsageMsg "-$OPT"
596       sarg=$OPTARG
597       ;;
598
599    t) # cluster type
600       [[ -n $targ ]] && syntaxError "multiple" $noUsageMsg "-$OPT"
601       targ=$OPTARG
602       ;;
603
604    U) # UID domain name
605       [[ -n $Uarg ]] && syntaxError "multiple" $noUsageMsg "-$OPT"
606       Uarg=$OPTARG
607       ;;
608
609    +[AcCnNprRstU]) # Invalid option
610       syntaxError "invalidOption" $usageMsg $OPT
611       ;;
612
613    :) # Missing argument
614       syntaxError "missingValue" $usageMsg $OPTARG
615       ;;
616
617    *) # Invalid option
618       syntaxError "invalidOption" $usageMsg $OPTARG
619       ;;
620  esac
621
622done  # end of while getopts :Ac:C:n:N:p:r:R:s:t:U: OPT do
623
624shift OPTIND-1
625[[ $# -ne 0 ]] && syntaxError "extraArg" $usageMsg $1
626
627[[ -z $targ ]] && targ="lc/lc2"
628
629[[ $targ != single* && ( -z $parg || ( -z $Narg && -z $narg ) ) ]] &&  \
630  syntaxError "missingArgs" $usageMsg
631
632[[ -n $narg && -n $Narg ]] &&  \
633  syntaxError "invalidCombination" $usageMsg "-n" "-N"
634
635
636##############################################################
637# If the cluster type is single, simulate missing parameters.
638##############################################################
639if [[ $targ = single* ]]
640then
641  if [[ -z $Narg && -z $narg ]]
642  then
643    print -- "$($hostname)" > $singleNode
644    Narg=$singleNode
645  fi
646
647  [[ -z $parg ]] &&  \
648    parg=$($hostname)
649
650  quorumDefault=$quorumNode
651  mmsdrservPort=0
652fi
653
654
655###########################################################
656# Check the value of the mandatory cluster type parameter.
657###########################################################
658IFS='/'
659set -f ; set -- $targ ; set +f
660clusterType=$1
661environmentType=$2
662IFS="$IFS_sv"
663
664case $clusterType in
665  lc )
666    [[ -z $environmentType ]] &&  \
667      environmentType=lc2
668    [[ $environmentType != lc2 ]] &&  \
669      invalidClusterType=yes
670    ;;
671
672  single )
673    [[ -z $environmentType ]] &&  \
674      environmentType=single
675    [[ $environmentType != single ]] &&  \
676      invalidClusterType=yes
677    ;;
678
679  * )
680    invalidClusterType=yes
681    ;;
682esac
683
684if [[ $invalidClusterType = yes ]]
685then
686  # Invalid value for cluster type.
687  printErrorMsg 153 $mmcmd "-t"
688   cleanupAndExit
689fi
690
691clusterSubtype=$environmentType
692
693
694########################################################
695# Check whether the prerequisite software is installed.
696########################################################
697checkPrereqs $environmentType
698if [[ $? -ne 0 ]]
699then
700  # The prerequisite software is not installed.
701  printErrorMsg 349 $mmcmd $($hostname)
702  cleanupAndExit
703fi
704
705
706##########################################################################
707# Set global variables.  These are normally determined automatically,
708# but since a cluster does not exist yet, they need to be set explicitly.
709##########################################################################
710export MMMODE=$clusterType
711export environmentType=$environmentType
712ourNodeName=$(hostname)
713
714
715##################################################
716# Check the mandatory node descriptors parameter.
717##################################################
718if [[ -n $Narg ]]
719then
720  # The -N parameter may be either a list or a file.  Which is it?
721  if [[ -f $Narg ]]
722  then
723    # It is a file; verify its existence and create our own copy.
724    checkUserFile $Narg $inputNodes
725    [[ $? -ne 0 ]] && cleanupAndExit
726  else
727    # It is not a file, so it must be a list.
728    # Convert the input node list into a file.
729    $rm -f $inputNodes
730    IFS=','
731    for nodeDesc in $Narg
732    do
733      print -- "$nodeDesc" >> $inputNodes
734      checkForErrors "writing to $inputNodes" $?
735    done
736    IFS="$IFS_sv"    # Restore the default IFS setting.
737  fi  # end of if [[ -f $Narg ]]
738
739else
740  # Since -N was not specified, -n must have been.
741  # Check the node names file parameter and create our own copy.
742  checkUserFile $narg $inputNodes
743  [[ $? -ne 0 ]] && cleanupAndExit
744fi  # end of if [[ -n $Narg ]]
745
746# Make sure that at least one node is designated as quorum,
747# and count the number of quorum nodes.
748# If there are more than 7 quorum nodes, issue a warning;
749# If there are more than 128 quorum nodes, issue an error and quit.
750if [[ $clusterType = lc ]]
751then
752  quorumNodeCount=$($awk -F: '             \
753    BEGIN { nqnodes = 0 }                  \
754    $1 ~ /^#/ || NF <= 1 { next }          \
755    $2 ~ "quorum" && $2 !~ "nonquorum" {   \
756      { nqnodes += 1 }                     \
757    }                                      \
758    END { print nqnodes }                  \
759  ' $inputNodes)
760
761  if [[ $quorumNodeCount -eq 0 ]]
762  then
763    # At least one quorum node must be defined.
764    printErrorMsg 53 $mmcmd
765    cleanupAndExit
766  fi
767
768  if [[ $quorumNodeCount -gt $maxQuorumNodes ]]
769  then
770    # Error:  The number of quorum nodes exceeds the maximum allowed.
771    printErrorMsg 393 $mmcmd $maxQuorumNodes
772    cleanupAndExit
773  fi
774
775  if [[ $quorumNodeCount -gt $maxRecQuorumNodes ]]
776  then
777    # Warning:  The number of quorum nodes exceeds the recommended maximum.
778    printErrorMsg 394 $mmcmd $maxRecQuorumNodes
779  fi
780fi  # end of if [[ $clusterType = lc ]]
781
782
783###################################################
784# Process the optional remote commands parameters.
785###################################################
786if [[ -n $rarg ]]
787then
788  if [[ ! -x $rarg ]]
789  then
790    # Path is not an executable.
791    printErrorMsg 422 $mmcmd ${rarg%% *}
792    cleanupAndExit
793  fi
794  rshPath="$rarg"
795  rsh="$rshPath"
796  export GPFS_rshPath="$rshPath"
797else
798  rshPath="_DEFAULT_"
799fi
800
801if [[ -n $Rarg ]]
802then
803  if [[ ! -x $Rarg ]]
804  then
805    # Path is not an executable.
806    printErrorMsg 423 $mmcmd ${Rarg%% *}
807    cleanupAndExit
808  fi
809  rcpPath="$Rarg"
810  rcp="$rcpPath"
811  export GPFS_rcpPath="$rcpPath"
812else
813  rcpPath="_DEFAULT_"
814fi
815
816
817#################################################
818# Check the optional -c ConfigFile parameter.
819#################################################
820if [[ -n $carg && ( ! -f $carg || ! -r $carg ) ]]
821then
822  # Can't read the file.
823  printErrorMsg 43 $mmcmd $carg
824  cleanupAndExit
825fi
826
827
828####################################################
829# Fail the command if an sdrfs file already exists.
830# This should never happen, as mmcrcluster should
831# only be run once before the sdrfs file exists.
832####################################################
833if [[ -f $mmsdrfsFile ]]
834then
835  printErrorMsg 348 $mmcmd $($hostname)
836  cleanupAndExit
837fi
838
839
840##################################
841# Set up trap exception handling.
842##################################
843trap pretrap2 HUP INT QUIT KILL
844
845
846#######################################################
847# Determine the lookup order for resolving host names.
848#######################################################
849[[ $osName != AIX ]] && resolveOrder=$(setHostResolveOrder)
850
851
852########################################
853# Process the primary server parameter.
854########################################
855# Find the name and IP address of the primary server.
856hostResult=$($host $parg)
857set -f ; set -- $hostResult ; set +f
858primaryServer=$1
859primaryIPaddr=${3%%,*}    # Exclude everything after the first comma.
860if [[ -z $primaryIPaddr ]]
861then
862  # Invalid node name specified.
863  printErrorMsg 54 $mmcmd $parg
864  cleanupAndExit
865fi
866
867
868#####################################################
869# Process the backup server parameter, if specified.
870#####################################################
871if [[ -n $sarg ]]
872then
873  # Find the name and IP address of the secondary server.
874  hostResult=$($host $sarg)
875  set -f ; set -- $hostResult ; set +f
876  backupServer=$1
877  backupIPaddr=${3%%,*}    # Exclude everything after the first comma.
878  if [[ -z $backupIPaddr ]]
879  then
880    # An invalid node name was specified.
881    printErrorMsg 54 $mmcmd $sarg
882    cleanupAndExit
883  fi
884
885  # Verify that the two servers are different.
886  if [[ $primaryServer = $backupServer ]]
887  then
888    printErrorMsg 346 $mmcmd $primaryServer
889    cleanupAndExit
890  fi
891else
892  backupServer="_NOSECONDARY_"
893fi   # end of if [[ -n $sarg ]]
894
895
896######################################
897# Process the cluster name parameter.
898######################################
899if [[ -z $Carg || $Carg = "." ]]
900then
901  clusterName=$primaryServer
902else
903  if [[ $Carg = *.* ]]
904  then
905    clusterName=$Carg
906  else
907    clusterName=${Carg}.${primaryServer#*.}
908  fi
909fi
910
911
912##########################################
913# Generate a unique cluster identifier.
914##########################################
915clusterId=$($mmcrclusterid $primaryIPaddr)
916
917# Create the overloaded clType and clusterIdAndSt parameters
918# that will be passed to the checkNewClusterNode routine.
919if [[ $clusterType = $environmentType ]]
920then
921  clType=$clusterType
922else
923  clType="${clusterType}/${environmentType}"
924fi
925clusterIdAndSt="${clusterId}:${clusterSubtype}"
926
927
928######################################################################
929# Generate the node information for the mmsdrfs file.
930#
931# Loop through the nodes to be added to the sdrfs file, checking
932# as we go.  When the loop is done we know which nodes can be added
933# to the sdrfs file, which ones can't, and whether the primary and
934# backup servers belong to the cluster.  A MEMBER_NODE line will be
935# generated for each node that can be added to the new GPFS cluster.
936######################################################################
937$rm -f $tmpsdrfs $goodnodes $processedNodes
938$touch $tmpsdrfs $goodnodes $processedNodes
939exec 3<&-
940exec 3< $inputNodes
941while read -u3 nodeDesc
942do
943  # Skip empty and comment lines.
944  [[ $nodeDesc = *([$BLANKchar$TABchar])   ]] && continue
945  [[ $nodeDesc = *([$BLANKchar$TABchar])#* ]] && continue
946
947  # Keep track of the total number of nodes specified by the user.
948  totalNodeCount=$totalNodeCount+1
949
950  # Parse the node descriptor.
951  IFS=':'
952  set -f ; set -- $nodeDesc ; set +f
953  nodeName=$1
954  nodeRoles=$2
955  nodeName2=$3
956  IFS="$IFS_sv"
957
958  # Assume default values for the node role fields.
959  designation=$CLIENT
960  quorumField=$quorumDefault
961
962  # Process the node roles list.
963  if [[ -n $nodeRoles ]]
964  then
965    IFS="-"
966    set -f ; set -- $nodeRoles ; set +f
967    IFS="$IFS_sv"
968    while [[ -n $1 ]]
969    do
970      role=$1  # Convert the node's role to lower case only.
971      case $role in
972
973        $CLIENT )
974          designation=$CLIENT
975          ;;
976
977        $MANAGER )
978          designation=$MANAGER
979          ;;
980
981        $QUORUM )
982          quorumField=$quorumNode
983          ;;
984
985        $NONQUORUM )
986          quorumField=$nonQuorumNode
987          ;;
988
989        * )  # Invalid node designations specified.
990          printErrorMsg 293 $mmcmd "$nodeDesc"
991          fatalError=yes
992          break 2
993          ;;
994      esac
995
996      # Move to the next field.
997      shift
998    done  # end while [[ -n $1 ]]
999  fi  # end if [[ -n $nodeRoles ]]
1000
1001  # At this point, nodeName can be any one of the following:
1002  # a fully-qualified adapter port name, a short name, or an IP address.
1003  # Determine the values for all three.  We will designate the fully
1004  # qualified hostname as the reliable hostname for the node.
1005  hostResult=$($host $nodeName)
1006  set -f ; set -- $hostResult ; set +f
1007  daemonNodeName=$1
1008  shortName=${1%% *|.*}    # Exclude everything after the first dot.
1009  ipa=${3%%,*}             # Exclude everything after the first comma.
1010  if [[ -z $ipa ]]
1011  then
1012    # An invalid node name was specified.
1013    printErrorMsg 54 $mmcmd $nodeName
1014    fatalError=yes
1015    break
1016  fi
1017
1018  # At this point, if it was specified, nodeName2 could be a
1019  # fully-qualified adapter port name, a short name, or an IP address.
1020  # Convert it to a fully-qualified node name in case it is not one already.
1021  if [[ -n $nodeName2 ]]
1022  then
1023    hostResult=$($host $nodeName2)
1024    set -f ; set -- $hostResult ; set +f
1025    adminNodeName=$1
1026    adminShortName=${1%% *|.*}  # Exclude everything after the first dot.
1027    adminIpa=${3%%,*}           # Exclude everything after the first comma.
1028    if [[ -z $adminIpa ]]
1029    then
1030      # An invalid admin node name was specified.
1031      printErrorMsg 54 $mmcmd $nodeName2
1032      fatalError=yes
1033      break
1034    fi
1035  else
1036    # The user did not set a distinct admin node name, so set the
1037    # admin node names to be the same as the daemon node names.
1038    adminNodeName=$daemonNodeName
1039    adminShortName=$shortName
1040  fi
1041
1042  # Make sure neither node name (admin or daemon) is specified more than once.
1043  $grep -qw $daemonNodeName $processedNodes > /dev/null 2>&1
1044  if [[ $? -eq 0 ]]
1045  then
1046    # The node is specified twice.
1047    printErrorMsg 347 $mmcmd $nodeName
1048    fatalError=yes
1049    break
1050  fi
1051  if [[ $adminNodeName != $daemonNodeName ]]
1052  then
1053    $grep -qw $adminNodeName $processedNodes > /dev/null 2>&1
1054    if [[ $? -eq 0 ]]
1055    then
1056      # The node is specified twice.
1057      printErrorMsg 347 $mmcmd $nodeName2
1058      fatalError=yes
1059      break
1060    fi
1061  fi
1062
1063  # Assign a node number to the node.
1064  nodeNumber=$nodeNumber+1
1065  gsNodeNumber=$nodeNumber
1066  adapterType=""
1067
1068  if [[ $environmentType = single ]]
1069  then
1070    adapterType="lo"
1071    if [[ $nodeNumber -gt 1 ]]
1072    then
1073      # Invalid node name specified.
1074      printErrorMsg 54 $mmcmd $nodeName
1075      fatalError=yes
1076      break
1077    fi
1078  fi  #  end of if [[ $environmentType = single ]]
1079
1080  # Add the daemon and admin node names to the list of processed nodes.
1081  print -- "${daemonNodeName}:${adminNodeName}" >> $processedNodes
1082  checkForErrorsAndReturn "writing to file $processedNodes" $?
1083
1084  # Build a line with the local node data for the node.  The full-blown
1085  # MEMBER_NODE line will be created further down when we have all of the
1086  # information that we need.
1087  sdrfsLine="$nodesetId:$MEMBER_NODE::0:$nodeNumber:$shortName:$ipa"
1088  sdrfsLine="$sdrfsLine:$adminNodeName:$designation:$adapterType:$lapiWindow"
1089  sdrfsLine="$sdrfsLine:$switchNumber:$OLD_NODE:$adapterType:$daemonNodeName"
1090  sdrfsLine="$sdrfsLine:$adminShortName::::$quorumField:$gsNodeNumber:"
1091
1092  # Invoke the checkNewClusterNode function to assure that the
1093  # node is new and that its level of GPFS supports clusters.
1094  # If it passes these tests, a skeleton sdrfs file is stored on the node.
1095  printInfoMsg 416 "$(date)" $mmcmd $daemonNodeName
1096  runOutput=$(run on1 $adminNodeName checkNewClusterNode  \
1097     $clType $primaryServer $backupServer "$sdrfsLine"    \
1098     "$rshPath" "$rcpPath" "$clusterIdAndSt" 2> $errMsg)
1099  rc=$?
1100  IFS=':'
1101  set -f ; set -- $runOutput ; set +f
1102  IFS="$IFS_sv"
1103  keyword=$1
1104  nodeStatus=$2
1105  adapterType=$3
1106  installedDaemonVersion=$4
1107  installedProductVersion=$5
1108  installedOsName=$6
1109
1110  if [[ $rc = 0 && $nodeStatus = success && $keyword = checkNewClusterNode ]]
1111  then
1112    # The checkNewClusterNode call succeeded.
1113    # Build the line that will represent this node in the mmsdrfs file.
1114    nodeCount=$nodeCount+1
1115    sdrfsLine="$nodesetId:$MEMBER_NODE::$nodeCount:$nodeNumber:$shortName:$ipa"
1116    sdrfsLine="$sdrfsLine:$adminNodeName:$designation:$adapterType:$lapiWindow"
1117    sdrfsLine="$sdrfsLine:$switchNumber:$OLD_NODE:$adapterType:$daemonNodeName"
1118    sdrfsLine="$sdrfsLine:$adminShortName:$installedDaemonVersion:$installedProductVersion"
1119    sdrfsLine="$sdrfsLine:$installedOsName:$quorumField:$gsNodeNumber:"
1120
1121    # Add the MEMBER_NODE line to the other lines
1122    # that will go in the mmsdrfs file.
1123    print -- "$sdrfsLine" >> $tmpsdrfs
1124    checkForErrorsAndReturn "Writing to file $tmpsdrfs" $?
1125    [[ $? -ne 0 ]] && break
1126
1127    # Add the node name to the list of successful nodes.
1128    print -- "$adminNodeName" >> $goodnodes
1129    checkForErrorsAndReturn "Writing to file $goodnodes" $?
1130    [[ $? -ne 0 ]] && break
1131
1132    # If this node is one of the server nodes, set a flag to indicate that
1133    # the server was found, and set the server name to the admin node name.
1134    if [[ $adminNodeName  = $primaryServer ||
1135          $daemonNodeName = $primaryServer ]]
1136    then
1137      primaryServer=$adminNodeName
1138      primaryInCluster=yes
1139    fi
1140    if [[ $adminNodeName  = $backupServer ||
1141          $daemonNodeName = $backupServer ]]
1142    then
1143      backupServer=$adminNodeName
1144      backupInCluster=yes
1145    fi
1146
1147    # Is this a quorum node?
1148    [[ $quorumField != $nonQuorumNode ]] &&  \
1149      quorumNodeCount=$quorumNodeCount+1
1150
1151    # Keep track of the daemon version and os installed.
1152    [[ $installedDaemonVersion -lt $lowestVersion ]] &&  \
1153      lowestVersion=$installedDaemonVersion
1154    [[ $installedDaemonVersion -gt $highestVersion ]] &&  \
1155      highestVersion=$installedDaemonVersion
1156    [[ -n $installedOsName && $installedOsName != $osEnvironment ]] &&  \
1157      osEnvironment="mixed"
1158
1159  else
1160    # The checkNewClusterNode call failed.
1161    # Not all errors are considered terminal.
1162    # If an individual node fails for a known reason,
1163    # we will not include it in the cluster but will
1164    # continue with the rest of the nodes.
1165
1166    # Tell the world what went wrong.
1167    if [[ $nodeStatus = not_new ]]
1168    then
1169      # The node already belongs to a cluster.
1170      printErrorMsg 348 $mmcmd $adminNodeName
1171    elif [[ $nodeStatus = not_supported ]]
1172    then
1173      # Wrong GPFS code level.
1174      printErrorMsg 349 $mmcmd $adminNodeName
1175    elif [[ $nodeStatus = ipa_alias ]]
1176    then
1177      # IP address aliasing is not supported.
1178      printErrorMsg 476 $mmcmd $nodeName
1179    elif [[ $nodeStatus = ipa_missing ]]
1180    then
1181      # The daemon node adapter was not found on the admin node.
1182      printErrorMsg 175 $mmcmd $nodeName $nodeName2
1183    elif [[ $rc = $MM_HostDown || $rc = $MM_ConnectTimeout ]]
1184    then
1185      # The node cannot be reached.
1186      printErrorMsg 340 $mmcmd $adminNodeName
1187    else
1188      # Unexpected error.  Display error messages.
1189      [[ -s $errMsg ]] && $cat $errMsg 1>&2
1190      [[ $rc -eq 0 ]] && rc=1
1191      checkForErrorsAndReturn "checkNewClusterNode $adminNodeName" $rc
1192      run on1 $adminNodeName removeFromCluster > /dev/null 2>&1 &
1193#     break
1194    fi
1195
1196    # If any of the server nodes fails, give up.
1197    if [[ $adminNodeName = $primaryServer || $adminNodeName = $backupServer ]]
1198    then
1199      fatalError=yes
1200      break
1201    fi
1202
1203    # Append the node name to the list of failed nodes.
1204    failedNodes="$failedNodes\n\t\t$adminNodeName"
1205
1206    # Adjust the node number for the next iteration.
1207    nodeNumber=$nodeNumber-1
1208
1209  fi  # end of if [[ $rc = 0 && $nodeStatus = success ]]
1210
1211  $rm -f $errMsg
1212
1213done  # end of while read -u3 nodeDesc (Loop through the nodes to be added)
1214
1215
1216#####################################################
1217# There is no point continuing if not even one node
1218# will be added to the cluster.
1219#####################################################
1220if [[ $totalNodeCount -eq 0 ]]
1221then
1222  # The user provided input file appears to be empty.
1223  # Note that we can have either -N or -n specified but not both.
1224  printErrorMsg 329 $mmcmd $Narg $narg
1225  cleanupAndExit
1226fi
1227
1228if [[ ! -s $goodnodes ]]
1229then
1230  # The command failed.
1231  printErrorMsg 389 $mmcmd
1232  cleanupAndExit
1233fi
1234
1235
1236######################################################
1237# If no severe errors were detected so far,
1238# ensure certain other requirements are met as well.
1239######################################################
1240if [[ -z $fatalError ]]
1241then
1242  # Ensure that the server nodes are members of the cluster
1243  # and were successfully initialized (checkNewClusterNode).
1244  if [[ -z $primaryInCluster ]]
1245  then
1246    printErrorMsg 352 $mmcmd "$primaryServer"
1247    fatalError=yes
1248  fi
1249  if [[ -z $backupInCluster && $backupServer != "_NOSECONDARY_" ]]
1250  then
1251    printErrorMsg 352 $mmcmd "$backupServer"
1252    fatalError=yes
1253  fi
1254
1255  # Ensure that there is at least one quorum node in the cluster.
1256  if [[ $quorumNodeCount -eq 0 ]]
1257  then
1258    printErrorMsg 53 $mmcmd
1259    fatalError=yes
1260  fi
1261
1262  # Ensure the node on which mmcrcluster runs (this node) is
1263  # going to be a member of the cluster.
1264  if [[ ! -f $mmfsNodeData ]]
1265  then
1266    # Run the command from a node that is part of the cluster.
1267    printErrorMsg 322 $mmcmd
1268    fatalError=yes
1269  fi
1270fi  # end of if [[ -z $fatalError ]]
1271
1272
1273#########################################################
1274# If no severe errors were detected so far,
1275# build the new mmsdrfs file.
1276#########################################################
1277if [[ -z $fatalError ]]
1278then
1279  #-------------------------------------------------
1280  # Create a mmsdrfs file with gen number 2 since
1281  # the nodes already have files with gen number 1.
1282  #-------------------------------------------------
1283  # Create the version line.
1284  newGenNumber=2   # gen number 2, since the nodes already have gen number 1
1285  [[ $backupServer = "_NOSECONDARY_" ]] && backupServer=""
1286  [[ $rshPath = "_DEFAULT_" ]] && rshPath=""
1287  [[ $rcpPath = "_DEFAULT_" ]] && rcpPath=""
1288  timeStamp=$($perl -e 'print time')
1289  sdrfsLine="$GLOBAL_ID:$VERSION_LINE::$CURRENT_SDRFS_FORMAT:$CURRENT_SDRFS_VERSION"
1290  sdrfsLine="$sdrfsLine:$newGenNumber::$MMMODE:$primaryServer:$backupServer"
1291  sdrfsLine="$sdrfsLine::$rshPath:$rcpPath:$clusterId:$clusterSubtype"
1292  sdrfsLine="$sdrfsLine:$timeStamp:$availableField:$clusterName"
1293  sdrfsLine="$sdrfsLine:$newKeyGenNumber:$secLevel:$committedKeyGenNumber"
1294  sdrfsLine="$sdrfsLine:$keyfileFormatLevel:"
1295  print -- "$sdrfsLine" > $newsdrfs
1296
1297  # Add threatening comment lines - DO NOT MESS WITH THIS FILE
1298  sdrfsLine="$GLOBAL_ID:$COMMENT_LINE::1:"
1299  print -- "$sdrfsLine" >> $newsdrfs
1300  sdrfsLine="$GLOBAL_ID:$COMMENT_LINE::2:$warningText"
1301  print -- "$sdrfsLine" >> $newsdrfs
1302  sdrfsLine="$GLOBAL_ID:$COMMENT_LINE::3:"
1303  print -- "$sdrfsLine" >> $newsdrfs
1304
1305  # Add a header line for the nodeset.
1306  sdrfsLine="$nodesetId:$NODESET_HDR:::$nodeCount:$commProtocol:$cipherList"
1307  sdrfsLine="$sdrfsLine:$tcpPort:$obsoleteField:$obsoleteField:$availableField"
1308  sdrfsLine="$sdrfsLine:$lowestVersion:$highestVersion:$osEnvironment"
1309  sdrfsLine="$sdrfsLine:$availableField:$eventsPort:$mmsdrservPort:"
1310  print -- "$sdrfsLine" >> $newsdrfs
1311  checkForErrors "writing to file $newsdrfs" $?
1312
1313  # Copy the lines describing the individual nodes.
1314  $cat $tmpsdrfs >> $newsdrfs
1315  checkForErrorsAndReturn "Writing to file $newsdrfs" $?
1316
1317  #--------------------------
1318  # Build the mmfs.cfg file.
1319  #--------------------------
1320  # Start the mmfs.cfg file with the warning text.
1321  print -- "#   " >  $newcfg
1322  print -- "#   WARNING:   This is a machine generated file.  Do not edit!      " >> $newcfg
1323  print -- "#   Use the mmchconfig command to change configuration parameters.  " >> $newcfg
1324  print -- "#   " >> $newcfg
1325
1326  # The following parameters are always specified
1327  # regardless of any value already existing in the config file.
1328  print -- "clusterName $clusterName" >> $newcfg
1329  print -- "clusterId $clusterId" >> $newcfg
1330  print -- "clusterType $MMMODE" >> $newcfg
1331  print -- "autoload $Aarg" >> $newcfg
1332  [[ $MMMODE = lc ]] && print -- "useDiskLease yes" >> $newcfg
1333  [[ -n $Uarg ]]     && print -- "uidDomain $Uarg"  >> $newcfg
1334  [[ -z $lowestVersion ]] && lowestVersion="$initialDaemonVersion"
1335  print -- "maxFeatureLevelAllowed $lowestVersion" >> $newcfg
1336  checkForErrorsAndReturn "Writing to file $newcfg" $?
1337
1338  # If a configuration file is specified (-c option),
1339  # verify its correctness and append it to our mmfs.cfg file.
1340  if [[ -n $carg ]]
1341  then
1342    processUserConfigFile $carg $tmpCfg
1343    if [[ -s $tmpCfg ]]
1344    then
1345      $cat $tmpCfg >> $newcfg
1346      checkForErrorsAndReturn "cat $tmpCfg >> $newcfg" $?
1347    fi
1348  fi
1349
1350  #--------------------------------------------
1351  # Add the mmfs.cfg data to the mmsdrfs file.
1352  #--------------------------------------------
1353  appendCfgFile $nodesetId $newcfg $newsdrfs
1354  checkForErrorsAndReturn "appendCfgFile" $?
1355
1356  #--------------------------------------------
1357  # Sort the new version of the mmsdrfs file.
1358  #--------------------------------------------
1359  LC_ALL=C $SORT_MMSDRFS $newsdrfs -o $newsdrfs
1360  checkForErrorsAndReturn "Sorting $newsdrfs" $?
1361
1362fi  # end of if [[ -z $fatalError ]]
1363
1364
1365############################################################
1366# If anything failed, remove the skeleton sdrfs files from
1367# the non-server nodes, issue an error message, and die.
1368############################################################
1369if [[ -n $fatalError ]]
1370then
1371  # Remove already-installed system files.
1372  printErrorMsg 351 $mmcmd
1373  $ln $goodnodes ${goodnodes}async
1374  $mmcommon onall_async ${goodnodes}async removeFromClusterCR &
1375
1376  # The command failed.
1377  printErrorMsg 389 $mmcmd
1378  cleanupAndExit
1379fi
1380
1381
1382##################################################################
1383# Put the new mmsdrfs file on the primary and secondary servers.
1384##################################################################
1385# Set some values that are expected by commitChanges.
1386getLocalNodeData
1387nsId=0
1388gpfsObjectInfo="0:1:"
1389
1390# Commit the changes.
1391trap "" HUP INT QUIT KILL
1392gpfsObjectInfo=$(commitChanges  \
1393   $nsId $nsId $gpfsObjectInfo $newGenNumber $newsdrfs  \
1394   $primaryServer FORCE $backupServer)
1395rc=$?
1396if [[ $rc -ne 0 ]]
1397then
1398  # We cannot replace the file in the sdr.
1399  printErrorMsg 381 $mmcmd
1400
1401  # Remove already-installed system files.
1402  printErrorMsg 351 $mmcmd
1403  $ln $goodnodes ${goodnodes}async
1404  $mmcommon onall_async ${goodnodes}async removeFromClusterCR &
1405  cleanupAndExit
1406fi
1407
1408# Restore interrupts.
1409trap posttrap HUP INT QUIT KILL
1410
1411
1412#######################################################################
1413# At this point, skeleton sdrfs files have been put on the non-server
1414# nodes in the success list and the real sdrfs file containing the
1415# nodes from the cluster has been created and put on the server nodes.
1416# If there are any nodes in the failure list, we issue a message
1417# telling the user to use the mmaddnode command to add them to the
1418# sdrfs file once they become reachable.
1419#######################################################################
1420# Report any nodes that could not be added.
1421[[ -n $failedNodes ]] &&  \
1422  printErrorMsg 353 $mmcmd "$failedNodes"
1423
1424# If not all of the nodes were added to the cluster,
1425# tell the user how many made it through.
1426[[ $nodeCount -lt $totalNodeCount ]] &&  \
1427  printErrorMsg 12 $mmcmd $nodeCount $totalNodeCount
1428
1429# Issue "command was successful" message.
1430printErrorMsg 272 $mmcmd
1431
1432
1433#######################################################################
1434# Update the mmsdrfs file on all nodes that were successfully added
1435# to the GPFS cluster.  This process is asynchronous.
1436#######################################################################
1437propagateSdrfsFile async $goodnodes $newsdrfs $newGenNumber
1438
1439cleanupAndExit $rc
1440
Note: See TracBrowser for help on using the repository browser.