#!/bin/ksh
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 2005,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 
# @(#)41 1.9.1.1 src/avs/fs/mmfs/ts/admin/mmchfileset.sh, mmfs, avs_rgpfs24, rgpfs24s007a 10/18/06 12:02:51
################################################################################
#
# Usage:
#   mmchfileset Device {FilesetName | -J JunctionPath}
#                      {[-j NewFileSetName] [-t Comment]}
#
# where:
#   Device          is the device name of the file system.
#   FilesetName     is the fileset name.
#   JunctionPath    is the fileset junction path name.
#   NewFilesetName  is the new fileset name to be given to an existing fileset.
#   Comment         is a user-provided description of the fileset.
#                     The total length cannot exceed 255 characters.
#
################################################################################

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

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

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

LOCAL_FILES=" "


# Local variables
usageMsg=514


# Local functions



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


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

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

# The first argument is always the file system name.
device=$arg1
deviceName=${device##+(/)dev+(/)}  # name stripped of /dev/ prefix
fqDeviceName="/dev/$deviceName"    # fully-qualified name (with /dev/ prefix)

# The device name must be followed by a fileset name or -J and a junction path.
if [[ $arg2 = "-J"* ]]
then
  junctionName=${arg2#-J}
  if [[ -z $junctionName ]]
  then
    junctionName=$arg3
    shift 3
  else
    shift 2
  fi
else
  filesetName=$arg2
  checkName filesetName 255 "$filesetName"
  [[ $? -ne 0 ]] && cleanupAndExit
  [[ $arg3 = "-J"* ]] &&  \
    syntaxError "invalidCombination" $usageMsg "-J" "FilesetName"
  shift 2
fi

# Process the rest of the parameters.
while getopts :j:t: OPT
do
  case $OPT in
    j) # New fileset name
       [[ -n $jflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT"
       jflag="-$OPT"; jarg="$OPTARG"
       newFilesetName=$jarg
       checkName filesetName 255 "$newFilesetName"
       [[ $? -ne 0 ]] && cleanupAndExit
       ;;

    t) # New comment string
       [[ -n $tflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT"
       tflag="-$OPT"; targ="$OPTARG"
       userComments="$targ"
       checkName lengthCheckOnly 255 "$userComments"
       [[ $? -ne 0 ]] && cleanupAndExit
       ;;

    +[jt]) # Invalid option
       syntaxError "invalidOption" $usageMsg $OPT
       ;;

    :) # Missing argument
       syntaxError "missingValue" $usageMsg $OPTARG
       ;;

    *) # Invalid option
       syntaxError "invalidOption" $usageMsg $OPTARG
       ;;

  esac
done  # end of while getopts :j:t: OPT do
shift OPTIND-1

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


######################################################################
# Set up trap exception handling and ensure that the local copy of
# the mmsdrfs file is up-to-date.  There is no need to lock the file.
######################################################################
trap pretrap2 HUP INT QUIT KILL
gpfsInitOutput=$(gpfsInit nolock)
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 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
fi


#############################
# Verify the junction name.
#############################
if [[ -n $junctionName ]]
then
  # The file system must be mounted.
  mountPoint=$(findMountpoint $deviceName)
  if [[ -z $mountPoint ]]
  then
    # File system is not mounted.
    printErrorMsg 552 $mmcmd $device
    cleanupAndExit
  fi

  # Find the device ID of the mounted GPFS file system.
  gpfsDeviceID=$($perl -e '($dev) = stat "'$mountPoint'"; printf "%u", $dev;')

  # Ensure the junction path name is fully qualified.
  [[ $junctionName != /* ]] && junctionName="${PWD%/}/${junctionName}"
  junctionName=${junctionName%%/}  # Strip any trailing slashes.

  # Find the device ID and inode number of the junction.
  # The result is a colon-separated device and inode numbers.
  junctionDevAndIno=$($perl -e ' ($dev,$ino) = stat "'$junctionName'";
                                 if ($dev ne "") { printf "%u:%u", $dev,$ino }')

  # The junction must be within the mounted file system.
  if [[ $gpfsDeviceID != ${junctionDevAndIno%:*} ]]
  then
    printErrorMsg 550 $mmcmd "$junctionName" $device
    cleanupAndExit
  fi

  # Create the extended junction path name.
  junctionName="-J /GPFS:${junctionDevAndIno#*:}${junctionName}"
fi  # end of if [[ -n $junctionName ]]


##########################################################################
# Invoke the tschfileset command on the local node.
# Display any error messages and exit if any of the following are true:
#   - the command completed successfully
#   - a junction path name is specified
#   - there is an unacceptable error
#       (anything other than daemon down or quorum wait)
#   - the user comment string contains blanks or tabs
#       (the existing infrastructure cannot deal with imbedded blanks)
#   - the fileset name (old or new) contains path name expansion triggers
#   - this is a single node cluster
##########################################################################
[[ -n $newFilesetName ]] && newFilesetName="-j $newFilesetName"

set -f
if [[ -n $userComments ]]
then
  $tschfileset $fqDeviceName  \
    $filesetName $junctionName $newFilesetName -t "$userComments" 2>$errMsg
  rc=$(remapRC $?)
else
  $tschfileset $fqDeviceName  \
    $filesetName $junctionName $newFilesetName 2>$errMsg
  rc=$(remapRC $?)
fi
set +f

if [[ $rc -ne $MM_DaemonDown && $rc -ne $MM_QuorumWait ||
      "$userComments"   = *+([;$BLANKchar$TABchar])*   ||
      -n $junctionName || $MMMODE = single ]]
then
  if [[ $rc -eq $MM_DaemonDown ]]
  then
    # GPFS is down on this node.
    printErrorMsg 109 $mmcmd
  elif [[ $rc -eq $MM_QuorumWait ]]
  then
    # GPFS is not ready for commands.
    printErrorMsg 110 $mmcmd
  elif [[ $rc -eq $MM_ConnectionReset ]]
  then
    # An internode connection was reset.
    printErrorMsg 257 $mmcmd
  else
    # Either the command worked, or it is an unexpected error.
    [[ -s $errMsg ]] && $cat $errMsg 1>&2
#   [[ $rc -ne 0 ]] && printErrorMsg 113 "$mmcmd" "tschfileset" $rc
  fi  # end of if [[ $rc -eq $MM_FsNotFound ]]
  cleanupAndExit $rc
fi  # end of if [[ ($rc -ne $MM_DaemonDown && ... ]]
$rm -f $errMsg


#####################################################################
# We come here if the local GPFS daemon is not ready for commands.
# Find an active node and send the command there.
#####################################################################

# Create a file with the reliable names of the nodes in the cluster.
getNodeList $REL_HOSTNAME_Field $GLOBAL_ID $mmsdrfsFile > $nodefile
preferredNode=$ourNodeName

# Try the nodes one by one until you find a node that can execute the command.
if [[ -n $userComments ]]
then
  $mmcommon onactive $preferredNode $nodefile     \
     $NO_FILE_COPY $NO_MOUNT_CHECK NULL $NO_LINK  \
     tschfileset $fqDeviceName $filesetName $newFilesetName -t "$userComments"
  rc=$?
else
  $mmcommon onactive $preferredNode $nodefile     \
     $NO_FILE_COPY $NO_MOUNT_CHECK NULL $NO_LINK  \
     tschfileset $fqDeviceName $filesetName $newFilesetName
  rc=$?
fi

# if [[ $rc -ne 0 ]]
# then
#   # tschfileset failed.
#   printErrorMsg 104 $mmcmd tschfileset
#   cleanupAndExit $rc
# fi

cleanupAndExit $rc

