# Ueventd ------- Ueventd manages `/dev`, sets permissions for `/sys`, and handles firmware uevents. It has default behavior described below, along with a scripting language that allows customizing this behavior, built on the same parser as init. Ueventd has one generic customization parameter, the size of rcvbuf_size for the ueventd socket. It is customized by the `uevent_socket_rcvbuf_size` parameter, which takes the format of uevent_socket_rcvbuf_size For example uevent_socket_rcvbuf_size 16M Sets the uevent socket rcvbuf_size to 16 megabytes. ## /dev ---- Ueventd listens to the kernel uevent sockets and creates/deletes nodes in `/dev` based on the incoming add/remove uevents. It defaults to using `0600` mode and `root` user/group. It always creates the nodes with the SELabel from the current loaded SEPolicy. It has three default behaviors for the node path: 1. Block devices are created as `/dev/block/`. There are symlinks created to this node at `/dev/block///`, `/dev/block///by-name/`, and `/dev/block/by-name/` if the device is a boot device. 2. USB devices are created as `/dev/` if `DEVNAME` was specified for the uevent, otherwise as `/dev/bus/usb//` where `bus_id` is `uevent MINOR / 128 + 1` and `device_id` is `uevent MINOR % 128 + 1`. 3. All other devices are created as `/dev/` The permissions can be modified using a ueventd.rc script and a line that beings with `/dev`. These lines take the format of devname mode uid gid For example /dev/null 0666 root root When `/dev/null` is created, its mode will be set to `0666`, its user to `root` and its group to `root`. The path can be modified using a ueventd.rc script and a `subsystem` section. There are three to set for a subsystem: the subsystem name, which device name to use, and which directory to place the device in. The section takes the below format of subsystem devname uevent_devname|uevent_devpath [dirname ] `subsystem_name` is used to match uevent `SUBSYSTEM` value `devname` takes one of two options 1. `uevent_devname` specifies that the name of the node will be the uevent `DEVNAME` 2. `uevent_devpath` specified that the name of the node will be basename uevent `DEVPATH` `dirname` is an optional parameter that specifies a directory within `/dev` where the node will be created. For example subsystem sound devname uevent_devpath dirname /dev/snd Indicates that all uevents with `SUBSYSTEM=sound` will create nodes as `/dev/snd/`. ## /sys ---- Ueventd by default takes no action for `/sys`, however it can be instructed to set permissions for certain files in `/sys` when matching uevents are generated. This is done using a ueventd.rc script and a line that begins with `/sys`. These lines take the format of nodename attr mode uid gid For example /sys/devices/system/cpu/cpu* cpufreq/scaling_max_freq 0664 system system When a uevent that matches the pattern `/sys/devices/system/cpu/cpu*` is sent, the matching sysfs attribute, `cpufreq/scaling_max_freq`, will have its mode set to `0664`, its user to to `system` and its group set to `system`. Note that `*` matches as a wildcard and can be used anywhere in a path. ## Firmware loading ---------------- Ueventd automatically serves firmware requests by searching through a list of firmware directories for a file matching the uevent `FIRMWARE`. It then forks a process to serve this firmware to the kernel. The list of firmware directories is customized by a `firmware_directories` line in a ueventd.rc file. This line takes the format of firmware_directories [ ]* For example firmware_directories /etc/firmware/ /odm/firmware/ /vendor/firmware/ /firmware/image/ Adds those 4 directories, in that order to the list of firmware directories that will be tried by ueventd. Note that this option always accumulates to the list; it is not possible to remove previous entries. Ueventd will wait until after `post-fs` in init, to keep retrying before believing the firmwares are not present. ## Coldboot -------- Ueventd must create devices in `/dev` for all devices that have already sent their uevents before ueventd has started. To do so, when ueventd is started it does what it calls a 'coldboot' on `/sys`, in which it writes 'add' to every 'uevent' file that it finds in `/sys/class`, `/sys/block`, and `/sys/devices`. This causes the kernel to regenerate the uevents for these paths, and thus for ueventd to create the nodes. For boot time purposes, this is done in parallel across a set of child processes. `ueventd.cpp` in this directory contains documentation on how the parallelization is done.