2012-07-13 19 views
5

मैं लिनक्स वर्चुअल सर्वर (एलवीएस) में कुछ कार्यक्षमता जोड़ने के लिए लिनक्स कर्नेल को संशोधित कर रहा हूं।निर्यात किए गए प्रतीकों का वैकल्पिक रूप से केवल तभी उपयोग करें जब वे एक विस्थापित लिनक्स कर्नेल मॉड्यूल में मौजूद हों?

मैंने लोड-बैलेंसिंग के दौरान उपयोग किए जाने वाले कुछ कार्यों के साथ एक मॉड्यूल विकसित किया (जिसे मैंने net/netfilter/ipvs/ip_vs_utils.c कहा)। यहां सभी कार्यों को EXPORT_SYMBOL() का उपयोग करके निर्यात किया जाता है।

यह मॉड्यूल, तार्किक रूप से हर समय लोड नहीं होता है। मेरा इरादा उपयोगकर्ता को यह तय करने की अनुमति देना है कि क्या वह इस अतिरिक्त कार्यक्षमता का उपयोग करना चाहता है या नहीं (मॉड्यूल लोड करना या उतारना)।

मेरा प्रश्न यह है कि मैं इन कार्यों को कैसे लागू कर सकता हूं (मौजूदा मॉड्यूल चल रहा है या नहीं) मौजूदा (और निश्चित रूप से संशोधित) मॉड्यूल (net/netfilter/ipvs/ip_vs_core.c) से। कुछ इस तरह:

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

लाइ का जवाब अगर आपके 'अगर (ip_vs_utils काफी अच्छा है) 'कोड कर्नेल में हर समय होने का इरादा है; लेकिन यदि वह कोड स्वयं किसी अन्य लोड करने योग्य मॉड्यूल में स्थित है, तो शायद सरल मॉड्यूल निर्भरता बेहतर दृष्टिकोण है। पूर्ण विवरण के लिए 'depmod (8)' देखें। – sarnold

उत्तर

4

मैं तुम्हें एक ट्रैम्पोलिन हमेशा (या लगभग हमेशा) कर्नेल में लोड की जरूरत है।

ट्रैम्पोलिन कोड में, आपको ऐसे चर की आवश्यकता है।

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; 

और ट्रैम्पोलिन कोड में ट्रैम्पोलिन कार्यों को जोड़ने:

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; 
} 

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

जब ip_vs_utils भरी हुई है, तो आप ip_vs_utils.c में सभी चर, प्रवर्तन कोड init करने की जरूरत है Ip_vs_utils_afunc_ptr() को लागू किया जा रहा है, जबकि मॉड्यूल को अचानक अनलोड होने से बचाने के लिए

try_module_get() की आवश्यकता है। try_module_get()/module_put() के ओवरहेड को कम करने के लिए आप आरसीयू का भी उपयोग कर सकते हैं। (लेकिन यह कठिन है)

या आप इस्तेमाल किया कुछ यूज़रस्पेस में गतिशील लिंक की तरह ट्रैम्पोलिन-हैक (आप लिनक्स कर्नेल में एक बहुत बदलना पड़ सकता है) कर सकते हैं

+0

आपके उत्तर के लिए बहुत बहुत धन्यवाद, मुझे लगता है कि यह मेरे लिए काम करेगा। सिर्फ एक प्रश्न। क्या होता है यदि मेरे मॉड्यूल ip_vs_utils दूसरों के सामने लोड हो? लाइन 'ip_vs_utils_afunc_ptr = ip_vs_utils_afunc_impl नहीं होगी; 'एक त्रुटि फेंक दें क्योंकि ip_vs_utils_afunc_ptr अभी तक प्रतीक तालिका में नहीं है? – marcocamejo

+1

इस मामले में, आपको ट्राम्पोलिन को कर्नेल में जोड़ा जाना चाहिए (या एक मॉड्यूल जो सिस्टम बूट के दौरान हमेशा लोड होता है)। ट्रैम्पोलिन आमतौर पर असली कार्यान्वयन से बहुत छोटा होता है, इसे हमेशा लोड करना ठीक है। –

+0

क्या यह इस तरह से किया था। पुनः आपका बहुत - बहुत धन्यवाद! – marcocamejo