Messages in this thread | | | Date | Sat, 20 Dec 1997 12:36:25 -0500 (EST) | From | Jacques Gelinas <> | Subject | Re: Module versioning (was: Re: OFFTOPIC: binary modules, bad idea!) |
| |
On Sat, 20 Dec 1997, Dominik Kubla wrote:
> > Theodore T'so wrote: > [...] > : However, storing the information in a separate ELF section doesn't > : solve this, unless you actually have GCC generate the hash code. > : (If you store the hash code in slab.ver, you'd still have the same > : problem.) In fact, if you have GCC generate the hash code, it'd > : solve this problem whether the hash code is stored as part of the > : symbol name, or in a separate ELF section. > [...] > > Hmm, for ELF-based systems, one could try to use ELF symbol versioning > instead of a hash-code and since that is already part of the current > binutils it should not be a problem. The question however is if that > is sufficient for our purposes? Could someone with more understanding > how module versioning works comment on this?
The major problem with module versionning is not that much related to the technology (ELF trickery or preprocessor solution with .ver file). The problem is that genksyms does not know where to stop. This is a kernel header issue. Let me explain with an example.
---- In the kernel, you have this ---------
foo.h:
struct foo{ int count; int total; };
foo.c:
void foo_add (struct foo *p, int val) { p->count++; p->total += val; }
void foo_reset (struct foo *p) { p->count = p->total = 0; }
---- Then you have one module --------------
mod.c:
void modfoo (struct foo *p) { . . if (something){ foo_reset (p); } . . foo_add (p,1); . . }
---------------------------------------------
For mod.c, the exact structure (definition) of struct foo is not important. It is some sort of "handle". So one can add a third field to struct foo and recompile the kernel, BUT NOT the module and this will work.
The linux kernel really works like this. Mostly, you have some code which maintain a struct and the rest of the kernel use that as an opaque type
genksyms try to compute the proper versionning CRC for function foo_add and foo_reset. It simply walk the source and compute a CRC based on the exact definition of struct foo. Any change to struct foo will create a new CRC for foo_add() and foo_reset()
Now, if one change foo.h like this
foo.h:
#ifndef COMPILING_MODULES
struct foo{ int count; int total; };
#endif
This will hide the exact definition of struct foo to genksyms. As such the CRC won't include it and the functions foo_add() and foo_reset() won't have a new versionning signature. If one can compile the module with COMPILING_MODULES defined, this means that the module is really independant from the exact definition of struct foo, so all this is safe.
Once you have reorganised the kernel header to hide the exact definition of many kernel internal types and have successfully compile all modules with this, you are getting
-module with longer life (ie, module compile for kernel x.y.z work for kernel x.y.z+w)
-The ability to fiddle with makefile dependancies in a smarter ways, avoiding complete recompile everytime you touch a header.
This strategy is not that difficult to implement. Many struct in the kernel are manipulated with inline functions. Although they are logically "opaque" for modules, this is not really the case for the compiler. This means that although, at the source code level, one module never declare or access a struct directly, it nevertheless do that because of the inline functions. There are two solutions to this problem.
-drop the inline function when compiling module. In many case, this won't create any slowdown. We could end up with a new kernel CONFIG parameter such as CONFIG_MODULE_LONG_LIVE. A kernel header would look like
#ifdef CONFIG_MODULE_LONG_LIVE void foo_add(); void foo_reset(); #else inline void foo_add() { . . } inline void foo_reset() { . . } #endif
-Make the whole strategy with finer grain, which would yield some module with more dependancies than others. Currently insmod has no problem loading module compiled without versionning into a versionning kernel. So we can end up with some module compile with versionning and other without. Some will be long live, some won't.
Until such an issue is addressed, the .ver vs ELF versionning is mooth.
-------------------------------------------------------- Jacques Gelinas (jacques@solucorp.qc.ca) Linuxconf: The ultimate administration system for Linux. see http://www.solucorp.qc.ca/linuxconf new developments: remote GUI admin, multiple machines admin
| |