[Toybox] [PATCH] losetup: Wait for ueventd to create loop device on Android

Rob Landley rob at landley.net
Wed Aug 24 05:04:26 PDT 2022


On 8/24/22 05:04, Yi-yo Chiang wrote:
> Digging through git history and I believe AOSP has been using "tmpfs as /dev"
> plus "init and/or ueventd servicing uevents" since at least Android 1.0 (circa
> 2008,
> https://android.googlesource.com/platform/system/core/+/4f6e8d7a00cbeda1e70cc15be9c4af1018bdad53

Devtmpfs was introduced in 2009, so it wasn't an option in 2008. Plus it was
initially controversial because they had previously done a REALLY STUPID
implementation of the concept (I mean just spectacularly bad) that got ripped out:

https://lwn.net/Articles/331818/

Devtmpfs got cleaned up into something simple and elegant which solves half the
problem space of hotplug. It won't _eliminate_ the need for something like
ueventd because when a device shows up you often need to do more than just make
a /dev node for it. But for the "give me this dev node" case, when you make a
syscall() or insmod and a device shows up, it eliminates the race waiting for
asynchronous node creation: when the process gets control back, the node is there.

> I'm not sure if the 2013 article is outdated, or are AOSP still on its way to
> adopt devtmpfs. I'll bounce this question to David (dvander at google.com)

It's a bit like the old "is android going to use containers" question. Android
predated container support by years so it had to do other things at first, and
then had legacy dependencies on those other things. But eventually stuff like
minijail started working their way into the stack using container plumbing.

To clarify: I'm not pushing back against your patch because I think android
should be using devtmpfs instead. I already merged your patch, and expect that
to be the status quo for a while. I'm just going "over the next few years, this
is a thing you might want to look into". But if you're not already working on
it, I wouldn't expect to see it in the next android release or the one after that.

Sigh: there's a bunch of stuff I consider obvious that apparently isn't. Back
when I made initramfs use tmpfs in 2013 and didn't exactly advertise the
benefits of that either. The embedded guys knew but most other people didn't
notice. I should do some writeups on the advantages of various bits of
plumbing... Eh, throw it on the todo heap.

> OTOH I also wouldn't be surprised if some deeply modified Android distro
> (wilderness) is already using devtmpfs.

A quick google says devtmpfs is initialized in lineageos's boot messages, but
who knows what that means?

Hotplug has a whole mess of access handoffs to do securely, which I had to
understand deeply back when I was doing mdev but that was a decade ago and I'm
kind of stale on at this point.

"Device insertion" isn't the same as creating a /dev node. New hardware showing
up may trigger driver loading which may require an insmod and/or firmware
loading. (You could put the firmware in initramfs and solve the license issues
by having it be an externally loaded initramfs image, but no, they made a
special magic MECHANISM for it. Ugh.) And some devices don't even HAVE /dev
nodes (ethernet and wifi, thank you bill joy) and some have multiple nodes for
the same device (ala partitioned hard drives), and of course some device nodes
don't correspond to hardware at all (/dev/loop0)... This is why the original
devfs was horrible even BEFORE it tried to use solaris names for all the devices.

Also, devtmpfs doesn't usually create a world readable device, so a hotplug
manager may adjust permissions and ownership. (That 2013 article I linked to was
about letting drivers select permissions and uid:gid for the new node to show up
as, which is a layering violation because THE KERNEL DOES NOT KNOW WHAT ANY UID
OR GID OTHER THAN 0 OR 65534 MEAN, but that ship has apparently sailed...)

I'm sure I wrote documentation about this, I'm like COMPULSIVE about doing
that... Darn it, best I can find is an ancient half-assed version that trails
off into notes to self:

https://www.kernel.org/doc/local/hotplug-history.html

Another failure mode of mine. Sorry.

Anyway, the point of all this is devtmpfs solves a specific problem and clears
up some nasty races, but it is by no means ALL of hotplug, and reenginering a
pre-devtmpfs hotplug solution to NOT create its own /dev nodes requires a design
rethink. (Which is why I haven't cycled back around to mdev.c in toybox, because
it's not just "finish the code". I started mdev in 2005 and devtmpfs happened in
2009, I ALSO have to redesign bits of my old hotplug layer to not try to redo
what devtmpfs already does better, and have too many other things competing for
focus.)

But with devtmpfs as part of this complete breakfast, race conditions like the
one you just patched don't happen as much.

Rob


More information about the Toybox mailing list