{"id":36,"date":"2024-03-03T09:20:24","date_gmt":"2024-03-03T09:20:24","guid":{"rendered":"https:\/\/rethinkit.blog\/?p=36"},"modified":"2024-05-17T08:09:50","modified_gmt":"2024-05-17T08:09:50","slug":"generating-and-utilizing-kernel-uevents","status":"publish","type":"post","link":"https:\/\/rethinkit.blog\/?p=36","title":{"rendered":"Generating and Utilizing Kernel UEVENTS"},"content":{"rendered":"\n<hr class=\"wp-block-separator has-text-color has-contrast-color has-alpha-channel-opacity has-contrast-background-color has-background is-style-default\" style=\"margin-top:var(--wp--preset--spacing--10);margin-bottom:var(--wp--preset--spacing--10)\"\/>\n\n\n<div class=\"wp-block-post-excerpt has-urbanist-font-family\"><p class=\"wp-block-post-excerpt__excerpt\">Learn about how to interact with the Linux kernel using UEvents in your userspace applications! Guides on available tools to help your development. <\/p><\/div>\n\n\n<h4 class=\"wp-block-heading has-urbanist-font-family\" id=\"844b\"><strong>Table of Contents<\/strong><\/h4>\n\n\n\n<ol id=\"crgs0f5cktapjm54170\" class=\"has-urbanist-font-family wp-block-list\">\n<li><u>Overview<\/u><\/li>\n\n\n\n<li><a href=\"#t94rq13089\"><u>Monitoring Uevents<\/u><\/a><\/li>\n\n\n\n<li><a href=\"#yn80d156\"><u>Decoding Kernel Uevents<\/u><\/a><\/li>\n\n\n\n<li><a href=\"#sw3uq3377\"><u>Utilizing UEVENTs<\/u><\/a><\/li>\n\n\n\n<li><a href=\"#qmcxc291781\"><u>Testing UDEV Rules<\/u><\/a><\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading has-urbanist-font-family\" id=\"n7yfg206999\"><strong>Overview<\/strong><\/h4>\n\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;69f9b87c99d0a&quot;}\" data-wp-interactive=\"core\/image\" class=\"wp-block-image size-large is-resized wp-lightbox-container\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"757\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on-async--click=\"actions.showLightbox\" data-wp-on-async--load=\"callbacks.setButtonStyles\" data-wp-on-async-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/rethinkit.blog\/wp-content\/uploads\/2024\/03\/fa306b_a5ce9de7343f4c39b92c39f2496137b1mv2-1024x757.jpg\" alt=\"\" class=\"wp-image-37\" style=\"width:620px;height:auto\" srcset=\"https:\/\/rethinkit.blog\/wp-content\/uploads\/2024\/03\/fa306b_a5ce9de7343f4c39b92c39f2496137b1mv2-1024x757.jpg 1024w, https:\/\/rethinkit.blog\/wp-content\/uploads\/2024\/03\/fa306b_a5ce9de7343f4c39b92c39f2496137b1mv2-300x222.jpg 300w, https:\/\/rethinkit.blog\/wp-content\/uploads\/2024\/03\/fa306b_a5ce9de7343f4c39b92c39f2496137b1mv2-768x568.jpg 768w, https:\/\/rethinkit.blog\/wp-content\/uploads\/2024\/03\/fa306b_a5ce9de7343f4c39b92c39f2496137b1mv2.jpg 1460w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\taria-label=\"Enlarge image\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on-async--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.imageButtonRight\"\n\t\t\tdata-wp-style--top=\"state.imageButtonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><\/figure>\n\n\n\n<p class=\"has-urbanist-font-family\" id=\"7js01207114\">UEvents are generated using kobject APIs, such as <strong>kobject_uevent<\/strong>() 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&#8217;s sysfs files for any new changes.<\/p>\n\n\n\n<p class=\"has-urbanist-font-family\" id=\"365cx8047\">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)<\/p>\n\n\n\n<p class=\"has-urbanist-font-family\" id=\"byy0417959\">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:<\/p>\n\n\n\n<ul id=\"5b6skf5cktapjm54187\" class=\"has-urbanist-font-family wp-block-list\">\n<li>Tooling to monitor kernel uevents<\/li>\n\n\n\n<li>Uevent formatting<\/li>\n\n\n\n<li>Utilizing UEVENTS<\/li>\n\n\n\n<li>Testing UEVENTS<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading has-urbanist-font-family\" id=\"t94rq13089\"><strong>Monitoring Uevents<\/strong><\/h4>\n\n\n\n<p class=\"has-urbanist-font-family\" id=\"l0v2o14255\">There are several tools that are available for helping with monitoring and testing kernel uevents. For Yocto based distributions, at least, there is the <strong>udevadm <\/strong>application.<\/p>\n\n\n\n<pre class=\"wp-block-code has-urbanist-font-family\"><code>sh-5.0# udevadm monitor\nmonitor will print the received events for: \nUDEV - the event which udev sends out after rule processing \nKERNEL - the kernel uevent \n\nKERNEL&#91;9298.812693] change \/devices\/virtual\/misc\/usb_haxx (misc) KERNEL&#91;9298.818565] change \/devices\/virtual\/misc\/usb_haxx (misc) KERNEL&#91;9298.823931] change \/devices\/virtual\/misc\/usb_haxx (misc) KERNEL&#91;9298.825485] change \/devices\/virtual\/misc\/usb_haxx (misc) KERNEL&#91;9298.832052] change \/devices\/virtual\/misc\/usb_haxx (misc) KERNEL&#91;9298.835133] change \/devices\/virtual\/misc\/usb_haxx (misc) KERNEL&#91;9298.836787] change \/devices\/virtual\/misc\/usb_haxx (misc) KERNEL&#91;9298.842368] change \/devices\/virtual\/misc\/usb_haxx (misc) UDEV &#91;9298.961581] change \/devices\/virtual\/misc\/usb_haxx (misc) UDEV &#91;9304.731556] change \/devices\/virtual\/misc\/usb_haxx (misc) KERNEL&#91;9305.662434] change \/devices\/virtual\/misc\/usb_haxx (misc) KERNEL&#91;9305.664833] change \/devices\/virtual\/misc\/usb_haxx (misc) KERNEL&#91;9305.667829] change \/devices\/virtual\/misc\/usb_haxx (misc)<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-video\"><video controls src=\"https:\/\/rethinkit.blog\/wp-content\/uploads\/2024\/03\/Ubuntu20.04-Running-Oracle-VM-VirtualBox-2024-02-19-02-20-15-1.mp4\"><\/video><\/figure>\n\n\n\n<p class=\"has-urbanist-font-family\" id=\"zkhj4906\"><span style=\"text-decoration: underline;\">Useful Command Arguments:<\/span><\/p>\n\n\n\n<ul id=\"3vlxnf5cktapjm54204\" class=\"has-urbanist-font-family wp-block-list\">\n<li><strong>-p<\/strong> : prints properties associated with the uevent<\/li>\n\n\n\n<li><strong>-s<\/strong> : filters events based on subsystem\n<ul class=\"wp-block-list\">\n<li>Valid Values:\n<ul class=\"wp-block-list\">\n<li>usb, hid, etc&#8230;<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p class=\"has-urbanist-font-family\" id=\"rmmfu12489\">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 <strong>udevadm<\/strong>, <strong>busybox <\/strong>has an <strong>uevent <\/strong>applet that can be enabled and achieves a similar output.<\/p>\n\n\n\n<pre class=\"wp-block-code has-urbanist-font-family\"><code><code>sh-5.0# busybox uevent <\/code>\n<code>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<\/code><\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading has-urbanist-font-family\" id=\"yn80d156\"><strong>Decoding Kernel UEvents<\/strong><\/h4>\n\n\n\n<p class=\"has-urbanist-font-family\" id=\"eco7s37797\">Normally, an application or userspace entity that listens for kernel uevents, focuses on the following information:<\/p>\n\n\n\n<ul id=\"6bfr9f5cktapjm54223\" class=\"has-urbanist-font-family wp-block-list\">\n<li>Device Path &#8211; device which generated the uevent\n<ul class=\"wp-block-list\">\n<li>\/devices\/virtual\/misc\/usb_haxx<\/li>\n\n\n\n<li>\/devices\/pci0000:00\/0000:00:0c.0\/usb1\/1-2<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>UEvent Type &#8211; type of UEvent\n<ul class=\"wp-block-list\">\n<li>change<\/li>\n\n\n\n<li>add<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p class=\"has-urbanist-font-family\" id=\"gu4kl73326\"><span style=\"text-decoration: underline;\">Device Path<\/span><\/p>\n\n\n\n<p class=\"has-urbanist-font-family\" id=\"6fljt13033\">This is used to help filter kernel uevents. All UEvents are generated on the <strong>NETLINK_KOBJECT_UEVENT <\/strong>socket. Hence, an application may only be interested in changes occurring for a specific device or subsystem.<\/p>\n\n\n\n<p class=\"has-urbanist-font-family\" id=\"ai7f6119953\">UEvent Type<\/p>\n\n\n\n<p class=\"has-urbanist-font-family\" id=\"pqcc1121838\">Defined by<\/p>\n\n\n\n<pre class=\"wp-block-code has-urbanist-font-family\"><code>enum kobject_action { \n<blockquote>KOBJ_ADD, \nKOBJ_REMOVE,\nKOBJ_CHANGE,\nKOBJ_MOVE,\nKOBJ_ONLINE,\nKOBJ_OFFLINE,\nKOBJ_BIND,\nKOBJ_UNBIND,<\/blockquote>};<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-table has-urbanist-font-family\"><table class=\"has-accent-4-background-color has-background\"><thead><tr><th><strong>Kernel Enum<\/strong><\/th><th><strong>UEvent Action<\/strong><\/th><\/tr><\/thead><tbody><tr><td>KOBJ_ADD<\/td><td>add<\/td><\/tr><tr><td>KOBJ_REMOVE<\/td><td>remove<\/td><\/tr><tr><td>KOBJ_CHANGE<\/td><td>change<\/td><\/tr><tr><td>KOBJ_MOVE<\/td><td>move<\/td><\/tr><tr><td>KOBJ_ONLINE<\/td><td>online<\/td><\/tr><tr><td>KOBJ_OFFLINE<\/td><td>offline<\/td><\/tr><tr><td>KOBJ_BIND<\/td><td>bind<\/td><\/tr><tr><td>KOBJ_UNBIND<\/td><td>unbind<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h4 class=\"wp-block-heading has-urbanist-font-family\" id=\"sw3uq3377\"><strong>Utilizing UEVENTS<\/strong><\/h4>\n\n\n\n<p class=\"has-urbanist-font-family\" id=\"dtrxs63252\">The udev daemon has support for filtering and triggering commands based on the UEvent&#8217;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:<\/p>\n\n\n\n<pre class=\"wp-block-code has-urbanist-font-family\"><code>udevadm info -q property -p \/sys\/devices\/pci0000:00\/0000:00:0c.0\/usb1\/1-2 \n\nDEVPATH=\/devices\/pci0000:00\/0000:00:0c.0\/usb1\/1-2 \nDEVNAME=\/dev\/bus\/usb\/001\/017 \nDEVTYPE=usb_device \nDRIVER=usb PRODUCT=bda\/48a8\/1 \nTYPE=0\/0\/0 \nBUSNUM=001 \nDEVNUM=017 \nMAJOR=189 \nMINOR=16 \nSUBSYSTEM=usb \nUSEC_INITIALIZED=76909655318 \nID_VENDOR=Generic \nID_VENDOR_ENC=Generic \nID_VENDOR_ID=0bda \nID_MODEL=USB_Audio \nID_MODEL_ENC=USB\\x20Audio \nID_MODEL_ID=48a8 \nID_REVISION=0001 \nID_SERIAL=Generic_USB_Audio \nID_BUS=usb \nID_USB_INTERFACES=:010100:010200:030000: \nID_VENDOR_FROM_DATABASE=Realtek Semiconductor Corp. \nID_PATH=pci-0000:00:0c.0-usb-0:2 \nID_PATH_TAG=pci-0000_00_0c_0-usb-0_2 \nID_FOR_SEAT=usb-pci-0000_00_0c_0-usb-0_2 \nTAGS=:seat: CURRENT_TAGS=:seat:<\/code><\/pre>\n\n\n\n<p class=\"has-urbanist-font-family\" id=\"tca7o302280\"><span style=\"text-decoration: underline;\">Command Arguments:<\/span><\/p>\n\n\n\n<ul id=\"9pduept7087u3a169\" class=\"has-urbanist-font-family wp-block-list\">\n<li><strong>-q<\/strong> : signifies the category of information interested in\n<ul class=\"wp-block-list\">\n<li>Valid Values:<\/li>\n\n\n\n<li>name, symlink, path, property, all<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>-p<\/strong> : path to the device\n<ul class=\"wp-block-list\">\n<li>Valid Values:\n<ul class=\"wp-block-list\">\n<li>path to the device of interest<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p class=\"has-urbanist-font-family\" id=\"g7e1d100549\">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:<\/p>\n\n\n\n<pre class=\"wp-block-code has-urbanist-font-family\"><code><strong># Filter based on devpath and uevent action<\/strong> \nACTION==\"change\", DEVPATH==\"\/devices\/virtual\/misc\/usb_haxx\", RUN+=\"\/etc\/udev\/scripts\/uevent.sh\"<\/code><\/pre>\n\n\n\n<p class=\"has-urbanist-font-family\" id=\"v25l243335\">The rule matches any uevent that has a &#8220;<strong>change<\/strong>&#8221; action on the <strong>\/devices\/virtual\/misc\/usb_haxx<\/strong> device. If found, the rule will run the <strong>uevent.sh<\/strong> script, which will query for further device changes, or will issue some other operation.<\/p>\n\n\n\n<h4 class=\"wp-block-heading has-urbanist-font-family\" id=\"qmcxc291781\"><strong>Testing UDEV Rules<\/strong><\/h4>\n\n\n\n<p class=\"has-urbanist-font-family\" id=\"z28y91111\">The udevadm application has some very useful tools built in, and one of the possible arguments is the &#8220;<strong>trigger<\/strong>&#8221; command. The <strong>trigger <\/strong>option will allow users to test their udev rules that they&#8217;ve written for a particular device.<\/p>\n\n\n\n<pre class=\"wp-block-code has-urbanist-font-family\"><code><strong># Triggers an \"add\" action for the usb1 device<\/strong> \nsudo udevadm trigger -c add -y usb1<\/code><\/pre>\n\n\n\n<p id=\"z28y91111\">If monitoring from another terminal\/console, after running the <strong>trigger <\/strong>command, the <strong>monitor <\/strong>output will have the following<\/p>\n\n\n\n<pre class=\"wp-block-code has-urbanist-font-family\"><code>UDEV &#91;82838.795432] add \/devices\/pci0000:00\/0000:00:0c.0\/usb1 (usb) \n\nACTION=add \nDEVPATH=\/devices\/pci0000:00\/0000:00:0c.0\/usb1 \nSUBSYSTEM=usb \nSYNTH_UUID=0 \nDEVNAME=\/dev\/bus\/usb\/001\/001 \nDEVTYPE=usb_device \nDRIVER=usb \nPRODUCT=1d6b\/2\/515 \nTYPE=9\/0\/1 \nBUSNUM=001 \nDEVNUM=001 \nSEQNUM=4346 \nUSEC_INITIALIZED=3523846 \nID_VENDOR=Linux_5.15.0-56-generic_xhci-hcd \nID_VENDOR_ENC=Linux\\x205.15.0-56-generic\\x20xhci-hcd \nID_VENDOR_ID=1d6b \nID_MODEL=xHCI_Host_Controller \nID_MODEL_ENC=xHCI\\x20Host\\x20Controller \nID_MODEL_ID=0002 ID_REVISION=0515 \nID_SERIAL=Linux_5.15.0-56-generic_xhci-hcd_xHCI_Host_Controller_0000:00:0c.0 \nID_SERIAL_SHORT=0000:00:0c.0 ID_BUS=usb \nID_USB_INTERFACES=:090000: \nID_VENDOR_FROM_DATABASE=Linux Foundation \nID_AUTOSUSPEND=1 \nID_MODEL_FROM_DATABASE=2.0 root hub \nID_PATH=pci-0000:00:0c.0 \nID_PATH_TAG=pci-0000_00_0c_0 \nID_FOR_SEAT=usb-pci-0000_00_0c_0 \nMAJOR=189 \nMINOR=0 \nTAGS=:seat: \nCURRENT_TAGS=:seat:<\/code><\/pre>\n\n\n\n<p id=\"z28y91111\"><span style=\"text-decoration: underline;\">Command Arguments:<\/span><\/p>\n\n\n\n<ul id=\"4ogh2pt7087u3a196\" class=\"has-urbanist-font-family wp-block-list\">\n<li><strong>-c : <\/strong>uevent action\n<ul class=\"wp-block-list\">\n<li>Valid Values:\n<ul class=\"wp-block-list\">\n<li>add, change, bind, etc&#8230;<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>-y<\/strong>&nbsp;: device path substring match\n<ul class=\"wp-block-list\">\n<li>Valid Values:\n<ul class=\"wp-block-list\">\n<li>usb1<\/li>\n\n\n\n<li>Will match devices with &#8220;usb1&#8221; included in the device path.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-video\"><video controls src=\"https:\/\/rethinkit.blog\/wp-content\/uploads\/2024\/03\/Ubuntu20.04-Running-Oracle-VM-VirtualBox-2024-02-19-02-31-35-1.mp4\"><\/video><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Learn about how to interact with the Linux kernel using UEvents in your userspace applications!  Guides on available tools to help your development.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-36","post","type-post","status-publish","format-standard","hentry","category-technical"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/rethinkit.blog\/index.php?rest_route=\/wp\/v2\/posts\/36","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rethinkit.blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rethinkit.blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rethinkit.blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rethinkit.blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=36"}],"version-history":[{"count":9,"href":"https:\/\/rethinkit.blog\/index.php?rest_route=\/wp\/v2\/posts\/36\/revisions"}],"predecessor-version":[{"id":321,"href":"https:\/\/rethinkit.blog\/index.php?rest_route=\/wp\/v2\/posts\/36\/revisions\/321"}],"wp:attachment":[{"href":"https:\/\/rethinkit.blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=36"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rethinkit.blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=36"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rethinkit.blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=36"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}