Skip to content

Commit 269db7a

Browse files
tesujimathbehlendorf
authored andcommitted
vdev_id: extension for new scsi topology
On systems with SCSI rather than SAS disk topology, this change enables the vdev_id script to match against the block device path, and therefore create a vdev alias in /dev/disk/by-vdev. Reviewed-by: Tony Hutter <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Simon Guest <[email protected]> Closes openzfs#6592
1 parent 0c484ab commit 269db7a

File tree

3 files changed

+127
-3
lines changed

3 files changed

+127
-3
lines changed

cmd/vdev_id/vdev_id

+116-2
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ usage() {
100100
cat << EOF
101101
Usage: vdev_id [-h]
102102
vdev_id <-d device> [-c config_file] [-p phys_per_port]
103-
[-g sas_direct|sas_switch] [-m]
103+
[-g sas_direct|sas_switch|scsi] [-m]
104104
105105
-c specify name of alernate config file [default=$CONFIG]
106106
-d specify basename of device (i.e. sda)
@@ -135,7 +135,7 @@ map_channel() {
135135
MAPPED_CHAN=`awk "\\$1 == \"channel\" && \\$2 == ${PORT} \
136136
{ print \\$3; exit }" $CONFIG`
137137
;;
138-
"sas_direct")
138+
"sas_direct"|"scsi")
139139
MAPPED_CHAN=`awk "\\$1 == \"channel\" && \
140140
\\$2 == \"${PCI_ID}\" && \\$3 == ${PORT} \
141141
{ print \\$4; exit }" $CONFIG`
@@ -289,6 +289,117 @@ sas_handler() {
289289
echo ${CHAN}${SLOT}${PART}
290290
}
291291

292+
scsi_handler() {
293+
if [ -z "$FIRST_BAY_NUMBER" ] ; then
294+
FIRST_BAY_NUMBER=`awk "\\$1 == \"first_bay_number\" \
295+
{print \\$2; exit}" $CONFIG`
296+
fi
297+
FIRST_BAY_NUMBER=${FIRST_BAY_NUMBER:-0}
298+
299+
if [ -z "$PHYS_PER_PORT" ] ; then
300+
PHYS_PER_PORT=`awk "\\$1 == \"phys_per_port\" \
301+
{print \\$2; exit}" $CONFIG`
302+
fi
303+
PHYS_PER_PORT=${PHYS_PER_PORT:-4}
304+
if ! echo $PHYS_PER_PORT | grep -q -E '^[0-9]+$' ; then
305+
echo "Error: phys_per_port value $PHYS_PER_PORT is non-numeric"
306+
exit 1
307+
fi
308+
309+
if [ -z "$MULTIPATH_MODE" ] ; then
310+
MULTIPATH_MODE=`awk "\\$1 == \"multipath\" \
311+
{print \\$2; exit}" $CONFIG`
312+
fi
313+
314+
# Use first running component device if we're handling a dm-mpath device
315+
if [ "$MULTIPATH_MODE" = "yes" ] ; then
316+
# If udev didn't tell us the UUID via DM_NAME, check /dev/mapper
317+
if [ -z "$DM_NAME" ] ; then
318+
DM_NAME=`ls -l --full-time /dev/mapper |
319+
awk "/\/$DEV$/{print \\$9}"`
320+
fi
321+
322+
# For raw disks udev exports DEVTYPE=partition when
323+
# handling partitions, and the rules can be written to
324+
# take advantage of this to append a -part suffix. For
325+
# dm devices we get DEVTYPE=disk even for partitions so
326+
# we have to append the -part suffix directly in the
327+
# helper.
328+
if [ "$DEVTYPE" != "partition" ] ; then
329+
PART=`echo $DM_NAME | awk -Fp '/p/{print "-part"$2}'`
330+
fi
331+
332+
# Strip off partition information.
333+
DM_NAME=`echo $DM_NAME | sed 's/p[0-9][0-9]*$//'`
334+
if [ -z "$DM_NAME" ] ; then
335+
return
336+
fi
337+
338+
# Get the raw scsi device name from multipath -ll. Strip off
339+
# leading pipe symbols to make field numbering consistent.
340+
DEV=`multipath -ll $DM_NAME |
341+
awk '/running/{gsub("^[|]"," "); print $3 ; exit}'`
342+
if [ -z "$DEV" ] ; then
343+
return
344+
fi
345+
fi
346+
347+
if echo $DEV | grep -q ^/devices/ ; then
348+
sys_path=$DEV
349+
else
350+
sys_path=`udevadm info -q path -p /sys/block/$DEV 2>/dev/null`
351+
fi
352+
353+
# expect sys_path like this, for example:
354+
# /devices/pci0000:00/0000:00:0b.0/0000:09:00.0/0000:0a:05.0/0000:0c:00.0/host3/target3:1:0/3:1:0:21/block/sdv
355+
356+
# Use positional parameters as an ad-hoc array
357+
set -- $(echo "$sys_path" | tr / ' ')
358+
num_dirs=$#
359+
scsi_host_dir="/sys"
360+
361+
# Get path up to /sys/.../hostX
362+
i=1
363+
while [ $i -le $num_dirs ] ; do
364+
d=$(eval echo \${$i})
365+
scsi_host_dir="$scsi_host_dir/$d"
366+
echo $d | grep -q -E '^host[0-9]+$' && break
367+
i=$(($i + 1))
368+
done
369+
370+
if [ $i = $num_dirs ] ; then
371+
return
372+
fi
373+
374+
PCI_ID=$(eval echo \${$(($i -1))} | awk -F: '{print $2":"$3}')
375+
376+
# In scsi mode, the directory two levels beneath
377+
# /sys/.../hostX reveals the port and slot.
378+
port_dir=$scsi_host_dir
379+
j=$(($i + 2))
380+
381+
i=$(($i + 1))
382+
while [ $i -le $j ] ; do
383+
port_dir="$port_dir/$(eval echo \${$i})"
384+
i=$(($i + 1))
385+
done
386+
387+
set -- $(echo $port_dir | sed -e 's/^.*:\([^:]*\):\([^:]*\)$/\1 \2/')
388+
PORT=$1
389+
SLOT=$(($2 + $FIRST_BAY_NUMBER))
390+
391+
if [ -z "$SLOT" ] ; then
392+
return
393+
fi
394+
395+
CHAN=`map_channel $PCI_ID $PORT`
396+
SLOT=`map_slot $SLOT $CHAN`
397+
if [ -z "$CHAN" ] ; then
398+
return
399+
fi
400+
echo ${CHAN}${SLOT}${PART}
401+
}
402+
292403
alias_handler () {
293404
# Special handling is needed to correctly append a -part suffix
294405
# to partitions of device mapper devices. The DEVTYPE attribute
@@ -394,6 +505,9 @@ if [ -z "$ID_VDEV" ] ; then
394505
sas_direct|sas_switch)
395506
ID_VDEV=`sas_handler`
396507
;;
508+
scsi)
509+
ID_VDEV=`scsi_handler`
510+
;;
397511
*)
398512
echo "Error: unknown topology $TOPOLOGY"
399513
exit 1

etc/zfs/Makefile.am

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ pkgsysconf_DATA = \
44
vdev_id.conf.alias.example \
55
vdev_id.conf.sas_direct.example \
66
vdev_id.conf.sas_switch.example \
7-
vdev_id.conf.multipath.example
7+
vdev_id.conf.multipath.example \
8+
vdev_id.conf.scsi.example
89

910
EXTRA_DIST = $(pkgsysconf_DATA)

etc/zfs/vdev_id.conf.scsi.example

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
multipath no
2+
topology scsi
3+
phys_per_port 1
4+
# Usually scsi disks are numbered from 0, but this can be offset, to
5+
# match the physical bay numbers, as follows:
6+
first_bay_number 1
7+
8+
# PCI_ID HBA PORT CHANNEL NAME
9+
channel 0c:00.0 0 Y

0 commit comments

Comments
 (0)