File zfcp_san_disc of Package s390-tools

#!/bin/bash
#
# zfcp_san_disc
#
# Outputs a list of zFCP WWPNs or LUNs
#
# Usage:
#   zfcp_san_disc [-h | -W | -L -p <WWPN> ] -b <BUS_ID>
#
# Return codes
#   1  zFCP sysfs directory not available
#   2  Invalid command line parameter
#   3  Too many commands used
#   4  Error retrieving HBA list
#   5  Bus ID not found
#   6  Error retrieving Port list
#   7  WWPN not found
#   8  Bus ID sysfs directory not available
#   9  WWPN sysfs directory not available/unable to add port to Bus ID
#  10  Error retrieving LUN list
#  11  HBA API device not available
#

START_DIR=`pwd`
SCRIPT_NAME=`basename $0`
cd `dirname $0`
SCRIPT_DIR=`pwd`
cd "${START_DIR}"

FCP_SYS_DIR='/sys/bus/ccw/drivers/zfcp'

# Commands available
LIST_WWPN='-W'
LIST_LUN='-L'

COMMAND=''
BUSID=''
WWPN=''

echo_err()
{
	echo "$SCRIPT_NAME: $1" 1>&2
}

usage()
{
	echo "$0 [-h | $LIST_WWPN | $LIST_LUN -p <WWPN>] -b <BUS_ID>" 1>&2
	echo 1>&2
	echo "Commands:" 1>&2
	echo "	$LIST_WWPN		List WWPNs for the given BUS_ID" 1>&2
	echo "	$LIST_LUN		List LUNs for the given BUS_ID and WWPN" 1>&2
	echo "	-h		This usage information" 1>&2
	echo "Options:" 1>&2
	echo "	-b BUSID	Bus ID to use for listing" 1>&2
	echo "	-p WWPN		WWPN to use for listing" 1>&2
}

list_lun()
{
	local PRINT_WWPN
	local BUSID_DIR
	local WWPN_DIR
	local ADDED_PORT

}

deactivate()
{
    local ccw=$1

    echo 0 > /sys/bus/ccw/devices/$ccw/online
}

lun_remove()
{
    local syspath=$1
    local lun=$2

    echo "$lun" > $syspath/unit_remove
}

sg_remove()
{
    local sg=$1
    local sgnum

    sgnum=${sg#/dev/sg}
    : deactivate /sys/class/scsi_generic/sg$sgnum/device/delete
    echo 1 > /sys/class/scsi_generic/sg$sgnum/device/delete
    udevadm settle
}

while [ $# -gt 0 ]
do
	case "$1" in
		-b* )
			if [ "$1" == "-b" ]
			then
				shift
				BUSID="$1"
			else
				BUSID="${1:2}"
			fi
			BUSID=`echo $BUSID | tr A-F a-f`
			;;
		-p* )
			if [ "$1" == "-p" ]
			then
				shift
				WWPN="$1"
			else
				WWPN="${1:2}"
			fi
			WWPN=`echo $WWPN | tr A-FX a-fx`
			;;
		"$LIST_WWPN"|"$LIST_LUN" )
			if [ -z "$COMMAND" -o "$1" == "$COMMAND" ]
			then
				COMMAND=$1
			else
				echo_err "You have already specified the $COMMAND command, and cannot use the $1 command also."
				exit 3
			fi
			;;
		-h )
			usage
			exit 0
			;;
		* )
			usage
			echo_err "Unknown command line parameter : $1"
			exit 2
			;;
	esac
	shift
done

if [ -z "$BUSID" ] ; then
    echo_err "No bus ID given"
    exit 2
fi

if [ -z "$COMMAND" ] ; then
    echo_err "Please specify either -W or -L"
    exit 2
fi

if [ ! -d /sys/bus/ccw/devices/$BUSID ] ; then
    echo_err "Unknown bus ID $BUSID"
    exit 2
fi

read devtype < /sys/bus/ccw/devices/$BUSID/devtype
read cutype < /sys/bus/ccw/devices/$BUSID/cutype

if [ "$cutype" != "1731/03" ] ; then
    echo_err "Bus ID $BUSID is not an zfcp adapter"
    exit 2
fi

if [ "$devtype" != "1732/03" -a "$devtype" != "1732/04" ] ; then
    echo_err "Bus ID $BUSID is not an zfcp adapter"
    exit 2
fi

# Now we're sure we're dealing with zfcp devices
if [ ! -d "$FCP_SYS_DIR" ] ; then
    modprobe zfcp
fi

[ "$COMMAND" == "$LIST_LUN" -a -z "$WWPN" ] && usage && exit 2

read online < /sys/bus/ccw/devices/$BUSID/online

if [ "$online" != 1 ] ; then
    # Activate adapter
    echo 1 > /sys/bus/ccw/devices/$BUSID/online
    read online < /sys/bus/ccw/devices/$BUSID/online

    if [ "$online" != 1 ] ; then
	echo_err "Cannot activate zfcp adapter at $BUSID"
	exit 2
    fi
    trapcmd="deactivate $BUSID"
    trap "$trapcmd" EXIT
fi

for loop in 1 2 3 4 5 ; do
	read status < /sys/bus/ccw/devices/$BUSID/status
	(( $status & 0x10000000 )) && break;
done
read wwpn_status < /sys/bus/ccw/devices/$BUSID/status
if !(( $wwpn_status & 0x10000000 )) ; then
	echo_err "Adapter activation failed, status $wwpn_status"
	exit 3
fi

for host in /sys/bus/ccw/devices/$BUSID/host* ; do
    if [ -d $host ] ; then
	hba_num=${host##*host}
    fi
done
if [ -z "$hba_num" ] ; then
    echo_err "No SCSI host allocated"
    exit 3
fi

if [ "$COMMAND" == "$LIST_WWPN" ]
then
	for PRINT_WWPN in /sys/bus/ccw/devices/$BUSID/0x*
	do
		test -d $PRINT_WWPN && echo ${PRINT_WWPN##*/}
	done
	exit 0
elif [ "$COMMAND" != "$LIST_LUN" ]
then
    exit 1
fi

ERR=0
read allow_lun_scan < /sys/module/zfcp/parameters/allow_lun_scan
if [ "$allow_lun_scan" = "Y" ] ; then
    read port_type < /sys/class/fc_host/host${hba_num}/port_type
    if [ "$port_type" = "NPIV VPORT" ] ; then
	skip_activation=1
    fi
fi
if [ -z "$skip_activation" ] ; then
	WWPN_DIR=/sys/bus/ccw/devices/$BUSID/$WWPN
	if [ ! -d "${WWPN_DIR}" ]
	then
		echo_err "port $WWPN not found on zfcp $BUSID"
		exit 9
	fi

	# Activate WLUN
	if [ ! -d $WWPN_DIR/0xc101000000000000 ] ; then
	    echo 0xc101000000000000 > $WWPN_DIR/unit_add
	    orig_trapcmd="$trapcmd"
	    trapcmd="lun_remove $WWPN_DIR 0xc101000000000000; $trapcmd"
	    trap "$trapcmd" EXIT
	    activated=1

	    # Wait for udev to catch up
	    udevadm settle
	    sleep 1
	fi
	# Find corresponding sg device
	sgdev=$(lsscsi -t -g $hba_num:-:-:49409 | sed -n "s/.* fc:$WWPN.* \(\/dev\/sg[0-9]*\)[[:blank:]]*$/\1/p")
	if [ -c "$sgdev" ] ; then
	    if sg_luns $sgdev > /dev/null 2>&1 ; then
		LUN_LIST=`sg_luns $sgdev | sed -n 's/^    \(.*\)/\1/p'`
		trapcmd="sg_remove $sgdev; $trapcmd"
		trap "$trapcmd" EXIT
		wlun=1
	    else
		wlun=
	    fi
	fi
	if [ -z "$wlun" ] ; then
	    if [ -n "$activated" ] ; then
		trapcmd=$orig_trapcmd
		trap "$trapcmd" EXIT
		lun_remove $WWPN_DIR 0xc101000000000000
		activated=
	    fi
	    # Activate LUN 0
	    if [ ! -d $WWPN_DIR/0x0000000000000000 ] ; then
		echo 0 > $WWPN_DIR/unit_add
		orig_trapcmd=$trapcmd
		trapcmd="lun_remove $WWPN_DIR 0x0000000000000000; $trapcmd"
		trap "$trapcmd" EXIT
		activated=1
		# Wait for udev to catch up
		udevadm settle
		sleep 1
	    fi

	    # Find corresponding sg device
	    sgdev=$(lsscsi -t -g $hba_num:-:-:0 | sed -n "s/.* fc:$WWPN.* \(\/dev\/sg[^[:blank:]]*\)[[:blank:]]*$/\1/p")
	    if [ -c "$sgdev" ] ; then
		if sg_luns $sgdev > /dev/null 2>&1 ; then
		    LUN_LIST=`sg_luns $sgdev | sed -n 's/^    \(.*\)/\1/p'`
		fi
		if [ -n "$activated" ] ; then
		    trapcmd="sg_remove $sgdev; $trapcmd"
		    trap "$trapcmd" EXIT
		fi
	    else
		echo_err "Unable to activate LUN 0"
		trap "$trapcmd" EXIT
		lun_remove $WWPN_DIR 0x0000000000000000
		activated=
		sgdev=
		ERR=10
	    fi
	fi

	for LUN in $LUN_LIST ; do
	    echo 0x$LUN
	done
	exit $ERR
else
	for loop in 1 2 3 4 5 ; do
		if [ -n "$(ls -d /sys/class/fc_remote_ports/rport-${hba_num}:* 2>/dev/null)" ] ; then
			break
		else
			sleep 1
		fi
	done

	if [ -z "$(ls -d /sys/class/fc_remote_ports/rport-${hba_num}:* 2>/dev/null)" ]; then
		echo "The remote Fiber Channel port has not become available. Exiting"
		exit 1
	fi

	for rport in /sys/class/fc_remote_ports/rport-${hba_num}:* ; do
		[ -f ${rport}/port_name ] || continue
		read port_name < ${rport}/port_name
		if [ "$port_name" = "$WWPN" ] ; then
			for t in ${rport}/device/target* ; do
				[ -f ${t}/uevent ] || continue
				targetid=${t#*target}
				targetid=${targetid##*:}
				break
			done
		fi
	done
	lsscsi -xx ${hba_num}:0:${targetid}:- | sed -n "s/\[${hba_num}:0:${targetid}:\(0x[0-9a-f]*\)\].*/\1/p"
fi
openSUSE Build Service is sponsored by