Learn about how to interact with the Linux kernel using UEvents in your userspace applications! Guides on available tools to help your development.
Table of Contents
Overview

UEvents are generated using kobject APIs, such as kobject_uevent() from within kernel drivers. They can be used to communicate changes to a particular kernel device to userspace. Userspace can utilize these events to further query the device’s sysfs files for any new changes.
For example, the USB bus generates a kernel uevent whenever there is an addition or removal of a USB device. Userspace can use this to configure the USB device to the desired behavior, such as enabling USB auto-suspend. (disabled for every USB class other than hubs)
Having the ability in userspace to wait for asynchronous events is useful so cycles can go to handling other operations, and interrupted only when a change occurs. This post will cover topics such as:
- Tooling to monitor kernel uevents
- Uevent formatting
- Utilizing UEVENTS
- Testing UEVENTS
Monitoring Uevents
There are several tools that are available for helping with monitoring and testing kernel uevents. For Yocto based distributions, at least, there is the udevadm application.
sh-5.0# udevadm monitor
monitor will print the received events for:
UDEV - the event which udev sends out after rule processing
KERNEL - the kernel uevent
KERNEL[9298.812693] change /devices/virtual/misc/usb_haxx (misc) KERNEL[9298.818565] change /devices/virtual/misc/usb_haxx (misc) KERNEL[9298.823931] change /devices/virtual/misc/usb_haxx (misc) KERNEL[9298.825485] change /devices/virtual/misc/usb_haxx (misc) KERNEL[9298.832052] change /devices/virtual/misc/usb_haxx (misc) KERNEL[9298.835133] change /devices/virtual/misc/usb_haxx (misc) KERNEL[9298.836787] change /devices/virtual/misc/usb_haxx (misc) KERNEL[9298.842368] change /devices/virtual/misc/usb_haxx (misc) UDEV [9298.961581] change /devices/virtual/misc/usb_haxx (misc) UDEV [9304.731556] change /devices/virtual/misc/usb_haxx (misc) KERNEL[9305.662434] change /devices/virtual/misc/usb_haxx (misc) KERNEL[9305.664833] change /devices/virtual/misc/usb_haxx (misc) KERNEL[9305.667829] change /devices/virtual/misc/usb_haxx (misc)
Useful Command Arguments:
- -p : prints properties associated with the uevent
- -s : filters events based on subsystem
- Valid Values:
- usb, hid, etc…
- Valid Values:
Monitoring for uevents is helpful so that users can properly reference the correct device path and kobject event to trigger certain actions in the application. If your distribution does not include udevadm, busybox has an uevent applet that can be enabled and achieves a similar output.
sh-5.0# busybox uevent
add@/devices/pci0000:00/0000:00:0c.0/usb1/1-2 ACTION=add DEVPATH=/devices/pci0000:00/0000:00:0c.0/usb1/1-2 SUBSYSTEM=usb MAJOR=189 MINOR=12 DEVNAME=bus/usb/001/013 DEVTYPE=usb_device PRODUCT=1532/228/200 TYPE=0/0/0 BUSNUM=001 DEVNUM=013 SEQNUM=3624
Decoding Kernel UEvents
Normally, an application or userspace entity that listens for kernel uevents, focuses on the following information:
- Device Path – device which generated the uevent
- /devices/virtual/misc/usb_haxx
- /devices/pci0000:00/0000:00:0c.0/usb1/1-2
- UEvent Type – type of UEvent
- change
- add
Device Path
This is used to help filter kernel uevents. All UEvents are generated on the NETLINK_KOBJECT_UEVENT socket. Hence, an application may only be interested in changes occurring for a specific device or subsystem.
UEvent Type
Defined by
enum kobject_action {
KOBJ_ADD,
KOBJ_REMOVE,
KOBJ_CHANGE,
KOBJ_MOVE,
KOBJ_ONLINE,
KOBJ_OFFLINE,
KOBJ_BIND,
KOBJ_UNBIND,
};
Kernel Enum | UEvent Action |
---|---|
KOBJ_ADD | add |
KOBJ_REMOVE | remove |
KOBJ_CHANGE | change |
KOBJ_MOVE | move |
KOBJ_ONLINE | online |
KOBJ_OFFLINE | offline |
KOBJ_BIND | bind |
KOBJ_UNBIND | unbind |
Utilizing UEVENTS
The udev daemon has support for filtering and triggering commands based on the UEvent’s device path and action type. Each subsystem may define their own set of UEvent properties that can used within the udev rules created. To help find the types of properties that are available for a particular device, the following command can be used:
udevadm info -q property -p /sys/devices/pci0000:00/0000:00:0c.0/usb1/1-2
DEVPATH=/devices/pci0000:00/0000:00:0c.0/usb1/1-2
DEVNAME=/dev/bus/usb/001/017
DEVTYPE=usb_device
DRIVER=usb PRODUCT=bda/48a8/1
TYPE=0/0/0
BUSNUM=001
DEVNUM=017
MAJOR=189
MINOR=16
SUBSYSTEM=usb
USEC_INITIALIZED=76909655318
ID_VENDOR=Generic
ID_VENDOR_ENC=Generic
ID_VENDOR_ID=0bda
ID_MODEL=USB_Audio
ID_MODEL_ENC=USB\x20Audio
ID_MODEL_ID=48a8
ID_REVISION=0001
ID_SERIAL=Generic_USB_Audio
ID_BUS=usb
ID_USB_INTERFACES=:010100:010200:030000:
ID_VENDOR_FROM_DATABASE=Realtek Semiconductor Corp.
ID_PATH=pci-0000:00:0c.0-usb-0:2
ID_PATH_TAG=pci-0000_00_0c_0-usb-0_2
ID_FOR_SEAT=usb-pci-0000_00_0c_0-usb-0_2
TAGS=:seat: CURRENT_TAGS=:seat:
Command Arguments:
- -q : signifies the category of information interested in
- Valid Values:
- name, symlink, path, property, all
- -p : path to the device
- Valid Values:
- path to the device of interest
- Valid Values:
These are all defined within systemd. In the example above, these are the properties that belong with the USB subsystem, and users can write rules to match these properties. A simple rule can look like the following:
# Filter based on devpath and uevent action
ACTION=="change", DEVPATH=="/devices/virtual/misc/usb_haxx", RUN+="/etc/udev/scripts/uevent.sh"
The rule matches any uevent that has a “change” action on the /devices/virtual/misc/usb_haxx device. If found, the rule will run the uevent.sh script, which will query for further device changes, or will issue some other operation.
Testing UDEV Rules
The udevadm application has some very useful tools built in, and one of the possible arguments is the “trigger” command. The trigger option will allow users to test their udev rules that they’ve written for a particular device.
# Triggers an "add" action for the usb1 device
sudo udevadm trigger -c add -y usb1
If monitoring from another terminal/console, after running the trigger command, the monitor output will have the following
UDEV [82838.795432] add /devices/pci0000:00/0000:00:0c.0/usb1 (usb)
ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:0c.0/usb1
SUBSYSTEM=usb
SYNTH_UUID=0
DEVNAME=/dev/bus/usb/001/001
DEVTYPE=usb_device
DRIVER=usb
PRODUCT=1d6b/2/515
TYPE=9/0/1
BUSNUM=001
DEVNUM=001
SEQNUM=4346
USEC_INITIALIZED=3523846
ID_VENDOR=Linux_5.15.0-56-generic_xhci-hcd
ID_VENDOR_ENC=Linux\x205.15.0-56-generic\x20xhci-hcd
ID_VENDOR_ID=1d6b
ID_MODEL=xHCI_Host_Controller
ID_MODEL_ENC=xHCI\x20Host\x20Controller
ID_MODEL_ID=0002 ID_REVISION=0515
ID_SERIAL=Linux_5.15.0-56-generic_xhci-hcd_xHCI_Host_Controller_0000:00:0c.0
ID_SERIAL_SHORT=0000:00:0c.0 ID_BUS=usb
ID_USB_INTERFACES=:090000:
ID_VENDOR_FROM_DATABASE=Linux Foundation
ID_AUTOSUSPEND=1
ID_MODEL_FROM_DATABASE=2.0 root hub
ID_PATH=pci-0000:00:0c.0
ID_PATH_TAG=pci-0000_00_0c_0
ID_FOR_SEAT=usb-pci-0000_00_0c_0
MAJOR=189
MINOR=0
TAGS=:seat:
CURRENT_TAGS=:seat:
Command Arguments:
- -c : uevent action
- Valid Values:
- add, change, bind, etc…
- Valid Values:
- -y : device path substring match
- Valid Values:
- usb1
- Will match devices with “usb1” included in the device path.
- Valid Values:
Leave a Reply