aboutsummaryrefslogtreecommitdiffstats
mdevd: the mdevd program

mdevd
Software
skarnet.org

The mdevd program

mdevd is a uevent manager. It connects to the netlink and reads a series of uevents; for every uevent it reads, it performs actions according to its configuration file. Actions can be inserting a kernel module, creating or modifying device entries in /dev, etc.

mdevd's configuration file uses the exact same format as mdev. The differences between mdevd and mdev are:

  • mdev needs to be registered as a hotplug manager and the kernel spawns an instance of mdev per uevent; for every uevent, mdev has to parse its configuration file. By contrast, mdevd is a daemon: it's long-lived, and there is only one instance, reading a series of uevents and performing actions without forking; the configuration file is read and parsed only once.
  • Even though mdev can now be run as a daemon, via the -d option, there are still technical advantages to running mdevd over mdev.

Interface

     mdevd [ -v verbosity ] [ -D notif ] [ -I intake ] [ -o outputfd ] [ -I intake ] [ -O nlgroups ] [ -b kbufsz ] [ -f conffile ] [ -n | -N ] [ -s slashsys ] [ -d slashdev ] [ -F fwbase ] [ -C ]
  • mdevd reads and parses its configuration file /etc/mdev.conf.
  • It then connects to the netlink and reads from it, waiting for uevents.
  • It exits 0 on a SIGTERM.

Exit codes

  • 0: SIGTERM received, clean exit
  • 1: received an invalid event
  • 2: syntax error in the configuration file
  • 100: wrong usage
  • 111: system call failed

Signals

mdevd reacts to the following signals:

  • SIGHUP: re-read the configuration file
  • SIGTERM: exit as soon as possible

Options

  • -v verbosity : be more or less verbose. Default verbosity is 1. 0 will only print fatal error messages, 3 or more is seriously verbose debugging.
  • -D notif : when ready (actually listening to the netlink), write a newline to file descriptor notif then close it. This allows mdevd to use the s6 mechanism to notify readiness. notif cannot be lesser than 3. If this option is not given, no readiness notification is sent.
  • -o outputfd : send a copy of the complete uevent, with possible new fields, to file descriptor outputfd, after mdevd has handled them. (This can serve as a synchronization mechanism with an external program that needs a device to have been properly configured by the device manager before acting on the device.) The uevent is sent with the kernel format: fields are separated by a null character. The uevent is terminated by an additional null character. outputfd cannot be lesser than 3 and cannot be the same as notif. If for any reason, at any point, mdevd fails to write to outputfd, it stops writing, until it is restarted. (This is to preserve mdevd's memory stability guarantee.) By default, the uevents are not written anywhere.
  • -I intake : read the uevents from the netlink groups identified by the mask intake. The default is 1, meaning the netlink group where the kernel sends its events, and it should not be changed unless you have a very particular and rare setting (namely, a chain of device managers reading events and rebroadcasting them to other netlink groups).
  • -O nlgroups : after mdevd has handled the uevents, rebroadcast them to the netlink groups identified by the mask nlgroups. If the bit 0 or the bits specified in intake (see above) are set in nlgroups, a warning is printed and these bits are ignored, in order to avoid causing a loop. (Yes, you can still cause a loop by chaining two separate instances of mdevd. mdevd will protect you against accidents, not against intentional stupidity.)
  • -b kbufsz : try and reserve a kernel buffer of kbufsz bytes for the netlink queue. Too large a buffer wastes kernel memory; too small a buffer risks losing events. The default is 1048576, meaning 1 MiB, which should be enough for most systems; if you're getting "missed events" warnings from mdevd at coldplug time, try increasing this number.
  • -n : dry run. mdevd will not create or delete device nodes, and it will not spawn commands. Instead, it will print to stdout the actions it would have performed.
  • -N : configuration file test. mdevd will not run, it will only parse its configuration file and exit 0 on success or nonzero (with an error message) on failure. This option overrides, and is overridden by, -n.
  • -f conffile : read the configuration file from conffile. Default is /etc/mdev.conf. conffile must be an absolute path.
  • -s slashsys : assume the sysfs pseudo-filesystem is mounted on slashsys. Default is /sys. slashsys must be an absolute path.
  • -d slashdev : assume the device nodes are to be found in slashdev. Default is /dev. slashdev must be an absolute path.
  • -F fwbase : assume the firmware files, if any, are to be found in fwbase. Default is /lib/firmware. fwbase must be an absolute path.
  • -C : after initialization (when mdevd is ready), invoke mdevd-coldplug, so that a coldplug is automatically performed when mdevd starts. This option should only be used in situations where a drop-in replacement for mdev -d is needed, because it has the drawback of performing a coldplug every time mdevd is started — including when mdevd is killed and restarted. By default, mdevd does not perform a coldplug when it starts, and it is up to the administrator to properly organize their boot scripts to run mdevd-coldplug once, at boot time, when mdevd is ready. The examples/s6-rc subdirectory of the mdevd package shows a way to do this with the s6-rc service manager.

Configuration file

mdevd uses mdev's configuration file format. A good mdev.conf example is available here.

If mdevd cannot find its configuration file, it will use a simple, basic default configuration where it can create device nodes as root or delete them, and does nothing else.

A semantic difference with mdev is that a * directive will be run on every action type, not just ACTION=add and ACTION=remove. A & directive is in the same case (see the paragraph below).

execline command support

In addition to the traditional shell command spawning via the @, $ and * directives, mdevd also supports spawning a command with the execlineb launcher:

  • +cmd : spawns execlineb -Pc cmd when this line catches an event that has ACTION=add. This is the equivalent of @cmd.
  • -cmd : spawns execlineb -Pc cmd when this line catches an event that has ACTION=remove. This is the equivalent of $cmd.
  • &cmd : spawns execlineb -Pc cmd when this line catches an event no matter its action type (add, remove, or anything else). This is the equivalent of *cmd.

Note that unlike /bin/sh, execlineb is spawned without an absolute path, so in order for +, - and & to work, the execlineb command must be available in mdevd's PATH.

Notes

  • The examples/ subdirectory of the mdevd package contains examples on how to run mdevd under various init systems / supervisors. These examples do not show how to run mdevd as a logged service, because mdevd should normally be run early in the system's boot up sequence, before mounting the disks - so the presence of a mounted partition suitable for logging is not guaranteed. In normal use, mdevd is quite terse, so it runs smoothly without a dedicated logger, with its error messages going to the catch-all logger.