2012-07-13 3 views
5

Ich modifiziere einen Linux-Kernel, um dem virtuellen Linux-Server (LVS) einige Funktionen hinzuzufügen.Wie können exportierte Symbole optional nur dann verwendet werden, wenn sie in einem insmodierten Linux Kernel-Modul vorhanden sind?

Ich entwickelte ein Modul (das ich net/netfilter/ipvs/ip_vs_utils.c nannte) mit einigen Funktionen, die beim Lastenausgleich verwendet werden. Alle Funktionen werden hier mit EXPORT_SYMBOL() exportiert.

Dieses Modul ist logischerweise nicht ständig geladen. Meine Absicht ist es, dem Benutzer zu ermöglichen, zu entscheiden, ob er diese zusätzliche Funktionalität verwenden möchte oder nicht (Laden oder Entladen des Moduls).

Meine Frage ist, wie könnte ich diese Funktionen OPTIONAL (abhängig, ob das Modul läuft oder nicht) von einem vorhandenen (und natürlich geändert) Modul (net/netfilter/ipvs/ip_vs_core.c) aufrufen. Etwas wie folgt aus:

if(ip_vs_utils_IsLoaded) 
{ 
    function1(arg1, arg2, arg3); // being function1 defined on ip_vs_utils.c 
} 
+1

Antwort Lais ist ganz gut, wenn Ihr 'if (ip_vs_utils) 'Code soll die ganze Zeit im Kernel sein; Wenn sich dieser Code jedoch in einem anderen ladbaren Modul befindet, ist wahrscheinlich eine einfache Modulabhängigkeit der bessere Ansatz. Siehe 'depmod (8)' für alle Details. – sarnold

Antwort

4

Ich glaube, Sie brauchen ein Trampolin immer (oder fast immer) geladen in den Kernel.

In Trampolin-Code müssen Sie solche Variablen.

struct module *ip_vs_utils_mod; 
EXPORT_SYMBOL(ip_vs_utils_mod); 

/* function pointers */ 
ret_type (*ip_vs_utils_afunc_ptr)(func_arg_list); /* Add static if you put it in a header file! */ 
EXPORT_SYMBOL(ip_vs_utils_afunc_ptr); /* ******EXPORTED***** */ 

Wenn die ip_vs_utils geladen wird, müssen Sie alle Variablen init, Initialisierungscode in ip_vs_utils.c:

ip_vs_utils_mod = THIS_MODULE; 

/* init function pointers */ 

/* ip_vs_utils_afunc_impl is the real implementation 
* of the function, it is *****NOT***** needed to export it 
*/ 
ip_vs_utils_afunc_ptr = ip_vs_utils_afunc_impl; 

und das Trampolin Funktionen im Trampolin-Code hinzufügen:

ret_type ip_vs_utils_afunc(func_arg_list) 
{ 
    ret_type ret = DEFAULT_RET; 

    if (try_module_get(ip_vs_utils_mod)) { 
     ret = (*ip_vs_utils_afunc_ptr)(func_arg_list); 
     module_put(ip_vs_utils_mod); 
    } 
    return ret; 
} 

try_module_get() wird benötigt, um das Modul davor zu schützen, plötzlich entladen zu werden, während ip_vs_utils_afunc_ptr() aufgerufen wird. Sie können stattdessen auch RCU verwenden, um den Overhead von try_module_get()/module_put() zu reduzieren. (Aber es ist schwer)

Oder Sie können einige Trampolin-Hack wie Dynamic Link in Anwender genutzt werden kann (möglicherweise müssen Sie eine Menge in den Linux-Kernel ändern)

+0

Vielen Dank für Ihre Antwort, ich denke, das wird für mich funktionieren. Nur eine Frage. Was passiert, wenn mein Modul ip_vs_utils vor den anderen geladen wird? Wird nicht die Zeile 'ip_vs_utils_afunc_ptr = ip_vs_utils_afunc_impl;' einen Fehler ausgeben, weil ip_vs_utils_afunc_ptr noch nicht in der Symboltabelle ist? – marcocamejo

+1

In diesem Fall müssen Sie eventuell das Trampolin mit dem Kernel verbinden (oder ein Modul, das immer beim Systemstart geladen wird). Trampolin ist typischerweise extrem kleiner als die reale Implementierung, es ist in Ordnung, es immer geladen zu machen. –

+0

Hat es so gemacht. Nochmals vielen Dank! – marcocamejo

Verwandte Themen