2012-06-25 5 views
6

Ich habe einen Linux-Zeichen Gerätetreiber, der einen /dev/mything Eintrag erstellt, und dann ein C++/Qt-Programm, das das Gerät öffnet und es verwendet. Wenn das Programm ordnungsgemäß beendet wird, wird das Gerät mit exit() geschlossen und der Treiber wird ordnungsgemäß zurückgesetzt. Aber wenn das Programm abnormal beendet wird, über segfault oder SIGINT oder etwas, wird das Gerät nicht richtig geschlossen.Wie kann ein Linux-Zeichengerätetreiber erkennen, wenn ein Programm, das es verwendet, abnormal beendet wird?

Meine aktuelle Problemumgehung besteht darin, den Treiber neu zu laden, wenn es im Status "offen" stecken bleibt.

Diese Zeile in der Fahrer versucht, mehrere Programme gleichzeitig mit dem Gerät zu verhindern:

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

Dann ist dieses reinigt es auf:

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

Ich denke, exit()mything_release aufgerufen werden, verursacht aber SIGINT ist nicht. Wie kann ich den Fahrer für solche Situationen robuster machen?

EDIT:

Hier sind die Operationen, die ich umgesetzt haben. Vielleicht vermisse ich etwas?

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

Wenn der Prozess beendet wird oder beendet wird, wird der Kernel die Ressourcen freigeben. Einbeziehen der Referenzzählung in alle offenen Dateideskriptoren. – wildplasser

+0

Wenn dies der Fall ist, warum bekomme ich nach dem Beenden meines Programms mit SIGINT/segfault "Gerät oder Ressource beschäftigt", wenn ich versuche, das Programm erneut zu öffnen? Ich sehe diesen Fehler nicht, wenn ich ihn sauber verlasse und ihn wieder öffne. – Dave

+0

Ich kenne Ihren Code nicht. Vielleicht haben Sie den falschen Wert für den Bufcount? Vielleicht haben Sie keine der notwendigen Funktionen implementiert? – wildplasser

Antwort

1

Das Problem an dieser Linie in mything_release kocht, in setzen zu warten, einige Speicher zu füllen, schreibt:

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

Mit einem normalen Programmende, würde dies für 10 jiffies drehen und weiter entlang. Aber mit einem abnormalen Beenden von SIGINT oder etwas, ich denke, die unterbrechbare Timeout wurde unterbrochen und es -ERESTARTSYS zurückgegeben, was meine, wenn ich das gleiche zurückgeben.

Die Sache, die für mich gearbeitet wurde nur die if loszuwerden und nur warten:

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

Dieser Patch von Jahren machte mich glauben, dass ERESTARTSYS von einer Schließ-/_Release Funktion Rückkehr nicht gut ist Idee: http://us.generation-nt.com/answer/patch-fix-wrong-error-code-interrupted-close-syscalls-help-181191441.html

2

Dieser Test ist nicht erforderlich; Das Problem ist nicht abnormal Programm Beendigung (die, aus der Sicht Ihres Fahrers, ist genau wie eine normale close auf dem Gerät), sondern stattdessen ein Problem in der staatlichen Haltung Ihres Geräts. Mit anderen Worten, wenn Sie close(dev_fd) oder sogar exit(0) genau an der Stelle eingefügt haben, wo Ihr Programm abstürzt, haben Sie das gleiche Problem.

Sie sollten herausfinden, welcher Teil des Verhaltens Ihres Treibers verursacht, dass es in einem ausgelasteten Zustand bleibt, und das beheben.

+0

Ich habe oben den Rat von wildplasser genommen und einige Printk-Aufrufe in 'mything_release' eingefügt. Ich habe eine Zeile gefunden, die lautet: if (wait_event_interruptible_timeout (port-> inq, false, 10)) gibt "ERESTARTSYS;" zurück und erkennt, dass bei abnormaler Beendigung diese Zeile nie überschritten wird. Google lässt mich denken, ERESTARTSYS ist keine gute Sache, um von einer nahen Funktion zurückzukehren. – Dave

Verwandte Themen