6

エントリを作成する Linux キャラクター デバイス ドライバーと/dev/mything、デバイスを開いて使用する C++/Qt プログラムがあります。そのプログラムが で正常に終了した場合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_releaseSIGINT

編集:

ここに私が実装した操作があります。多分私は何かを逃していますか?

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

2 に答える 2

2

このテストは必要ありません。問題はプログラムの異常終了ではなく (ドライバーの観点からは、デバイスの正常な状態とまったく同じですclose)、デバイスの状態維持の問題です。つまり、プログラムがクラッシュしている正確なポイントに挿入したclose(dev_fd)場合でも、同じ問題が発生します。exit(0)

ドライバーの動作のどの部分がビジー状態のままになっているのかを突き止め、それを修正する必要があります。

于 2012-06-25T16:55:12.293 に答える
1

問題は の次の行に要約されmything_release、いくつかのメモリ書き込みが完了するのを待つために挿入されました。

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

通常のプログラムの終了では、これは 10 jiffy スピンして続行します。しかし、SIGINTなどからの異常終了により、中断可能なタイムアウトが中断され、それが返さ-ERESTARTSYSれたため、ifが同じものを返したと思います。

私にとってうまくいったことは、を取り除き、ifただ待つことでした:

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

何年も前のこのパッチによりERESTARTSYS、close/_release 関数から戻るのは良い考えではないと思いました: http://us.generation-nt.com/answer/patch-fix-wrong-error-code-interrupted-close- syscalls-help-181191441.html

于 2012-06-25T18:01:25.930 に答える