2012-07-13 16 views
5

Linux Sanal Sunucusuna (LVS) bazı işlevler eklemek için Linux Kernel'i değiştiriyorum.Dışa aktarılan sembolleri isteğe bağlı olarak, yalnızca modifiye edilmiş bir Linux Kernel modülünde mevcutsa nasıl kullanılır?

Yük dengeleme sırasında bazı işlevlerle birlikte bir modül geliştirdim (net/netfilter/ipvs/ip_vs_utils.c'u aradım). Buradaki tüm fonksiyonlar EXPORT_SYMBOL() kullanılarak verilir.

Bu modül, mantıksal olarak her zaman yüklenmez. Amacım, kullanıcının bu ek işlevselliği kullanmak isteyip istemediğine karar vermesine izin vermektir (modülü yükleme veya boşaltma).

Sorum şu: Bu işlevler (modül çalışıyorsa veya çalışmıyorsa) OPSİYONEL modülleri (net/netfilter/ipvs/ip_vs_core.c) (net/netfilter/ipvs/ip_vs_core.c) içinden nasıl çağırabilirim. Böyle bir şey:

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

sizin 'if (ip_vs_utils eğer Lai cevabı oldukça iyidir) 'kodun her zaman çekirdekte olması amaçlanmıştır; ancak bu kodun kendisi başka bir yüklenebilir modülde bulunuyorsa, muhtemelen basit modül bağımlılığı daha iyi bir yaklaşımdır. Tüm ayrıntılar için bkz. Depmod (8) – sarnold

cevap

4

Sana bir trambolin daima (ya da hemen hemen her zaman) çekirdeğin içine yüklenen gerek.

Trambolin kodunda, bu gibi değişkenlere gereksiniminiz vardır.

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; 

Ve trambolin kodunda trambolin işlevleri ekleyin:

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; 
} 
ip_vs_utils yüklendiğinde

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

, sen ip_vs_utils.c tüm değişkenleri başlatma kodu init gerekir Ip_vs_utils_afunc_ptr() çağrılırken modülün aniden boşalmasını önlemek için

try_module_get() gereklidir. Ayrıca, try_module_get()/module_put() ek yükünü azaltmak için RCU kullanabilirsiniz.

(Ama zor) Yoksa userspace dinamik bağlantı gibi trambolin-kesmek bazıları (sen Linux çekirdeğinde çok değiştirmek gerekebilir) kullanılması mümkün olabilecek

+0

Cevabınız için çok teşekkür ederim, bence bu benim için çalışacak. Sadece bir soru. Benim ip_vs_utils modülüm diğerlerinden önce yüklenirse ne olur? Ip_vs_utils_afunc_ptr satırı henüz bir sembol atamaz çünkü ip_vs_utils_afunc_ptr henüz sembol tablosunda değil. – marcocamejo

+1

Bu durumda, trambolinin çekirdeğe (veya sistem önyüklemesi sırasında her zaman yüklü olan bir modüle) bağlanması gerekebilir. Trambolin genellikle gerçek uygulamadan çok daha küçüktür, her zaman yüklü olmasını sağlamak için Tamam. –

+0

Bu şekilde mi? Yine, çok teşekkür ederim! – marcocamejo

İlgili konular