SYMLINK 이름에 상위 항목의 정보를 사용하는 udev 규칙을 만듭니다.

SYMLINK 이름에 상위 항목의 정보를 사용하는 udev 규칙을 만듭니다.

숨겨진 장치로 마운트되는 USB 장치에 대한 udev 규칙을 작성하려고 합니다. 이것은 udevadm info장치입니다:

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

  looking at device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2/1-1.2.3/1-1.2.3.3/1-1.2.3.3:1.0/0003:20CE:0023.0010/hidraw/hidraw15':
    KERNEL=="hidraw15"
    SUBSYSTEM=="hidraw"
    DRIVER==""

  looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2/1-1.2.3/1-1.2.3.3/1-1.2.3.3:1.0/0003:20CE:0023.0010':
    KERNELS=="0003:20CE:0023.0010"
    SUBSYSTEMS=="hid"
    DRIVERS=="hid-generic"
    ATTRS{country}=="00"

  looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2/1-1.2.3/1-1.2.3.3/1-1.2.3.3:1.0':
    KERNELS=="1-1.2.3.3:1.0"
    SUBSYSTEMS=="usb"
    DRIVERS=="usbhid"
    ATTRS{authorized}=="1"
    ATTRS{bAlternateSetting}==" 0"
    ATTRS{bInterfaceClass}=="03"
    ATTRS{bInterfaceNumber}=="00"
    ATTRS{bInterfaceProtocol}=="00"
    ATTRS{bInterfaceSubClass}=="00"
    ATTRS{bNumEndpoints}=="02"
    ATTRS{supports_autosuspend}=="1"

  looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2/1-1.2.3/1-1.2.3.3':
    KERNELS=="1-1.2.3.3"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{authorized}=="1"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bDeviceClass}=="00"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{bMaxPower}=="100mA"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bcdDevice}=="0100"
    ATTRS{bmAttributes}=="c0"
    ATTRS{busnum}=="1"
    ATTRS{configuration}==""
    ATTRS{devnum}=="25"
    ATTRS{devpath}=="1.2.3.3"
    ATTRS{idProduct}=="0023"
    ATTRS{idVendor}=="20ce"
    ATTRS{ltm_capable}=="no"
    ATTRS{manufacturer}=="MCL"
    ATTRS{maxchild}=="0"
    ATTRS{product}=="Mini-Circuits"
    ATTRS{quirks}=="0x0"
    ATTRS{removable}=="unknown"
    ATTRS{speed}=="12"
    ATTRS{urbnum}=="12"
    ATTRS{version}==" 1.10"

  looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2/1-1.2.3':
    KERNELS=="1-1.2.3"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{authorized}=="1"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bDeviceClass}=="09"
    ATTRS{bDeviceProtocol}=="02"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{bMaxPower}=="100mA"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bcdDevice}=="9224"
    ATTRS{bmAttributes}=="e0"
    ATTRS{busnum}=="1"
    ATTRS{configuration}==""
    ATTRS{devnum}=="6"
    ATTRS{devpath}=="1.2.3"
    ATTRS{idProduct}=="0610"
    ATTRS{idVendor}=="05e3"
    ATTRS{ltm_capable}=="no"
    ATTRS{manufacturer}=="GenesysLogic"
    ATTRS{maxchild}=="4"
    ATTRS{product}=="USB2.0 Hub"
    ATTRS{quirks}=="0x0"
    ATTRS{removable}=="fixed"
    ATTRS{speed}=="480"
    ATTRS{urbnum}=="70"
    ATTRS{version}==" 2.00"

  looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2':
    KERNELS=="1-1.2"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{authorized}=="1"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bDeviceClass}=="09"
    ATTRS{bDeviceProtocol}=="02"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{bMaxPower}=="100mA"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bcdDevice}=="9224"
    ATTRS{bmAttributes}=="e0"
    ATTRS{busnum}=="1"
    ATTRS{configuration}==""
    ATTRS{devnum}=="4"
    ATTRS{devpath}=="1.2"
    ATTRS{idProduct}=="0610"
    ATTRS{idVendor}=="05e3"
    ATTRS{ltm_capable}=="no"
    ATTRS{manufacturer}=="GenesysLogic"
    ATTRS{maxchild}=="4"
    ATTRS{product}=="USB2.0 Hub"
    ATTRS{quirks}=="0x0"
    ATTRS{removable}=="removable"
    ATTRS{speed}=="480"
    ATTRS{urbnum}=="80"
    ATTRS{version}==" 2.00"

  looking at parent device '/devices/platform/soc/3f980000.usb/usb1/1-1':
    KERNELS=="1-1"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{authorized}=="1"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bDeviceClass}=="09"
    ATTRS{bDeviceProtocol}=="02"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{bMaxPower}=="2mA"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bcdDevice}=="0200"
    ATTRS{bmAttributes}=="e0"
    ATTRS{busnum}=="1"
    ATTRS{configuration}==""
    ATTRS{devnum}=="2"
    ATTRS{devpath}=="1"
    ATTRS{idProduct}=="9514"
    ATTRS{idVendor}=="0424"
    ATTRS{ltm_capable}=="no"
    ATTRS{maxchild}=="5"
    ATTRS{quirks}=="0x0"
    ATTRS{removable}=="unknown"
    ATTRS{speed}=="480"
    ATTRS{urbnum}=="55"
    ATTRS{version}==" 2.00"

  looking at parent device '/devices/platform/soc/3f980000.usb/usb1':
    KERNELS=="usb1"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{authorized}=="1"
    ATTRS{authorized_default}=="1"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bDeviceClass}=="09"
    ATTRS{bDeviceProtocol}=="01"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{bMaxPower}=="0mA"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bcdDevice}=="0409"
    ATTRS{bmAttributes}=="e0"
    ATTRS{busnum}=="1"
    ATTRS{configuration}==""
    ATTRS{devnum}=="1"
    ATTRS{devpath}=="0"
    ATTRS{idProduct}=="0002"
    ATTRS{idVendor}=="1d6b"
    ATTRS{interface_authorized_default}=="1"
    ATTRS{ltm_capable}=="no"
    ATTRS{manufacturer}=="Linux 4.9.60-1-ARCH dwc_otg_hcd"
    ATTRS{maxchild}=="1"
    ATTRS{product}=="DWC OTG Controller"
    ATTRS{quirks}=="0x0"
    ATTRS{removable}=="unknown"
    ATTRS{serial}=="3f980000.usb"
    ATTRS{speed}=="480"
    ATTRS{urbnum}=="26"
    ATTRS{version}==" 2.00"

  looking at parent device '/devices/platform/soc/3f980000.usb':
    KERNELS=="3f980000.usb"
    SUBSYSTEMS=="platform"
    DRIVERS=="dwc_otg"
    ATTRS{busconnected}=="Bus Connected = 0x1"
    ATTRS{buspower}=="Bus Power = 0x1"
    ATTRS{bussuspend}=="Bus Suspend = 0x0"
    ATTRS{devspeed}=="Device Speed = 0x0"
    ATTRS{driver_override}=="(null)"
    ATTRS{enumspeed}=="Device Enumeration Speed = 0x1"
    ATTRS{fr_interval}=="Frame Interval = 0x1d4b"
    ATTRS{ggpio}=="GGPIO = 0x00000000"
    ATTRS{gnptxfsiz}=="GNPTXFSIZ = 0x01000306"
    ATTRS{gotgctl}=="GOTGCTL = 0x001c0001"
    ATTRS{gpvndctl}=="GPVNDCTL = 0x00000000"
    ATTRS{grxfsiz}=="GRXFSIZ = 0x00000306"
    ATTRS{gsnpsid}=="GSNPSID = 0x4f54280a"
    ATTRS{guid}=="GUID = 0x2708a000"
    ATTRS{gusbcfg}=="GUSBCFG = 0x20001700"
    ATTRS{hcd_frrem}=="HCD Dump Frame Remaining"
    ATTRS{hcddump}=="HCD Dump"
    ATTRS{hnp}=="HstNegScs = 0x0"
    ATTRS{hnpcapable}=="HNPCapable = 0x1"
    ATTRS{hprt0}=="HPRT0 = 0x00001405"
    ATTRS{hptxfsiz}=="HPTXFSIZ = 0x02000406"
    ATTRS{hsic_connect}=="HSIC Connect = 0x1"
    ATTRS{inv_sel_hsic}=="Invert Select HSIC = 0x0"
    ATTRS{mode}=="Mode = 0x1"
    ATTRS{mode_ch_tim_en}=="Mode Change Ready Timer Enable = 0x0"
    ATTRS{rd_reg_test}=="Time to read GNPTXFSIZ reg 10000000 times: 1330 msecs (133 jiffies)"
    ATTRS{regdump}=="Register Dump"
    ATTRS{regoffset}=="0xffffffff"
    ATTRS{regvalue}=="invalid offset"
    ATTRS{rem_wakeup_pwrdn}==""
    ATTRS{remote_wakeup}=="Remote Wakeup Sig = 0 Enabled = 0 LPM Remote Wakeup = 0"
    ATTRS{spramdump}=="SPRAM Dump"
    ATTRS{srp}=="SesReqScs = 0x1"
    ATTRS{srpcapable}=="SRPCapable = 0x1"
    ATTRS{wr_reg_test}=="Time to write GNPTXFSIZ reg 10000000 times: 330 msecs (33 jiffies)"

  looking at parent device '/devices/platform/soc':
    KERNELS=="soc"
    SUBSYSTEMS=="platform"
    DRIVERS==""
    ATTRS{driver_override}=="(null)"

  looking at parent device '/devices/platform':
    KERNELS=="platform"
    SUBSYSTEMS==""
    DRIVERS==""

내가 만들려는 규칙은 idVendor모든 USB 장치를 통과하고 필터링한 idProduct다음 심볼릭 링크를 통과 해야 합니다.그림Device to attenuators/%s{devpath}. 이것은 devpathhidraw 장치 자체가 아닌 USB 상위의 속성입니다.

규칙이 일치하고 올바르게 심볼릭 링크된 것 같습니다.USB장치는 정확하지만 hidraw 장치에 연결해야 합니다.

SUBSYSTEM=="usb", ATTRS{idVendor}=="20ce", ATTR{idProduct}=="0023", SYMLINK+="attenuators/%s{devpath}"

내가 시도한 솔루션은 다음과 같습니다. 그러나 그 중 아무 것도 작동하지 않는 것 같습니다.

1:

SUBSYSTEM=="usb", ATTRS{idVendor}=="20ce", ATTR{idProduct}=="0023", ENV{IS_ATTENUATOR}="t", ENV{DEV_PATH}="%s{devpath}"
SUBSYSTEM=="hidraw", ENV{IS_ATTENUATOR}=="t", SYMLINK+="attenuators/%E{DEV_PATH}"

2:

SUBSYSTEM=="usb", ATTRS{idVendor}=="20ce", ATTR{idProduct}=="0023", ENV{IS_ATTENUATOR}="t", ENV{DEV_PATH}="%s{devpath}"
ENV{IS_ATTENUATOR}!="t", GOTO="attenuator_end"
SUBSYSTEM=="hidraw", SYMLINK+="attenuators/%E{DEV_PATH}"

LABEL="attenuator_end"

3. 상위 속성만 참조해 보세요.

SUBSYSTEM=="hidraw", ATTR{idVendor}=="20ce", ATTR{idProduct}=="0023", SYMLINK+="attenuators/%s{devpath}"

몇 가지 테스트를 제외하면 그 중 장치를 연결할 수 있는 테스트는 거의 없는 것 같았습니다. 여기에 기본적인 이해가 부족한 것 같습니다. 어떤 도움이라도 대단히 감사하겠습니다!

답변1

귀하의 주요 문제는 %s{devpath}단순히 $devpath.

따라서 다음과 같이 작동해야 합니다.

SUBSYSTEM=="usb", ATTRS{idVendor}=="20ce", ATTRS{idProduct}=="0023", SYMLINK+="attenuators/$devpath"

ATTRS대신 ATTR에 일부 상위 노드를 필터링하고 있기 때문에 (끝에 있는 S에 주목하세요. 여러 번 혼동됩니다) . 바라보다udev 규칙에서 ATTRS와 ATTR의 차이점은 무엇입니까?

답변2

이것이 가장 간단하거나 가장 우아한 솔루션은 아닐 수도 있지만 "devpath"(장치의 버스/포트 경로가 포함됨)라는 파일을 찾을 때까지 hidraw 장치의 DEVPATH에서 디렉터리를 반복적으로 위로 이동하는 Python 스크립트를 작성했습니다. 포트). 일단 발견되면 (현재 하드 코딩된) 올바른 값과 비교하여 idVendor 및 idProduct를 확인하고 devpath올바른 경우 장치의 값을 인쇄합니다.

내 규칙은 다음과 같이 표시되었습니다.

SUBSYSTEM=="hidraw", PROGRAM="/path/to/script.py", SYMLINK+="attenuators/%c"

스크립트는 다음과 같습니다.

#!/usr/bin/env python3

import os, sys

path = '/sys' + os.environ["DEVPATH"]

while path != '/':
  if 'devpath' in os.listdir(path):
    with open(path + '/idVendor') as f:
      vendor = f.readline().rstrip()
    with open(path + '/idProduct') as f:
      product = f.readline().rstrip()

    if vendor != '20ce' or product != '0023':
      sys.exit(1)   

    with open(path + '/devpath') as f:
      print(f.readline().rstrip())
      sys.exit(0)
  else:
    path = os.path.dirname(path)

관련 정보