Linux device management is the unsung hero of every self-hosted infrastructure. When you plug in a USB drive, insert a PCIe card, or attach a network interface, the device manager is what creates the device nodes, sets permissions, and triggers the actions that make hardware usable. For self-hosted server administrators managing bare-metal infrastructure, homelab setups, or container hosts with GPU passthrough, choosing the right device management framework directly impacts system reliability, boot time, and device hot-plug behavior.
This guide compares three Linux device managers: systemd-udevd (the default on most modern distributions), eudev (the Gentoo fork focused on standalone operation), and mdev (the minimalist BusyBox-based manager for embedded and container environments).
Understanding Linux Device Management
The Linux kernel exposes hardware through the sysfs filesystem (/sys) and creates device nodes in devtmpfs (/dev). But the kernel doesn’t decide what permissions those nodes should have, what symlinks to create, or what actions to trigger when devices appear. That’s the job of the userspace device manager.
Device managers watch the kernel’s uevent netlink socket for hardware events and respond by:
- Creating or removing device nodes in
/dev - Setting ownership and permissions on device nodes
- Creating persistent symlinks (e.g.,
/dev/disk/by-id/) - Loading kernel modules on demand
- Running custom scripts or systemd units when devices appear
- Managing network interface naming
The three tools compared here approach this problem with very different design philosophies: full-featured integration, distribution independence, and minimal resource usage.
Tool Comparison at a Glance
| Feature | systemd-udevd | eudev | mdev |
|---|---|---|---|
| Origin | systemd project | Gentoo (forked from udev) | BusyBox project |
| Package Size | ~2 MB (with systemd) | ~1.5 MB | ~20 KB |
| Rule Syntax | Full udev rules | Full udev rules (compatible) | Simplified regex-based |
| Persistent Naming | Yes (extensive) | Yes (extensive) | No (basic only) |
| Hotplug Support | Full | Full | Basic |
| Dependency | systemd (optional) | None (standalone) | BusyBox only |
| Scripting | RUN+=, systemd units | RUN+=, scripts | Shell commands in config |
| Network Interface Naming | Predictable names | Predictable names | Kernel default naming |
| Best For | Desktop/server distros | systemd-free servers | Embedded, containers, initramfs |
| GitHub | systemd/systemd (10,800+ ★) | eudev-project/eudev (567 ★) | mirror/busybox (9,700+ ★) |
| Last Updated | Active (2026) | 2024-09 | Active (in BusyBox) |
systemd-udevd: The Full-Featured Default
systemd-udevd is the device manager shipped with systemd and used by default on virtually every major Linux distribution — Fedora, Ubuntu, Debian, Arch Linux, and RHEL derivatives. It’s deeply integrated with the rest of the systemd ecosystem, providing device-triggered service activation, predictable network interface naming, and extensive persistent naming for storage devices.
Key Features
| |
Persistent Storage Naming
One of udev’s most valuable features is creating stable symlinks for storage devices:
| |
GPU Passthrough Rules for Virtualization
For self-hosted virtualization with VFIO GPU passthrough, udev rules are essential:
| |
Docker Compose for Monitoring
| |
eudev: The Standalone Alternative
eudev (experimental udev) was forked by Gentoo Linux from the udev codebase when udev became tightly coupled with systemd. It maintains full compatibility with udev rules while operating independently of systemd. This makes it the go-to choice for servers running alternative init systems like OpenRC, runit, or s6.
When to Choose eudev
- Running Gentoo, Alpine Linux, or Void Linux
- Using OpenRC, runit, s6, or another non-systemd init
- Wanting udev functionality without pulling in systemd dependencies
- Building custom Linux images where minimal dependency trees matter
Rule Compatibility
eudev uses the exact same rule syntax as systemd-udevd:
| |
Building and Deploying
| |
mdev: The Minimalist Approach
mdev is BusyBox’s device manager — a tiny, regex-based alternative that handles the essential device management tasks with a fraction of the code. It’s designed for embedded systems, initramfs environments, and container runtimes where systemd’s overhead is unacceptable.
Configuration
mdev uses a simple configuration file format:
| |
Command Execution
Unlike udev’s rich RUN+= syntax, mdev uses a simpler approach:
| |
Use Cases
mdev shines in environments where resources are constrained:
- Initramfs: Early boot device management before the real root is mounted
- Containers: Minimal device node creation without systemd overhead
- Embedded devices: Routers, IoT gateways, and single-board computers
- Rescue systems: Live USB environments where every megabyte counts
Why Self-Host with Proper Device Management?
For self-hosted infrastructure, reliable device management is foundational:
Hardware Passthrough: GPU passthrough for virtual machines, USB device assignment to containers, and PCIe SR-IOV all depend on udev rules to bind devices to the correct drivers at boot time. Without proper device management, VFIO bindings fail and virtual machines can’t access hardware.
Storage Reliability: Persistent device naming (/dev/disk/by-id/) prevents data corruption when disk ordering changes. Without it, a drive added to the system could shift device node assignments, causing filesystems to mount on the wrong devices.
Automated Device Actions: Self-hosted servers benefit from automatic responses to hardware events — mounting backup drives when they’re connected, starting services when USB dongles are inserted, or isolating network interfaces when specific adapters appear.
For related reading on Linux device isolation, see our Linux PID namespace isolation guide. For hardware passthrough configurations, check our Linux IOMMU VFIO GPU passthrough guide.
Choosing the Right Device Manager
| Scenario | Recommended | Reason |
|---|---|---|
| Standard server/desktop | systemd-udevd | Distribution default, full features |
| Non-systemd server | eudev | Full udev compatibility, no systemd |
| Container/VM base image | mdev | Minimal footprint, adequate for containers |
| Embedded/IoT device | mdev | Tiny size, BusyBox integration |
| Initramfs/rescue | mdev | Already in BusyBox, fast boot |
| GPU passthrough host | systemd-udevd | Rich rule syntax, systemd integration |
| OpenRC-based server | eudev | Native OpenRC support |
Security Considerations
- Device node permissions: Ensure sensitive devices (
/dev/mem,/dev/kmem) are restricted to root only - RUN rule safety: udev RUN rules execute as root — validate scripts before deploying
- Symlink conflicts: Custom rules should use unique symlink paths to avoid collisions
- Rule ordering: Rules are processed in filename order — prefix custom rules with high numbers (99-)
- Audit device access: Monitor
/devpermissions changes for unauthorized modifications
FAQ
What is the difference between udev, systemd-udevd, and eudev?
udev is the original Linux device manager. systemd-udevd is the version integrated into the systemd project — it’s the default on most modern distributions. eudev is a Gentoo fork that maintains udev functionality while removing systemd dependencies. All three use the same rule syntax, so rules written for one generally work on all three.
Can I switch from systemd-udevd to eudev?
Yes, on distributions that support it. Gentoo and Alpine Linux use eudev by default. On systemd-based distributions, switching requires replacing the systemd-udev package and adjusting the init configuration. The rule files in /etc/udev/rules.d/ are compatible, so your custom rules will carry over.
When should I use mdev instead of udev?
Use mdev when you need minimal resource usage — in containers, initramfs environments, embedded devices, or rescue systems. mdev handles basic device node creation and permission setting but lacks persistent naming, complex rule matching, and systemd integration. If you need /dev/disk/by-id/ symlinks or network interface naming, you need udev or eudev.
How do I create a persistent symlink for a USB device?
First, identify the device’s attributes:
| |
Then create a rule:
| |
Reload rules: udevadm control --reload && udevadm trigger
Why did my network interface name change after upgrading?
Modern udev implementations use “predictable network interface names” based on firmware, topology, and MAC address (e.g., enp3s0 instead of eth0). If you prefer traditional naming, you can disable predictable names by creating /etc/udev/rules.d/80-net-setup-link.rules with:
| |
Or add net.ifnames=0 to your kernel boot parameters.
Does mdev support hotplugging?
mdev supports basic hotplug detection through the kernel’s hotplug mechanism. When a device is added or removed, mdev creates or removes the corresponding device node. However, it doesn’t support the rich event handling of udev — no property-based matching, no complex rule conditions, and no integration with service managers. For most embedded and container use cases, mdev’s hotplug support is sufficient.