#!/bin/ksh
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 1999,2007 
# 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 
# @(#)82 1.30.1.2 src/avs/fs/mmfs/ts/admin/mmfsck.sh, mmfs, avs_rgpfs24, rgpfs24s010a 2/12/07 10:38:18
#########################################################################
#
# Usage:
#   mmfsck Device [-n | -y] [-s | -v | -V] [-c | -o] [-t Directory]
#            [-N {all | mount | Node[,Node...] | NodeFile | NodeClass}]
#
#########################################################################

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

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

# Local variables
usageMsg=300
integer rc=0
integer nodeCount=0


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

#####################################################################
# Process the command arguments.
# Note that we do not use getopts to check the syntax.  tsfsck has some
# unorthodox debugging options that cannot be handled with getopts.
# The detailed syntax checking is left for the ts command.
# Here we make sure that we have the minimum needed to continue.
#####################################################################
[[ $arg1 = '-?' || $arg1 = '-h' || $arg1 = '--help' || $arg1 = '--' ]] &&  \
  syntaxError "help" $usageMsg

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

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

while [[ -n $1 ]]
do
  if [[ $1 = "-N"* ]]
  then
    # Intercept the -N parameter.
    [[ -n $Nflag ]] && syntaxError "multiple" $noUsageMsg "-N"
    Nflag="-N"
    if [[ $1 = "-N" ]]
    then
      [[ -z $2 ]] && syntaxError "missingValue" $noUsageMsg "-N"
      Narg="$2"
      nodeList="$2"
      shift
    else
      Narg=${1#-N}
      nodeList=${1#-N}
    fi
  else
    # Pass all other parameters to the tsfsck command.
    argList="$argList $1"
  fi  # end of if [[ $token = "-N"* ]]

  # Move to the next token
  [[ -n $1 ]] && shift

done  # end of while [[ -n $token ]]


#####################################################################
# Set up trap exception handling and ensure that the local copy of
# the mmsdrfs is up-to-date.  There is no need to lock mmsdrfs 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 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
fi


#######################################################
# If a list of nodes was specified via the -N option,
# convert it to a verified list of daemon node names.
#######################################################
if [[ -n $Nflag ]]
then
  if [[ $nodeList = all || $nodeList = mount ]]
  then
    # Add the keyword ("all" or "mount") to the argList string.
    argList="$argList -N $nodeList "
  else
    # Verify the node list and convert it to a file of daemon node names.
    createVerifiedNodefile "$nodeList" $DAEMON_NODENAME_Field no $nodefile
    [[ $? -ne 0 ]] && cleanupAndExit

    # Convert the output data from a file to a comma-separated list.
    newNodeList=$(print -- $(cat $nodefile) | $sed 's/ /,/g')

    # Add the verified node list to the argList string.
    argList="$argList -N $newNodeList "
  fi  # end of if [[ $nodeList = all || $nodeList = mount ]]
fi  # end of if [[ -n $Nflag ]]


##################################################
# First try to run the command on the local node.
##################################################
${mmcmdDir}/${links}/mmfsck $fqDeviceName $argList
rc=$(remapRC $?)

# If acceptable error (daemon not running, waiting for quorum),
# try some other node.  Otherwise, get out; the command either
# worked or the errors are not acceptable.
if [[ $rc -ne $MM_DaemonDown && $rc -ne $MM_QuorumWait || $MMMODE = single ]]
then
  if [[ $rc -eq $MM_ConnectionReset ]]
  then
    # An internode connection was reset.
    printErrorMsg 257 $mmcmd
  fi
  cleanupAndExit $rc
fi


############################################################################
# If the local daemon is not available, send the command to an active node.
############################################################################

# Create a file with the reliable names of the nodes in the cluster.
nodeCount=$(getNodeFile $REL_HOSTNAME_Field $GLOBAL_ID $mmsdrfsFile $nodefile)
[[ $nodeCount = 0 ]] &&  \
  checkForErrors "$mmcmd: No nodes found in the cluster." 1

# Try the nodes one by one until you find a node that can execute the command.
preferredNode=0     # We have no idea where to go first; let mmcommon decide.
$mmcommon linkCommand $preferredNode $nodefile mmfsck $fqDeviceName $argList
rc=$?

cleanupAndExit $rc

