[Toybox] Pondering mdev...

Isaac ibid.ag at gmail.com
Sun Aug 25 18:09:39 PDT 2013


On Sun, Aug 25, 2013 at 03:41:15AM -0500, Rob Landley wrote:
> On 08/22/2013 11:17:17 PM, Isaac wrote:
> >> >I guess that means modprobe is higher up.
> >> >(Do we want to use depmod when we use modprobe? The alternative is
> >> >doing a
> >> >file-by-file search, which is more complicated.)
> >>
> >> I suspect we need the functionality, and that funky char-major-%d-%d
> >> aliasing. That's the main difference between insmod and modprobe.
> >> Needing a separate demod database is iffy, presumably scanning a
> >> config file and the modules to find the right things to load
> >> shouldn't be that hard to do at runtime. (After the first module
> >> they should be cached...)
> >
> >depmod is basically precaching it all.
> 
> Question: given 30 years of Moore's Law, does this actually buy us
> anything on a modern system?
> 
> Answer: further down, I see it does.
> 
> >To generate modules.alias, this should work:
> >find /lib/modules/`uname -r` -name '*.ko' | { while read M
> >  do
> >    for x in `modinfo -F alias`; do echo alias "$x `basename $M
> >.ko`"; done
> >  done } >/lib/modules/`uname -r`/modules.alias
> >
> >The C for which is trivially different from modinfo...
> 
> Question: Can we scan it at runtime? If we know the module we need
> is somewhere under /lib/modules/$(uname -m) and it ends in .ko and
> we can identify it from the data in the module... why shouldn't we
> just do that?
> 
> Answer: Because Ubuntu manages to have 153 megabytes of crap in
> /lib/modules/$(uname -r) split up into 3300 separate files.
> 
> >On first run, the full search can be extremely slow.
> >I tested with grep -r alias= <module_dir>, and got 38 seconds;
> >subsequent runs ran 1.14 seconds.
> 
> Here I did:
> 
> # echo 1 > /proc/sys/vm/drop_caches;
> # time cat $(find /lib/modules/$(uname -r) -name "*.ko") > /dev/null
> 
> real	0m17.345s
> user	0m0.268s
> sys	0m1.228s
> 
> So yeah, that's significant.
> 
> Looking at the man page, the .bin versions don't seem hugely useful.
> (If parsing a text file is a big deal, you're doing it wrong.)

Agreed; I can parse modules.alias in about a dozen lines.
modules.dep is pretty trivial, if we even use it.

 
> Wow, do we really need all of these?

No. See below.

> modules.alias modules.builtin modules.ccwmap modules.dep modules.devname
> modules.ieee1394map modules.inputmap modules.isapnpmap modules.ofmap
> modules.order modules.pcimap modules.seriomap modules.softdep
> modules.symbols
> modules.usbmap
> 
> Even after reading the man page, I don't have a clear idea what
> depmod is doing if it's creating all that. alias, builtin, and dep I
> sort of understand. ccwmap?

Apparently modules.*map is "legacy", if I understand correctly.

modules.devname is theoretically for autoloading on device opening, if 
I understand right.
I have not bothered looking at that, period.

modules.symbols is essentially using symbol exports as aliases. So properly it's something like this:
find $MODDIR -name '*.ko' |while read M; do
  nm $M |sed -ne "s/$/`basename $M .ko`/g" -e 's/^.* t /alias symbol:/gp'
  done |sort
But that is a slow, cumbersome, and hideous approach.

In theory, that should not be needed because there's a field that tells all the dependencies, built into the module.
In practice, there may be a number of situations where relying on that field is
a bad idea; at least, that's what module-init-tools options suggest.

modules.dep is something I've been debating about.
Ostensibly, all the information is in files that we're going to mmap() anyway.
The simplest apprach to trying to load all the modules in theright order is probably to recursively:
1-check if it's loaded, return in that case
2-mmap(), enumerate immediate dependencies
3-load dependencies, one at a time, via the same function
4-if that returns success, load the mmap'ed module.

This way, modules get loaded in order, and we don't try to load them twice.
...On the other hand, it's impossible to know ahead of time what 
modules will be loaded without extra code...

> ofmap... Open Firmware? On x86? isapnpmap... ISA plug and play? In
> 2013? really? The PCI bus replaced ISA 20 years ago and they're
> creating a map of modules to support the old one? (I'm aware of
> legacy platform devices, but if you're building your CMOS clock
> driver a module something is _wrong_...)
> 
> <misspiggy>I don't understand any of this.</misspiggy>
> 
> >And that's not really ideal for a fast boot; I count 125
> >"modalias" files,
> >with 67 unique device aliases.
> >
> >Meanwhile, a search of modules.alias is ~0.02 seconds.
> >
> >Or would this essentially "run depmod if it hasn't been run yet"?
> >If so, I'm fine with that. But it would be nice to be _able_ to
> >have all
> >the caches generated beforehand.
> 
> The problem with dynamically generating it is /lib/modules could be
> in squashfs. There's no guarantee we can write after system
> generation. I'd love for it to be transparent, but it would have to
> be under /var or something for that, and it could be a tmpfs...

> >I'm attaching resolve_modalias.c; this is a toy that was mainly
> >intended
> >as a demonstration of the method of searching.
> >It does an exhaustive search, because I wanted to get both drivers
> >for my
> >wireless card (even if a module is blacklisted, it ends up in
> >modules.alias)
> >And it's not really ideal in other ways (starting a linked list
> >with an empty
> >entry, etc.)
> 
> I'm not a domain expert on modules. I build static kernels almost
> exclusively. This is an area where I'm happy to defer to the
> judgement of people who know what a good solution looks like.
> 
> I would like a simple solution, but I'm not wrapping my head around
> the problem domain well enough to be able to _discard_ a lot of the
> stuff it's doing. (It looks like depmod needs -b to work on a
> directory other than /lib/modules/$(uname -r). The concept of -P is
> kind of horrible, as is the existence of depmod.conf...)

depmod -P? My manpage (module-init-tools 3.11.1) doesn't document that.
(Looking it up, I agree. Added complexity for the sake of...adding
complexity to the code that uses the output.)
It lists:
-a "all modules"
-A "only if there are newer modules" (I think find has a relevant option?)
-b basedir
-c conffile
-e "check if symbols are provided by the kernel, rather than assuming that 
any we can't find are"
-F System.map (needed for -e, so that builtins can be checked for.
-n "write all files to stdout instead of acting"
-v "show all the symbol resolution work"
and -V/-h

Of these, -a reflects a little oddity:
depmod /path/to/module.ko
appends entries for module.ko to the appropriate files.
-b is important.
-n I can see for debugging.

I don't _think_ -v is needed in addition to -n, but it might be useful for some people.
If it's implemented, I would make it optional (under TOYBOX_DEBUG?)

-eF may be useful for some people, but is not generally useful.

-A I'd prefer to leave to find.

In other words, I'd probably want to do this:
USE_DEPMOD(NEWTOY(depmod, "ab:"USE_TOYBOX_DEBUG("n"), TOYFLAG_SBIN))
GLOBALS(
char * basedir;
)
"eF:" could be added if someone needs it.

files created are modules.symbols, modules.builtin, and modules.aliases; tries writing in basedir by default, but in /tmp/modules/`uname -r` if that's not possible.

modprobe basically calls recursive_modprobe() (the 4-step process 
I mentioned above) which calls itself till all the modules are loaded.
To resolve the aliases, it looks in $basedir or 
(/lib/modules/$(uname -r) || /tmp/modules/$(uname -r))

dependencies could be obtained either by ELF parsing for the symbols 
or by looking at the depends: field.
I'm inclined to do a first pass that ignores symbols altogether, then 
add symbol support (which *I* haven't a clue how to do, apart from including elf.h...).  To use symbols,
-depmod needs to read ELF exports
-modprobe needs to read ELF imports
-modprobe needs to lookup "symbol:" aliases for each imported symbol in modules.symbols

Thanks,
Isaac Dunham

 1377479379.0


More information about the Toybox mailing list