#!/bin/ksh
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 1997,2006 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
# @(#)20 1.163.1.5 src/avs/fs/mmfs/ts/admin/mmcrfs.sh, mmfs, avs_rgpfs24, rgpfs24s007a 10/18/06 13:06:14
################################################################################
#
#  Usage:
#    mmcrfs Mountpoint Device {"DiskDesc[;DiskDesc...]" | -F DescFile}
#           [-A {yes | no | automount}] [-D {posix | nfs4}]
#           [-j {cluster | scatter}] [-k {posix | nfs4 | all}]
#           [-B BlockSize] [-i InodeSize] [-I IndirectSize] [ -L LogFileSize]
#           [-m DefaultMetadataReplicas] [-M MaxMetadataReplicas]
#           [-n NumNodes] [-N NumInodes[:NumInodesToPreallocate]] [-Q {yes | no}]
#           [-r DefaultDataReplicas] [-R MaxDataReplicas]
#           [-s {roundRobin | random | balancedRandom}]
#           [-u {yes | no}]
#           [-v {yes | no}] [-z {yes | no}]
#           [-E {yes | no}] [-S {yes | no}]
#           [-K {no | whenpossible | always}]
#
#  where
#    MountPoint    is the mount point directory of the new file system.
#    Device        is the device name of the new filesystem (/dev/sg0).
#    DiskDescList  is a list of semicolon-separated disk descriptors.
#    DescFile      is a file containing disk descriptors, one per line.
#
#  See the Admin guide for detailed descriptions of the optional flags.
#
#  Notes:  The [-z] option will be allowed only if DMAPI is enabled.
#          The [-i InodeSize], [-I IndirectSize], [-L LogFileSize] and
#          [-s {roundRobin|random|balancedRandom}] options are undocumented.
#
################################################################################

# Include global declarations and service routines.
. /usr/lpp/mmfs/bin/mmglobfuncs
. /usr/lpp/mmfs/bin/mmsdrfsdef
. /usr/lpp/mmfs/bin/mmfsfuncs

sourceFile="mmcrfs.sh"
[[ -n $DEBUG || -n $DEBUGmmcrfs ]] && set -x
$mmTRACE_ENTER "$*"

# Local work files.  Names should be of the form:
#   fn=${tmpDir}fn.${mmcmd}.$$

descfile=${tmpDir}descfile.${mmcmd}.$$     # temp file for descriptors
tsddFile=${tmpDir}tsddFile.${mmcmd}.$$     # disk descriptors in tscrfs format
freeDisks=${tmpDir}freeDisks.${mmcmd}.$$   # available unused disks

LOCAL_FILES=" $descfile $tsddFile $freeDisks "


# Local variables
usageMsg=420
integer seqNo=0

# Values for /etc/filesystems stanza lines
sgVFS_Line_Value="mmfs"       # only acceptable value
sgTYPE_Line_Value="mmfs"      # only acceptable value
sgNODENAME_Line_Value="-"     # only acceptable value
sgACCOUNT_Line_Value="false"  # only acceptable value
sgRW_OPT_Value="rw"           # only acceptable value
sgOTHER_OPT_Value=""

# Local functions



#######################
# Mainline processing
#######################


#######################################
# Process the command line arguments.
#######################################
[[ $arg1 = '-?' || $arg1 = '-h' || $arg1 = '--help' || $arg1 = '--' ]] &&  \
  syntaxError "help" $usageMsg

[[ $argc -lt 3  ]] &&  \
  syntaxError "missingArgs" $usageMsg

# Retrieve the positional parameters.
mountPoint=$arg1
device=$arg2

# The disk descriptors were either given as the third command line argument,
# or in a readable file given as the fourth command line argument.
if [[ $arg3 = "-F" ]]
then
  # -F specified.  The fourth argument must be a file name.
  if [[ -z $arg4 ]]
  then
    syntaxError "missingFile" $usageMsg
  else
    # Verify the existence of the file and create our own copy.
    checkUserFile $arg4 $descfile
    [[ $? -ne 0 ]] && cleanupAndExit
    shift 4
  fi  # end of if [[ -z $arg4 ]]
else
  desclist=$arg3
  # Ensure that semi-colon is used as a disk name separator.
  [[ "$desclist" = *+([,${BLANKchar}${TABchar}])* ]] &&  \
    syntaxError "badSeparator_notSemicolon" $noUsageMsg
  shift 3
fi  # end of if [[ $arg3 = "-F" ]]

# Save the remainder of the argument list for later processing by mmcrfsc.
argList=$@

# Check for the no-longer-valid -C <nodesetId> parameter.
# Simultaneously, make a quick check for other invalid options.
# The detailed checking will be done later by mmcrfsc.
while getopts :a:A:B:c:C:D:E:f:F:G:i:I:j:k:K:l:L:m:M:n:N:Q:r:R:s:S:U:u:v:w:Z:z: OPT
do
  case $OPT in
    C) # create the file system in the specified nodeset
       syntaxError "obsoleteOption" $usageMsg "-$OPT"
       ;;

    N) # maximum number of inodes
       [[ -n $Nflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT"
       Nflag="-$OPT"; Narg=$OPTARG;
       ;;

    [aABcDEfFGijIkKlLmMnNQrRsSUuvwZz]) # all other valid options
       : # detailed checking will be done later
       ;;

    +[aABcCDEfFGijIkKlLmMnNQrRsSUvwZz]) # invalid option specified
       syntaxError "invalidOption" $usageMsg $OPT
       ;;

    :) # missing required value after an option
       syntaxError "missingValue" $usageMsg $OPTARG
       ;;

    *) # invalid option specified
       syntaxError "invalidOption" $usageMsg $OPTARG
       ;;
  esac
done  # end of while getopts

# Verify the device name.
deviceName=${device##+(/)dev+(/)}  # name stripped of /dev/ prefix
fqDeviceName="/dev/$deviceName"    # fully-qualified name with /dev/ prefix
if [[ $deviceName = /* ]]
then
  printErrorMsg 169 $mmcmd $device
  cleanupAndExit
elif [[ $deviceName = */* ]]
then
  printErrorMsg 170 $mmcmd $device
  cleanupAndExit
else
  checkName deviceName 255 "$deviceName"
  [[ $? -ne 0 ]] && cleanupAndExit
fi

# Verify the mount point parameter.
checkName pathName 1023 "$mountPoint"
[[ $? -ne 0 ]] && cleanupAndExit

if [[ $mountPoint = ${mountPoint#/} ]]
then
  # The mountpoint must not be a relative path name.
  printErrorMsg 148 $mmcmd $mountPoint
  cleanupAndExit
fi

if [[ $fqDeviceName = $mountPoint ]]
then
  # The mount point cannot be the same as the device name.
  printErrorMsg 305 $mmcmd $mountPoint
  cleanupAndExit
fi

# Process the -N option (mmcrfsc is not suited for this option).
# Verify that the value is of the form NumInodes[:NumInodesToPreallocate]
if [[ -n $Narg ]]
then
  IFS=":"
  set -f ; set -- $Narg ; set +f
  numInodes=$1
  numInodesToPreallocate=$2
  IFS="$IFS_sv"

  [[ -z $numInodes ]] &&  \
    syntaxError "invalidOption" $usageMsg "$Nflag $Narg"

  n=$(checkIntRange $Nflag $numInodes)
  [[ $? -ne 0 ]] && cleanupAndExit
  Narg=$n

  if [[ -n $numInodesToPreallocate && $numInodesToPreallocate != 0 ]]
  then
    n=$(checkIntRange $Nflag $numInodesToPreallocate)
    [[ $? -ne 0 ]] && cleanupAndExit
    Narg="${Narg}:$n"
  fi
fi  # end of if [[ -n $Narg ]]


#######################################################################
# Set up trap exception handling and call the gpfsInit function.
# It will ensure that the local copy of the mmsdrfs and the rest of
# the GPFS system files are up-to-date and will obtain the sdr lock.
#######################################################################
trap pretrap HUP INT QUIT KILL
gpfsInitOutput=$(gpfsInit $lockId)
setGlobalVar $? $gpfsInitOutput

# Determine the lookup order for resolving host names.
[[ $osName != AIX ]] && resolveOrder=$(setHostResolveOrder)


############################################################################
# Go through the mmsdrfs file and make sure that the file system we
# are about to create does not already exist and that the new mount
# point is not already in use by some other file system in the nodeset.
#
# Simultaneously, we will create a file containing the reliable node names
# of the nodes in the nodeset.  This file will be later used to propagate
# the changes to /etc/filesystems.
#
# We will also create a file containing the names of all disks that
# belong to some file system.  This file will be used to assure that
# none of the new disks are already in use.
############################################################################
$rm -f $newsdrfs $nodefile $freeDisks
$touch $freeDisks  # Ensure the file exists even if empty.
IFS=":"            # Change the field separator to ':'.
exec 3<&-
exec 3< $mmsdrfsFile
while read -u3 sdrfsLine
do
  # Parse the line.
  set -f ; set -A v -- - $sdrfsLine ; set +f

  IFS="$IFS_sv"    # Restore the default IFS settings.
  printLine=true   # Assume the line will be printed.

  # Change some of the fields depending on the type of line.
  case ${v[$LINE_TYPE_Field]} in

    $VERSION_LINE )
       # Increment the generation number.
       newGenNumber=${v[$SDRFS_GENNUM_Field]}+1
       v[$SDRFS_GENNUM_Field]=$newGenNumber
       ;;

    $MEMBER_NODE )
       # Add the reliable node name to nodefile.
       print -- "${v[$REL_HOSTNAME_Field]}" >> $nodefile
       checkForErrors "writing to file $nodefile" $?

       # If this is the line for the node that is executing
       # this command, set the preferredNode variable.
       [[ ${v[$NODE_NUMBER_Field]} = $ourNodeNumber ]] &&  \
         preferredNode=${v[$REL_HOSTNAME_Field]}
       ;;

    $SG_HEADR )
       # Make sure that the file system that we want to create
       # does not already exist.
       if [[ ${v[$DEV_NAME_Field]} = $deviceName ]]
       then
         printErrorMsg 107 $mmcmd $device
         cleanupAndExit
       fi

       # Make a list of the used minor numbers in the nodeset.
       existingMinorNumbers="$existingMinorNumbers ${v[$DEV_MINOR_Field]}"
       ;;

    $SG_ETCFS )
       # Make sure that the new mount point is not already used
       # by some other file system in the nodeset.
       if [[ ${v[$LINE_NUMBER_Field]} = $MOUNT_POINT_Line &&
             ${v[$ETCFS_TEXT_Field]}  = $mountPoint ]]
       then
         printErrorMsg 107 $mmcmd $mountPoint
         cleanupAndExit
       fi

       # See if any of the existing file systems requires
       # the system automounter.
       if [[ ${v[$LINE_NUMBER_Field]} = $MOUNT_Line &&
             ${v[$ETCFS_TEXT_Field]}  = *automount* ]]
       then
         automountMounts=true
       fi
       ;;

    $SG_DISKS )
       # Collect the SG_DISKS lines for all free disks into a file.
       # These are the disks that are available to the new file system.
       if [[ ${v[$NODESETID_Field]} = $FREE_DISK ]]
       then
         print_newLine >> $freeDisks
         printLine=false
       fi
       ;;

    * )  # Pass all other lines without a change.
       ;;

  esac  # end of Change some of the fields

  # Build and write the line to the new mmsdrfs file.
  if [[ $printLine = true ]]
  then
    print_newLine >> $newsdrfs
    checkForErrors "writing to file $newsdrfs" $?
  fi

  IFS=":"  # Change the separator back to ":" for the next iteration.

done  # end while read -u3 mmsdrfsFile

IFS="$IFS_sv"  # Restore the default IFS settings.


#############################################################
# If a descriptor list is specified on the command line,
# create a file with one disk descriptor per line.
# Note: If the input is in a file, descfile was created
#       by the checkUserFile function.
#############################################################
if [[ -n $desclist ]]
then
  # Move the descriptors into a temporary file.
  $rm -f $descfile
  IFS=";"
  for diskDesc in $desclist
  do
    [[ -z $diskDesc ]] && continue
    print -- "$diskDesc" >> $descfile
    checkForErrors "writing to file $descfile" $?
  done  # end for diskDesc in $desclist
  IFS="$IFS_sv"
fi  # end of if [[ -n $desclist ]]


##########################################################
# Make sure that there is at least one free disk line.
##########################################################
if [[ ! -s $freeDisks ]]
then
  printErrorMsg 470 $mmcmd $mmcmd mmcrnsd
  cleanupAndExit
fi


##########################################################
# Process the descriptors for the new disks.  If a disk
# is successfully validated, its descriptor is converted
# into the format recognized by the tscrfs command.
##########################################################
$rm -f $tsddFile
foundErrors=false
fsHomeCluster=$HOME_CLUSTER

exec 3<&-
exec 3< $descfile
while read -u3 mmDiskDesc
do
  # Skip empty and comment lines.
  [[ $mmDiskDesc = *([$BLANKchar$TABchar])   ]] && continue
  [[ $mmDiskDesc = *([$BLANKchar$TABchar])#* ]] && continue

  # Parse mmDiskDesc to get the name of the disk.
  IFS=':'
  set -f ; set -- $mmDiskDesc ; set +f
  diskName=$1
  IFS="$IFS_sv"

  if [[ -z $diskName ]]
  then
    # The disk name must be specified in the disk descriptor.
    printErrorMsg 23 $mmcmd

    # Show the bad descriptor.
    printErrorMsg 386 $mmcmd "$mmDiskDesc"

    # The command will fail, but before giving up, we will check the
    # remainder of the descriptors to flush out as many errors as possible.
    foundErrors=true
    [[ $sdrLocked = yes ]] &&  \
      freeLockOnServer $primaryServer $ourNodeNumber >/dev/null
    sdrLocked=no

    # Move to the next descriptor.
    continue
  fi

  # Locate and extract the FREE_DISK line for this disk.
  $rm -f $tmpfile
  seqNo=seqNo+1
  freeDiskLine=$($awk -F: '                                                   \
    # If the line is for our disk, assign it to freeDiskLine.                 \
    # Do not put the line in the temp file.                                   \
    $'$DISK_NAME_Field' == "'$diskName'"  {                                   \
        { $'$LINE_NUMBER_Field' = "'$seqNo'" }                                \
        { print  $1":" $2":" $3":" $4":" $5":" $6":" $7":" $8":" $9":"$10":"  \
                $11":"$12":"$13":"$14":"$15":"$16":"$17":"$18":"$19":"$20":"  \
                $21":"$22":"$23":"$24":"$25":"$26":"$27":" }                  \
        { next }                                                              \
     }                                                                        \
    # If the line is for some other disk, add it to tmpfile.                  \
    { print $0 >> "'$tmpfile'" }                                              \
  ' $freeDisks)
  checkForErrors awk $?

  # Prepare the freeDisks file for the next iteration.
  # It will contain all of its original lines except the line
  # that describes the disk that is currently being processed.
  $touch $tmpfile  # ensure file exists even if empty
  $mv $tmpfile $freeDisks
  checkForErrors "mv $tmpfile $freeDisks" $?

  # If not found, issue an appropriate error message.
  if [[ -z $freeDiskLine ]]
  then
    # Check whether the disk already belongs to some file system.
    fileSystem=$(findFSforDisk "$diskName" $newsdrfs)
    if [[ $fileSystem = $deviceName ]]
    then
      # This disk was already processed;
      # this must be due to a duplicate entry in the input list since
      # the file system did not exist at the start of this command.
      printErrorMsg 88 $mmcmd $diskName
      # Show the bad descriptor.
      printErrorMsg 386 $mmcmd "$mmDiskDesc"
    elif [[ -n $fileSystem ]]
    then
      # The disk already exists in some other file system.
      printErrorMsg 265 $mmcmd $diskName $fileSystem
      # Show the bad descriptor.
      printErrorMsg 386 $mmcmd "$mmDiskDesc"
    else
      # Print error stating disk descriptor should refer to an existing NSD.
      printErrorMsg 415 $mmcmd "$mmDiskDesc"
    fi

    # The command will fail, but before giving up, we will check the
    # remainder of the descriptors to flush out as many errors as possible.
    foundErrors=true
    [[ $sdrLocked = yes ]] &&  \
      freeLockOnServer $primaryServer $ourNodeNumber >/dev/null
    sdrLocked=no

    # Move to the next descriptor.
    continue
  fi  # end of if [[ -z $freeDiskLine ]]

  # Check the correctness of the disk descriptor.  If everything is OK,
  # validateAndConvertNsdDescriptor will convert the descriptor into its
  # tscrfs format and will create the SG_DISKS line for the new disk.
  validateDescriptorOutput=$(validateAndConvertNsdDescriptor  \
              "$mmDiskDesc" $freeDiskLine $deviceName $fsHomeCluster NULL)
  rc=$?
  if [[ $rc -ne 0 ]]
  then
    # If an error was found, the validate routine issued a message.
    # We will now print the entire descriptor to help the guy some more.
    printErrorMsg 386 $mmcmd "$mmDiskDesc"

    # The command will fail, but before giving up, we will check the remainder
    # of the descriptors to flush out as many errors as possible.
    foundErrors=true
    [[ $sdrLocked = yes ]] &&  \
      freeLockOnServer $primaryServer $ourNodeNumber >/dev/null
    sdrLocked=no

    # Move to the next descriptor.
    continue
  fi   # end of if [[ $rc -ne 0 ]]

  # If the descriptor seems to be OK, parse the output
  # from the validateAndConvertNsdDescriptor routine.
  set -f ; set -- $validateDescriptorOutput ; set +f
  updatedDiskLine="$1"
  tsDiskDesc="$2"
  diskUsage="$3"

  # Add the converted descriptor to the input for tscrfs.
  print -- "$tsDiskDesc" >> $tsddFile
  checkForErrors "writing to file $tsddFile" $?

  # Add the SG_DISKS line for the new disk to the mmsdrfs file.
  print -- "$updatedDiskLine" >> $newsdrfs
  checkForErrors "writing to file $newsdrfs" $?

  # Keep track of the overall disk usage.
  [[ $diskUsage != metadataOnly && $diskUsage != descOnly ]] && onedata=ok
  [[ $diskUsage != dataOnly && $diskUsage != descOnly ]]     && onemeta=ok

done   # end of while read -u3 mmDiskDesc


# Give up if there were errors with one or more of the descriptors.
if [[ $foundErrors = true ]]
then
  # Command failed.
  printErrorMsg 389 $mmcmd
  cleanupAndExit
fi

# Were there disks to begin with?
if [[ -z $onemeta && -z $onedata ]]
then
  # No disks were specified.
  printErrorMsg 264 $mmcmd
  cleanupAndExit
fi

# Make sure that not all of the disks are dataOnly or metadataOnly.
if [[ -z $onemeta ]]
then
  # All disks are dataOnly.
  printErrorMsg 198 $mmcmd
  cleanupAndExit
fi

if [[ -z $onedata ]]
then
  # All disks are metadataOnly.
  printErrorMsg 197 $mmcmd
  cleanupAndExit
fi

# If there are any SG_DISKS lines for remaining free disks,
# put them back in the mmsdrfs file.
if [[ -s $freeDisks ]]
then
  $cat $freeDisks >> $newsdrfs
  checkForErrors "cat $freeDisks >> $newsdrfs" $?
fi


# Before checking the rest of the parameters,
# we need to determine the current maxblocksize in effect.
maxblocksize=$($mmcommon onactive $preferredNode $nodefile  \
  $NO_FILE_COPY $NO_MOUNT_CHECK NULL $NO_LINK tsctl showCfgValue maxblocksize)
rc=$?
if [[ -z $maxblocksize || $rc -ne 0 ]]
then
  [[ $rc -eq 0 ]] && rc=1
  if [[ $rc -eq $MM_DaemonDown || $rc -eq $MM_QuorumWait ]]
  then
    :  # Do nothing; a message was already issued.
  elif [[ $rc -eq $MM_ConnectionReset ]]
  then
    # An internode connection was reset.
    printErrorMsg 257 $mmcmd
  elif [[ -n $maxblocksize ]]
  then
    # If there was some output, assume it is an error message.
    print -u2 $maxblocksize
  else
    # An unexpected error occurred during the tsctl operation.
    printErrorMsg 171 $mmcmd "mmcommon onactive tsctl showCfgValue maxblocksize" $rc
  fi
  # The command failed.
  printErrorMsg 389 $mmcmd
  cleanupAndExit $rc
fi

# Use mmcrfsc to check the rest of the arguments.
# Error messages will be issued by mmcrfsc.
mmcrfscOutput=$($mmcrfsc M $maxblocksize $argList)
rc=$?
[[ $rc -eq 123 ]] && printErrorMsg $usageMsg $mmcmd
[[ $rc -ne   0 ]] && cleanupAndExit

# Parse the mmcrfsc output.
set -f ; set -- $mmcrfscOutput ; set +f
sgMOUNT_Line_Value=$1
sgMTIME_OPT_Value=$2
quotaOption=$3
sgATIME_OPT_Value=$4
shift 4
tsArguments="$*"

# If something is wrong, get out.
[[ -z $tsArguments ]] && cleanupAndExit

# Append the value of the -N NumInodes[:NumInodesToPreallocate] parameter.
[[ -n $Narg ]] && tsArguments="$tsArguments $Nflag $Narg"

# Translate the quota option into its /etc/filesystems format.
# The other mount options, mtime and atime, are set by mmcrfsc.
if [[ $quotaOption = enableQuota ]]
then
  sgQUOTA_OPT_Value=$QUOTA_ACTIVATED
else
  sgQUOTA_OPT_Value=$QUOTA_DISACTIVATED
fi

# Figure out what should the major number be.
if [[ $osName = Linux ]]
then
  checkVfsNumber
  devMajor=$currentMajorNumber
fi
[[ -z $devMajor ]] && devMajor=$defaultMajorNumber

# Assign a minor number to the file system.
# Keep trying until we get a minor number that is not used by anybody.
rc=0
minor=""
while [[ -z $minor && $rc -eq 0 ]]
do
  # Assign a minor number to the file system.
  devMinor=$(assignDevMinor "$existingMinorNumbers")
  rc=$?
  if [[ $rc -eq 0 ]]
  then
    # Check whether the new device number is being used by somebody.
    inuse=$($ls -lL /dev 2>/dev/null | $grep "^${fsDeviceType}.* $devMajor, *$devMinor ")
    if [[ -z $inuse ]]
    then
      # The number seems to be free.
      minor=$devMinor
    fi

    # Add the number to the list of existing minor numbers.
    existingMinorNumbers="$existingMinorNumbers $devMinor"

  fi  # end of if [[ $rc -eq 0 ]]
done # end of while [[ -z $minor && $rc -eq 0 ]]

if [[ -z $minor ]]
then
  print -u2 "$mmcmd:  Cannot assign a minor number for the file system."
  cleanupAndExit
fi


# If this is the first automountable GPFS file system,
# run the automount command on the nodes in the cluster.
if [[ $sgMOUNT_Line_Value = automount && -z $automountMounts ]]
then
  # Determine the value of the automountDir parameter.
  automountDir=$(showCfgValue automountDir)
  [[ -z $automountDir ]] && automountDir=$defaultAutomountDir

  # Run the automount command on the nodes on which GPFS is active.
  # On nodes that do not have GPFS running right now, this will be
  # done by the mmchecksubsys processing when the daemon is started.
  $mmcommon onactive $preferredNode $nodefile        \
      $NO_FILE_COPY $NO_MOUNT_CHECK NULL $NO_LINK    \
      tsdsh $mmremote startAutomounter $automountDir >$tmpfile 2>&1
  rc=$?

  # Ignore errors but show messages from the nodes, if any.
  if [[ $rc -ne 0 && $rc -ne $MM_DaemonDown && -s $tmpfile ]]
  then
    $awk '                             \
      # Skip the lines with rc values. \
      $2 == "rc" { next }              \
      # Print everything else.         \
      { print $0 }                     \
    ' $tmpfile
  fi  # end of if [[ -s $tmpfile ]]
fi  # end of if [[ $sgMOUNT_Line_Value = automount && -z $automountMounts ]]


# Build the rest of the SG-related lines for the new file system.
# Note:  In order to preserve the tab characters in the /etc/filesystems lines,
#        we temporarily reset the value of the IFS variable to exclude the tab.
IFS=' '

newLine="$fsHomeCluster:$SG_HEADR:$deviceName::$minor::::"
print "$newLine" >> $newsdrfs

newLine="$fsHomeCluster:$SG_ETCFS:$deviceName:$MOUNT_POINT_Line:$mountPoint:"
print "$newLine" >> $newsdrfs

newLine="$fsHomeCluster:$SG_ETCFS:$deviceName:$DEV_Line"
newLine="$newLine:$DEV_Line_Prefix$fqDeviceName"
print "$newLine" >> $newsdrfs

newLine="$fsHomeCluster:$SG_ETCFS:$deviceName:$VFS_Line"
newLine="$newLine:$VFS_Line_Prefix$sgVFS_Line_Value"
print "$newLine" >> $newsdrfs

newLine="$fsHomeCluster:$SG_ETCFS:$deviceName:$NODENAME_Line"
newLine="$newLine:$NODENAME_Line_Prefix$sgNODENAME_Line_Value"
print "$newLine" >> $newsdrfs

newLine="$fsHomeCluster:$SG_ETCFS:$deviceName:$MOUNT_Line"
newLine="$newLine:$MOUNT_Line_Prefix$sgMOUNT_Line_Value"
print "$newLine" >> $newsdrfs

newLine="$fsHomeCluster:$SG_ETCFS:$deviceName:$TYPE_Line"
newLine="$newLine:$TYPE_Line_Prefix$sgTYPE_Line_Value"
print "$newLine" >> $newsdrfs

newLine="$fsHomeCluster:$SG_ETCFS:$deviceName:$ACCOUNT_Line"
newLine="$newLine:$ACCOUNT_Line_Prefix$sgACCOUNT_Line_Value"
print "$newLine" >> $newsdrfs

newLine="$fsHomeCluster:$SG_MOUNT:$deviceName::$sgRW_OPT_Value"
newLine="$newLine:$sgMTIME_OPT_Value:$sgATIME_OPT_Value"
newLine="$newLine:$sgQUOTA_OPT_Value:$sgOTHER_OPT_Value:::::::::::::"
print "$newLine" >> $newsdrfs
checkForErrors "writing to file $newsdrfs" $?

IFS="$IFS_sv"


# The last step in creating the new mmsdrfs file is sorting it.
LC_ALL=C $SORT_MMSDRFS $newsdrfs -o $newsdrfs
checkForErrors "sorting $newsdrfs" $?


#############################
# Invoke the tscrfs command.
#############################
$mmcommon onactive $preferredNode $nodefile                         \
                   $tsddFile $NO_MOUNT_CHECK NULL $NO_LINK          \
                   tscrfs "$fqDeviceName -F $tsddFile $tsArguments"
rc=$?
if [[ $rc -ne 0 ]]
then
  # tscrfs failed.
  printErrorMsg 100 $mmcmd $device
  cleanupAndExit $rc
fi


#############################################################
# Put the mmsdrfs file into the sdr.  This will make the new
# file system visible to nodes that have not come up yet.
# Nodes that are currently active are handled below.
#############################################################
trap "" HUP INT QUIT KILL
gpfsObjectInfo=$(commitChanges  \
   $fsHomeCluster $nsId $gpfsObjectInfo $newGenNumber $newsdrfs $primaryServer)
rc=$?
if [[ $rc -ne 0 ]]
then
  # The commit step failed; we cannot replace the file in the sdr.
  printErrorMsg 381 $mmcmd
  cleanupAndExit
fi


#############################################################
# Unlock the sdr.
#############################################################
freeLockOnServer $primaryServer $ourNodeNumber >/dev/null
sdrLocked=no
trap posttrap HUP INT QUIT KILL


#########################################################################
# Make the new file system visible to the nodes.  This includes adding
# a stanza to /etc/filesystems, creating the character mode device,
# and creating the mount point directory.  This process is asynchronous.
#########################################################################
propagateSdrfsFile async $nodefile $newsdrfs $newGenNumber


###################################################
# If installed, invoke the syncfsconfig user exit.
###################################################
if [[ -x $syncfsconfig ]]
then
   print -- "$mmcmd:  Starting $syncfsconfig ..."
   $syncfsconfig
   print -- "$mmcmd:  $syncfsconfig finished."
fi

cleanupAndExit 0

