Recent from talks
Nothing was collected or created yet.
This article's lead section may be too short to adequately summarize the key points. (November 2014) |
| udev | |
|---|---|
| Developers | Greg Kroah-Hartman and Kay Sievers |
| Initial release | November 2003 |
| Stable release | 258.1[1]
/ 13 October 2025 |
| Repository | |
| Written in | C |
| Operating system | Linux |
| Type | Device node |
| License | GPLv2 |
| Website | Official website |
udev (userspace /dev) is a device manager for the Linux kernel. As the successor of devfsd and hotplug, udev primarily manages device nodes in the /dev directory. At the same time, udev also handles all user space events raised when hardware devices are added into the system or removed from it, including firmware loading as required by certain devices. udev was developed by Greg Kroah-Hartman and Kay Sievers, with much help from Dan Stekloff, among others.
Rationale
[edit]It is an operating system's kernel that is responsible for providing an abstract interface of the hardware to the rest of the software. Being a monolithic kernel, the Linux kernel does exactly that: device drivers are part of the Linux kernel, and make up more than half of its source code.[2] Hardware can be accessed through system calls or over their device nodes.
To be able to deal with peripheral devices that are hotplug-capable in a user-friendly way, a part of handling all of these hotplug-capable hardware devices was handed over from the kernel to a daemon running in user-space. Running in user space serves security and stability purposes.
Design
[edit]Device drivers are part of the Linux kernel, in which their primary functions include device discovery, detecting device state changes, and similar low-level hardware functions. After loading a device driver into memory from the kernel, detected events are sent out to the userspace daemon udevd. It is the device manager, udevd, that catches all of these events and then decides what shall happen next. For this, udevd has a very comprehensive set of configuration files, which can all be adjusted by the computer administrator, according to their needs.
- In case a new storage device is connected over USB, udevd is notified by the kernel and itself notifies the udisksd-daemon. That daemon could then mount the file systems.
- In case a new Ethernet cable is plugged into the Ethernet NIC, udevd is notified by the kernel and itself notifies the NetworkManager-daemon. The NetworkManager-daemon could start dhclient for that NIC, or configure according to some manual configuration.
The complexity of doing so forced application authors to re-implement hardware support logic. Some hardware devices also required privileged helper programs to prepare them for use. These often have to be invoked in ways that could be awkward to express with the Unix permissions model (for example, allowing users to join wireless networks only if they are logged into the video console). Application authors resorted to using setuid binaries or run service daemons to provide their own access control and privilege separation, potentially introducing security holes each time.[3]
HAL was created to deal with these challenges, but is now deprecated in most Linux distributions, its functionality being replaced by udevd.
Overview
[edit]Unlike traditional Unix systems, where the device nodes in the /dev directory have been a static set of files, the Linux udev device manager dynamically provides only the nodes for the devices actually present on a system. Although devfs used to provide similar functionality, Greg Kroah-Hartman cited a number of reasons[4] for preferring udev over devfs:
- udev supports persistent device naming, which does not depend on, for example, the order in which the devices are plugged into the system. The default udev setup provides persistent names for storage devices. Any hard disk is recognized by its unique filesystem id, the name of the disk and the physical location on the hardware it is connected to.
- udev executes entirely in user space, as opposed to devfs's kernel space. One consequence is that udev moved the naming policy out of the kernel and can run arbitrary programs to compose a name for the device from the device's properties, before the node is created; there, the whole process is also interruptible and it runs with a lower priority.
The udev, as a whole, is divided into three parts:
- Library libudev that allows access to device information; it was incorporated into the systemd 183 software bundle.[5]
- User space daemon udevd that manages the virtual /dev.
- Administrative command-line utility udevadm for diagnostics.
The system gets calls from the kernel via netlink socket. Earlier versions used hotplug, adding a link to themselves in /etc/hotplug.d/default with this purpose.
Operation
[edit]
udev is a generic device manager running as a daemon on a Linux system and listening (via a netlink socket) to uevents the kernel sends out if a new device is initialized or a device is removed from the system. The udev package comes with an extensive set of rules that match against exported values of the event and properties of the discovered device. A matching rule will possibly name and create a device node and run configured programs to set up and configure the device.
udev rules can match on properties like the kernel subsystem, the kernel device name, the physical location of the device, or properties like the device's serial number. Rules can also request information from external programs to name a device or specify a custom name that will always be the same, regardless of the order devices are discovered by the system.
In the past a common way to use udev on Linux systems was to let it send events through a socket to HAL, which would perform further device-specific actions. For example, HAL would notify other software running on the system that the new hardware had arrived by issuing a broadcast message on the D-Bus IPC system to all interested processes. In this way, desktops such as GNOME or K Desktop Environment 3 could start the file browser to browse the file systems of newly attached USB flash drives and SD cards.[6]
By the middle of 2011 HAL had been deprecated by most Linux distributions as well as by the KDE, GNOME[7] and Xfce[8] desktop environments, among others. The functionality previously embodied in HAL has been integrated into udev itself, or moved to separate software such as udisks and upower.
- udev provides low-level access to the linux device tree. Allows programs to enumerate devices and their properties and get notifications when devices come and go.
- dbus is a framework to allow programs to communicate with each other, securely, reliably, and with a high-level object-oriented programming interface.
- udisks (formerly known as DeviceKit-disks) is a daemon that sits on top of libudev and other kernel interfaces and provides a high-level interface to storage devices and is accessible via dbus to applications.
- upower (formerly known as DeviceKit-power) is a daemon that sits on top of libudev and other kernel interfaces and provides a high-level interface to power management and is accessible via dbus to applications.
- NetworkManager is a daemon that sits on top of libudev and other kernel interfaces (and a couple of other daemons) and provides a high-level interface to network configuration and setup and is accessible via dbus to apps.[9]
udev receives messages from the kernel, and passes them on to subsystem daemons such as Network Manager. Applications talk to Network Manager over D-Bus.
HAL is obsolete and only used by legacy code. Ubuntu 10.04 shipped without HAL. Initially a new daemon DeviceKit was planned to replace certain aspects of HAL, but in March 2009, DeviceKit was deprecated in favor of adding the same code to udev as a package: udev-extras, and some functions have now moved to udev proper.
History
[edit]udev was introduced in Linux 2.5. The Linux kernel version 2.6.13 introduced or updated a new version of the uevent interface. A system using a new version of udev will not boot with kernels older than 2.6.13 unless udev is disabled and a traditional /dev directory is used for device access.
In April 2012, udev's codebase was merged into the systemd source tree, making systemd 183 the first version to include udev.[5][10][11] In October 2012, Linus Torvalds criticized Kay Sievers's approach to udev maintenance and bug fixing related to firmware loading, stating:[12]
Yes, doing it in the kernel is "more robust". But don't play games, and stop the lying. It's more robust because we have maintainers that care, and because we know that regressions are not something we can play fast and loose with. If something breaks, and we don't know what the right fix for that breakage is, we revert the thing that broke. So yes, we're clearly better off doing it in the kernel. Not because firmware loading cannot be done in user space. But simply because udev maintenance since Greg gave it up has gone downhill.
In 2012, the Gentoo Linux project created a fork of systemd's udev codebase in order to avoid dependency on the systemd architecture. The resulting fork is called eudev and it makes udev functionality available without systemd. A stated goal of the project is to keep eudev independent of any Linux distribution or init system.[13] The Gentoo project describes eudev as follows:[14]
eudev is a fork of systemd-udev with the goal of obtaining better compatibility with existing software such as OpenRC and Upstart, older kernels, various toolchains and anything else required by users and various distributions.
On May 29, 2014, support for firmware loading through udev was dropped from systemd, as it has been decided that it is the kernel's task to load firmware.[15] Two days later, Lennart Poettering suggested this patch be postponed until kdbus starts to be utilized by udev; at that point, the plan was to switch udev to use kdbus as the underlying messaging system, and to get rid of the userspace-to-userspace netlink-based transport.[16]
References
[edit]- ^ "Release 258.1". 13 October 2025. Retrieved 21 October 2025.
- ^ Marti, Don (2 July 2007). "Are top Linux developers losing the will to code?". ComputerworldUK. Archived from the original on 19 July 2016. Retrieved 2 June 2024.
- ^ Pennington, Havoc (2003-07-10), Making Hardware Just Work
- ^ Greg Kroah-Hartman. "udev and devfs - The final word". Archived from the original (Plain text) on 2011-07-09. Retrieved 2008-01-24.
- ^ a b c "systemd/systemd". GitHub. Retrieved 2016-08-21.
- ^ "Dynamic Device Management in Udev" (PDF). Linux Magazine. 2006-10-01. Retrieved 2008-07-14.[permanent dead link]
- ^ "HALRemoval". 2011-06-28. Archived from the original on 2011-11-26. Retrieved 2011-09-13.
- ^ "Thunar-volman and the deprecation of HAL in Xfce". 2010-01-17. Archived from the original on 2017-12-26. Retrieved 2017-12-25.
- ^ Lennart Poettering (2010-04-25). "Relationship between udev, hal, Dbus and DeviceKit?".
- ^ Sievers, Kay (2012-04-03). "The future of the udev source tree". linux-hotplug (Mailing list). Retrieved 2013-05-22.
- ^ Sievers, Kay, "Commit importing udev into systemd", systemd, retrieved 2013-05-22
- ^ Linus Torvalds (2012-10-03). "Re: udev breakages". linux-kernel (Mailing list). Retrieved 2014-10-28.
- ^ "gentoo/eudev – README.md". GitHub. Retrieved 2017-12-25.
- ^ "Gentoo Linux Projects – Gentoo eudev project". Archived from the original on 2015-09-04. Retrieved 2017-12-25.
- ^ "[systemd-devel] [PATCH] Drop the udev firmware loader". 2014-05-29.
- ^ "[systemd-devel] [PATCH] Drop the udev firmware loader". 2014-05-31.
External links
[edit]Introduction
Definition and Purpose
Udev is a userspace device manager for the Linux kernel that dynamically creates, removes, and renames device nodes in the/dev directory in response to kernel events.[1] It operates as a daemon, listening for uevents from the kernel via a netlink socket, which notify the system of hardware additions, removals, or state changes.[7] This allows udev to populate /dev with appropriate device files, including major and minor numbers, based on device attributes exposed through sysfs.[7]
The primary purpose of udev is to provide a flexible, policy-driven solution for device detection, persistent naming, and event-triggered actions, succeeding earlier mechanisms like devfs and the hotplug subsystem.[7] Unlike devfs, which handled device management within the kernel and suffered from limitations such as inflexible naming policies and inability to customize behavior without kernel modifications, udev shifts this logic to userspace for greater configurability.[7] It also addresses issues in static /dev population methods, like race conditions during boot-time device enumeration and the need for predefined device files that may not match runtime hardware.[7]
By bridging the kernel's hardware abstraction layer—via uevents and sysfs—with userspace applications, udev enables advanced features such as automatic filesystem mounting, permission management for device nodes, and the creation of symbolic links for consistent device identification across reboots or hardware changes.[1] This userspace approach supports hotplugging of peripherals like USB devices and network interfaces, ensuring seamless integration without requiring kernel recompilation or static configurations.[8]
Key Components
The key components of udev form a cohesive system for managing device events in Linux userspace. At its core is the udevd daemon, which operates as a background process to handle incoming device notifications from the kernel.[1] Complementing this are the libudev library for programmatic access to device information and the udevadm utility for administrative tasks. These elements work together to ensure dynamic device management without kernel modifications.[9] The udevd daemon, implemented as the systemd-udevd.service unit, listens for uevents from the kernel—such as device additions, removals, or state changes—and processes them by matching against rules to manage device nodes, permissions, symlinks, and network interface names.[1] It maintains an internal database of device properties derived from sysfs attributes and uevent data, enabling efficient handling of hardware events.[1] Libudev serves as the programmatic interface to udev's functionality, offering an API for applications to enumerate, query, and monitor local devices through functions like udev_enumerate_new() for listing devices and udev_monitor_new_from_netlink() for event subscriptions. Although deprecated in favor of the sd-device API in modern systemd versions, libudev remains available for legacy compatibility and provides access to the udev database populated by udevd. The udevadm command-line tool facilitates interaction with udev for testing, debugging, and control, supporting operations such as querying device information with udevadm info, triggering kernel events via udevadm trigger, monitoring uevents with udevadm monitor, and simulating rule processing through udevadm test.[9] It interfaces directly with the udevd daemon and the udev database to inspect or manipulate runtime behavior without requiring root privileges for read-only queries.[9] Since its integration into systemd in 2012, these components—udevd, libudev, and udevadm—have been bundled as part of the systemd package, with udevd specifically renamed to systemd-udevd while preserving the traditional udev naming conventions for compatibility.[10] In operation, udevd relies internally on libudev for device object management during event processing, while udevadm leverages libudev to query the database and communicate with udevd; for instance, udevd receives kernel uevents via a netlink socket, processes them using libudev structures, and exposes results accessible via udevadm.[1] This modular design allows applications to interact seamlessly with hardware changes managed by the daemon.Design and Architecture
Core Principles
Udev operates entirely in userspace, enabling dynamic management of device nodes in the /dev directory without requiring kernel recompilation or modifications, which prevents kernel bloat and enhances system flexibility.[11] This design allows administrators to customize device handling through scripts and rules, leveraging kernel-provided interfaces like sysfs for device information and netlink sockets for event notifications, rather than embedding such logic directly into the kernel.[11] At its core, udev employs an event-driven model that responds to kernel-generated uevents in real time, ensuring immediate handling of device additions, removals, or changes without polling.[11] These events, triggered by hardware hotplug activities such as USB insertions or PCI card additions, allow udev to create or remove device files on demand, supporting efficient management of dynamic hardware environments.[11] As a successor to devfs and hotplug, this approach builds on prior mechanisms but shifts the complexity to userspace for greater maintainability.[11] Persistent device naming is a foundational principle, achieved by associating stable identifiers—such as serial numbers, bus topologies, or vendor-specific attributes—with device nodes to maintain consistent names across reboots and hardware reconfigurations.[11] For instance, a USB device might be named based on its unique serial number rather than volatile kernel-assigned addresses, preventing issues like shifting disk labels that could disrupt system operations.[11] Udev's architecture emphasizes modularity through the separation of concerns: device detection via sysfs, naming via configurable schemes, and action execution via external programs, promoting extensibility and integration with other tools.[11] This division allows independent development of components like libsysfs for querying device properties and namedev for applying naming rules, facilitating adaptations for diverse hardware without monolithic changes.[11] By focusing on hotplug events, udev efficiently populates /dev only as needed.Event Processing Mechanism
The event processing mechanism in udev begins with the Linux kernel's kobject subsystem, which generates uevents to notify userspace of device changes such as addition or removal. These uevents are transmitted from the kernel to userspace applications like the udev daemon (udevd) via netlink sockets, a bidirectional communication channel between kernel and user space. Specifically, the kernel invokes functions likekobject_uevent() to broadcast events with an action type, such as KOBJ_ADD for device addition or KOBJ_REMOVE for removal, encapsulating device information for further processing.[12]
Upon reception, the udevd daemon, managed by the systemd-udevd.service, listens on the netlink socket for these multicast uevents and enqueues them for handling. Uevents are formatted as environment variables, including key details like ACTION=add or ACTION=remove to indicate the event type, alongside attributes such as DEVPATH (the sysfs path), SUBSYSTEM (the device category), and KERNEL (the kernel name for the device). This queue management ensures concurrent events are processed asynchronously without blocking the kernel; events lacking interdependencies—such as those for unrelated devices—execute in parallel, limited by configurable parameters like the maximum number of child processes to prevent resource exhaustion.[13][14]
Once enqueued, udevd matches incoming uevents against device attributes to identify and classify them precisely. Matching occurs by comparing event variables to criteria like subsystem names or specific attributes (e.g., ATTR{idVendor} for a device's vendor ID), enabling targeted filtering before rule application. The overall flow proceeds as follows: the kernel detects a device change and sends the uevent via netlink; udevd receives and parses it, adding to the queue; attributes are evaluated for matching; and finally, suitable filters and rules are applied to determine subsequent actions. This architecture maintains efficient, non-blocking operation even under high event volumes, supporting dynamic device management in Linux systems.[13][12]
Operation
Device Event Handling
Udev handles device events by processing kernel-generated uevents for addition, removal, or changes to devices in the system, executing the appropriate operational steps to manage device nodes and related resources.[2] These events are queued and processed by the udev daemon, which responds dynamically to maintain the /dev directory and inform other system components.[15] For add events, udev first detects the new device through the incoming uevent, then creates the corresponding device node in /dev with permissions set based on configuration, establishes any specified symlinks, and executes programs if directed to do so.[2] This sequence ensures the device becomes immediately accessible to user-space applications.[15] Remove events trigger the opposite process: udev removes the device node from /dev, cleans up associated symlinks, updates its internal database, and notifies dependent services to handle the device's unavailability.[2] This cleanup prevents stale references and allows graceful shutdown of related processes.[15] Change events occur when a device's properties are modified, prompting udev to update attributes, adjust permissions, or rename nodes and symlinks as needed to reflect the new state.[2] Such updates maintain consistency without full recreation or removal of the device node.[15] Udev supports both synchronous and asynchronous processing modes for events, with defaults configured to prioritize speed through parallel execution over strict sequential ordering, allowing multiple events to be handled concurrently.[15] Short-running tasks, such as node creation, execute synchronously, while longer operations may defer to external mechanisms.[2] In case of errors during event processing, such as timeouts or failed operations, udev logs details via syslog for debugging and employs fallback behaviors like default permissions or termination of worker processes after a configurable timeout (default 180 seconds).[15] This ensures system stability by preventing indefinite hangs and allowing recovery through standard kernel defaults.[2]Rule Application and Actions
When udev processes a device event, it evaluates rules sequentially from files in directories such as/lib/udev/rules.d, /run/udev/rules.d, /etc/udev/rules.d, and others, in lexical order based on filename. Files in /etc/udev/rules.d take precedence over those in other directories if names conflict. Each rule consists of match keys that test device attributes against the event, and if all matches succeed, the associated assignment keys are applied to configure the device.
The matching process uses keys like SUBSYSTEM, which identifies the subsystem of the event device (e.g., "block" for storage devices), and ATTRS{filename}, which searches the device path upward through parent devices for sysfs attributes matching specified values. All ATTRS keys in a rule must match attributes from the same device in the hierarchy. Operators such as == for exact equality and != for inequality or absence refine these matches, allowing precise filtering of events like device addition or removal. The IMPORT key further enhances matching by pulling in additional properties, such as from parent devices or external programs, to import variables into the device's environment for subsequent evaluation.
Upon a successful match, udev executes actions defined by assignment keys. The SYMLINK key creates symbolic links to the device node, enabling user-friendly naming (e.g., linking a USB drive to /dev/disk/by-id/usb-...), with multiple links separated by spaces and higher-priority links overriding others via the link_priority attribute. Permissions are set using GROUP to assign a group ownership and OWNER to specify a user, ensuring secure access to the node. For dynamic behaviors, the RUN key invokes external programs or built-ins after all rules are processed, such as running a script to mount a USB drive.
Programmatic actions leverage the environment populated during matching, where keys like ENV{key} set custom properties that are passed as variables to executed programs, allowing scripts to access device details like serial numbers or paths. These programs run asynchronously unless specified otherwise, integrating with broader system tasks while inheriting the event's context.
In cases of multiple matching rules for the same device, later rules in the sequence override earlier ones for assignments like symlinks or environment variables, unless a final assignment operator (:=) is used to lock a value permanently. This resolution ensures consistent device configuration without ambiguity.
Configuration and Customization
Rules and Configuration Files
Udev's configuration relies on a hierarchical system of rule files and a primary daemon configuration file to define how device events are handled. The rule files are organized in specific directories, with system-provided defaults located in/usr/lib/udev/rules.d/ and local administrator customizations placed in /etc/udev/rules.d/, where the latter directory takes precedence to allow overrides without modifying system files. Additional directories such as /run/udev/rules.d/ for runtime changes and /usr/local/lib/udev/rules.d/ may also be used, but files are processed in priority order from /etc/ to lower-priority locations.[1]
Rule files must end with the .rules extension to be recognized; others are ignored. They are read and applied in lexical (alphabetical) order across all directories, ensuring predictable processing. Empty lines are skipped, and lines beginning with # serve as comments, facilitating maintenance without affecting rule evaluation.[1]
The syntax of rules is token-based, consisting of comma-separated expressions that include match keys for device attributes and operators for assignments or actions. For instance, a match key like KERNEL=="sd*" identifies block storage devices starting with "sd", while assignment operators such as = or := set properties, as in NAME="%k" to assign the kernel device name to the symlink. Other operators include += for appending to lists and -= for removal, enabling flexible device naming and property management.[1]
The daemon's behavior is configured via /etc/udev/udev.conf, which supports overrides in /run/udev/udev.conf or system directories like /usr/lib/udev/udev.conf. Key options include udev_log to set the logging verbosity (e.g., "info" or "debug"), children_max to limit concurrent event processing (defaulting to system resource limits if set to 0), and event_timeout to define the wait period for subsystem replies (default 180 seconds).[16]
For testing and validation, the udevadm test command simulates a device event on a specified path (e.g., a sysfs entry), outputting the matched rules, applied assignments, and any actions like RUN program executions, helping administrators debug configurations without live system changes.[9]
Advanced Customization Options
Udev supports advanced customization through the use of environment variables within rules, enabling precise matching and assignment based on device properties. For instance, theENV{ID_SERIAL} variable allows rules to reference a device's unique serial number, facilitating persistent naming schemes that remain consistent across reboots regardless of detection order. This is particularly useful for storage devices or peripherals where predictable identifiers are essential for scripting or mounting. Environment variables can be matched using operators like == or assigned with = in rule files, expanding on basic syntax by incorporating dynamic device attributes from sysfs.[2][17]
Integration with the hardware database (hwdb) provides a centralized mechanism for mapping vendor and product identifiers to udev properties, stored in source files under /usr/lib/udev/hwdb.d/ and compiled into a binary database at /etc/udev/hwdb.bin. This database uses modalias-like keys, such as usb:v*p*d* for USB devices, to associate values like custom properties (e.g., EV_KEY=1 for input devices), allowing udev to automatically enrich device events with vendor-specific details without explicit rules. Administrators can extend the database by adding .hwdb files in /etc/udev/hwdb.d/, which override system defaults after recompilation with systemd-hwdb update, ensuring tailored mappings for niche hardware.[18][19]
Event inhibition offers control over udev's processing pipeline via OPTIONS directives in rules, such as ignore_device, which skips further handling of matching events to prevent unnecessary node creation or actions for irrelevant hardware. This is valuable for suppressing noise from virtual or duplicate devices, reducing system overhead during hotplug events. Similarly, ignore_remove discards subsequent removal notifications for specified devices, maintaining stability in dynamic environments. These options must be placed at the end of a rule to take effect after all prior matches and assignments.[17]
Udev leverages the MODALIAS environment variable, derived from device modalias strings in sysfs, to automate kernel module loading by invoking modprobe $MODALIAS for events carrying this key, ensuring drivers are bound promptly without manual intervention. This mechanism supports efficient autoloading for bus-specific hardware, such as USB or PCI devices, by matching aliases against available modules. However, udev's built-in firmware loading capability, which previously handled binary blobs via similar events, was deprecated and removed in 2014 to delegate this responsibility to the kernel.[5][20]
Debugging advanced configurations relies on tools like udevadm monitor, which captures real-time kernel uevents and post-rule udev events, outputting device paths and properties for tracing event flow. Invoked with options such as --kernel for raw uevents or --udev for processed ones, it aids in verifying rule triggers during device insertion or removal. Verbose logging can be enabled via the udev_log setting in /etc/udev/udev.conf at the debug level, directing detailed output to the system journal for analysis of rule evaluation and errors. The udevadm test command further simulates events on specific devices, displaying verbose processing steps when the --verbose flag is used.[21][17]
