2009-11-16 16 views
16

का उपयोग करने के लिए जब मैं एलकेएमपीजी (See Section 4.1.4. Unregistering A Device) पढ़ रहा था और try_module_get/module_put फ़ंक्शंस का उपयोग करने के लिए मुझे यह स्पष्ट नहीं था। कुछ एलकेएमपीजी उदाहरण उनमें से कुछ का उपयोग करते हैं, कुछ नहीं करते हैं।लिनक्स कर्नेल मॉड्यूल: try_module_get/module_put

भ्रम को जोड़ने के लिए, try_module_get 2.6.24 स्रोत में 193 फाइलों में 282 बार दिखाई देता है, फिर भी Linux Device Drivers (LDD3) और Essential Linux Device Drivers में, वे नहीं एक भी कोड उदाहरण में दिखाई देता है।

मुझे लगा कि वर्ष register_chrdev इंटरफेस (cdev इंटरफ़ेस द्वारा 2.6 में अधिक्रमित) से संबद्ध थे, लेकिन वे केवल एक ही फाइल में एक साथ दिखाई देते 8 बार:

find -type f -name *.c | xargs grep -l try_module_get | sort -u | xargs grep -l register_chrdev | sort -u | grep -c . 

तो जब यह करने के लिए उचित है इन कार्यों का उपयोग करें और क्या वे किसी विशेष इंटरफ़ेस या परिस्थितियों के सेट के उपयोग से बंधे हैं?

संपादित

मैं LKMPG से sched.c उदाहरण भरी हुई और निम्न प्रयोग करने की कोशिश की:

[email protected]:~/kernel-source/lkmpg/2.6.24$ tail /proc/sched -f & 
Timer called 5041 times so far 
[1] 14594 

[email protected]:~$ lsmod | grep sched 
sched     2868 1 

[email protected]:~$ sudo rmmod sched 
ERROR: Module sched is in use 

इस ओर जाता है मुझे विश्वास है कि कर्नेल अब यह खुद लेखांकन है करता है और हो जाता है/डालता है अप्रचलित हो सकता है। क्या कोई इसे सत्यापित कर सकता है?

+0

वहाँ उपधारा 'संदर्भ गिनती manipulation' में अध्याय 14 में' try_module_get' में से एक घटना है, (पेज 367) –

+0

मैं हाल ही में मेरे पिछले टिप्पणी में LDD पुस्तक –

उत्तर

15

आपको अनिवार्य रूप से try_module_get (THIS_MODULE) का उपयोग नहीं करना चाहिए; बहुत सारे ऐसे उपयोग असुरक्षित हैं क्योंकि यदि आप पहले से ही अपने मॉड्यूल में हैं, तो संदर्भ गणना को टक्कर देने में बहुत देर हो चुकी है - हमेशा एक छोटी (छोटी) विंडो होगी जहां आप अपने मॉड्यूल में कोड निष्पादित कर रहे हैं लेकिन संदर्भ में वृद्धि नहीं हुई है गिनती। अगर कोई उस विंडो में मॉड्यूल को ठीक से हटा देता है, तो आप एक अनलोड किए गए मॉड्यूल में कोड चलाने की खराब स्थिति में हैं।

विशिष्ट उदाहरण आप LKMPG में जुड़े हुए जहां कोड struct file_operations में .owner क्षेत्र की स्थापना करके try_module_get करता है() खुला() विधि में आधुनिक कर्नेल में हैंडल किया जाएगा:

struct file_operations fops = { 
     .owner = THIS_MODULE, 
     .open = device_open, 
     //... 
}; 

इस वसीयत VFS कोड मॉड्यूल को से पहले मॉड्यूल का संदर्भ लेता है, जो असुरक्षित विंडो को समाप्त करता है - या तो try_module_get() कॉल से पहले .open(), या try_module_get() विफल हो जाएगा और VFS मॉड्यूल में कभी कॉल नहीं करेगा। किसी भी मामले में, हम कभी भी मॉड्यूल से कोड नहीं चलाते हैं जिसे पहले से ही अनलोड किया गया है।

केवल अच्छा समय try_module_get उपयोग करने के लिए() है जब आप इसे में कॉल करने या किसी तरह से इसे का उपयोग (पहले एक अलग मॉड्यूल पर एक संदर्भ ले जाना चाहते हैं जैसे फ़ाइल खुला कोड उदाहरण मैं समझाया में करता है के रूप में ऊपर)। कर्नेल स्रोत में try_module_get (THIS_MODULE) के कई उपयोग हैं, लेकिन अधिकतर यदि उनमें से सभी गुप्त बग हैं जिन्हें साफ़ किया जाना चाहिए।

कारण आप, अनलोड करने के लिए Sched उदाहरण है कि आपके

$ tail /proc/sched -f & 

आदेश/proc/खुला है, और

 Our_Proc_File->owner = THIS_MODULE; 
sched.c कोड में

की वजह से Sched रहता है में सक्षम नहीं थे ओपनिंग/proc/शेड शेड्यूल मॉड्यूल की संदर्भ गणना को बढ़ाता है, जो आपके lsmod दिखाता है कि 1 संदर्भ के लिए खाते हैं।शेष कोड की त्वरित स्किम से, मुझे लगता है कि अगर आप अपनी पूंछ कमांड को मार कर/proc/शेड्यूल करते हैं, तो आप शेड्यूल मॉड्यूल को हटाने में सक्षम होंगे।

+0

--- ठीक है, के रूप में मैं जानता हूँ कि मतलब काम करते हुए वॉचडॉग डिवाइस ड्राइवर पर, नो-वे-आउट नामक एक सुविधा है, जिसका अर्थ यह है कि एक बार यह डिवाइस शुरू हो जाने पर, आप इसे रोक नहीं सकते। इसी कारण से, इस मॉड्यूल को अनलोड नहीं किया जा सका, इसलिए, डिवाइस चालक के खुले() कार्यान्वयन में, डिवाइस ड्राइवर मॉड्यूल के साथ एक __module_get (THIS_MODULE) का उपयोग किया जाता है, हम जानते हैं, जब मॉड्यूल की संदर्भ गणना शून्य नहीं होती है , आप इसे अनलोड नहीं कर सकते हैं। एक निष्कर्ष में, शायद यही वह मामला है जहां आपको मॉड्यूल_get, मॉड्यूल_पुट, आदि का उपयोग करने की आवश्यकता है धन्यवाद। –

+0

'init_module' फ़ंक्शन के भीतर से' try_module_get' सुरक्षित है, लेकिन 'cleanup_module' से पहले किसी बिंदु पर मिलान' मॉड्यूल_पूट 'करना होगा। – fche

संबंधित मुद्दे