#!/bin/bash
#
# Name: probe-luns
# Copyright: (c)2002-2004 Hewlett-Packard Company
#
# Description: forces a rescan at certain connection addresses
#              by the scsi mid-layer
#
# CD		04/21/04 Search for targets by keying off of the
#                        "target" string only
# CD		05/17/04 put a delay in between each add/remove scsi
#                        command so as not to panic the kenrel
# CD 		05/19/04 changed sleep to usleep so that the delay
#                        works on both Red Hat and SUSE
# CD		06/11/04 Changes for SLES 9 (2.6 kernel)

# defines

LUNSTART=0
LUNEND=32

# This is the delay in microseconds between each echo "scsi..." command

PROBEDELAY=100000

# forces a rescan of the SCSI midlayer for all qla* adapters

scan_all () {

 # get a list of qla* adapters in the system

 ADAPTERS=`find /proc/scsi | grep /[0-9].* | grep qla | sort -u`

 # perform midlayer removal

 for i in $ADAPTERS
 do
	# get list of targets

	TARGETS=`cat ${i} | grep target | grep -v adapter | awk 'BEGIN {FS="="} {print $1}' | awk 'BEGIN {FS="-"} {print $4}'`
	INST=`echo $i | awk 'BEGIN {FS="/"} {print $5}'`

	for j in $TARGETS
	do
		CNT=$LUNSTART

		# send scsi remove command to midlayer
		while [ $CNT -le $LUNEND ]
		do
			printf "\rRemoving $i, target $j, LUN $CNT"
			echo "scsi remove-single-device $INST $i $j $CNT" > /proc/scsi/scsi
			usleep $PROBEDELAY
			CNT=`expr $CNT + 1`
		done
	done
 done

 echo ""

 # perform midlayer scanning

 for i in $ADAPTERS
 do

	# get list of targets

        TARGETS=`cat ${i} | grep target | grep -v adapter | awk 'BEGIN {FS="="} {print $1}' | awk 'BEGIN {FS="-"}
{print $4}'`
	INST=`echo $i | awk 'BEGIN {FS="/"} {print $5}'`

	for j in $TARGETS
	do
		CNT=$LUNSTART

		# send scsi add command to midlayer

		while [ $CNT -le $LUNEND ]
		do
			printf "\rScanning $i, target $j, LUN $CNT"
			echo "scsi add-single-device $INST 0 $j $CNT" > /proc/scsi/scsi
			usleep $PROBEDELAY
			CNT=`expr $CNT + 1`
		done
	done
 done

 echo ""
 print_scsi
}

# scan a particular adapter instance

scan_instance () {
 INST=$1

 # verify that instance exists

 DIRS="/proc/scsi/qla2200 /proc/scsi/qla2300 /proc/scsi/qla2xxx"
 FOUND=n

 for i in $DIRS
 do
	find ${i}/${INST} 1>/dev/null 2>/dev/null

  	if [ $? -eq 0 ]
  	then
   		FOUND=y
   		ADAPTER="${i}/${INST}"
  	fi
 done

 if [ "$FOUND" = "n" ]
 then
	echo "There is no SCSI adapter instance $INST"  
	exit 1
 fi

 # get list of targets

 TARGETS=`cat ${ADAPTER} | grep target | grep -v adapter | awk 'BEGIN {FS="="} {print $1}' | awk 'BEGIN {FS="-"} {print $4}'`

 # remove LUNs in midlayer for this adapter instance

 for j in $TARGETS
 do
	CNT=$LUNSTART

	# send scsi remove command to midlayer
	while [ $CNT -le $LUNEND ]
	do
		printf "\rRemoving ${i}/${INST}, target $j, LUN $CNT"
		echo "scsi remove-single-device $INST $i $j $CNT" > /proc/scsi/scsi
		usleep $PROBEDELAY
		CNT=`expr $CNT + 1`
	done
 done

 echo ""

 # force midlayer to rescan this adapter instance

 for j in $TARGETS
 do
	CNT=$LUNSTART

	# send scsi add command to midlayer

	while [ $CNT -le $LUNEND ]
	do
		printf "\rScanning ${i}/${INST}, target $j, LUN $CNT"
		echo "scsi add-single-device $INST 0 $j $CNT" > /proc/scsi/scsi
		usleep $PROBEDELAY
		CNT=`expr $CNT + 1`
	done
 done

 echo ""
 print_scsi ${INST}
}

print_scsi () {
  
 # if there is no arguments passed in, get all instance numbers
 # on the system

 if [ "$1" = "" ]
 then
	hbas=`find /proc/scsi | grep /[0-9].* | grep qla | sort -u | awk 'BEGIN {FS="/"} {print $5}'`
 else
 	hbas=$1
 fi

 # print data from /proc/scsi/scsi

 printf "\r                                                      \n\n"
 for inst in ${hbas} 
 do
    cat /proc/scsi/scsi | tr -d '\n'|
    awk '{ for(i=1;i<=NF;i++) if(index($i,"scsi")!=0)printf("\n%s ",$i); else printf("%s ",$i)}' | \
    awk 'BEGIN{n=split("scsi|Channel|Id|Lun|Vendor|Model|Rev|Type",ar,"|");} \
         {for(i=1;i<NF;i++)for(j=1;j<=n;j++) \
          if(index($i,ar[j])){printf(" %s",index($i,"scsi")?$i:$(i+1));break}print "";}' | \
    awk '{if(index($0,"scsi'${inst}'")) \
          printf("%-6.6s %2.2s %2.2s %2.2s %-10.10s %-10.10s %-10.10s %s\n", $1,$2,$3,$4,$5,$6,$7,index($8,"known")?"":$8);}'
  done
  echo
}

#
# script main
#

# parse argument 1

if [ $# -eq 0 ]
then
 echo "Usage: probe-luns -a|-i instance"
 echo ""
 echo "-a: force SCSI midlayer to rescan all qla2200 and qla2300 devices"
 echo "-i: force SCSI midlayer to rescan a specific instance"
 exit 0
elif [ "$1" = "-a" ]
then
 scan_all
elif [ "$1" = "-i" ]
then
 if [ $# -ne 2 ]
 then
 	echo "-i requires an argument"
 	exit 1
 fi

 scan_instance $2
else
 echo "$1: Invalid argument"
 exit 1
fi

exit 0 
