#!/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 
# @(#)71 1.112 src/avs/fs/mmfs/ts/admin/mmchecksubsys.sh, mmfs, avs_rgpfs24, rgpfs240610b 10/28/05 01:24:23
#######################################################################
#
# mmchecksubsys is called by mmfsenv.
# This script verifies that all GPFS system files are at the latest
# level and then waits indefinitely for the proper conditions to exist
# for mmfs to come up.  If the conditions do not exist, a message is
# printed every minute for a while indicating what is being waited for.
# After so many messages, a larger time interval occurs between messages.
# The conditions checked for depend on the execution environment.
#
#######################################################################


#######################################################################
# If this has not been done yet by the caller, determine the pathname
# of the mm commands directory and include the global declarations.
#######################################################################
if [[ $commandPath != set ]]
then
  # Decide where to look for the commands.  The normal install directory
  # is /usr/lpp/mmfs/bin.  This can be changed by setting the MMFSDIR
  # environment variable to something other than /usr/lpp/mmfs.
  # If MMFSDIR is not used, before assuming the default install directory,
  # we will check if the mmfs binaries are in the same place where this
  # script resides.  This is a development aid for running out of a build tree.
  if [[ -n $MMFSDIR ]]
  then
    mmcmdDir="${MMFSDIR}/bin"
  else
    if [[ -z ${0%%/*} ]]
    then
      fullname="$0"
    else
      fullname="${PWD%/}/$0"
    fi
    progDir=${fullname%/*}

    if [[ -f ${progDir}/mmfs ]]
    then
      mmcmdDir="$progDir"
    else
      mmcmdDir="/usr/lpp/mmfs/bin"
    fi
  fi

  # Determine the values of mmcmdSubdir and mmcmdSuffix.
  set -f ; set -- $(/bin/uname -a) ; set +f
  osName=$1
  osVersion=$4
  if [[ -f ${mmcmdDir}/mmfs || $osName != AIX || $osVersion < 5 ]]
  then
    mmcmdSubdir=""
    mmcmdSuffix=""

  else
    # We must be running on top of AIX 5.
    # Determine whether the current kernel is 64-bit.
    kernelMode=$(${mmcmdDir}/mmkerninfo)
    if [[ $kernelMode = 64 ]]
    then
      mmcmdSubdir="aix64"
      mmcmdSuffix="64"
    else
      mmcmdSubdir="aix32"
      mmcmdSuffix=""
    fi
  fi

  # Include global declarations and service routines.
  . ${mmcmdDir}/mmglobfuncs
  . ${mmcmdDir}/mmsdrfsdef
  . ${mmcmdDir}/mmfsfuncs

  commandPath=set

fi # end of if [[ $commandPath != set ]]

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

# Local variables

intervala=10          # 10 6-second intervals is a message per minute.
intervalb=50          # 50 6-second intervals is a message every 5 minutes.
integer timeout=1
integer longwait=5    # Do 5 short waits before starting the long ones.
rvsd="rvsd"
havsd="/usr/bin/ha.vsd"
runningCmnd=""
rshPath=""
rcpPath=""


# Local routines


####################################################################
#
# Function:  Compare the release level of the currently-installed
#            code against the daemon version level for the nodeset.
#
# Input:     None
#
# Output:    None
#
# Returns:   0 - success
#            1 - incompatible release
#
####################################################################
function checkDaemonVersion
{
  typeset sourceFile="mmchecksubsys.sh"
  [[ -n $DEBUG || -n $DEBUGcheckDaemonVersion ]] && set -x
  $mmTRACE_ENTER "$*"

  typeset maxFeatureLevelAllowed
  typeset recordedProductVersion

  # Determine the value of the maxFeatureLevelAllowed parameter.
  maxFeatureLevelAllowed=$(showCfgValue maxFeatureLevelAllowed)

  # Warn the user if the current release information for
  # the node in the mmsdrfs file is not up to date.
  recordedProductVersion=$(getNodeInfo $PRODUCT_VERSION_Field  \
           $NODE_NUMBER_Field $ourNodeNumber $nsId $mmsdrfsFile)
  if [[ $recordedProductVersion != $productVersion ]]
  then
    print -u2 "$mmcmd: The release information for this node in the GPFS configuration files is not up to date."
    print -u2 "     Recorded Release: $recordedProductVersion  Installed Release: $productVersion."
    print -u2 "     Use the mmchconfig release=LATEST command to update the information."
    print -u2 "     Processing continues ..."
  fi

  # If maxFeatureLevelAllowed is not established yet, assume the lowest value.
  if [[ -z $maxFeatureLevelAllowed ]]
  then
    print -u2 "$mmcmd: The GPFS release level for nodeset $nsId cannot be determined (assumed $initialDaemonVersion)."
    printErrorMsg 344 $mmcmd "\"mmchconfig release=LATEST -C $nsId\""
    maxFeatureLevelAllowed=$initialDaemonVersion
  fi

  # Compare the daemon release levels.
  if [[ $compatibleDaemonVersion -gt $maxFeatureLevelAllowed ]]
  then
    rc=1
    print -u2 "$mmcmd: The GPFS code installed on this node is not compatible with the"
    print -u2 "     rest of the nodes in nodeset $nsId."

  elif [[ $currentDaemonVersion -lt $maxFeatureLevelAllowed ]]
  then
    rc=1
    print -u2 "$mmcmd: The GPFS code installed on this node is at a lower level than the"
    print -u2 "     rest of the nodes in nodeset $nsId."
    print -u2 "$mmcmd: Upgrade the node and run mmchconfig release=LATEST, or"
    print -u2 "     shutdown GPFS on all nodes and run mmchconfig release=$currentDaemonVersion"

  elif [[ $currentDaemonVersion -gt $maxFeatureLevelAllowed ]]
  then
    rc=0
    print -u2 "$mmcmd: The GPFS code installed on this node is at a higher level than the"
    print -u2 "     rest of the nodes in nodeset $nsId."
    print -u2 "$mmcmd: Processing continues but some functionality may not be available."
    print -u2 "$mmcmd: Upgrade the back level nodes and run mmchconfig release=LATEST"

  else
    # The node is at the right level.
    rc=0
  fi

  return $rc

}  #----------- end of function checkDaemonVersion -------------


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

$rm -f $errMsg

# Set up trap exception handling.
trap pretrap2 HUP INT QUIT KILL

# If not already done by mmautoload, make sure that
# the GPFS environment is properly initialized.
if [[ -n $GPFSINIT && $GPFSINIT != '""' ]]
then
  # If GPFSINIT is set in mmautoload, strip the surrounding quotes.
  GPFSINIT=${GPFSINIT#\"}
  gpfsInitOutput=${GPFSINIT%\"}
else
  # Verify the GPFS environment.

  # If AIX, verify there is an mmfs entry in /etc/vfs.
  # If Linux, figure out what is the correct major number.
  checkVfsNumber
  rc=$?
  if [[ $rc -ne 0 ]]
  then
    $rm -f $GLOBAL_FILES $LOCAL_FILES
    return $rc
  fi

  # If the major number of the /dev entries is incorrect, remove
  # one of the system files to force the environment to be rebuild.
  [[ $currentMajorNumber -ne $neededMajorNumber ]] && \
    $rm -f $mmfscfgFile

  # Make sure that the local copies of the mmsdrfs, mmfs.cfg,
  # and the rest of the system files are up to date.
  export MOUNT_POINT_CHECK=all
  gpfsInitOutput=$(gpfsInit nolock)
  rc=$?
  unset MOUNT_POINT_CHECK
  if [[ -z $gpfsInitOutput || $rc -ne 0 ]]
  then
    # The GPFS configuration information is missing.
    printErrorMsg 195 $mmcmd
    $rm -f $GLOBAL_FILES $LOCAL_FILES
    [[ $rc -eq 0 ]] && rc=1
    return $rc
  fi
fi

# Parse the output from the gpfsInit call.
setGlobalVar 0 $gpfsInitOutput

if [[ $MMMODE != lc && $MMMODE != single ]]
then
  # Unknown GPFS cluster type.
  printErrorMsg 338 $mmcmd $MMMODE
  $rm -f $GLOBAL_FILES $LOCAL_FILES
  return 1
fi

# Parse the Gpfs object information.
IFS=:
set -f ; set -- $gpfsObjectInfo ; set +f
runningCmnd=$3
IFS="$IFS_sv"


# Extract needed information from the mmsdrfs file.
vsdDisk=false
nonVsdDisk=false
IFS=":"
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.

  # Extract information from fields in various lines.
  case ${v[$LINE_TYPE_Field]} in

    $SG_DISKS )
      if [[ ${v[$NODESETID_Field]} != $FREE_DISK ]]
      then
        if [[ ${v[$NSD_SUBTYPE_Field]} = "vsd" ]]
        then
          vsdDisk=true
        else
          nonVsdDisk=true
        fi
      fi
      ;;

    $SG_ETCFS )
      if [[ ${v[$LINE_NUMBER_Field]} = $MOUNT_Line &&
            ${v[$ETCFS_TEXT_Field]}  = *automount* ]]
      then
        automountMounts=true
      fi
      ;;

  esac  # end of "Extract information from fields in various lines"

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

done  # end while read -u3 sdrfsLine

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

if [[ $nonVsdDisk = false && $vsdDisk = true ]]
then
  # If all of the disks are VSD based, normally we will wait for rvsd.
  # The exception is if the user explicitly set wait4RVSD to 'no'.
  waitForVsdSubsys=$(showCfgValue wait4RVSD)
  [[ -z $waitForVsdSubsys ]] && waitForVsdSubsys=yes
else
  # If there are non-VSD based disks, we will not wait for rvsd so
  # that the mounting of the non-VSD based file system can proceed.
  waitForVsdSubsys=no
fi


##################################################################
# Ensure mmsdrserv is not running on this node unless it has to.
##################################################################
[[ $ourNodeName != $primaryServer && $ourNodeName != $backupServer ]] &&  \
  killSdrServ >/dev/null 2>&1


##############################
# Start the automount daemon.
##############################
if [[ -n $automountMounts ]]
then
  # Determine the value of the automountDir parameter.
  [[ $osName = Linux ]] &&  \
    automountDir=$(showCfgValue automountDir)
  [[ -z $automountDir ]] && automountDir=$defaultAutomountDir

  # Start the automount daemon.
  startAutomounter $automountDir

fi  # end of if [[ $automountMounts = true ]]


##############################################################
# In a single node environment, there is nothing more to do.
##############################################################
if [[ $MMMODE = single ]]
then
  $rm -f $GLOBAL_FILES $LOCAL_FILES
  return 0
fi


#######################################################
# Make sure the code level on this node is compatible
# with code in the rest of the nodes in the nodeset.
#######################################################
# checkDaemonVersion
# rc=$?
# if [[ $rc -ne 0 ]]
# then
#   $rm -f $GLOBAL_FILES $LOCAL_FILES
#   return $rc
# fi


########################################################
# Wait until all conditions for daemon startup are met.
########################################################
while true
do
  if [[ -z $gpfsObjectInfo ]]
  then
    # Get the latest Gpfs object via a call to gpfsInit.
    # This will rebuild the environment if needed.
    export MOUNT_POINT_CHECK=all
    gpfsInitOutput=$(gpfsInit nolock 2>$errMsg)
    rc=$?
    unset MOUNT_POINT_CHECK
    if [[ -z $gpfsInitOutput || $rc -ne 0 ]]
    then
      # The GPFS configuration information is missing.
      printErrorMsg 195 $mmcmd 2>> $errMsg
    else
      # Parse the GpfsInit output.
      setGlobalVar 0 $gpfsInitOutput

      # Parse the Gpfs object information.
      IFS=':'
      set -f ; set -- $gpfsObjectInfo ; set +f
      IFS="$IFS_sv"
      runningCmnd=$3
    fi  # end of if [[ -z $gpfsInitOutput || $rc -ne 0 ]]
  fi  # end of if [[ -z $gpfsObjectInfo ]]

  if [[ -z $gpfsObjectInfo ]]
  then
    whatfor="cluster data repository"
  elif [[ -n $runningCmnd ]]
  then
    # An mm administration command is in progress.
    whatfor="$runningCmnd"
    gpfsObjectInfo=""    # Force gpfsInit to be executed again.

  else
    # If waitForVsdSubsys is set to 'yes', ensure rvsd is up and ready.
    if [[ $waitForVsdSubsys = yes && -x $havsd && $osName = AIX &&
          -z $(LC_ALL=C $lssrc -l -s $rvsd | $fgrep "active=1, state=idle") ]]
    then
      # rvsd is up but it is not ready yet.
      whatfor="rvsd-ready"
    else
      # All subsystems seem to be on-line.
      $rm -f $errMsg
      break
    fi  # end of if [[ $waitForVsdSubsys = yes ... ]]
  fi  # end of if [[ -z $gpfsObjectInfo ]]

  timeout=timeout-1
  if [[ $timeout -le 0 ]]
  then
    # Show detailed error messages if any.
    [[ -s $errMsg ]] && $cat $errMsg 1>&2
    $rm -f $errMsg
    # Tell the user what it is that we are waiting for.
    printErrorMsg 142 $mmcmd "$whatfor"
    if [[ $longwait -gt 0 ]]
    then
       longwait=longwait-1
       timeout=$intervala
    else
       timeout=$intervalb
    fi
  fi
  $sleep 6
done

$rm -f $GLOBAL_FILES $LOCAL_FILES
$mmTRACE_EXIT "$MMMODE environment verified rc=0"
return 0

