[RFC] mdev: support reading events from stdin, add features to mdev -s
Natanael Copa
ncopa at alpinelinux.org
Wed Apr 15 20:13:55 UTC 2015
On Wed, 15 Apr 2015 18:46:08 +0200
Denys Vlasenko <vda.linux at googlemail.com> wrote:
> On Mon, Apr 13, 2015 at 7:15 PM, Isaac Dunham <ibid.ag at gmail.com> wrote:
> > Here's a patch series to add mdev -i and make mdev -s a little more
> > featureful, so rules like this one:
> > $MODALIAS=.* root:root 660 @modprobe "$MODALIAS"
> > will work even with coldplug.
> >
> > mdev -i reads hotplug events from stdin, in a format proposed by Laurent Bercot
> > wherein each "line" is terminated with '\0' (rather than '\n') and each event
> > is terminated by an additional '\0'.
> > Internally, each event is loaded into the environment (without copying) at
> > the start of handle_event(), then the environment is cleared before
> > handle_event() returns.
> > This is done instead of using a new key lookup method because helper
> > scripts rely extensively on environment variables; if we did not load
> > the events into the environment at some point, autoloading modules and
> > other important features would no longer work.
> >
> > The new mdev -s (FEATURE_MDEV_NEWSCAN) uses the same codepath as mdev -i
> > instead of calling make_device() directly.
> >
> > Both mdev -i and the new mdev -s are compile-time options, separately
> > selectable.
>
> How about the following applet, which would listen to netlink and spawn a helper
> for every new message?
This would be a nice addition, but as said, solves different issue than
what mdev -i tries to solve.
Problem 1: At boot you have many events in short time. One fork for
every event will slow things down. We want avoid that.
Problem 2: The netlink listening daemon will need stay in memory
forever, even during the long periods without any events. We want it to
be microscopic.
As discussed in the other thread, we are interested in solving it by
having a minimalistic netlink listener which will (on demand) spawn
mdev -i and pass over events via socket. A timeout will make sure mdev
-i exits during the longer periods without any events. That way we
avoid "forkbombing" at bootup and we avoid having big binary in memory
all times.
My first approach (and what Bercot seems to prefer) was that the netlink
daemon reads the events and forwards them to event handler (Dunham's
mdev -i) via a pipe. I forked the nldev[1] project (which does exactly
the same as your ndev) and twisted it to forward the events via a
pipe[2]. I have not tested if it works with Dunham's mdev -i (yet) but
it would probably do so with a minor modification (separate events with
\0) as Bercot suggested[3].
My second approach was to separate the always-in-memory netlink
listener and netlink reader in 2 processes, turning the netlink
listener into a socket activator only. I renamed the fork to nlplug[4]
to avoid confusion with the original nldev.
I have the socket activator working[5], but I need to fix the reader[6]
to forward the events via pipe to mdev -i (basicaly redo what i did
with the original nldev).
The netlink reader could be integrated in mdev -i, but I am
interested in also avoid a fork for every modprobe $MODALIAS and
hacking mdev to do both would probably make it too big to ever get it
into busybox. There was also Becker, who had strong opinions about
passing the events via fifos using a more general purpose fifo manager.
The way Dunham implemented mdev -i should work for all 3 approaches (I
assume - i haven't reviewed the code yet):
- nl listener/reader combined (Bercot's approach)
- nl socket activator with separate reader (my nlplug approach)
- general purpose fifo manager (Becker's approach)
While at it, there is one more problem, or use case, that I would like
to solve: read and handle events from netlink til given blockdevice (by
UUID or LABEL or /dev/* name) appears and exit. Think initramfs who
waits for root=$blockdevice to show up before doing switch_root - but
is still able to use a device on a slow USB controller without waiting
more than absolutely necessary. (I need in fact need to look for 2
devices, one with a boot package repository and one with a system
config - alpine linux installs this on a tmpfs as root)
I intend implement that in my nlplug unless someone have better
suggestion for this.
-nc
--
[1]:http://git.r-36.net/nldev/
[2]:http://git.alpinelinux.org/cgit/ncopa/nldev/tree/nldev.c?id=ba51e3b67883f80462b667aa776e89168347739d
[3]: http://lists.busybox.net/pipermail/busybox/2015-March/082534.html
[4]:http://git.alpinelinux.org/cgit/ncopa/nlplug
[5]:http://git.alpinelinux.org/cgit/ncopa/nlplug/tree/nlsockd.c
[6]:http://git.alpinelinux.org/cgit/ncopa/nlplug/tree/nlplug.c
More information about the busybox
mailing list