#!/bin/ksh
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 1998,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 
# @(#)02 1.64 src/avs/fs/mmfs/ts/admin/mmmvfs.sh, mmfs, avs_rgpfs24, rgpfs24s001a 3/30/06 14:59:15
##############################################################################
#
# Usage:
#   mmmvfs Device -W newDeviceName
#
# where
#   Device            is the file system to be renamed.
#   -W newDeviceName  is the new name for the file system.
#
##############################################################################

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

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


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

oldNodes=${tmpDir}oldNodes.${mmcmd}.$$
newNodes=${tmpDir}newNodes.${mmcmd}.$$
oldcfgFile=${tmpDir}oldcfgFile.${mmcmd}.$$

LOCAL_FILES=" $oldNodes $newNodes $oldcfgFile "

# Local variable declarations
usageMsg=185
newNodesetIdFound=no
oldNodesetId=""
fsMountPoint=""
existingMountPoints=""
existingMinorNumbers=""
newVSDfound=""
newDiskLeaseRequired=""
newLVfound=""
existingLVfound=""
existingVSDfound=""
existingDiskLeaseRequired=""
preferredNode=0


# Local functions



#######################
# Mainline processing.
#######################


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

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

[[ $argc -gt 3 ]] && syntaxError "help" $usageMsg

device=$arg1   # Save the file system device (always the first parameter).
shift 1        # Drop the device name from the parameter list.

while getopts :W: OPT
do
  case $OPT in

    W) # Rename the file system to the specified name.
       newFsName=$OPTARG
       ;;

    +[W]) syntaxError "invalidOption" $usageMsg $OPT
       ;;

    :) syntaxError "missingValue" $usageMsg $OPTARG
       ;;

    *) # invalid option specified
       syntaxError "invalidOption" $usageMsg $OPTARG
       ;;
  esac
done

shift OPTIND-1
[[ $# != 0 ]] && syntaxError "extraArg" $usageMsg $1


#####################################################################
# Verify the correctness of the input new device name parameter.
# The correctness of the existing device name is checked in findFS.
#####################################################################
newDeviceName=${newFsName##+(/)dev+(/)}  # name stripped of /dev/ prefix
newfqDeviceName="/dev/$newDeviceName"    # name with /dev/ prefix
if [[ $newDeviceName != ${newDeviceName#*/} ]]
then
  if [[ $newDeviceName = ${newDeviceName#/} ]]
  then
    printErrorMsg 170 $mmcmd $newFsName
  else
    # Name starts with a slash, but not /dev/.
    printErrorMsg 169 $mmcmd $newFsName
  fi
  cleanupAndExit
fi


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


###########################################################
# Make sure the specified file system exists and is local.
###########################################################
findFSoutput=$(findFS "$device" $mmsdrfsFile)
[[ -z $findFSoutput ]] && cleanupAndExit

# Parse the output from the findFS function.
set -f ; set -- $findFSoutput ; set +f
fqDeviceName=$1
deviceName=$2
fsHomeCluster=$3

# Exit with a message if the command was invoked for a remote file system.
if [[ $fsHomeCluster != $HOME_CLUSTER ]]
then
  # Command is not allowed for remote file systems.
  printErrorMsg 106 $mmcmd $device $fsHomeCluster
  cleanupAndExit 1
fi


##############################################
# Create the new version of the mmsdrfs file.
##############################################
$rm -f $newsdrfs $nodefile $allQuorumNodes
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.

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

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

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

       # Create a list of the quorum nodes.
       if [[ ${v[$CORE_QUORUM_Field]} = $quorumNode ]]
       then
         print -- "${v[$REL_HOSTNAME_Field]}" >> $allQuorumNodes
         checkForErrors "writing to file $allQuorumNodes" $?
       fi

       # If the node that is executing this command is part of the nodeset,
       # designate it as a "preferred node"
       [[ ${v[$NODE_NUMBER_Field]} = $ourNodeNumber ]] && \
         preferredNode=${v[$REL_HOSTNAME_Field]}
       ;;

    $SG_HEADR )  # This is a fs header line.
       # Make sure that the new file system name does not already exist.
       if [[ ${v[$DEV_NAME_Field]} = $newDeviceName ]]
       then
         printErrorMsg 107 $mmcmd $newFsName
         cleanupAndExit
       fi
       # If the line is for our file system, replace the
       # existing file system name with the new one.
       [[ ${v[$DEV_NAME_Field]} = $deviceName ]] && \
         v[$DEV_NAME_Field]=$newDeviceName
       ;;

    $SG_MOUNT | $SG_DISKS | $AUTHORIZED_FS )
       # If the line is for our file system, replace the
       # existing file system name with the new one.
       [[ ${v[$DEV_NAME_Field]} = $deviceName ]] && \
         v[$DEV_NAME_Field]=$newDeviceName
       ;;

    $SG_ETCFS )  # This is an /etc/filesystem line.
       # If the line is for our file system, replace the
       # existing file system name with the new one.
       # If it is the line for the device name, change the
       # device name to reflect the new device name as well.
       if [[ ${v[$DEV_NAME_Field]} = $deviceName ]]
       then
         v[$DEV_NAME_Field]=$newDeviceName
         if [[ ${v[$LINE_NUMBER_Field]} = $DEV_Line ]]
         then
           v[$ETCFS_TEXT_Field]="$DEV_Line_Prefix$newfqDeviceName"
         fi
       fi
       ;;

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

  esac  # end Change some of the fields

  # Build and write the line to the new mmsdrfs file.
  print_newLine >> $newsdrfs
  checkForErrors "writing to file $newsdrfs" $?

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

done  # end while read -u3 sdrfsLine

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


####################################################################
# Invoke tschfs with the -W parameter to rename the file system.
# This call, if successful, schedules the fs name change.
# The change is committed or rolled back depending on what name
# is used on the next file system request.  This in turn will
# depend on whether the mmsdrfs changes are successfully committed.
####################################################################
$mmcommon onactive $preferredNode $nodefile \
                   $NO_FILE_COPY $fqDeviceName $CHECK_ALL $NO_LINK \
                   tschfs $fqDeviceName -W $newDeviceName
rc=$?
if [[ $rc -ne 0 ]]
then
  # The tschfs step failed.
  printErrorMsg 104 $mmcmd tschfs
  cleanupAndExit
fi


############################################################
# Replace the mmsdrfs file in the sdr with the new version.
############################################################
trap "" HUP INT QUIT KILL
gpfsObjectInfo=$(commitChanges \
   $nsId $nsId $gpfsObjectInfo $newGenNumber $newsdrfs $primaryServer)
rc=$?
if [[ $rc -ne 0 ]]
then
  # Cannot replace the file in the sdr.
  printErrorMsg 381 $mmcmd
  cleanupAndExit
fi


######################################################################
# Finalize the stripe group descriptor changes (see comments above)
# by making a simple mmlsfs call to force the daemon to open the
# file system.  The -r option on mmlsfs is an arbitrary choice.
######################################################################
$mmcommon linkCommand  \
  $preferredNode $nodefile mmlsfs $newfqDeviceName -r > /dev/null 2>&1


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


#########################################################
# Propagate the changes to all the nodes in the cluster.
#########################################################
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

