#!/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 
# @(#)44 1.8 src/avs/fs/mmfs/ts/admin/mmlinkfileset.sh, mmfs, avs_rgpfs24, rgpfs240610b 1/23/06 01:56:54
###############################################################################
#
# Usage:
#   mmlinkfileset Device FilesetName [-J JunctionPath]
#
# where:
#   Device            is the device name of the file system.
#
#   FilesetName       is the fileset name.
#
#   JunctionPath      is the fileset junction path name.
#                     If not specified, it defaults to $PWD/FilesetName
#
###############################################################################

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

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

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

LOCAL_FILES=" "


# Local variables
usageMsg=515


# Local functions



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


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

[[ $argc -lt 2 ]] &&  \
  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 second argument is always the fileset name.
filesetName=$arg2

# Move past the positional parameters.
shift 2

# Process the rest of the parameters.
while getopts :J: OPT
do
  case $OPT in
    J) # New junction name
       [[ -n $Jflag ]] && syntaxError "multiple" $noUsageMsg "-$OPT"
       Jflag="-$OPT"; Jarg="$OPTARG"
       junctionName=$Jarg
       ;;

    +[J]) # 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: OPT do
shift OPTIND-1

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

# If not specified, default the junction name to the fileset name.
[[ -z $junctionName ]] && junctionName="$filesetName"


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

# 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;')


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

checkName lengthCheckOnly 1023 "$junctionName"
[[ $? -ne 0 ]] && cleanupAndExit

# Find the last component of the junction name and its parent directory.
junctionBaseName=${junctionName##*/}
junctionParentDir=${junctionName%/*}

checkName junctionName 255 "$junctionBaseName"
[[ $? -ne 0 ]] && cleanupAndExit

if [[ $junctionBaseName = '.' || $junctionBaseName = '..' ]]
then
  # Name is not allowed.
  printErrorMsg 551 $mmcmd "$junctionName"
  cleanupAndExit
fi

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

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

# Create the extended junction path name.
junctionName="/GPFS:${junctionDevAndIno#*:}${junctionName}"


####################################
# Invoke the tslinkfileset command.
####################################
$tslinkfileset $fqDeviceName "$filesetName" -J "$junctionName"
rc=$(remapRC $?)

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.
  : # [[ $rc -ne 0 ]] && printErrorMsg 113 "$mmcmd" "tslinkfileset" $rc
fi  # end of if [[ $rc -eq $MM_FsNotFound ]]

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

cleanupAndExit $rc

