2012-07-13 7 views
5

Modyfikuję jądro Linuxa, aby dodać trochę funkcjonalności do Linux Virtual Server (LVS).Jak używać eksportowanych symboli opcjonalnie tylko wtedy, gdy są one obecne w niewytworzonym module jądra systemu Linux?

Opracowałem moduł (który nazwałem net/netfilter/ipvs/ip_vs_utils.c) z kilkoma funkcjami używanymi podczas równoważenia obciążenia. Wszystkie funkcje tutaj są eksportowane za pomocą EXPORT_SYMBOL().

Ten moduł logicznie nie jest ładowany przez cały czas. Moją intencją jest pozwolić użytkownikowi zdecydować, czy chce skorzystać z tej dodatkowej funkcjonalności, czy nie (załadowanie lub wyładowanie modułu).

Moje pytanie brzmi: w jaki sposób mogę wywołać te funkcje OPCJONALNIE (w zależności od tego, czy moduł działa) z istniejącego (i oczywiście zmodyfikowanego) modułu (net/netfilter/ipvs/ip_vs_core.c). Coś takiego:

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

odpowiedź Lai jest dość dobry, jeśli plik 'if (ip_vs_utils) 'kod ma być cały czas w kernelu; ale jeśli ten kod znajduje się w innym ładowalnym module, prawdopodobnie lepszym rozwiązaniem jest prawdopodobnie zależność od modułu. Zobacz 'depmod (8)', aby uzyskać szczegółowe informacje. – sarnold

Odpowiedz

4

myślę, że trzeba trampolina zawsze (lub prawie zawsze) załadowany do jądra.

W kodzie trampoliny potrzebne są takie zmienne.

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***** */ 

Kiedy ip_vs_utils załadowaniu trzeba init wszystkie zmienne, kod inicjalizacji w 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; 

i dodać w kodzie funkcji trampolina trampolina:

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() jest potrzebny, aby zabezpieczyć moduł przed nagle rozładowaniem podczas wywoływania funkcji ip_vs_utils_afunc_ptr(). Można również użyć RCU, aby zmniejszyć narzut try_module_get()/module_put(). (Ale to jest trudne)

Albo można stosować niektóre trampolina-siekać jak Dynamic Link w przestrzeni użytkownika (może trzeba zmienić wiele w jądrze Linux)

+0

Dziękuję bardzo za odpowiedź, myślę, że to zadziała dla mnie. Tylko pytanie. Co się stanie, jeśli mój moduł ip_vs_utils zostanie załadowany przed innymi? Czy linia 'ip_vs_utils_afunc_ptr = ip_vs_utils_afunc_impl;' nie wygeneruje błędu, ponieważ ip_vs_utils_afunc_ptr nie znajduje się jeszcze w tablicy symboli? – marcocamejo

+1

W takim przypadku może być konieczne dołączenie trampoliny do jądra (lub modułu, który jest zawsze ładowany podczas uruchamiania systemu). trampolina jest zwykle ekstremalnie mniejsza od rzeczywistej implementacji, można ją zawsze załadować. –

+0

Czy to w ten sposób. Jeszcze raz bardzo dziękuję! – marcocamejo

Powiązane problemy