2012-07-04 12 views
12

में चुनिंदा() और मतदान() का प्रभाव अनुकरण करें जो मैं विकसित कर रहा हूं लिनक्स कर्नेल ड्राइवरों में से एक कर्नेल (sock_create(), sock->ops->bind(), और इसी तरह) में नेटवर्क संचार का उपयोग कर रहा है।कर्नेल सॉकेट प्रोग्रामिंग

समस्या यह है कि डेटा प्राप्त करने के लिए कई सॉकेट होंगे। तो मुझे कुछ ऐसी चीज चाहिए जो कर्नेल स्पेस में select() या poll() अनुकरण करेगी। चूंकि ये फ़ंक्शन फ़ाइल डिस्क्रिप्टर का उपयोग करते हैं, इसलिए मैं सिस्टम कॉल का उपयोग नहीं कर सकता जब तक कि मैं सॉकेट बनाने के लिए सिस्टम कॉल का उपयोग नहीं करता, लेकिन यह कर्नेल में काम करने के बाद से अनावश्यक लगता है।

तो मैं अपने स्वयं के हैंडलर (custom_sk_data_ready()) में डिफ़ॉल्ट sock->sk_data_ready हैंडलर लपेटने की सोच रहा था, जो एक सेमफोर अनलॉक करेगा। फिर मैं अपना खुद का kernel_select() फ़ंक्शन लिख सकता हूं जो सेमफोर को लॉक करने का प्रयास करता है और जब तक यह खुला नहीं होता तब तक अवरुद्ध प्रतीक्षा करता है। इस तरह से कर्नेल फ़ंक्शन तब तक सो जाता है जब तक सैमफोर custom_sk_data_ready() द्वारा अनलॉक नहीं किया जाता है। एक बार kernel_select() लॉक हो जाता है, यह इसे अनलॉक करने के लिए अनलॉक करता है और custom_sk_data_ready() पर कॉल करता है। तो सॉकेट बाध्य करने से पहले custom_sk_data_ready() चलाने के लिए केवल एक ही अतिरिक्त प्रारंभिकता है ताकि custom_select() पर पहली कॉल झूठी ट्रिगर न हो।

मुझे एक संभावित समस्या दिखाई देती है। यदि एकाधिक प्राप्त होते हैं, तो custom_sk_data_ready() पर एकाधिक कॉल सेमफोर अनलॉक करने का प्रयास करेंगे। इसलिए एकाधिक कॉल खोने और sock का उपयोग करने के लिए ट्रैक करने के लिए, इस्तेमाल किए जाने वाले सॉकेट में पॉइंटर्स की एक तालिका या सूची होना आवश्यक होगा। और custom_sk_data_ready() को तालिका/सूची में ध्वजांकित करना होगा जो इसे सॉकेट किया गया था।

क्या यह विधि ध्वनि है? या मानक सिस्टम कॉल का उपयोग करते समय मुझे बस उपयोगकर्ता/कर्नेल स्पेस समस्या के साथ संघर्ष करना चाहिए?

प्रारंभिक ढूँढना:

sock संरचना के सभी कॉलबैक कार्यों व्यवधान संदर्भ में कहा जाता है। इसका मतलब है कि वे सो नहीं सकते हैं। मुख्य कर्नेल थ्रेड को तैयार सॉकेट की सूची में सोने की अनुमति देने के लिए, म्यूटेक्स का उपयोग किया जाता है, लेकिन custom_sk_data_ready() को म्यूटेक्स पर स्पिनलॉक की तरह कार्य करना चाहिए (mutex_trylock() बार-बार कॉल करना)। इसका मतलब यह भी है कि किसी गतिशील आवंटन को GFP_ATOMIC ध्वज का उपयोग करना चाहिए।


अतिरिक्त संभावना:

हर खुले सॉकेट के लिए, की जगह प्रत्येक सॉकेट के sk_data_ready() एक कस्टम (custom_sk_data_ready()) के साथ और एक कार्यकर्ता (struct work_struct) और काम कतार (struct workqueue_struct) पैदा करते हैं। प्रत्येक कार्यकर्ता के लिए एक आम process_msg() फ़ंक्शन का उपयोग किया जाएगा। कर्नेल मॉड्यूल-स्तरीय वैश्विक सूची बनाएं जहां प्रत्येक सूची तत्व में सॉकेट के लिए पॉइंटर होता है और इसमें कार्यकर्ता संरचना होती है। जब डेटा सॉकेट पर तैयार होता है, custom_sk_data_ready() उसी सॉकेट के साथ मेल खाने वाले सूची तत्व को निष्पादित और ढूंढ देगा, और फिर सूची तत्व की कार्य कतार और कार्यकर्ता के साथ queue_work() पर कॉल करें। फिर process_msg() फ़ंक्शन को कॉल किया जाएगा, और struct work_struct * पैरामीटर (पता) की सामग्री के माध्यम से मेल खाने वाले सूची तत्व को या तो container_of() मैक्रो का उपयोग करके संरचना संरचना को रखने वाली सूची संरचना का पता प्राप्त करने के लिए उपयोग कर सकते हैं।

कौन सी तकनीक सबसे अधिक ध्वनि है?

+0

क्या आपके पास 'मतदान' करने वाला उपयोगकर्ता-स्थान सहायक प्रोग्राम नहीं हो सकता है? 'पोल' या 'चयन' के साथ मल्टीप्लेक्सिंग इनपुट शेड्यूलर से संबंधित है (चूंकि रुकने की प्रक्रिया निष्क्रिय है, इसलिए अन्य प्रक्रियाएं चल सकती हैं) इसलिए मैं कर्नेल के अंदर ऐसा नहीं करूँगा! –

+1

@ बेसिलस्टारनकेविच: यही कारण है कि मैं केवल 'मतदान() 'और' चयन() 'की नींद अवरोधन अनुकरण करने की कोशिश कर रहा हूं। कर्नेल से उन दो सिस्टम कॉल का उपयोग करना एक अंतिम उपाय है। मुझे संदेह है कि उपयोगकर्ता अंतरिक्ष सहायक में 'मतदान() 'और' चयन()' चलाने में समस्याएं हैं। सहायक के पास फ़ाइल डिस्क्रिप्टर तक पहुंच होनी चाहिए (जो 'sock_create() 'में नहीं किया गया है) और संभावित रूप से कर्नेल स्पेस में रहने वाली सॉकेट तक पहुंचने की अनुमति है। तो अब उपयोगकर्ता अंतरिक्ष सहायक में सॉकेट निर्माण होना चाहिए और मॉड्यूल को उपयोगकर्ता स्पेस फ़ाइल डिस्क्रिप्टर के आधार पर सॉकेट ढूंढना होगा। अब यह और अधिक जटिल हो गया है। – Joshua

+0

आपको कर्नेल में ऐसा कोई नहीं करना चाहिए। – mpe

उत्तर

3

आपका दूसरा विचार लगता है जैसे यह काम करेगा।

सीईपीएच कोड ऐसा लगता है जैसे यह कुछ समान करता है, net/ceph/messenger.c देखें।

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