zfs/cmd/sas_switch_id/sas_switch_id

97 lines
2.4 KiB
Bash
Executable File

#!/bin/sh
#
# sas_switch_id
#
# Callout script for multipathd to obtain disk UUIDs. Combine the UUID
# from the scsi_id program with the SAS switch port number and enclosure
# bay number, if available. This naming convention enables easier
# identification of the physical drive location when multiple disk
# enclosures are accessed via a SAS switch. For other storage
# topologies just return the undecorated UUID of the drive.
PHYS_PER_PORT=4
DEV=
usage() {
cat << EOF
Usage: sas_switch_id [-d disk] [-p phys_per_port]
-d Basename of the disk device [default=none]
-p Number of PHYs per switch port [default=${PHYS_PER_PORT}]
-h Show this message
EOF
exit 0
}
while getopts 'd:p:h' OPTION; do
case ${OPTION} in
d)
DEV=${OPTARG}
;;
p)
PHYS_PER_PORT=${OPTARG}
;;
h)
usage
;;
esac
done
if [ -z "$DEV" ] ; then
echo "Error: missing required option -d"
exit 1
fi
UUID=`/lib/udev/scsi_id --whitelisted --device=/dev/$DEV`
if [ $? != 0 -o -z "$UUID" ] ; then
exit 1
fi
sys_path=`udevadm info -q path -p /sys/block/$DEV`
dirs=(`echo "$sys_path" | tr / ' '`)
switch_port_dir="/sys"
# Get path up to /sys/.../hostX
for (( i=0; i<${#dirs[*]}; i++ )); do
d=${dirs[$i]}
switch_port_dir=$switch_port_dir/$d
echo $d | egrep -q -e '^host[0-9]+$' && break
done
if [ $i = ${#dirs[*]} ] ; then
echo $UUID
exit 0
fi
# The directory three levels beneath /sys/.../hostX contains
# symlinks to phy devices that reveal the switch port number.
# Lowest phy number is $PHYS_PER_PORT*switch_port_number.
for (( j=(($i+1)) ; j<(($i+4)); j++ )); do
switch_port_dir=$switch_port_dir/${dirs[$j]}
done
pushd $switch_port_dir > /dev/null
PHY=`ls -d phy* 2>/dev/null | head -1 | awk -F: '{print $NF}'`
PORT=$(( $PHY / $PHYS_PER_PORT ))
popd > /dev/null
if [ -z "$PHY" ] ; then
echo $UUID
exit 0
fi
# Look in /sys/.../sas_device/end_device-X for the bay_identifier
# attribute.
end_device_dir=$switch_port_dir
for (( k=$j ; k<${#dirs[*]} ; k++ )); do
d=${dirs[$k]}
end_device_dir=$end_device_dir/$d
if echo $d | egrep -q -e '^end_device' ; then
end_device_dir=$end_device_dir/sas_device/$d
break
fi
done
SLOT=`cat $end_device_dir/bay_identifier 2>/dev/null`
if [ -z "$SLOT" ] ; then
echo $UUID
exit 0
fi
echo "$UUID-switch-port:$PORT-slot:$SLOT"