home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / lib / udev / path_id < prev    next >
Encoding:
Text File  |  2009-05-14  |  11.5 KB  |  575 lines

  1. #!/bin/sh
  2.  
  3. # provide the shortest possible unique hardware path to a device
  4. # for the Linux Persistent Device Naming scheme
  5. #
  6. # Copyright (C) 2005-2006 SUSE Linux Products GmbH
  7. # Author:
  8. #    Hannes Reinecke <hare@suse.de>
  9. #
  10. #    This program is free software; you can redistribute it and/or modify it
  11. #    under the terms of the GNU General Public License as published by the
  12. #    Free Software Foundation version 2 of the License.
  13.  
  14. SYSFS=/sys
  15. RESULT=1
  16. TYPE=
  17. OPWD="`pwd`"
  18. full_sysfs_path=
  19. full_sysfs_device_path=
  20.  
  21. if [ -z "$DEVPATH" -a -z "$1" ] ; then
  22.     exit 1
  23. fi
  24.  
  25. if [ -z "$DEVPATH" ] ; then
  26.     case "$1" in
  27.         $SYSFS/*)
  28.             DEVPATH="${1#$SYSFS}"
  29.             ;;
  30.         *)
  31.             DEVPATH=$1
  32.             ;;
  33.     esac
  34. fi
  35.  
  36. if [ ! -e $SYSFS$DEVPATH/dev ] ; then
  37.     exit 1
  38. fi
  39.  
  40. case "$DEVPATH" in
  41.     /devices/*)
  42.         cd "$SYSFS$DEVPATH/subsystem";
  43.         TYPE="`pwd -P`"
  44.         cd "$OPWD"
  45.         TYPE="${TYPE##*/}"
  46.         ;;
  47.     /class/*)
  48.         TYPE="${DEVPATH#/class/}"
  49.         TYPE="${TYPE%%/*}"
  50.         ;;
  51.     /block/*)
  52.         TYPE=block
  53.         ;;
  54.     *)
  55.         exit 1
  56.         ;;
  57. esac
  58.  
  59. get_port_offset () {
  60.     local type offset port
  61.     type=$1
  62.     offset=$2
  63.     for i in $type[0-9]* ; do
  64.         : i $i
  65.         port="${i#$type}"
  66.         if [ "$port" -lt "$offset" ] ; then offset=$port ; fi
  67.     done
  68.     echo $offset
  69. }
  70.  
  71. handle_pci () {
  72.     local DEV=$1
  73.     cd -P $1
  74.     DEV=${PWD}
  75.     pci_id=${DEV##*/}
  76.     host_dev_path=$DEV
  77.  
  78.     # cciss devices don't have a separate sysfs node
  79.     for blk_link in block*; do
  80.         if [ -L "$blk_link" ]; then
  81.         case "$blk_link" in
  82.             *cciss*)
  83.             d=cciss-${blk_link#*cciss\!}
  84.             ;;
  85.         esac
  86.         fi
  87.     done
  88.     while [ ! -z "$host_dev_path" ] ; do
  89.         case "$host_dev_path" in
  90.             */pci[0-9]*)
  91.                 host_dev_path=${host_dev_path%/*}
  92.                 ;;
  93.             *)
  94.                 break
  95.                 ;;
  96.         esac
  97.     done
  98.     if [ "$d" ]; then
  99.         d="pci-$pci_id-$d"
  100.     else
  101.         d="pci-$pci_id"
  102.     fi
  103.     D="$host_dev_path"
  104.     RESULT=0
  105. }
  106.  
  107. handle_platform () {
  108.     local DEV=$1
  109.     cd -P $1
  110.     DEV=${PWD}
  111.     platform_id=${DEV##*/}
  112.     host_dev_path=$DEV
  113.     while [ ! -z "$host_dev_path" ] ; do
  114.         case "$host_dev_path" in
  115.             */platform*)
  116.                 host_dev_path=${host_dev_path%/*}
  117.                 ;;
  118.             *)
  119.                 break
  120.                 ;;
  121.         esac
  122.     done
  123.     if [ "$d" ]; then
  124.         d="platform-$platform_id-$d"
  125.     else
  126.         d="platform-$platform_id"
  127.     fi
  128.     D="$host_dev_path"
  129.     RESULT=0
  130. }
  131.  
  132. handle_serio () {
  133.     local DEV=$1
  134.     cd -P $1
  135.     DEV=${PWD}
  136.     serio_id=${DEV##*/serio}
  137.     host_dev_path=$DEV
  138.     while [ ! -z "$host_dev_path" ] ; do
  139.         case "$host_dev_path" in
  140.             */serio*)
  141.                 host_dev_path=${host_dev_path%/*}
  142.                 ;;
  143.             *)
  144.                 break
  145.                 ;;
  146.         esac
  147.     done
  148.     if [ "$d" ]; then
  149.         d="serio-$serio_id-$d"
  150.     else
  151.         d="serio-$serio_id"
  152.     fi
  153.     D="$host_dev_path"
  154.     RESULT=0
  155. }
  156.  
  157. handle_ide () {
  158.     : handle_ide $*
  159.     local DEV=$1
  160.     local port idedev idecontroller
  161.     # IDE
  162.     : DEV $DEV
  163.     port=${DEV##*/}
  164.     idedev=${DEV%/*}
  165.     idecontroller=${idedev%/*}
  166.     # port info if the controller has more than one interface
  167.     port="${port#ide}"
  168.     : port $port d $d
  169.     : idedev $idedev kernel_port $port
  170.     case "${port#*.}" in
  171.         0)
  172.             channel=0
  173.             ;;
  174.         1)
  175.             channel=1
  176.             ;;
  177.         *)
  178.             echo "Error: $idedev is neither master or slave" >&2
  179.             ;;
  180.     esac
  181.     cd $idecontroller
  182.     offset="`get_port_offset ide ${port%.*}`"
  183.     cd "$OPWD"
  184.     :  port offset $offset
  185.     port=$((${port%.*} - $offset))
  186.     if [ "$d" ] ; then
  187.         d="ide-${port}:$channel-$d"
  188.     else
  189.         d="ide-${port}:$channel"
  190.     fi
  191.     D=$idecontroller
  192.     RESULT=0
  193. }
  194.  
  195. handle_scsi () {
  196.     : handle_scsi $*
  197.     local DEV=$1
  198.     local cil controller_port controller_dev
  199.     # SCSI device
  200.     cil="${DEV##*/}"
  201.     cil="${cil#*:}"
  202.     target_dev=${DEV%/*}
  203.     target_id=${target_dev##*/target}
  204.     cd "$target_dev"
  205.     target_num=0
  206.     for tid in ${target_id}* ; do
  207.         target_num=$(( $target_num + 1 ))
  208.     done
  209.     controller_port=${target_dev%/*}
  210.     controller_dev="${controller_port%/*}"
  211.     : controller_dev $controller_dev
  212.     : controller_port $controller_port
  213.     # a host controller may have more than one interface/port
  214.     controller_port="${controller_port##*/host}"
  215.     #
  216.     cd "$controller_dev"
  217.     controller_offset=$(get_port_offset host $controller_port)
  218.     cd "$OPWD"
  219.     controller_port=$(( $controller_port - $controller_offset))
  220.     scsi_id="scsi-${controller_port}:${cil}"
  221.     if [ "$d" ] ; then
  222.         d="${scsi_id}-$d"
  223.     else
  224.         d="$scsi_id"
  225.     fi
  226.     D="$controller_dev"
  227.     RESULT=0
  228. }
  229.  
  230. handle_firewire () {
  231.     : handle_firewire $*
  232.     local DEV=$1
  233.     if [ -f "$D/ieee1394_id" ] ; then
  234.         read ieee1394_id < $D/ieee1394_id
  235.     fi
  236.     if [ -z "$ieee1394_id" ] ; then
  237.         : no IEEE1394 ID
  238.         RESULT=1
  239.         return
  240.     fi
  241.     fw_host_dev=${DEV%/fw-host*}
  242.     # IEEE1394 devices are always endpoints
  243.     d="ieee1394-0x$ieee1394_id"
  244.     D="$fw_host_dev"
  245.     RESULT=0
  246. }
  247.  
  248. handle_fc () {
  249.     : handle_fc $*
  250.     local DEV=$1
  251.     local cil controller_port controller_dev
  252.     # SCSI-FC device
  253.     fc_tgt_hcil="${DEV##*/}"
  254.     fc_tgt_lun="${fc_tgt_hcil##*:}"
  255.     fc_tgt_path="${DEV%/*}"
  256.     fc_tgt_num="${fc_tgt_path##*/}"
  257.     fc_tgt_dev="${fc_tgt_path}/fc_transport/${fc_tgt_num}"
  258.     if [ -e "$fc_tgt_dev/port_name" ]; then
  259.         read wwpn < $fc_tgt_dev/port_name
  260.     fi
  261.     if [ -z "$wwpn" ] ; then
  262.         : no WWPN
  263.         D=
  264.         RESULT=1
  265.         return
  266.     fi
  267.     # Linux currently knows about 32bit luns
  268.     tmp_lun3=$(printf "%04x" $(($fc_tgt_lun & 0xFFFF)))
  269.     tmp_lun2=$(printf "%04x" $(( ($fc_tgt_lun >> 16) & 0xFFFF)))
  270.     tmp_lun1="0000"
  271.     tmp_lun0="0000"
  272.     if (($fc_tgt_lun == 0)) ; then
  273.         lun="0x0000000000000000"
  274.     else
  275.         lun="0x${tmp_lun3}${tmp_lun2}${tmp_lun1}${tmp_lun0}"
  276.     fi
  277.     controller_dev="${fc_tgt_path%/host[0-9]*}"
  278.     # FC devices are always endpoints
  279.     d="fc-${wwpn}:${lun}"
  280.     D="$controller_dev"
  281.     RESULT=0
  282. }
  283.  
  284. handle_sas () {
  285.     : handle_sas $*
  286.     local DEV=$1
  287.     local cil adapter controller_dev
  288.     local lun
  289.     lun=${DEV##*:}
  290.     # SAS device
  291.     sas_end_path="${DEV%%/target*}"
  292.     sas_host_path="${sas_end_path%%/port*}"
  293.     sas_phy_path="${sas_end_path#*/host*/}"
  294.     sas_phy_path="${sas_phy_path%%/*}"
  295.     sas_phy_path="${sas_host_path}/${sas_phy_path}"
  296.  
  297.     sas_phy_id=255
  298.     for phy in $sas_phy_path/phy-*/sas_phy/phy-* ; do
  299.         if [ -d "$phy" ] ; then
  300.             read phy_id < $phy/phy_identifier
  301.             if [ $phy_id -lt $sas_phy_id ]; then
  302.                 sas_phy_id=$phy_id
  303.             fi
  304.         fi
  305.     done
  306.  
  307.     if [ $sas_phy_id -eq 255 ] ; then
  308.         : no initiator address
  309.         D=
  310.         RESULT=1
  311.         return
  312.     fi
  313.  
  314.     sas_port_id="${sas_phy_path##*/port-}"
  315.     sas_port_dev="/sys/class/sas_port/port-${sas_port_id}"
  316.     if [ -e "$sas_port_dev/num_phys" ] ; then
  317.         read phy_port < $sas_port_dev/num_phys
  318.     fi
  319.  
  320.     sas_end_id="${sas_end_path##*end_device-}"
  321.     sas_end_dev="/sys/class/sas_device/end_device-${sas_end_id}"
  322.     if [ -e "$sas_end_dev/sas_address" ]; then
  323.         read end_address < $sas_end_dev/sas_address
  324.         read end_id < $sas_end_dev/phy_identifier
  325.     fi
  326.     if [ -z "$end_address" ] ; then
  327.         : no end device address
  328.         D=
  329.         RESULT=1
  330.         return
  331.     fi
  332.     sas_end_address="$end_address:$end_id"
  333.     controller_dev="${sas_host_path%/host[0-9]*}"
  334.     # SAS devices are always endpoints
  335.     d="sas-phy${sas_phy_id}:${phy_port}-${sas_end_address}-lun$lun"
  336.     D="$controller_dev"
  337.     RESULT=0
  338. }
  339.  
  340. handle_iscsi() {
  341.     local DEV=$1
  342.     local iscsi_session_dir
  343.     local iscsi_session iscsi_session_path
  344.     local iscsi_connection iscsi_connection_path
  345.     local iscsi_scsi_lun
  346.     # iSCSI device
  347.     iscsi_session_dir="${DEV%%/target*}"
  348.     iscsi_session="${iscsi_session_dir##*/}"
  349.     iscsi_session_path=/sys/class/iscsi_session/${iscsi_session}
  350.     if [ ! -d "$iscsi_session_path" ] ; then
  351.         : no iSCSI session path
  352.         RESULT=1
  353.         return
  354.     fi
  355.     # Currently we're not doing MC/S
  356.     for conn in ${iscsi_session_dir}/connection* ; do
  357.         iscsi_conn_num=${conn##*:}
  358.         if [ "$iscsi_conn_num" = '0' ] ; then
  359.         iscsi_connection=$(basename $conn)
  360.         fi
  361.     done
  362.     if [ -z "$iscsi_connection" ] ; then
  363.         : no iSCSI connection found
  364.         RESULT=1
  365.         return
  366.     fi
  367.     iscsi_connection_path=/sys/class/iscsi_connection/${iscsi_connection}
  368.     if [ ! -d "$iscsi_connection_path" ] ; then
  369.         : no iSCSI connection path
  370.         RESULT=1
  371.         return
  372.     fi
  373.     if [ -e "${iscsi_session_path}/targetname" ]; then
  374.         read iscsi_tgtname < ${iscsi_session_path}/targetname
  375.     fi
  376.     if [ -z "$iscsi_tgtname" ] ; then
  377.         : No iSCSI Targetname
  378.         RESULT=1
  379.         return
  380.     fi
  381.     if [ -e "${iscsi_connection_path}/persistent_address" ] ; then
  382.         read iscsi_address < ${iscsi_connection_path}/persistent_address
  383.     fi
  384.     if [ -z "$iscsi_address" ] ; then
  385.         : No iSCSI Target address
  386.         RESULT=1
  387.         return
  388.     fi
  389.     if [ -e "${iscsi_connection_path}/persistent_port" ] ; then
  390.         read iscsi_port < ${iscsi_connection_path}/persistent_port
  391.     fi
  392.     iscsi_scsi_lun="${DEV##*:}"
  393.     d="ip-${iscsi_address}:${iscsi_port}-iscsi-${iscsi_tgtname}-lun-${iscsi_scsi_lun}"
  394.     RESULT=0
  395. }
  396.  
  397. handle_usb () {
  398. : handle_usb $*
  399.     local DEV=$1
  400.     cd -P $1
  401.     DEV=${PWD}
  402.     port_id=${DEV##*/}
  403.     port_num=${port_id#*-}
  404.     host_dev_path=$DEV
  405.     while [ ! -z "$host_dev_path" ] ; do
  406.         case "$host_dev_path" in
  407.             */usb*)
  408.                 usb_host_path=$host_dev_path
  409.                 host_dev_path="${host_dev_path%/*}"
  410.                 ;;
  411.             *)
  412.                 break
  413.                 ;;
  414.         esac
  415.     done
  416.     : host_dev_path $host_dev_path
  417.     usb_host_num=${usb_host_path##*/usb}
  418.  
  419.     cd "$host_dev_path"
  420.     usb_host_offset=$(get_port_offset usb $usb_host_num)
  421.     usb_host_port=$(($usb_host_num - $usb_host_offset))
  422.     cd "$OPWD"
  423.     if [ "$d" ] ; then
  424.         d="usb-$usb_host_port:$port_num-${d}"
  425.     else
  426.         d="usb-$usb_host_port:$port_num"
  427.     fi
  428.     D="$host_dev_path"
  429.     RESULT=0
  430. }
  431.  
  432. handle_device () {
  433.     full_sysfs_path="$SYSFS$DEVPATH"
  434.     case "$DEVPATH" in
  435.         /devices/*)
  436.             full_sysfs_path="${full_sysfs_path%/*}"
  437.             # skip parent device of the same subsystem
  438.             if [ -L $full_sysfs_path/subsystem ]; then
  439.                 cd "$full_sysfs_path/subsystem";
  440.                 subsys="`pwd -P`"
  441.                 cd "$OPWD"
  442.                 subsys="${subsys##*/}"
  443.                 if [ "$subsys" = "$TYPE" ]; then
  444.                     : skip same subsystem parent
  445.                     full_sysfs_path="${full_sysfs_path%/*}"
  446.                 fi
  447.             fi
  448.             # skip subsystem directory
  449.             subsys="${full_sysfs_path##*/}"
  450.             if [ "$subsys" = "$TYPE" ]; then
  451.                 : skip subsystem directory
  452.                 full_sysfs_path="${full_sysfs_path%/*}"
  453.             fi
  454.             cd $full_sysfs_path
  455.             ;;
  456.         *)
  457.             # old sysfs layout
  458.             if [ ! -L $full_sysfs_path/device ]; then
  459.                 full_sysfs_path="${full_sysfs_path%/*}"
  460.                 : full_sysfs_path "$full_sysfs_path"
  461.                 if [ ! -L $full_sysfs_path/device -o ! -f $full_sysfs_path/dev ]; then
  462.                     return
  463.                 fi
  464.             fi
  465.             if [ -L $full_sysfs_path/device/device ]; then
  466.                 cd $full_sysfs_path/device/device
  467.             else
  468.                 cd $full_sysfs_path/device
  469.             fi
  470.             ;;
  471.     esac
  472.     full_sysfs_device_path="`pwd -P`"
  473.     cd "$OPWD"
  474.  
  475.     D=$full_sysfs_device_path
  476.     while [ ! -z "$D" ] ; do
  477.         case "$D" in
  478.             */ide[0-9]/[0-9].[0-9]*|*/ide[0-9][0-9]/[0-9][0-9].[0-9]*)
  479.                 handle_ide "$D"
  480.                 ;;
  481.             */css0/*)
  482.                 if [ -r $full_sysfs_device_path/wwpn ]; then
  483.                     read wwpn < $full_sysfs_device_path/wwpn
  484.                 fi
  485.                 if [ -r $full_sysfs_device_path/fcp_lun ]; then
  486.                     read lun < $full_sysfs_device_path/fcp_lun
  487.                 fi
  488.                 if [ -r $full_sysfs_device_path/hba_id ]; then
  489.                     read bus_id < $full_sysfs_device_path/hba_id
  490.                 fi
  491.                 if [ "$bus_id" -a "$wwpn" -a "$lun" ]; then
  492.                     # S/390 zfcp adapter
  493.                     d="ccw-$bus_id-zfcp-$wwpn:$lun"
  494.                     RESULT=0
  495.                 else
  496.                     # DASD devices
  497.                     bus="ccw"
  498.                     adapter=${D##*/}
  499.                     d="$bus-$adapter"
  500.                     RESULT=0
  501.                 fi
  502.                 D=
  503.                 ;;
  504.             */rport-[0-9]*:[0-9]*-[0-9]*/*)
  505.                 handle_fc "$D"
  506.                 ;;
  507.             */end_device-[0-9]*:[0-9]*:[0-9]*/*)
  508.                 handle_sas "$D"
  509.                 ;;
  510.             */fw-host[0-9]*/*)
  511.                 handle_firewire "$D"
  512.                 ;;
  513.             */session[0-9]*/*)
  514.                 handle_iscsi "$D"
  515.                 D=
  516.                 ;;
  517.             */host[0-9]*/[0-9]*:[0-9]*:[0-9]*:[0-9]*)
  518.                 handle_scsi "$D"
  519.                 ;;
  520.             */ttyUSB*)
  521.                 D=${D%/ttyUSB*}
  522.                 ;;
  523.             */usb[0-9]*/[0-9]*/*)
  524.                 handle_usb "$D"
  525.                 ;;
  526.             */pci[0-9]*:[0-9]*)
  527.                 handle_pci "$D"
  528.                 ;;
  529.             */serio[0-9]*)
  530.                 handle_serio "$D"
  531.                 ;;
  532.             */platform/*)
  533.                 handle_platform "$D"
  534.                 ;;
  535.             */devices)
  536.                 D=
  537.                 ;;
  538.             *)
  539.                 : not handled
  540.                 RESULT=1
  541.                 return
  542.                 ;;
  543.         esac
  544.     done
  545.     if [ "$TYPE" = "scsi_tape" ] ; then
  546.         devname=${full_sysfs_path##*/}
  547.         rewind="${devname%%st*}"
  548.         mode="${devname##*st}"
  549.         case "$mode" in
  550.             *l)
  551.                 mode="l"
  552.                 ;;
  553.             *m)
  554.                 mode="m"
  555.                 ;;
  556.             *a)
  557.                 mode="a"
  558.                 ;;
  559.             *)
  560.                 mode=""
  561.                 ;;
  562.         esac
  563.         if [ "$d" ]; then
  564.             d="$d-${rewind}st${mode}"
  565.         fi
  566.     fi
  567. }
  568.  
  569. handle_device
  570. if [ -z "$d" ]; then
  571.     exit 1
  572. fi
  573. echo "ID_PATH=$d"
  574. exit 0
  575.