Add tun to static device list in hardware manager (#5547)

Some devices are provided by kernel modules which potentially get loaded
later at startup. Those are not listed by udev, and hence add-ons do
not get permissions for these types of devices as long as the kernel
module is not loaded.

Typically, such devices are created by the kmod-static-nodes.service
systemd service. Ideally, we would read the output of that service and
add those specifically. However, there are very few devices which
use static nodes, and we actually only really interested in tun. So
let's simply add this static node in case udev does not list it already.
This commit is contained in:
Stefan Agner 2025-01-15 09:56:32 +01:00 committed by GitHub
parent 6183b9719c
commit d4c047bd01
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -16,6 +16,33 @@ from .policy import HwPolicy
_LOGGER: logging.Logger = logging.getLogger(__name__)
# Some device nodes get created system on startup by kmod-static-nodes.service,
# which in turn uses /usr/bin/kmod to get a list of static device nodes which
# are provided by kernel modules. These type of devices are not listed by udev
# and hence not listed through pyudev. However, on first access the kernel
# module is loaded automatically.
# Which nodes are exposed by module is system specific, so ideally Supervisor
# should read the output of kmod (e.g. /run/tmpfiles.d/static-nodes.conf). But
# this seems a bit overkill, since we are currently only interested in tun.
_STATIC_NODES: list[Device] = [
Device(
"tun",
Path("/dev/net/tun"),
Path("/sys/devices/virtual/misc/tun"),
"misc",
None,
[],
{
"DEVNAME": "/dev/net/tun",
"DEVPATH": "/devices/virtual/misc/tun",
"MAJOR": "10",
"MINOR": "200",
"SUBSYSTEM": "misc",
},
[],
)
]
class HardwareManager(CoreSysAttributes):
"""Hardware manager for supervisor."""
@ -114,6 +141,11 @@ class HardwareManager(CoreSysAttributes):
continue
self._devices[device.sys_name] = Device.import_udev(device)
# Add static nodes if not found through udev (e.g. module not yet loaded)
for device in _STATIC_NODES:
if device.name not in self._devices:
self._devices[device.name] = device
async def load(self) -> None:
"""Load hardware backend."""
self._import_devices()