2012-06-25 2 views
6

मेरे पास एक लिनक्स कैरेक्टर डिवाइस ड्राइवर है जो /dev/mything एंट्री बनाता है, और फिर एक सी ++/क्यूटी प्रोग्राम जो डिवाइस खोलता है और इसका उपयोग करता है। यदि वह प्रोग्राम exit() के साथ सही ढंग से बाहर निकलता है, तो डिवाइस बंद हो जाता है और ड्राइवर ठीक से रीसेट हो जाता है। लेकिन अगर कार्यक्रम असामान्य रूप से बाहर निकलता है, segfault या SIGINT या कुछ के माध्यम से, डिवाइस ठीक से बंद नहीं होता है।एक लिनक्स कैरेक्टर डिवाइस ड्राइवर कैसे पता लगा सकता है जब इसका उपयोग करने वाला प्रोग्राम असामान्य रूप से बाहर निकलता है?

मेरा वर्तमान वर्कअराउंड ड्राइवर को फिर से लोड करना है अगर यह "खुले" राज्य में फंस जाता है।

ड्राइवर में इस लाइन एक साथ डिवाइस का उपयोग कर कई कार्यक्रमों को रोकने की कोशिश करता है:

int mything_open(struct inode* inode, struct file* filp) { 
    ... 
    if (port->rings[bufcount].virt_addr) return -EBUSY; 
    ... 
} 

तो यह साफ अप:

int mything_release(struct inode* inode, struct file* filp) { 
    ... 
    port->rings[bufcount].virt_addr = NULL; 
    ... 
} 

मुझे लगता है कि exit() के नाम से जाना mything_release लेकिन SIGINT खड़ी कर रहा है नहीं है। मैं इस तरह की स्थिति में ड्राइवर को और अधिक मजबूत कैसे बना सकता हूं?

संपादित करें:

यहाँ संचालन मैं लागू कर दिया है कर रहे हैं। शायद मुझे कुछ याद आ रहा है?

static struct file_operations fatpipe_fops = { 
    .owner = THIS_MODULE, 
    .open =  mything_open, 
    .release = mything_release, 
    .read =  mything_read, 
    .write = mything_write, 
    .ioctl = mything_ioctl 
}; 
+2

जब प्रक्रियाएं निकलती हैं या समाप्त हो जाती हैं, तो कर्नेल संसाधनों को मुक्त कर देगा। किसी भी खुले फ़ाइल वर्णनकर्ताओं पर संदर्भ गणना शामिल है। – wildplasser

+0

यदि ऐसा है, तो यह क्यों है कि मेरे प्रोग्राम के बाद SIGINT/segfault के साथ समाप्त हो जाता है, जब मैं प्रोग्राम को फिर से खोलने का प्रयास करता हूं तो मुझे 'डिवाइस या संसाधन व्यस्त' मिलता है? अगर मैं इसे साफ़ से बाहर निकलता हूं और इसे दोबारा खोलता हूं तो मुझे वह त्रुटि दिखाई नहीं देती है। – Dave

+0

मुझे आपका कोड पता नहीं है। शायद आपके पास bufcount के लिए गलत मूल्य है? शायद आपने आवश्यक कार्यों में से एक को लागू नहीं किया है? – wildplasser

उत्तर

1

समस्या mything_release में इस लाइन के लिए नीचे उबला हुआ, में डाल कुछ स्मृति के लिए पूरा करने के लिए प्रतीक्षा करने के लिए लिखते हैं: एक सामान्य कार्यक्रम बाहर निकलने के साथ

if (wait_event_interruptible_timeout(port->inq, false, 10)) return -ERESTARTSYS; 

, इस 10 jiffies के लिए स्पिन और साथ जारी रहेगा। लेकिन SIGINT या किसी चीज़ से असामान्य निकास के साथ, मुझे लगता है कि इंटरप्टिबल टाइमआउट बाधित हो गया है और यह -ERESTARTSYS लौटा, जिससे मेरा वापस लौटाया जा सके।

बात है कि मेरे लिए काम किया बस if से छुटकारा पाने के लिए और बस इंतज़ार था:

wait_event_interruptible_timeout(port->inq, false, 10); 

साल पहले से इस पैच मुझे विश्वास है कि एक करीबी/_release समारोह से लौट रहे ERESTARTSYS एक अच्छा नहीं है बनाया विचार: http://us.generation-nt.com/answer/patch-fix-wrong-error-code-interrupted-close-syscalls-help-181191441.html

2

इस परीक्षण की कोई आवश्यकता नहीं है; समस्या असामान्य प्रोग्राम समाप्ति नहीं है (जो, आपके ड्राइवर के दृष्टिकोण से, डिवाइस पर सामान्य close की तरह है) लेकिन इसके बजाय आपके डिवाइस को रखने में राज्य में समस्या है। दूसरे शब्दों में, यदि आपने close(dev_fd) या exit(0) को उस सटीक बिंदु पर डाला जहां आपका प्रोग्राम क्रैश हो रहा है, तो आपको एक ही समस्या होगी।

आपको यह पता लगाना चाहिए कि आपके चालक के व्यवहार का कौन सा हिस्सा व्यस्त राज्य में रहना और इसे ठीक करना है।

+0

मैंने ऊपर से जंगली प्लेसर्स की सलाह ली, और 'mything_release' में कुछ प्रिंटक कॉल डाले। मुझे एक पंक्ति मिली जो 'if (wait_event_interruptible_timeout (port-> inq, false, 10)) वापसी -ERESTARTSYS; ', और एहसास हुआ कि असामान्य समाप्ति के साथ, यह उस पंक्ति से पहले कभी नहीं मिलता है। Google मुझे लगता है कि एक करीबी फ़ंक्शन से वापस लौटने के लिए ERESTARTSYS ठीक नहीं है। – Dave

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