X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;ds=sidebyside;f=extras%2Fpath_id;h=aecc40cc9bee2db6baaedf0dc9dfdfbb2619bf25;hb=a05098641e448cbdb7b742826c3a0bc35a8a1c1f;hp=dfb997b3403bd019ff7e341db0d06114cbc49c1f;hpb=0105b9330cace0a1492003968a5d2552f1b64f43;p=elogind.git diff --git a/extras/path_id b/extras/path_id old mode 100755 new mode 100644 index dfb997b34..aecc40cc9 --- a/extras/path_id +++ b/extras/path_id @@ -15,33 +15,37 @@ # DEVPATH=/block/sda/sda3 path_id # path_id -# example for all block devices on a system: -# for i in `find /sys/block -name dev` ;do DEVPATH="`echo $i | sed -e 's@^/sys\|/dev@@g'`" path_id ; done +# examples for all block devices on a system: +# for i in `find /sys/class/block`; do DEVPATH="`echo $i | sed -e 's@^/sys\|/dev@@g'`"; path_id; done -# examples: # SCSI cdrom -# /block/sr0 -> /devices/pci0002:30/0002:30:0c.0/host0/0:0:1:0 -# result: pci-0002:30:0c.0-scsi-0:0:1:0 +# /class/block/sr0 -> /devices/pci0002:30/0002:30:0c.0/host0/target0:0:0/0:0:1:0 +# pci-0002:30:0c.0-scsi-0:0:1:0 +# # SCSI disk -# /block/sda -> /devices/pci0002:30/0002:30:0c.0/host0/0:0:4:0 -# result: pci-0002:30:0c.0-scsi-0:0:4:0 +# /class/block/sda -> /devices/pci0002:30/0002:30:0c.0/host0/target0:0:0/0:0:4:0 +# pci-0002:30:0c.0-scsi-0:0:4:0 +# # SATA disk, 4 channels per controller -# /block/sda -> /devices/pci0001:00/0001:00:07.0/0001:05:0c.0/host0/0:0:0:0 -# result: pci-0001:05:0c.0-scsi-0:0:0:0 +# /class/block/sda -> /devices/pci0001:00/0001:00:07.0/0001:05:0c.0/host0/target0:0:0/0:0:0:0 +# pci-0001:05:0c.0-scsi-0:0:0:0 +# # IDE disk -# /block/hda -> /devices/pci0002:02/0002:02:0d.0/ide0/0.0 -# result: pci-0002:02:0d.0-ide-0.0 +# /class/block/hda -> /devices/pci0002:02/0002:02:0d.0/ide0/0.0 +# pci-0002:02:0d.0-ide-0.0 +# # IDE cdrom on a Mac ASIC: -# /block/hdc -> /devices/pci0001:01/0001:01:17.0/0.80000000:mac-io/0.00020000:ata-3/ide1/1.0 -# result: mac-io_ata-3_master +# /class/block/hdc -> /devices/pci0001:01/0001:01:17.0/0.80000000:mac-io/0.00020000:ata-3/ide1/1.0 +# mac-io_ata-3_master +# # IDE cdrom on a Mac ASIC, with ide-scsi: -# /block/sr0 -> /devices/pci0001:01/0001:01:17.0/0.80000000:mac-io/0.0001f000:ata-4/ide0/0.1/host2/2:0:0:0 -# result: mac-io_ata-4_slave +# /class/block/sr0 -> /devices/pci0001:01/0001:01:17.0/0.80000000:mac-io/0.0001f000:ata-4/ide0/0.1/host2/target2:0:0/2:0:0:0 +# mac-io_ata-4_slave # USB CDrom drive without 'serial' number: # reusing 'product' and 'manufacturer' string, if available -# /block/sr0 -> /devices/pci0001:00/0001:00:04.0/0001:02:0b.0/usb4/4-2/4-2:1.0/host4/4:0:0:0 -# result: usb-storage-odd-Freecom-USIDERev930:0:0:0 +# /class/block/sr0 -> /devices/pci0001:00/0001:00:04.0/0001:02:0b.0/usb4/4-2/4-2:1.0/host4/4:0:0:0 +# usb-storage-odd-Freecom-USIDERev930:0:0:0 # devices may have several interfaces on one PCI device, like IDE: # pci-0001:00:04.0_ide1-master @@ -52,24 +56,14 @@ # interface # # match order is important. -# first IDE to find ide-scsi devices. -# then SCSI -# first usb-storage -# then firewire sbp2 -# then the rest +# first IDE to find ide-scsi devices, then SCSI +# first usb-storage, then firewire sbp2, then the rest SYSFS=/sys RESULT=1 -CDROM= TYPE= OPWD="`pwd`" -# Check for 'pwd -P' -if $(pwd -P > /dev/null 2>&1); then - pwd_cmd="pwd -P" -else - pwd_cmd="pwd" -fi -full_sysfs_class_path= +full_sysfs_path= full_sysfs_device_path= if [ -z "$DEVPATH" -a -z "$1" ] ; then @@ -87,31 +81,30 @@ if [ -z "$DEVPATH" ] ; then esac fi -if [ ! -d $SYSFS$DEVPATH ] ; then - exit 1 -fi -if [ ! -f $SYSFS$DEVPATH/dev ] ; then +if [ ! -e $SYSFS$DEVPATH/dev ] ; then exit 1 fi case "$DEVPATH" in - /block/*) - TYPE=block + /devices/*) + cd "$SYSFS$DEVPATH/subsystem"; + TYPE="`pwd -P`" + cd "$OPWD" + TYPE="${TYPE##*/}" ;; /class/*) TYPE="${DEVPATH#/class/}" TYPE="${TYPE%%/*}" ;; + /block/*) + TYPE=block + ;; *) exit 1 ;; esac - -# -## -# -get_port () { +get_port_offset () { local type offset port type=$1 offset=$2 @@ -120,9 +113,28 @@ get_port () { port="${i#$type}" if [ "$port" -lt "$offset" ] ; then offset=$port ; fi done - if [ "$port" != "0" ] ; then - echo $(($2 - $offset)) - fi + echo $offset +} + +handle_pci () { + local DEV=$1 + cd -P $1 + DEV=${PWD} + pci_id=${DEV##*/} + + host_dev_path=$DEV + while [ ! -z "$host_dev_path" ] ; do + case "$host_dev_path" in + */pci[0-9]*) + host_dev_path=${host_dev_path%/*} + ;; + *) break;; + esac + done + + d="pci-$pci_id-$d" + D="$host_dev_path" + RESULT=0 } handle_block_ide () { @@ -131,42 +143,15 @@ handle_block_ide () { local port idedev idecontroller # IDE : DEV $DEV - d=$DEV - case "$DEV" in - # remove ide-scsi part, leave only channel info - */ide[0-9]*/host[0-9]*) - while [ ! -z "$d" ] ; do - case "$d" in - */host[0-9]*) - d="${d%/*}" - continue - ;; - *) - break - ;; - esac - done - ;; - esac - idedev=$d - while [ ! -z "$d" ] ; do - case "$d" in - */ide[0-9]*) - port="${d##*/}" - d="${d%/*}" - continue - ;; - *) - break - ;; - esac - done - idecontroller=$d + + port=${DEV##*/} + idedev=${DEV%/*} + idecontroller=${idedev%/*} # port info if the controller has more than one interface port="${port#ide}" : port $port d $d : idedev $idedev kernel_port $port - case "${idedev##*.}" in + case "${port#*.}" in 0) channel=0 ;; @@ -176,159 +161,231 @@ handle_block_ide () { *) echo "Error: $idedev is neither master or slave" >&2 esac - case "$d" in - *:mac-io/*) - : mac-io: $d - d="`echo $d | sed -e 's@^.*:mac-io[^:]\+:\([^/]\+\).*@mac-io_\1@'`" - ;; - /sys/devices) - # PCMCIA devices - ifname=${full_sysfs_class_path##*/} - set -- `sed -n "/$ifname/p" /var/lib/pcmcia/stab` - d="pcmcia-$1" - ;; - *) - d="pci-${d##*/}" - # d="`echo $d | sed -e 's@^.*/\([^/]\{1,\}\)/.@pci-\1@'`" - ;; - esac cd $idecontroller - port="`get_port ide $port`" + offset="`get_port_offset ide ${port%.*}`" cd "$OPWD" - : hardware_port $port - if [ -z "$port" ] ; then - d="${d}-ide-0:$channel" + : port offset $offset + port=$((${port%.*} - $offset)) + if [ "$d" ] ; then + d="ide-${port}:$channel-$d" else - d="${d}-ide-${port}:$channel" + d="ide-${port}:$channel" fi - + D=$idecontroller RESULT=0 } handle_block_scsi () { -: handle_block_scsi $* + : handle_block_scsi $* local DEV=$1 local cil controller_port controller_dev # SCSI device cil="${DEV##*/}" cil="${cil#*:}" - controller_dev=$DEV - while [ ! -z "$controller_dev" ] ; do - case "$controller_dev" in - */host[0-9]*) - controller_port=$controller_dev - controller_dev="${controller_dev%/*}" - ;; - *) break ;; - esac + target_dev=${DEV%/*} + target_id=${target_dev##*/target} + cd "$target_dev" + target_num=0 + for tid in ${target_id}* ; do + target_num=$(( $target_num + 1 )) done + + controller_port=${target_dev%/*} + controller_dev="${controller_port%/*}" + : controller_dev $controller_dev : controller_port $controller_port # a host controller may have more than one interface/port - controller_port="${controller_port##*/}" - controller_port="${controller_port##host}" + controller_port="${controller_port##*/host}" # - case "$controller_dev" in - # grand central, old powermacs - *:gc/*) - adapter="`echo $controller_dev | sed -e 's@/[^/]\{1,\}$@@;s@^.*/@@;s@^.*:@@'`" - bus="gc" - ;; - # PARISC devices - *parisc*) - adapter="${controler_dev##*/}" - bus=parisc; - ;; - *) - adapter="${controller_dev##*/}" - bus="pci" - ;; - esac cd "$controller_dev" - controller_port="`get_port host $controller_port`" + controller_offset=$(get_port_offset host $controller_port) cd "$OPWD" - d="$bus-$adapter" - if [ -z "$controller_port" ] ; then - controller_port=0 + controller_port=$(( $controller_port - $controller_offset)) + scsi_id="scsi-${controller_port}:${cil}" + + if [ "$d" ] ; then + d="${scsi_id}-$d" + else + d="$scsi_id" fi - d="${d}-scsi-${controller_port}:${cil}" + + D="$controller_dev" RESULT=0 } -handle_block_usb_storage () { -: handle_block_usb_storage $* +handle_block_firewire () { + :handle_block_firewire $* + local DEV=$1 + + if [ -f "$D/ieee1394_id" ] ; then + read ieee1394_id < $D/ieee1394_id + fi + + if [ -z "$ieee1394_id" ] ; then + : no IEEE1394 ID + RESULT=1 + return + fi + + fw_host_dev=${DEV%/fw-host*} + # IEEE1394 devices are always endpoints + d="ieee1394-0x$ieee1394_id" + D="$fw_host_dev" + + RESULT=0 +} + +handle_block_fc () { +: handle_block_fc $* local DEV=$1 - cil="${DEV##*/}" - cil="${cil#*:}" - controller_dev=$DEV - while [ ! -z "$controller_dev" ] ; do - case "$controller_dev" in - */host[0-9]*) - controller_dev="${controller_dev%/*}" + local cil controller_port controller_dev + # SCSI-FC device + fc_tgt_hcil="${DEV##*/}" + fc_tgt_lun="${fc_tgt_hcil##*:}" + fc_tgt_path="${DEV%/*}" + fc_tgt_num="${fc_tgt_path##*/}" + fc_tgt_dev="${fc_tgt_path}/fc_transport:${fc_tgt_num}" + if [ -e "$fc_tgt_dev/port_name" ]; then + read wwpn < $fc_tgt_dev/port_name + fi + if [ -z "$wwpn" ] ; then + : no WWPN + RESULT=1 + return + fi + # Linux currently knows about 32bit luns + tmp_lun3=$(printf "%04x" $(($fc_tgt_lun & 0xFFFF))) + tmp_lun2=$(printf "%04x" $(( ($fc_tgt_lun >> 16) & 0xFFFF))) + tmp_lun1="0000" + tmp_lun0="0000" + + if (($fc_tgt_lun == 0)) ; then + lun="0x0000000000000000" + else + lun="0x${tmp_lun3}${tmp_lun2}${tmp_lun1}${tmp_lun0}" + fi + controller_dev="${fc_tgt_path%/host[0-9]*}" + + # FC devices are always endpoints + d="fc-${wwpn}:${lun}" + D="$controller_dev" + RESULT=0 +} + +handle_block_sas () { + : handle_block_sas $* + local DEV=$1 + local cil adapter controller_dev + # SAS device + sas_host_path="${DEV%%/phy*}" + sas_phy_path="${DEV#*/host*/}" + sas_phy_path="${sas_phy_path%%/target*}" + sas_phy_id="${sas_phy_path%%/*}" + sas_rphy_id="${sas_phy_path##*/}" + sas_phy_dev="${sas_host_path}/${sas_phy_id}/sas_phy:${sas_phy_id}" + if [ -e "$sas_phy_dev/sas_address" ]; then + read phy_address < $sas_phy_dev/sas_address + read phy_port < $sas_phy_dev/port_identifier + read phy_id < $sas_phy_dev/phy_identifier + fi + if [ -z "$phy_address" ] ; then + : no initiator address + RESULT=1 + return + fi + sas_phy_address="$phy_address:$phy_port:$phy_id" + sas_rphy_dev="${sas_host_path}/${sas_phy_id}/${sas_rphy_id}/sas_rphy:${sas_rphy_id}" + if [ -e "$sas_rphy_dev/sas_address" ]; then + read rphy_address < $sas_rphy_dev/sas_address + read rphy_id < $sas_rphy_dev/phy_identifier + fi + if [ -z "$rphy_address" ] ; then + : no initiator address + RESULT=1 + return + fi + sas_rphy_address="$rphy_address:$rphy_id" + + controller_dev="${sas_host_path%/host[0-9]*}" + + # SAS devices are always endpoints + d="sas-${sas_phy_address}-${sas_rphy_address}" + D="$controller_dev" + + RESULT=0 +} + +handle_usb () { +: handle_usb $* + local DEV=$1 + cd -P $1 + DEV=${PWD} + port_id=${DEV##*/} + port_num=${port_id#*-} + host_dev_path=$DEV + while [ ! -z "$host_dev_path" ] ; do + case "$host_dev_path" in + */usb*) + usb_host_path=$host_dev_path + host_dev_path="${host_dev_path%/*}" ;; *) break ;; esac done - : controller_dev $controller_dev - # - # usb-storage devs have a serial number, hopefully unique - serial= - if [ -f $controller_dev/../serial ] ; then - serial="`sed -e 's@^[ -]\{1,\}\|[ -]\{1,\}$@@g;s@[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_0123456789]@@g' < $controller_dev/../serial`" - : serial XXX_${serial}_XXX - d="usb-$serial" - serial="`echo $serial | sed -e 's@[ 0]\{1,\}@@g'`" - fi - if [ -z "$serial" ] ; then - # no serial, broken device - # has eventually binary junk in vpd - identifier= - if [ -f $controller_dev/../product ] ; then - product="`sed -e 's@^[ -]\{1,\}\|[ -]\{1,\}$@@g;s@[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_0123456789]@@g' < $controller_dev/../product`" - fi - if [ -f $controller_dev/../manufacturer ] ; then - manufacturer="`sed -e 's@^[ -]\{1,\}\|[ -]\{1,\}$@@g;s@[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_0123456789]@@g' < $controller_dev/../manufacturer`" - fi - if [ -z "$product" -o -z "$manufacturer" ] ; then - read idvendor < $controller_dev/../idVendor - read idproduct < $controller_dev/../idProduct - identifier="0x${idvendor}-0x${idproduct}" - else - identifier="${manufacturer}-${product}" - fi - d="usb-${identifier}" - fi - d="$d:$cil" - RESULT=0 + : host_dev_path $host_dev_path + usb_host_num=${usb_host_path##*/usb} + cd "$host_dev_path" + usb_host_offset=$(get_port_offset usb $usb_host_num) + usb_host_port=$(($usb_host_num - $usb_host_offset)) + cd "$OPWD" + if [ "$d" ] ; then + d="usb-$usb_host_port:$port_num-${d}" + else + d="usb-$usb_host_port:$port_num" + fi + + D="$host_dev_path" + RESULT=0 } handle_block () { - full_sysfs_class_path="$SYSFS$DEVPATH" - if [ ! -f $full_sysfs_class_path/dev ] ; then return ; fi - # the main device has (hopefully) a symlink to the real device - # a partition is a subdir of the main (raw) device - if [ ! -L $full_sysfs_class_path/device ] ; then - if [ -f $full_sysfs_class_path/range ] ; then return ; fi - full_sysfs_class_path="${full_sysfs_class_path%/*}" - : full_sysfs_class_path "$full_sysfs_class_path" - if [ ! -L $full_sysfs_class_path/device -o ! -f $full_sysfs_class_path/dev ] ; then - return + full_sysfs_path="$SYSFS$DEVPATH" + if [ -L $full_sysfs_path/subsystem ]; then + # new sysfs block layout + full_sysfs_path="${full_sysfs_path%/*}" + cd "$full_sysfs_path/subsystem"; + subsys="`pwd -P`" + cd "$OPWD" + subsys="${subsys##*/}" + if [ "$subsys" == "block" ]; then + # parent is "block", it's a partition, move one up + full_sysfs_path="${full_sysfs_path%/*}" fi + cd $full_sysfs_path + else + # old sysfs block layout + if [ ! -L $full_sysfs_path/device ] ; then + if [ -f $full_sysfs_path/range ] ; then return ; fi + full_sysfs_path="${full_sysfs_path%/*}" + : full_sysfs_path "$full_sysfs_path" + if [ ! -L $full_sysfs_path/device -o ! -f $full_sysfs_path/dev ] ; then + return + fi + fi + cd $full_sysfs_path/device fi - cd $full_sysfs_class_path/device - full_sysfs_device_path="`$pwd_cmd`" + full_sysfs_device_path="`pwd -P`" cd "$OPWD" D=$full_sysfs_device_path + while [ ! -z "$D" ] ; do case "$D" in */ide[0-9]/[0-9].[0-9]*|*/ide[0-9][0-9]/[0-9][0-9].[0-9]*) handle_block_ide "$D" ;; - */usb[0-9]*/[0-9]*/host[0-9]*/[0-9]*:[0-9]*:[0-9]*:[0-9]*) - handle_block_usb_storage "$D" - ;; */css0/*) if [ -r $full_sysfs_device_path/wwpn ]; then read wwpn < $full_sysfs_device_path/wwpn @@ -350,46 +407,75 @@ handle_block () { d="$bus-$adapter" RESULT=0 fi + D= + ;; + */rport-[0-9]*:[0-9]*-[0-9]*/*) + handle_block_fc "$D" + ;; + */phy-[0-9]*:[0-9]*/*) + handle_block_sas "$D" + ;; + */fw-host[0-9]*/*) + handle_block_firewire "$D" ;; */host[0-9]*/[0-9]*:[0-9]*:[0-9]*:[0-9]*) - # check for ieee1394 sbp2 - if test -f $D/ieee1394_id ; then - read ieee1394_id < $D/ieee1394_id - d="`echo ieee1394-${ieee1394_id} | sed -e 's@:@-@g'`" - RESULT=0 - else - handle_block_scsi "$D" - fi + handle_block_scsi "$D" + ;; + */usb[0-9]*/[0-9]*/*) + handle_usb "$D" + ;; + */pci[0-9]*:[0-9]*) + handle_pci "$D" + ;; + */devices) + D= ;; - *) : not handled RESULT=1 return - ;; esac - # look for a partition - if [ "$full_sysfs_class_path" != "$SYSFS$DEVPATH" ] ; then - dp="`echo $SYSFS$DEVPATH | sed -e 's@^/.*/@@;s@^[^0-9]\{1,\}@@;s@.*_@@'`" - case "$d" in - *[0-9]) - d="${d}p${dp}" - ;; + done + + if [ "$TYPE" == "scsi_tape" ] ; then + devname=${full_sysfs_path##*/} + rewind="${devname%%st*}" + mode="${devname##*st}" + case "$mode" in + *l) + mode="l" + ;; + *m) + mode="m" + ;; + *a) + mode="a" + ;; *) - d="${d}${dp}" + mode="" ;; esac + if [ "$d" ]; then + d="$d-${rewind}st${mode}" + fi fi - # done - echo "ID_PATH=$d" } case "$TYPE" in - block) + block) handle_block + echo "ID_PATH=$d" ;; - *) + scsi_tape) + handle_block + echo "ID_PATH=$d" + ;; + input) + handle_usb $SYSFS$DEVPATH/device + echo "ID_PATH=$d" + ;; + *) RESULT=1 ;; esac