Udev

看似無法區分的設備的 Udev 規則

  • August 1, 2019

我正在嘗試使用 udev 自動設置指向 Intel RealSense D415 的符號連結。這是因為我在機器上使用了多個攝像頭,並且需要能夠通過文件名可靠地引用它們(重啟時不會改變)。

RealSense D415 在/dev. 我為前兩個設置符號連結沒有問題,但據我所知,第一個和第三個設備是相同的,除瞭如果先插入另一台相機可能會改變的KERNELKERNELS屬性。

如何使用 udev 規則來區分這些?

輸出sudo udevadm info -ap /devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.0/video4linux/video0

 looking at device '/devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.0/video4linux/video0':
   KERNEL=="video0"
   SUBSYSTEM=="video4linux"
   DRIVER==""
   ATTR{dev_debug}=="0"
   ATTR{index}=="0"
   ATTR{name}=="Intel(R) RealSense(TM) 415: Int"

 looking at parent device '/devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.0':
   KERNELS=="2-1:1.0"
   SUBSYSTEMS=="usb"
   DRIVERS=="uvcvideo"
   ATTRS{authorized}=="1"
   ATTRS{bAlternateSetting}==" 0"
   ATTRS{bInterfaceClass}=="0e"
   ATTRS{bInterfaceNumber}=="00"
   ATTRS{bInterfaceProtocol}=="00"
   ATTRS{bInterfaceSubClass}=="01"
   ATTRS{bNumEndpoints}=="01"
   ATTRS{iad_bFirstInterface}=="00"
   ATTRS{iad_bFunctionClass}=="0e"
   ATTRS{iad_bFunctionProtocol}=="00"
   ATTRS{iad_bFunctionSubClass}=="03"
   ATTRS{iad_bInterfaceCount}=="03"
   ATTRS{interface}=="Intel(R) RealSense(TM) 415 Depth"
   ATTRS{supports_autosuspend}=="1"

 looking at parent device '/devices/pci0000:00/0000:00:14.0/usb2/2-1':
   KERNELS=="2-1"
   SUBSYSTEMS=="usb"
   DRIVERS=="usb"
   ATTRS{authorized}=="1"
   ATTRS{avoid_reset_quirk}=="0"
   ATTRS{bConfigurationValue}=="1"
   ATTRS{bDeviceClass}=="ef"
   ATTRS{bDeviceProtocol}=="01"
   ATTRS{bDeviceSubClass}=="02"
   ATTRS{bMaxPacketSize0}=="9"
   ATTRS{bMaxPower}=="440mA"
   ATTRS{bNumConfigurations}=="1"
   ATTRS{bNumInterfaces}==" 5"
   ATTRS{bcdDevice}=="508f"
   ATTRS{bmAttributes}=="c0"
   ATTRS{busnum}=="2"
   ATTRS{configuration}==""
   ATTRS{devnum}=="2"
   ATTRS{devpath}=="1"
   ATTRS{idProduct}=="0ad3"
   ATTRS{idVendor}=="8086"
   ATTRS{ltm_capable}=="no"
   ATTRS{manufacturer}=="Intel(R) RealSense(TM) 415"
   ATTRS{maxchild}=="0"
   ATTRS{product}=="Intel(R) RealSense(TM) 415"
   ATTRS{quirks}=="0x0"
   ATTRS{removable}=="removable"
   ATTRS{serial}=="736613021813"
   ATTRS{speed}=="5000"
   ATTRS{urbnum}=="56"
   ATTRS{version}==" 3.10"

 looking at parent device '/devices/pci0000:00/0000:00:14.0/usb2':
   KERNELS=="usb2"
   SUBSYSTEMS=="usb"
   DRIVERS=="usb"
   ATTRS{authorized}=="1"
   ATTRS{authorized_default}=="1"
   ATTRS{avoid_reset_quirk}=="0"
   ATTRS{bConfigurationValue}=="1"
   ATTRS{bDeviceClass}=="09"
   ATTRS{bDeviceProtocol}=="03"
   ATTRS{bDeviceSubClass}=="00"
   ATTRS{bMaxPacketSize0}=="9"
   ATTRS{bMaxPower}=="0mA"
   ATTRS{bNumConfigurations}=="1"
   ATTRS{bNumInterfaces}==" 1"
   ATTRS{bcdDevice}=="0415"
   ATTRS{bmAttributes}=="e0"
   ATTRS{busnum}=="2"
   ATTRS{configuration}==""
   ATTRS{devnum}=="1"
   ATTRS{devpath}=="0"
   ATTRS{idProduct}=="0003"
   ATTRS{idVendor}=="1d6b"
   ATTRS{interface_authorized_default}=="1"
   ATTRS{ltm_capable}=="yes"
   ATTRS{manufacturer}=="Linux 4.15.0-36-generic xhci-hcd"
   ATTRS{maxchild}=="10"
   ATTRS{product}=="xHCI Host Controller"
   ATTRS{quirks}=="0x0"
   ATTRS{removable}=="unknown"
   ATTRS{serial}=="0000:00:14.0"
   ATTRS{speed}=="5000"
   ATTRS{urbnum}=="101"
   ATTRS{version}==" 3.00"

 looking at parent device '/devices/pci0000:00/0000:00:14.0':
   KERNELS=="0000:00:14.0"
   SUBSYSTEMS=="pci"
   DRIVERS=="xhci_hcd"
   ATTRS{broken_parity_status}=="0"
   ATTRS{class}=="0x0c0330"
   ATTRS{consistent_dma_mask_bits}=="64"
   ATTRS{d3cold_allowed}=="1"
   ATTRS{dbc}=="disabled"
   ATTRS{device}=="0xa2af"
   ATTRS{dma_mask_bits}=="64"
   ATTRS{driver_override}=="(null)"
   ATTRS{enable}=="1"
   ATTRS{irq}=="123"
   ATTRS{local_cpulist}=="0-3"
   ATTRS{local_cpus}=="f"
   ATTRS{msi_bus}=="1"
   ATTRS{numa_node}=="-1"
   ATTRS{revision}=="0x00"
   ATTRS{subsystem_device}=="0x310c"
   ATTRS{subsystem_vendor}=="0x17aa"
   ATTRS{vendor}=="0x8086"

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

輸出sudo udevadm info -ap /devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.3/video4linux/video2

 looking at device '/devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.3/video4linux/video2':
   KERNEL=="video2"
   SUBSYSTEM=="video4linux"
   DRIVER==""
   ATTR{dev_debug}=="0"
   ATTR{index}=="0"
   ATTR{name}=="Intel(R) RealSense(TM) 415: Int"

 looking at parent device '/devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.3':
   KERNELS=="2-1:1.3"
   SUBSYSTEMS=="usb"
   DRIVERS=="uvcvideo"
   ATTRS{authorized}=="1"
   ATTRS{bAlternateSetting}==" 0"
   ATTRS{bInterfaceClass}=="0e"
   ATTRS{bInterfaceNumber}=="03"
   ATTRS{bInterfaceProtocol}=="00"
   ATTRS{bInterfaceSubClass}=="01"
   ATTRS{bNumEndpoints}=="00"
   ATTRS{iad_bFirstInterface}=="03"
   ATTRS{iad_bFunctionClass}=="0e"
   ATTRS{iad_bFunctionProtocol}=="00"
   ATTRS{iad_bFunctionSubClass}=="03"
   ATTRS{iad_bInterfaceCount}=="02"
   ATTRS{interface}=="Intel(R) RealSense(TM) 415 RGB"
   ATTRS{supports_autosuspend}=="1"

 looking at parent device '/devices/pci0000:00/0000:00:14.0/usb2/2-1':
   KERNELS=="2-1"
   SUBSYSTEMS=="usb"
   DRIVERS=="usb"
   ATTRS{authorized}=="1"
   ATTRS{avoid_reset_quirk}=="0"
   ATTRS{bConfigurationValue}=="1"
   ATTRS{bDeviceClass}=="ef"
   ATTRS{bDeviceProtocol}=="01"
   ATTRS{bDeviceSubClass}=="02"
   ATTRS{bMaxPacketSize0}=="9"
   ATTRS{bMaxPower}=="440mA"
   ATTRS{bNumConfigurations}=="1"
   ATTRS{bNumInterfaces}==" 5"
   ATTRS{bcdDevice}=="508f"
   ATTRS{bmAttributes}=="c0"
   ATTRS{busnum}=="2"
   ATTRS{configuration}==""
   ATTRS{devnum}=="2"
   ATTRS{devpath}=="1"
   ATTRS{idProduct}=="0ad3"
   ATTRS{idVendor}=="8086"
   ATTRS{ltm_capable}=="no"
   ATTRS{manufacturer}=="Intel(R) RealSense(TM) 415"
   ATTRS{maxchild}=="0"
   ATTRS{product}=="Intel(R) RealSense(TM) 415"
   ATTRS{quirks}=="0x0"
   ATTRS{removable}=="removable"
   ATTRS{serial}=="736613021813"
   ATTRS{speed}=="5000"
   ATTRS{urbnum}=="56"
   ATTRS{version}==" 3.10"

 looking at parent device '/devices/pci0000:00/0000:00:14.0/usb2':
   KERNELS=="usb2"
   SUBSYSTEMS=="usb"
   DRIVERS=="usb"
   ATTRS{authorized}=="1"
   ATTRS{authorized_default}=="1"
   ATTRS{avoid_reset_quirk}=="0"
   ATTRS{bConfigurationValue}=="1"
   ATTRS{bDeviceClass}=="09"
   ATTRS{bDeviceProtocol}=="03"
   ATTRS{bDeviceSubClass}=="00"
   ATTRS{bMaxPacketSize0}=="9"
   ATTRS{bMaxPower}=="0mA"
   ATTRS{bNumConfigurations}=="1"
   ATTRS{bNumInterfaces}==" 1"
   ATTRS{bcdDevice}=="0415"
   ATTRS{bmAttributes}=="e0"
   ATTRS{busnum}=="2"
   ATTRS{configuration}==""
   ATTRS{devnum}=="1"
   ATTRS{devpath}=="0"
   ATTRS{idProduct}=="0003"
   ATTRS{idVendor}=="1d6b"
   ATTRS{interface_authorized_default}=="1"
   ATTRS{ltm_capable}=="yes"
   ATTRS{manufacturer}=="Linux 4.15.0-36-generic xhci-hcd"
   ATTRS{maxchild}=="10"
   ATTRS{product}=="xHCI Host Controller"
   ATTRS{quirks}=="0x0"
   ATTRS{removable}=="unknown"
   ATTRS{serial}=="0000:00:14.0"
   ATTRS{speed}=="5000"
   ATTRS{urbnum}=="101"
   ATTRS{version}==" 3.00"

 looking at parent device '/devices/pci0000:00/0000:00:14.0':
   KERNELS=="0000:00:14.0"
   SUBSYSTEMS=="pci"
   DRIVERS=="xhci_hcd"
   ATTRS{broken_parity_status}=="0"
   ATTRS{class}=="0x0c0330"
   ATTRS{consistent_dma_mask_bits}=="64"
   ATTRS{d3cold_allowed}=="1"
   ATTRS{dbc}=="disabled"
   ATTRS{device}=="0xa2af"
   ATTRS{dma_mask_bits}=="64"
   ATTRS{driver_override}=="(null)"
   ATTRS{enable}=="1"
   ATTRS{irq}=="123"
   ATTRS{local_cpulist}=="0-3"
   ATTRS{local_cpus}=="f"
   ATTRS{msi_bus}=="1"
   ATTRS{numa_node}=="-1"
   ATTRS{revision}=="0x00"
   ATTRS{subsystem_device}=="0x310c"
   ATTRS{subsystem_vendor}=="0x17aa"
   ATTRS{vendor}=="0x8086"

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

這裡似乎有一個區別因素:

ATTRS{interface}=="Intel(R) RealSense(TM) 415 Depth"

對比

ATTRS{interface}=="Intel(R) RealSense(TM) 415 RGB"

要區分多個攝像頭,您可能需要這個:

ATTRS{serial}=="736613021813"

udev(7)手冊頁說:

如果在單個規則中指定了與父設備匹配的多個密鑰,則所有這些密鑰必須在同一個父設備上匹配。

使介面可區分的屬性在父塊中,使相機可區分的屬性在祖父塊中。因此,您必須使用多個規則行。

對於每個攝像頭,應該有一組這樣的規則:

SUBSYSTEM=="video4linux", ATTRS{serial}!="736613021813", GOTO="not_first_camera"
SUBSYSTEM=="video4linux", KERNEL=="video*", ATTRS{interface}=="Intel(R) RealSense(TM) 415 Depth", SYMLINK+="cam1_depth"
SUBSYSTEM=="video4linux", KERNEL=="video*", ATTRS{interface}=="Intel(R) RealSense(TM) 415 RGB", SYMLINK+="cam1_rgb"
LABEL="not_first_camera"

如果相機序列號不匹配,第一個規則會繞過以下兩個規則。這樣,在第一條規則和與之關聯的 LABEL 之間,我們可以確定我們正在談論的相機的身份,並可以專注於區分介面。

每個塊都應該有一個唯一的LABEL=行和一個GOTO=與唯一標籤匹配的語句。當然,您可以根據需要命名SYMLINKs。

引用自:https://unix.stackexchange.com/questions/479302