On Tue, Mar 10, 2015 at 01:37:41PM +0100, Harald Becker wrote:
> Hi Laurent !
> >... I dislike the idea of integrating early init functions into mdev, 
> >because those
> >functions are geographically (as in the place where they're performed) close 
> >to mdev,
> > but they have nothing to do with mdev logically.
> 
> Sorry, I don't agree. mdev's purpose is to setup the device file system
> infrastructure, or at least to help with setting up this. Ok, at first leave
> out proc and sysfs, there you may be right, but what about devpts on
> /dev/pts, or /dev/mqueue, etc., and finally the tmpfs for /dev itself. Do
> you really say they do not belong to the device file system infrastructure?
> Or all those symlinks like /dev/fd, /dev/stdin, /dev/stdout, etc., do you
> consider them not to belong to mdev? Not talking about setting owner
> informations and permissions for those entries in the device file system.
> 

In my humble opinion, these do not belong to mdev the busybox applet.
"Do one thing" means *method*, not just problem area - just like
cut, head, and tail are separate programs, despite all selecting
portions of a text input based on mathematical criteria.
And mdev takes care of setting up devices by looking at information
from the kernel (via uevent or environment; the two are very similar).

If you don't make this distinction, how do you argue that lspci should
not query the PCI ID database via DNS (-Q), or that it's out of scope
for an init system to fold in the device manager?

Now, if you added support for using busybox as pre-compiled init
"scripts", it would be reasonable for an applet to do this.
(Yes, I've heard of such things being done with busybox.)

> >  ... but here it's different. s6-devd spawns a helper program for
> >every event, like /proc/sys/kernel/hotplug would do, but it reads the
> >events from the netlink so they're serialized.
> 
> Spawning a process for every event produce massive slowdown on system
> startup. My intention is to fork only one process, parse the conf table once
> and then read sanitized events from stdin, scanning the in memory conf table
> and invoking the right operations.

If you use a similar format to uevent (eg, "VAR1=VAL1\0VAR2=VAL2\0\0"
or something similar) this sounds desireable to me. 
I suppose this could be "mdev -i".

However, I'd suggest figuring out how to make environment variable
hooks work the same in mdev -s/-i and just plain mdev first.
Otherwise, mdev -i would be at a disadvantage.
Note: while it's trivial to swap out the environment with each event,
this is probably a Bad Idea for a longer-lived process, due to the
potential for leaks and other chaos.

Factors that make me want this:
* mdev can noticeably slow down boot (I've set up mdev as hotplug helper
with Debian, and notice that the resulting initrd takes a second or two
more than udev to load.) I would assume that loading all the modules
in Debian results in a fork bomb.
* hotplug is a rare event, but with modern hardware it frequently causes
a sudden burst of activity.
A flash drive frequently triggers 5+ events, and plugging in a phone/
turning on mass storage may cause a dozen or more.
Even plugging in an SD card may cause 3 or more events.

> >  In your design, the long-lived process forks a unique helper that
> >reads mdev.conf... so it's not meant to be used with any program
> >compatible with /proc/sys/kernel/hotplug - it's only meant to be
> >used with mdev. So, why fork at all ? Your temporary instance is
> >unnecessary - just have a daemon that parses mdev.conf, then
> >listens to the netlink, and handles the events itself.
> 
> No, it is not unnecessary. The long lived instance tries to stay at low
> memory usage, then forks and second instance read mdev.conf into the memory
> table. When the event system goes idle, as it is most of the time, the
> second instance dies and memory is freed to the system.
 
When I'm doing something particularly memory intensive (in my case,
*usually* linking a large program), I sometimes stop every service
and program I can.
This has allowed me to build at least one program I could not have built
otherwise.
There may be times when there's memory pressure that the user is unaware
of, but frequently the user controls both memory pressure and hotplug.

The long lived instance probably needs to stay out of busybox to make
this really minimize memory use, though. Certainly it shouldn't be in
the same binary as mdev. (Some people use multiple busybox binaries,
which is probably more optimal.)

> >  Seriously, udev is a hard problem. udevd is bloated and its configuration
> >is too complex; mdev is close to the point where parsing a config file for
> >every invocation will become too expensive - I believe that it has not
> >reached that point yet, but if you add more stuff to the conf language, it
> >will.
> 
> Right, adding more to the conf language adds complexity there, but removes
> complexity of the surrounding scripts and collect system specific
> information at a central place (or places), usually hidden deep in the
> startup scripts or some config files they use.

As someone who regularly experiments with extremely minimalist systems
(including rewriting init or rc scripts) for entertainment's sake,
I have to say that information put in the startup scripts is not
"hidden deep". Information in config files, maybe; but startup scripts
are the most "shallow" alternative (where it's easiest to wade in and
poke around.)


Now, a comment or two on design of mdev -i and the netlink listener:
I really *would* like there to be a timeout of some sort; in my
experience, 1 second may be rather short, and 5 seconds is usually
ample.
I also think that the timeout should be adjustable.
Now, the timeout could be done in at least two ways:
(a) timeout in mdev -i:
disable timeout on read (or set timeout for executing rules)
parse input and execute rules
at the end of execution, reset timeout for read
(b) timeout in netlink daemon:
listen for events
on event:
        disable timeout
        check state of mdev/pipe
        respawn if needed
        write event to pipe
        check write result; if needed, retry
        reset timeout
on timeout:
        close pipe and let mdev die when it finishes

Everything but the timeout has to be done anyhow in both mdev and the
netlink daemon.

In (a), the timeout could be set on the mdev commandline, or in mdev.conf;
if it is set on the mdev commandline, *that* needs to be specified on
the netlink daemon's commandline or in its config file.
In (b), the timeout is specified in the netlink daemon's commandline or
in its config file.

Somehow, I find myself prefering option (b); managing timeouts seems to
be the job of a daemon rather than a hotplugger, and it fits logically
with everything else that the netlink daemon is doing.


Thanks,
Isaac Dunham
_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to