This is the README for the module notification package. It'll
explain in detail what you have to do to have your loadable modules 
loaded when needed and unloaded when no longer in use. This functionality
will allow you to build a trimmed down kernel and to only load the extra
functionality whenver you need it, and reclaim the RAM as soon as you
no longer need it.

FIRST OF ALL: This software is extremely ALPHA. If you take a look at the
kernel patches, you'll find a number of comments that indicate that I don't
really know waht I am doing. This also hasn't been tried on more than one
linux machine yet (at the time of writing). It _does_ work reliably on my
machine, and has done so for quite several weeks. This doesn't mean it won't
eat up your diploma thesis or melt down your video card. I have no idea how
such things could happen, but I won't be responsible if Murphy has more
phantasy than me. You have been warned!

If you are still with me after that disclaimer, congratulations! So let's
get on with the install....

First, you patch your kernel with the included patch. That will include the
kernel support for module notification  as well as the FANCY BEEPER in your
kernel. If you don't want the beeper thingie, don't worry, everything is
properly "#ifdef"ed (I hope :-), so it won't hurt at all. Build your kernel
as usual, answering "y" to the question about the module notification 
(it will be listed after the busmice and the fancy beeper).

Next, compile the modreq program (you _can_ use the included binary, but as
you'll have to run this thing as root, compiling yourself is strongly
recommended. Don't trust me!). There is nothing really worth adjusting in
there, so a simple "make modreq" should be enough.

Now comes the tough part --- making your configuration file. Each line of it
starts with a capital letter, indicating what kind of module is configured.
Then comes an identifier which helps to find the right line for the request,
and then a flag which states whether superuser status is required for this
(1) or not(0). The rest of the line is taken as the command to execute.

This sounds complicated, but it's a lot easier once you see a few examples.
I'll give you a guided tour through my configuration file now....

   # Config file
   F 	"msdos" 	0 	/sbin/modprobe msdos

A line starting with an "F" indicates the request for a filesystem. So this
line says that whenever someone tries to mount an "msdos" filesystem, the
command "/sbin/modprobe msdos" should be executed.

   F 	"minix" 	0 	/sbin/modprobe minix

The same goes for the minix filesystem

   F 	"iso9660" 	0 	/sbin/modprobe isofs

And for the iso9660 filesystem. It should be noted, however, that only the
first four characters of the names are significant. 

   N 	"eth0" 		1 	/sbin/modprobe ne2000

A line starting with "N" stands for a network device. It gets activated by
"ifconfig eth0 up". Of course, which module you want to load depends on what
kind of network card is in your machine. 
Note that you have to have superuser status to activate this line. This
isn't exactly necessary for the ne2000 module, but you might not want to
have other people start up your ppp connection.

   D 	23 		1 	/sbin/insmod mcd mcd_irq=11; sleep 5

A "D" stands for "device". Instead of a name you have a major number in the
second column. This line say that whenever the superuser tries to access
major number 23 (and fails because there is no such device), the mitsumi
driver should be loaded with irq set to 11, followed by a 5 second pause.
(I modularized the mcd driver myself, and it is _not_ yet really stable. The
wait is necessary because the drive needs some initializatioon time).

   E	1234  		0 	/sbin/modprobe iBCS

"E" stands for "executable format". Whenever the kernel fails to find an
executable format for an exec call, it will tell modreq about the first four
bytes of the file. These, interpreted as an integer, are matched to the
second column. Obviously, 1234 is _not_ the correct number for iBCS, but I
currently don;t have any SCO executables at hand to find out about the right
number. The same goes for ELF executables. If _you_ do, just try to start
one and take a look at modreq's logfile. Please tell me about those numbers,
so I can get them right in later releases.

   U	"mcd."		0	sleep 1; /sbin/rmmod mcd &

"U" means that the usage count of an module went down to 0, i.e. it is no
longer used. There is two problems with this....

a) I have no idea how to access the name of the module from the
MOD_DEC_COUNT macro. This means that what you write into the second column
ins't the name of the module, but the name of the sourcefile the macro is to
be found in. For things like CD drivers or network drivers, this is
certainly unique. For filesystems, however, it isn't....... I'm very open to
suggestions!

b) As modeq gets called at the moment the usage count is decremented, it is
a very bad idea to remove the module right away --- after all, its code is
still executed. For this reason, it won't work, either (it used to, and boy
did the kernel complain ;-). However, the kernel won;t get out of the module
until the process started by modreq returns..... Which is why the above
command runs in the background, and sleeps one second before removing the
module. 

   U 	* 		0	/tmp/oink

This one is just to show that you can also use "*" in the second column. It
tells modreq to call /tmp/oink each time a module is no longer used (and
isn't the mcd module, as that was taken care of already). You might simply
try to remove all loaded modules, and have the kernel figure out which ones
it still needs....

That's all there is to config files --- you might want to start out with the
one I just explained, and modify it to your needs. Once you think you are
done, copy it to /etc/modreq.config; That's where the daemon will look for
it.

Next you should create the modreq device. Do

  mknod /dev/modreq c 10 129

You definitely want to change the permissions to 600, so no unprivileged 
users can mess around with your module notification!

If you haven't booted your new kernel yet, do so
now. During bootup, you should see a line "Loadable module notification 
installed", just after the serial ports have been initialized. From now on, 
the kernel will try to speak to your modreq daemon whenver some call failed
that might succeed after the appropriate module was loaded. If the daemon
wasn't started, however, everything behaves jst the way it usually does.

Now start modreq by typing

    ./modreq

and try to do some things on another console that need a module loaded.
Switch back to the one you started the daemon on, and check the output ---
it will look something like this:

where=1, major=23(""), suser=1
Compare 68,23 to 70,1868854125
Compare 68,23 to 70,1768843629
Compare 68,23 to 70,963605353
Compare 68,23 to 78,829452400
Compare 68,23 to 68,23
Sending '/sbin/insmod mcd mcd_irq=11; sleep 5
'
where=5, major=778330989("mcd."), suser=1
Compare 85,778330989 to 70,1868854125
Compare 85,778330989 to 70,1768843629
Compare 85,778330989 to 70,963605353
Compare 85,778330989 to 78,829452400
Compare 85,778330989 to 68,23
Compare 85,778330989 to 69,1234
Compare 85,778330989 to 85,778330989
Sending 'sleep 1; /sbin/rmmod mcd &
'

The lines starting with "Compare" correspond to the lines of your config
file. So when "where=1" and "major=23" (which means a DEVICE request for
major 23), the 5th line matched, and the command was executed.
Some time later, a request with "where=5" and major="mcd." came in (which
means a MODULE NO LONGER USED request from a file starting with "mcd."), and
the mcd module was promptly unloaded.

If it doesn't work like advertised for you --- well, try to figure out why
not, and tell me about it :-). All this debugging output is there for a
reason.... Well, the config file is read anew for every request, so modreq
will notice immediatly when you change it!

Now if it _did_ work, you can install it as standard on your system. Execute
the "stop" script, which will gracefully shut the daemon down. Hitting 
CTRL-C on it will _not_ bring it down gracefully, so do use the supllied 
script! Next, move the modreq executable to a suitable place (e.g. /etc),
and add a line like 

   /etc/modreq  2>&1 >/usr/adm/modreq.log &

to your rc.local file. Take care to put it before anything that might need
to have a module loaded (rc.local might actually be too late in the bootup
process...). Now reboot, and all your modules should be loaded
automatically. If something doesn't work, take a look at the log file.

A few more words of caution......

a) When treated well, this packet has worked for me for quite some time now.
   However, it is rather fragile against unexpected signals and also
   against other processes accessing its device. Don't! Nothing serious
   should happen, but processes requesting modules might be lost in kernel
   mode. If this happens to you, switch to another VC and type

      echo xxxxxxxxxxxxxxx >/dev/modreq

   This helps most of the time. If it happened without actually doing nasty
   things, I'd like to know what exactly caused modreq to fall over.

b) When you look at the logfile, you wil probably find lots of requests 
   for unkonwn executable formats, with the string representation of major
   being some kind of command. These are shell scripts that don't have
   the #!/bin/sh in their first line. It does no harm at all, just slows
   things down a bit when starting them. It's good style to put that line
   in, though, so you might as well do it.

c) Make sure (and that is, absolutely SURE) that whatever you call from
   modreq doesn't ask for a module to be loaded. That includes not using
   the shell scripts mentioned in the previous paragraph. If it happens,
   it might cause a wonderful deadlock --- the second request will block
   because modreq doesn't answer it (actually hasn't seen it yet, as it
   still busy working on the first), and the first one won't be answered 
   because the second blocks. Ouch. If it happens, do the same thing as in
   a). If it happens too often, tell me about it, I know how to change it,
   I am just a bit lazy..... 

That's it --- good luck to you. I know it's still pretty rough, but as I had
promised this stuff about a month or so ago, I thought I'd rather use the
free evening and get it out there. There are a few things I'd like to do
"some day", but we all know when "some day" is..... So if you want anything
done, you have to

a) do it yourself (preferred solution, send me patches!)
b) fascinate me (which will get it done very quickly, at the expense
   of some other stuff, mainly studies)
c) bug me about it over and over again, till I simply give in to shut you
   up, or
d) bribe me into doing it (there is plush animals, there is chocolate, there
   is postcards from your home country.... you get the idea?)

Send any comments, bug reports, death threats, winning lottery tickets and
beautyful women to

    Bernd Meyer    
    eMail: bernie@wombat.hanse.de   OR   bernies@umibox.hanse.de
    snail: Schafshagenberg 2, D-21077 Hamburg, Germany
     
The wombat address is the preferred one.

All that's left to say is "mount -t iso9660 /dev/cdrom", which will load
two modules...

   Bernie

