10

I have two Linux kernel modules, one of which may provide some function to another. But use of that function is not essential, the second module may (and should) work even if the first module is not present.

If I just export the function from the first module and use it in second module, the second module depends on that symbol and can't be loaded without first module.

One of the solutions is to have user script that looks into /proc/kallsym for the function in the first module, and if it's present there, the script passes its address as a parameter to the second module, which then makes pointer out of it. But I don't like that solution for obvious reasons.

If there more correct and elegant solution that will allow second module go get address of some symbol in the first module, but avoid hard dependency ?

Eugene
  • 291
  • 2
  • 9

3 Answers3

8

Finally I've found the solution: kernel has symbol_get() and symbol_put() which give me the opportunity to lookup arbitrary symbol in another module (it needs to be exported, of course) and prevent module from unloading while I'm using its symbol.

Eugene
  • 291
  • 2
  • 9
1

I think if module B depends on module A, the module B can not be successfully loaded without module A is loaded first.

In fact, only after module A inserted first, the symbols which module B needed which exported from module A will appear in the /proc/kallsym file.

The solution to your situation: in module B, module_init() function should have some codes to check the module A is already there or not, if not, load A first. i.e. Using request_module() to load A, or create a more fancy method to using try_then_request_module().

tian_yufeng
  • 1,780
  • 10
  • 8
  • Module B needs to work even if there is no module A at all (suppose that A provides an interface to some hardware accel that is not present on a machine). – Eugene Mar 29 '13 at 12:52
  • There was query_module() interface in 2.4 that did almost exactly what I need, but it was removed in 2.6. I wonder if there is some replacement... – Eugene Mar 29 '13 at 12:54
1

there are more elegant solutions but require kernel changes. Basically, kernel is enhanced to house module registrations. When a module is loaded and wants to expose itself to other modules, he will register into the kernel with a well-known int -- which is just an index into the kernel array that stores references to registered modules. Now, any module that wants to acquire a reference to another module will simply ask the kernel for a new reference to this module -- using same, well-known int. These new references must short lived (i.e. you get a reference to it but put it back in same context). To allow for long lived connections, you must make a protocol between the two so when either module gets unloaded he/she knows how to inform the other module that he's going away.