如何创建一个udev规则来禁用其中一个Android设备?
我有一部HTC Android手机。
每次我将它连接到计算机时,我都会收到一条消息:
Android Phone: Could not open MTP device "[usb:002,003]"
数字可能不同。 但手机连接正确。
usb-devices
输出
T: Bus=02 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 28 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=0bb4 ProdID=0f91 Rev=02.33 S: Manufacturer=HTC S: Product=Android Phone S: SerialNumber=FA41BWB00560 C: #Ifs= 2 Cfg#= 1 Atr=c0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 3 Cls=06(still) Sub=01 Prot=01 Driver=usbfs I: If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=00 Driver=(none)
lsusb
Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 002 Device 002: ID 048d:1336 Integrated Technology Express, Inc. SD/MMC Cardreader Bus 002 Device 004: ID 0bb4:0f91 HTC (High Tech Computer Corp.) Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 001 Device 002: ID 04b8:0898 Seiko Epson Corp. Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 004 Device 002: ID 046d:c05a Logitech, Inc. M90/M100 Optical Mouse Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
lsusb -t
/: Bus 07.Port 1: Dev 1, Class=root_hub, Driver=ohci-pci/2p, 12M /: Bus 06.Port 1: Dev 1, Class=root_hub, Driver=ohci-pci/3p, 12M /: Bus 05.Port 1: Dev 1, Class=root_hub, Driver=ohci-pci/3p, 12M /: Bus 04.Port 1: Dev 1, Class=root_hub, Driver=ohci-pci/3p, 12M |__ Port 1: Dev 2, If 0, Class=Human Interface Device, Driver=usbhid, 1.5M /: Bus 03.Port 1: Dev 1, Class=root_hub, Driver=ohci-pci/3p, 12M /: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/6p, 480M |__ Port 1: Dev 4, If 0, Class=Imaging, Driver=usbfs, 480M |__ Port 1: Dev 4, If 1, Class=Vendor Specific Class, Driver=, 480M |__ Port 3: Dev 2, If 0, Class=Mass Storage, Driver=usb-storage, 480M /: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/6p, 480M |__ Port 2: Dev 2, If 0, Class=Vendor Specific Class, Driver=, 480M |__ Port 2: Dev 2, If 1, Class=Printer, Driver=usblp, 480M |__ Port 2: Dev 2, If 2, Class=Mass Storage, Driver=usb-storage, 480M
udevadm info -q all -n /dev/bus/usb/002/004
P: /devices/pci0000:00/0000:00:13.2/usb2/2-1 N: bus/usb/002/004 S: libmtp-2-1 E: BUSNUM=002 E: COLORD_DEVICE=1 E: COLORD_KIND=camera E: DEVLINKS=/dev/libmtp-2-1 E: DEVNAME=/dev/bus/usb/002/004 E: DEVNUM=004 E: DEVPATH=/devices/pci0000:00/0000:00:13.2/usb2/2-1 E: DEVTYPE=usb_device E: DRIVER=usb E: GPHOTO2_DRIVER=PTP E: ID_BUS=usb E: ID_FOR_SEAT=usb-pci-0000_00_13_2-usb-0_1 E: ID_GPHOTO2=1 E: ID_MEDIA_PLAYER=1 E: ID_MODEL=Android_Phone E: ID_MODEL_ENC=Android\x20Phone E: ID_MODEL_ID=0f91 E: ID_MTP_DEVICE=1 E: ID_PATH=pci-0000:00:13.2-usb-0:1 E: ID_PATH_TAG=pci-0000_00_13_2-usb-0_1 E: ID_REVISION=0233 E: ID_SERIAL=HTC_Android_Phone_FA41BWB00560 E: ID_SERIAL_SHORT=FA41BWB00560 E: ID_USB_INTERFACES=:060101:ffff00: E: ID_VENDOR=HTC E: ID_VENDOR_ENC=HTC E: ID_VENDOR_FROM_DATABASE=HTC (High Tech Computer Corp.) E: ID_VENDOR_ID=0bb4 E: MAJOR=189 E: MINOR=131 E: PRODUCT=bb4/f91/233 E: SUBSYSTEM=usb E: TAGS=:seat:uaccess: E: TYPE=0/0/0 E: USEC_INITIALIZED=611981507
dmesg
[ 40.632283] usb 2-1: new high-speed USB device number 3 using ehci-pci [ 40.765458] usb 2-1: New USB device found, idVendor=0bb4, idProduct=0f91 [ 40.765469] usb 2-1: New USB device strings: Mfr=2, Product=3, SerialNumber=4 [ 40.765475] usb 2-1: Product: Android Phone [ 40.765480] usb 2-1: Manufacturer: HTC [ 40.765485] usb 2-1: SerialNumber: FA41BWB00560 [ 40.766646] usb-storage 2-1:1.1: USB Mass Storage device detected [ 40.767102] scsi host10: usb-storage 2-1:1.1 [ 40.864690] usb 2-1: USB disconnect, device number 3 [ 41.613079] usb 2-1: new high-speed USB device number 4 using ehci-pci [ 41.746616] usb 2-1: New USB device found, idVendor=0bb4, idProduct=0f91 [ 41.746626] usb 2-1: New USB device strings: Mfr=2, Product=3, SerialNumber=4 [ 41.746633] usb 2-1: Product: Android Phone [ 41.746638] usb 2-1: Manufacturer: HTC [ 41.746643] usb 2-1: SerialNumber: FA41BWB00560 [ 101.942087] usb 2-1: reset high-speed USB device number 4 using ehci-pci
我还发现,在连接手机后的短时间内,会声明一个USB存储设备
I: If#= 0 Alt= 0 #EPs= 3 Cls=06(still) Sub=01 Prot=01 Driver=usbfs I: If#= 1 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage
然后断开连接,将类更改为ff
。
I: If#= 0 Alt= 0 #EPs= 3 Cls=06(still) Sub=01 Prot=01 Driver=usbfs I: If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=00 Driver=(none)
从dmesg
输出,很明显手机连接了两次。
- [40.632283]第一个连接为USB总线2 dev 3
- [40.864690]已断开连接
- [41.613079]第二个连接为USB总线2 dev 4
问题是:
-
两种电话连接模式都使用相同的属性
idProduct
/bcdDevice
/bcdDevice
。 -
libmtp udev规则仅使用
idProduct
/idProduct
来过滤设备以及非重要/公共属性ACTION!="add"
,ENV{MAJOR}!="?*"
和SUBSYSTEM=="usb"
-
libmtp udev规则使用
ATTR
(不是ATTRS
),它确实准确定位此设备节点/devices/pci0000:00/0000:00:13.2/usb2/2-1
。 所以我们不能使用interfaces节点细节,因为它们是这个节点的子节点。
要了解正在进行的操作,请使用udevadm monitor
。 仅查看没有详细信息的活动。
- 拔掉手机
- 打开终端并运行
udevadm monitor -u
,-u
仅显示UDEV事件(用于清洁输出) - 插上手机,等到事情稳定下来
- 按Ctrl + C停止监控
要获取详细信息(环境属性),请使用udevadm monitor -u -p
代替并比较该节点的输出:
-
UDEV [107.024195] add /devices/pci0000:00/0000:00:13.2/usb2/2-1 (usb)
-
UDEV [107.998137] add /devices/pci0000:00/0000:00:13.2/usb2/2-1 (usb)
注意ID_USB_INTERFACES
的区别
另一种更简洁的方法,使用udev规则只收集我们需要的东西:
-
在
LABEL="libmtp_usb_rules"
之后立即向/lib/udev/rules.d/69-libmtp.rules
添加规则:ATTR{idVendor}=="0bb4", ATTR{idProduct}=="0f91", RUN+="/bin/sh -c 'env >> /home/username/udev-phone-mtp_%E{SEQNUM}.log'"
-
重新加载规则
sudo udevadm control -R
-
重新插电话一次。
-
应该触发此规则两次。 比较该节点的输出:
diff udev-phone-mtp_*.log
应该带:(这只是有趣的部分)
< ID_USB_INTERFACES=:060101:080650: --- > ID_USB_INTERFACES=:060101:ffff00:
正是Pilot6(OP)能够在重新连接之前使用usb-devices
捕获它。
我建议在LABEL="libmtp_usb_rules"
之后将此规则添加到/lib/udev/rules.d/69-libmtp.rules
:
ATTR{idVendor}=="0bb4", ATTR{idProduct}=="0f91", ENV{ID_USB_INTERFACES}==":060101:080650:", GOTO="libmtp_rules_end"