2012-06-25 5 views
6

/dev/mythingエントリを作成するLinuxキャラクタデバイスドライバ、次にデバイスを開いて使用するC++/Qtプログラムがあります。そのプログラムが正しく終了すると、exit()、デバイスが閉じられ、ドライバが正しくリセットされます。しかし、プログラムがsegfaultまたはSIGINTなどで異常終了すると、デバイスが正しく閉じられません。Linuxのキャラクタデバイスドライバは、それを使用するプログラムが異常終了すると、どのように検出できますか?

私の現在の回避策は、ドライバが「オープン」状態になってもリロードすることです。ドライバで

この行が同時にデバイスを使用して複数のプログラムを防ぐためにしようとします:

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ていると思いますそうではありません。このような状況に対して、ドライバをより堅牢にするにはどうすればよいですか?

EDIT:

は、ここで私が実装した操作です。多分私は何かを欠いているでしょうか?

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で終了した後に、プログラムを再オープンしようとすると、 'Device or resource busy'が発生するのはなぜですか?私はそれをきれいに終了して、それを再び開くと、私はそのエラーは表示されません。 – Dave

+0

あなたのコードは分かりません。 bufcountに間違った価値があるかもしれませんか?必要な機能の1つを実装していない可能性がありますか? – wildplasser

答えて

1

mything_releaseにこのラインに煮詰め問題、いくつかのメモリを待つ入れる完了するにはこう書いている:

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

通常のプログラムを終了して、これは10個の単位jiffiesのためのスピンと一緒に続けるだろう。しかし、SIGINTまたは何かからの異常な終了により、割り込み可能なタイムアウトが中断し、-ERESTARTSYSが返され、私のifが同じものを返す原因となったと思います。

私のために働いた事はただifを取り除くと待つだけになった:

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

年前からこのパッチは私が近い/ _release関数からERESTARTSYSを返すことは良くないと信じて作られましたidea: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

私は上記のwildplasserの助言を受け取り、 'mything_release'にいくつかのprintk呼び出しを挿入しました。 'if(wait_event_interruptible_timeout(port-> inq、false、10))を返す-ERESTARTSYS;'という行を見つけました。異常終了すると、決してその行を越えることはありません。 Googleでは、ERESTARTSYSがクローズ機能から復帰するのは大丈夫だとは思わない。 – Dave

関連する問題