了解 libusb 中的 udev 规则和权限

了解 libusb 中的 udev 规则和权限

我的扫描仪有问题。 Xsane 仅以 root 身份运行。作为普通用户使用它没有找到任何设备。将用户添加到组中sanedscanner没有帮助。

最后我通过改变解决了问题

# 'libusb' device nodes
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", MODE="0664"

# 'libusb' device nodes
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", MODE="0666"

/lib/udev/rules.d/50-udev-default.rules

但是我不明白为什么这有效以及它是否有任何负面副作用。我猜想这会给任何 USB 设备上的所有用户提供写入权限,但我不知道这是否正确、为什么正确以及为什么这可以解决扫描仪问题。

谁能详细解释一下为什么它有效以及它是否有任何副作用。

我的系统是:ubuntu 12.04,扫描仪是从存储库安装的HP PSC 1200 all in one设备。hplip

答案1

libusb旨在允许 USB 设备的用户空间驱动程序:换句话说,它允许应用程序向libusb设备发送本身不理解的命令。

因此,libusb必须将从计算机传递到 USB 设备的任何数据视为写入操作。这甚至包括琐碎的写入,例如向扫描仪发送命令来描述其扫描功能。

对设备的只读访问仅libusb适用于会自发向计算机发送数据的设备,例如键盘或鼠标。

答案2

看起来 Udev(位于 man 中)在插入 USB 设备等动态设备时对其进行管理。然后它会在 /dev 中的某处实例化它们。 (就像我的例子中的 /dev/bus/usb/002 一样。)这个 /dev 节点必须有一些权限,Udev 从 /lib/udev/rules.d/ 中的文件获取权限,有一些神秘的语法与设备到条目。

在这种情况下,来自 usb 子系统的任何 usb_device 类型的文件都会获得指定的文件模式。(标准权限,664 为 rw-rw-r--,666 为 rw-rw-rw-。)因此,您向所有 usb 设备授予了所有各种写入权限。如果您不信任所有用户,这听起来不是一件好事。如果您是唯一的用户,您可能可以相信自己。Libusb 似乎需要对 usb 设备节点的写入权限才能执行其操作,并且如果不需要,它拒绝执行任何操作。这听起来不太对劲,因为我只是想从设备读取。

权限可以更具体,您可以通过 USB 供应商 (VID) 和产品 ID (PID) 等指定设备。因此,可以创建一个仅适用于您的扫描仪的文件,并为所有其他 USB 设备保留默认权限。有一个关于 Udev 的页面:https://wiki.archlinux.org/index.php/udev这看起来对这一切很有用。如果您创建一个以较高数字开头的文件,例如“60-my-usb-scanner.rules”(较高的数字优先),并且有一个列出您的扫描仪的规则,例如:

SUBSYSTEM=="usb", ATTRS{idVendor}=="f1e2", ATTRS{idProduct}=="1f2e", MODE="0666"

这应该只是设置指定设备的权限(VID = 0xF1E2,PID = 0x1F2E,注意:对 udev 使用小写十六进制数字)。然后,您可以通过执行以下命令让 Udev 注意此更改:

udevadm control --reload-rules

答案3

只是分享一个对我有用的答案。

操作系统:乌布努图 20.04

要查找可用于过滤设备的相应属性,请首先使用lsusb查找您的设备/dev/bus/usb

....
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 003: ID 13d3:56d5 IMC Networks Integrated Camera
Bus 003 Device 002: ID 0fc5:b080 Delcom Engineering USB FS IO # <-- My device
...

然后,使用命令udevadm info -a -n /dev/bus/usb/<bus_num>/<device_num>(在我的例子中udevadm info -a -n /dev/bus/usb/003/002)获取udev规则密钥表。由于该表将遍历父设备,因此第一个设备应该是您想要的设备。

looking at device '/devices/pci0000:00/0000:00:08.1/0000:04:00.4/usb3/3-2':
KERNEL=="3-2"
SUBSYSTEM=="usb"
DRIVER=="usb"
ATTR{product}=="USB FS IO"
ATTR{bNumInterfaces}==" 1"
ATTR{bDeviceProtocol}=="00"
ATTR{configuration}==""
ATTR{bMaxPower}=="250mA"
ATTR{version}==" 2.00"
ATTR{bmAttributes}=="a0"
ATTR{maxchild}=="0"
ATTR{idVendor}=="0fc5"
ATTR{avoid_reset_quirk}=="0"
ATTR{idProduct}=="b080"
ATTR{devpath}=="2"
ATTR{tx_lanes}=="1"
ATTR{manufacturer}=="Delcom Products Inc."   # <--- help me id the device
...

请记住,要设置规则,您需要使用此处提供的确切格式,即,如果是SUBSYSTEM=="usb"and ATTR{idVendor},则它应该是文件中的格式.rules,而不是SUBSYSTEMS=="usb"and ATTRS{idVendor}

最后,使用 . 创建您自己的 udev 规则sudo <editor_you_like> /etc/udev/rules.d/<order_to_be_executed>-<hint_name>.rules。对我来说,我使用它是99-Delcom_dev.rules因为我希望它比其他规则更晚执行,并且可以轻松提醒我这个规则是关于什么的。在规则文件中写入如下内容:

SUBSYSTEM=="usb", ATTR{idVendor}=="0fc5", ATTR{idProduct}=="b080", MODE="0666"

相关内容