#! /bin/sh
#
# Script Name : adpt-iscsi-mount 
# 
# Mount iSCSI devices listed in /etc/fstab.adaptec
# to the mount point as specified.
#

# Variable assignments

BASEDIR=/usr/local
PATH=/sbin:/bin:/usr/sbin:/usr/bin:$BASEDIR/sbin:$BASEDIR/bin:$PATH
FSTAB_FILE="/etc/fstab.adaptec"
PROCFILE="/proc/scsi/scsi"
LUN="Lun"
RETRYNUMBER=5
SLEEP_INTERVAL=1


#---------------------------------------------------------------
# Routine : adpt_fsck()
#
# The adpt_fsck  subroutine tries to do a fsck on the imported 
# target file systems.
#
# Check the partitions that has been already mounted with mount
# Check if the partitions mounted matches with all the partitions
# which has been listed in the file /etc/fstab.adaptec to be
# mounted.If there is any partition which has been listed in the
# file but not mounted,then it should be mounted.
#---------------------------------------------------------------

adpt_fsck()
{
   local target_device=$1 retries=$RETRYNUMBER sleep_interval=$SLEEP_INTERVAL
   fileSystemType=$2
  
   while [ $retries -gt 0 ]; 
   do 
       if [ -e $target_device ]; then # Check if the device exists

            #
            # Do an fsck to check for errors in the specified file system !
            #
            # The '-a' option automatically repairs the file system if 
            # there is any error which has been reported by fsck.This is also
            # an workaround for 'fsck' not to inherit the file descriptor of  
            # fstab.adaptec file as the standard input.Fsck does not receive
            # inputs from a file. 
            #

            fsck -a -t $fileSystemType $target_device

            err=$?

            echo "The return value of fsck is $err"

            if   [ $err -le 1 ]; then   # fsck has been successful

                    echo "File system check OK ! No errors"
                    return 0

            elif [ $err -eq 8 ]; then    # Assume device is not yet available

                    sleep $sleep_interval
                    retries=$(($retries - 1))
                    echo " !! Device probe has failed , $retries retries are remaining !!"

            elif [ $err -ge 2 ]; then    # Fatal error 

                    echo "!! Automated fsck failed on $target_device failed !!"
                    echo "!! Please try out fsck manually !!"
                    return 1

            fi
        else 
            sleep $sleep_interval
            retries=$((retries - 1))
            echo "!! The device $target_device is not available, $retries retries remaining !!" 
        fi
   done
   return 1
}
             
#-----------------------------------------------------------------------------
# Routine : adpt_mount()
#
# The adpt_mount subroutine tries to mount the filesystems as specified in the
# file /etc/fstab.adaptec
#-----------------------------------------------------------------------------
 
adpt_mount()
{
  local targetDevice=$1
  local mountPoint=$2
  local fileSystemType=$3
  local mountOptions=$4 
 
  # Check to see if the device entry in /etc/fstab.adaptec 
  # matches with the mount output.If the entry is present then 
  # the filesystem need not be mounted. 

  for device in `mount  | grep "$targetDevice" | awk '{ print $1 }'` ; do
      if [ "$targetDevice" = "$device" ] ; then
         return
      fi
  done

  #
  # The user could have specified a /dev/iscsi/... link
  # in the /etc/fstab.adaptec file.  If this is the case,
  # the output from the mount command may not match
  # (it may contain the actual device, whereas the user
  # specified the /dev/iscsi/... link).  Thus, if it's
  # a symlink in the /etc/fstab.adaptec file, we need to
  # resolve the link and do an additional check.
  #

  if [ -L $targetDevice ]; then
        lnname=`ls -l $targetDevice | cut -d ">" -f 2 | cut -d " " -f 2`
        targetFileSystem=$lnname
  fi

  for device in  `mount |grep "$targetDevice"|awk '{print $1}'`;do
        if [ "$targetDevice" = "$device" ];then
            return
        fi
  done

  # Do a file system check before doing a mount 
  
  echo "Calling fsck ....."

  if adpt_fsck $targetDevice $fileSystemType; then
        mount -t $fileSystemType $targetDevice $mountPoint
  fi
} 

# ************************************
#          SCRIPT STARTS HERE
# ************************************


# Check if the file /etc/fstab.adaptec is available"
# If the file is not present, then exit
                                                                                                                             
if [ ! -f $FSTAB_FILE ]; then
        echo "This script requires /etc/fstab.adaptec file to be be present !"
        echo "Please provide the file with contents as specified below and rerun the script !"
        echo "File_System_to_mount  Mount_Point  File_System_Type  Mount_Options"
        exit 1
fi;
                                                                                                                             
#
# Read the /proc/scsi/scsi file and find out the number of Luns
#

if [ ! -f $PROCFILE ]; then 
   echo "Lun[s] not visible to the SCSI Mid Layer Core of Linux"
   echo "Remote Luns not mapped to the local drives !"  
   exit 0
fi

lunCount=`cat $PROCFILE | grep $LUN | wc -l`

echo "$lunCount LUN[s] are visible to the SCSI Mid layer"
 

# Assign a counter to track the number of partition entries read

count=1

#
# Read the fstab.adaptec file where in we have the listing of the devices
# which has to be mounted
#

cat $FSTAB_FILE | while read devToMount mountPoint fileSystemType mountOptions
do
    case $devToMount 
    in
    \#*) continue ;; #  ignore comments
    '')  continue ;; # ignore empty lines
    esac
  
    echo "--------------------------------------------------------------- "
    echo "Following are the entry number $count in the fstab.adaptec file "
    echo "--------------------------------------------------------------- "
    echo $devToMount
    echo $mountPoint
    echo $fileSystemType
    echo $mountOptions
    
    count=`expr $count + 1`

    if echo $options | grep -v -q noauto ; then
       adpt_mount $devToMount $mountPoint $fileSystemType $mountOptions
    fi
done 
