Viewing Fibre Channel Devices in Linux

Linux has great facilities to view what is happening with the hardware and kernel, but the information isn’t always in one place or organized for humans to look at. Seeing the fibre channel HBAs and the attached devices is a prime example. Getting a quick view is a royal pain. Here is a bash script that simply walks the device tree and extracts information from various places and presents it in a more human readable form.

#!/bin/bash

#
# fc_info script gives a tree-like view of the fiber channel adapters and
# the devices attached to them.  The information is all there, but it's
# spread all over the place and kind of a pain to get when you just want
# a summary of everything that's attached.
# I wrote this to just organize it all and make it easier for troubleshooting
# and identifying where things are.
#
# Scott Garrett
#

trap 'rm -f /tmp/*.$$ ; exit 0' 0 1 2 3 13 15

FC_HOST_DIR="/sys/class/fc_host"

function printwwn()
{
	echo $1 | sed -e 's/^0x//' -e 's/../&:/g;s/:$//'
}

# The LUN size option was added in version .25 of lsscsi, but RHEL/CentOS 6
# still has version .23 of lsscsi.  If you happen to have a newever version
# installed, then might as well display the size.
if [ -x /usr/bin/lsscsi ]
then
	size_parameter=""
	if [ $( lsscsi -V 2>&1 | awk '{ print $2; }' | cut -f 2 -d '.' ) -ge 25 ]
	then
		size_parameter="-s"
	fi
fi

# List installed HBAs and whether their status

for HBA in ${FC_HOST_DIR}/*
{
	echo "$( basename ${HBA} )"

	echo "Model:               $( cat ${HBA}/symbolic_name )"
	echo "WWNN:                $( printwwn $( cat ${HBA}/node_name ) )"
	echo "WWPN:                $( printwwn $( cat ${HBA}/port_name ) )"
	echo "Fabric Name:         $( printwwn $( cat ${HBA}/fabric_name ) )"
	echo "Port Type:           $( cat ${HBA}/port_type )"
	echo "Port Speed:          $( cat ${HBA}/speed )"
	echo "Port State:          $( cat ${HBA}/port_state )"
	echo "Target ID Bind Type: $( cat ${HBA}/tgtid_bind_type )"

	echo
	echo "Connected Devices on $( basename ${HBA} ):"

	for R_PORT in ${HBA}/device/rport*
	{
		echo "     WWPN: $( printwwn $( cat $R_PORT/fc_remote_ports/$( basename $R_PORT )/port_name ) ) ($( cat $R_PORT/fc_remote_ports/$( basename $R_PORT )/port_state ))"

		if [ -x /usr/bin/lsscsi ]
		then
			devices=$( lsscsi -t | grep $( cat $R_PORT/fc_remote_ports/$( basename $R_PORT )/port_name ) | awk '{ print $1; }' | tr -d '[]' )

			if [ "$devices" ]
			then
				echo "          Connected LUNs:"
			fi

			for device in $devices
			{
				lsscsi $size_parameter $device | sed -e "s/^/          /"
			}
		fi
	}

	echo
} 

Leave a Comment