Mail archive

Re: [alpine-devel] udev replacement on Alpine Linux

From: Jude Nelson <>
Date: Tue, 12 Jan 2016 22:47:45 -0500

Hi Laurent, thank you as always for your input.

On Tue, Jan 12, 2016 at 6:37 PM, Laurent Bercot <>

> On 12/01/2016 21:06, Jude Nelson wrote:
>> I've been using vdev and libudev-compat it on my production machine
>> for several months.
> Sure, but since you're the author, it's certainly easier for you
> than for other people. ;)

Agreed; I was just pointing out that the system has been seeing some
real-world use :)

> I use it with heavily with Chromium (YouTube and
>> Google Hangouts work) and udev-enabled Xorg (hotplugged input devices
>> work as expected). My encrypted swap partition's device-mapped nodes
>> and directories show up where they should, and my Android development
>> tools work with my Android phone when I plug it in.
> That's neat, and very promising.
> I doubt you're the right person to ask, but do you have any
> experience running libudev-compat with a different hotplug
> manager than vdev ? I'd like to stick with (s)mdev as long as
> I can make it work.

I haven't tried this myself, but it should be doable. Vdev's
event-propagation mechanism is a small program that constructs a uevent
string from environment variables passed to it by vdev and writes the
string to the appropriate place. The vdev daemon isn't aware of its
existence; it simply executes it like it would for any another matching
device-event action. Another device manager could supply the same program
with the right environment variables and use it for the same purposes.

> I wouldn't say it's ready for prime time just yet, though. In
>> particular, because libudev-compat uses (dev)tmpfs to record and
>> distribute event messages as regular files (under
>> /dev/metadata/udev/events), a program can leak files and directories
>> simply by exiting without shutting down libudev (i.e. failing freeing
>> up the struct udev_device).
> That may be OOT, but I'm interested in hearing the rationale for
> that choice. An event is ephemeral, a file is (relatively) permanent;
> recording events as regular files does not sound like a good match,
> unless you have a reference counting process/thread somewhere that
> cleans up an event as soon as it's consumed.

Tmpfs and devtmps are designed for holding ephemeral state already, so I'm
not sure why the fact that they expose data as regular files is a concern?

I went with a file-oriented model specifically because it made
reference-counting simple and easy--specifically, by using hard-links. The
aforementioned event-propagation tool writes the uevent into a scratch area
under /dev, hard-links it into each libudev-compat monitor directory under
/dev/metadata/udev, and unlinks the file (there is a directory in
/dev/metadata/udev for each struct udev_monitor created by each
libudev-compat program). When the libudev-compat client wakes up next, it
consumes any new event-files (in delivery order) and unlinks them, thereby
ensuring that once each libudev-compat client "receives" the event, the
event's resources are fully reclaimed.

> Anyway, unless I'm misunderstanding the architecture completely,
> it sounds like leaks could be prevented by wrapping programs you're
> not sure of.

I couldn't think of a simpler way that was also as robust. Unless I'm
misunderstanding something, wrapping an arbitrary program to clean up the
files it created would, in the extreme, require coming up with a way to do
so on SIGKILL. I'd love to know if there is a simple way to do this,

> My plan is to have libudev-compat store
>> its events to a special-purpose FUSE filesystem called eventfs [1]
>> that automatically removes orphaned files and denies all future
>> access to them.
> Unfortunately, FUSE is a deal breaker for the project I'm working on.
> I'm under the impression that you're slightly overengineering this;
> you shouldn't need a specific filesystem to distribute events. My
> s6-ftrig-* set of tools distribute events to arbitrary subscribers
> without needing anything specific - the mechanism is just directories
> and named pipes.
> But I don't know the details of libudev, so I may be missing
> something, and I'm really interested in learning more.

I went with a specialized filesystem for two reasons; both of which were to
fulfill libudev's API contract:
* Efficient, reliable event multicasting. By using hard-links as described
above, the event only needs to be written out once, and the OS only needs
to store one copy.
* Automatic multicast channel cleanup. Eventfs would ensure that no matter
how a process dies, its multicast state would be come inaccessible and be
reclaimed once it is dead (i.e. a subsequent filesystem operation on the
orphaned state, no matter how soon after the process's exit, will fail).

Both of the above are implicitly guaranteed by libudev, since it relies on
a netlink multicast group shared with the udevd process to achieve them.

It is my understanding (please correct me if I'm wrong) that with
s6-ftrig-*, I would need to write out the event data to each listener's
pipe (i.e. once per struct udev_monitor instance), and I would still be
responsible for cleaning up the fifodir every now and then if the
libudev-compat client failed to do so itself. Is my understanding correct?

Again, I would love to know of a simpler approach that is just as robust.

> Instead, I've been running a script
>> every now and then that clears out orphaned directories in
>> /dev/metadata/udev/events.
> A polling cleaner script works if you have no sensitive data.
> A better design, though, is a notification-based cleaner, that
> is triggered as soon as a reference expires. And I'm almost
> certain you don't need eventfs for this :)
I agree that a notification-based cleaner could be just as effective, but I
wonder whether or not the machinery necessary to track all libudev-compat
processes in a reliable and efficient manner would be simpler than
eventfs? Would love to know what you had in mind :)

Thanks for your feedback,

> --
> Laurent
> ---
> Unsubscribe:
> Help:
> ---

Received on Tue Jan 12 2016 - 22:47:45 UTC