Re: useful LKM?

Jacques Gelinas (jack@solucorp.qc.ca)
Wed, 1 Oct 1997 22:21:23 -0400 (EDT)


On Wed, 1 Oct 1997, Raul Miller wrote:

> > > For linux kernel modules to be useful, you'd have to be able to build
> > > modules in a fashion which is independent of the current kernel
> > > configuration. Is anyone working on this?
>
> Martin von Loewis <martin@mira.isdn.cs.tu-berlin.de> wrote:
> > Module versioning is supposed to do exactly that. Why don't you use it?
>
> Because it doesn't work well enough. As I stated in my original
> configuration, with major changes in the kernel configuration what
> happens is that the modules won't load.

They are not loading because they should not. Mostly the versionning is
there to prevent from unloading incompatible modules.

Modules become incompatible because you have select a new feature in the
kernel and this feature has an effect on some kernel structure which are
directly or indirectly accessed by the module.

Currently, the problem with this strategy (versionning) is that too many
features in the kernel have some effect on the layout of various
structures. There are various solutions to this problem.

1-Create an API just for module which insulate the module from the
internal of the kernel. This way, the modules will be always compatible
and the versionning will server its purposes: Make module from various
kernel release operate with various kernel releases.

This has never been done because it represent another layer most
developper don't want.

2-Avoid changing the layout of some structure conditionnally. For example,
we have often stuff like

struct foo {
int pid;
.
.
#ifdef THIS_KERNEL_FEATURE
struct foototo *toto;
#endif
.
.
#ifdef THIS_OTHER_FEATURE
struct fooxxx *xxx;
#endif
};

In many case, just by leaving the field toto and xxx there, even if they
won't be use at all will keep the same "versionning" and module will
continue to load.

Obviously there is a memory penalty by doing so.

3-I suspect that genksyms (the utility which compute the versionning key
for symbols) is a little too effective. This utility walk all function
prototype and compute a CRC. It walks each argument of the prototype and
locate its structure. It then read the structure and follow each
sub-structure, creating a very large string. It computes the CRC out of
this string.

Many structure contain pointer to sub-structure. Those sub-structure are
never accessed directly by most modules. At most, they are sometime
manipulated as a handle to call another function, so the exact layout of
these sub-structures are irrelevant to the module code.

We already have one define in the kernel includes called __KERNEL__. It
allows one to differentiate usage of a header file between a kernel source
and a application source.

We could introduce a new define (or more) that can affect what is visible
from one part of the kernel source (one module in fact). For example,
modules could be compiled with -D__MODULE__ and various headers could be
changed this way

#ifdef __KERNEL

#ifndef __MODULE__

struct foo{
.
.
};
#endif

.
.
#endif

This means that when compiling a module, one would be sure that it does
not rely on those internal structure. Once we have this in place, genksyms
may be changed slightly so "struct foo" will be elimininated from the CRC
computation.

This last solution should provide a reliable and simple way to slowly
isolate the various modules from the low level stuff in the kernel. They
are already independant of it. But genksyms is not aware of that. By using
this __MODULE__ symbol, we would have the opportunity to safely make
genksyms less "curious" about the internal of the kernel.

This would produce safe "long live" modules (Modules which operates with
many different kernel releases).

-----

By combining solution 2 and 3, we would be in a better shape, without
inventing new APIs.

--------------------------------------------------------
Jacques Gelinas (jacques@solucorp.qc.ca)
Linuxconf: The ultimate administration system for Linux.
see http://www.solucorp.qc.ca/linuxconf
new developments: mail to fax gateway, disk quota management, RPM for redhat