mirror of
https://github.com/shenmintao/aic8800d80.git
synced 2026-11-10 16:49:17 +00:00
fix(udev): restrict mode switching to intended devices and events
Take the aic.rules portion of #129: restrict 1111:1111 switching to
88M80 USB devices, target the event's bus/device address, and eject only
whole disks on add. Add selection fixtures and document the product
restriction. Keep installer paths and existing firmware handling unchanged.
Co-authored-by: rtk94 <richardtknepp@gmail.com>
(cherry picked from commit e2c5835767)
This commit is contained in:
1 parent
20fb7181e6
commit
3a71c7188b
3 files changed
+89
-11
No files matched your search
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Check device/event selection using fixtures; does not switch real devices.
|
||||
|
||||
This models the basic equality/glob predicates used by aic.rules. Run
|
||||
udevadm verify separately to validate syntax with the real udev parser.
|
||||
"""
|
||||
|
||||
from fnmatch import fnmatchcase
|
||||
from pathlib import Path
|
||||
import re
|
||||
import unittest
|
||||
|
||||
|
||||
RULES = (Path(__file__).resolve().parents[2] / "aic.rules").read_text().splitlines()
|
||||
|
||||
|
||||
def matching_rules(device):
|
||||
result = []
|
||||
for rule in RULES:
|
||||
if not rule.strip() or rule.lstrip().startswith("#"):
|
||||
continue
|
||||
predicates = re.findall(r'([A-Z]+(?:\{[^}]+\})?)=="([^"]*)"', rule)
|
||||
if predicates and all(fnmatchcase(device.get(key, ""), value) for key, value in predicates):
|
||||
result.append(rule)
|
||||
return result
|
||||
|
||||
|
||||
class UdevTests(unittest.TestCase):
|
||||
def pandora(self, **changes):
|
||||
device = {"ACTION": "add", "SUBSYSTEM": "usb", "ENV{DEVTYPE}": "usb_device",
|
||||
"ATTR{idVendor}": "1111", "ATTR{idProduct}": "1111", "ATTR{product}": "88M80"}
|
||||
device.update(changes)
|
||||
return device
|
||||
|
||||
def test_88m80_uses_event_bus_and_device_numbers(self):
|
||||
for product in ("88M80", "88M80 USB WiFi"):
|
||||
with self.subTest(product=product):
|
||||
matches = matching_rules(self.pandora(**{"ATTR{product}": product}))
|
||||
self.assertEqual(len(matches), 1)
|
||||
# Both possible usb_modeswitch executable locations target this event's device.
|
||||
self.assertEqual(matches[0].count("-b $attr{busnum} -g $attr{devnum}"), 2)
|
||||
|
||||
def test_generic_1111_flash_disk_is_not_switched(self):
|
||||
for product in ("FLASH UDISK 2.30", "USB DISK", ""):
|
||||
with self.subTest(product=product):
|
||||
self.assertEqual(matching_rules(self.pandora(**{"ATTR{product}": product})), [])
|
||||
|
||||
def test_wrong_ids_interfaces_and_non_add_events_are_not_switched(self):
|
||||
for changes in ({"ACTION": "change"}, {"ACTION": "remove"},
|
||||
{"ENV{DEVTYPE}": "usb_interface"}, {"ATTR{idVendor}": "2222"},
|
||||
{"ATTR{idProduct}": "8d80"}):
|
||||
with self.subTest(changes=changes):
|
||||
self.assertEqual(matching_rules(self.pandora(**changes)), [])
|
||||
|
||||
def test_eject_only_on_add_of_a_whole_supported_disk(self):
|
||||
for product in ("5721", "5722", "5723", "5724", "5725", "5726", "5727", "572a", "572c", "572f"):
|
||||
disk = {"ACTION": "add", "SUBSYSTEM": "block", "ENV{DEVTYPE}": "disk", "KERNEL": "sdb",
|
||||
"ATTRS{idVendor}": "a69c", "ATTRS{idProduct}": product}
|
||||
with self.subTest(product=product):
|
||||
matches = matching_rules(disk)
|
||||
self.assertEqual(len(matches), 1)
|
||||
self.assertIn('/usr/bin/eject /dev/%k', matches[0])
|
||||
for changes in ({"ACTION": "change"}, {"ACTION": "remove"},
|
||||
{"ENV{DEVTYPE}": "partition", "KERNEL": "sdb1"}):
|
||||
self.assertEqual(matching_rules(dict(disk, **changes)), [])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main(verbosity=2)
|
||||
Reference in new issue
Block a user