1. ホーム
  2. c

[解決済み] lseek/write が突然 errno = 9 (Bad file descriptor) で -1 を返した。

2022-01-29 08:15:27

質問

私のアプリケーションでは lseek() を使用して、データを書き込む位置を探します。 を使用してファイルを開くと、正常に open() で、私のアプリケーションは lseek()write() を何度も繰り返しています。

ある時期に、あるユーザーに対して、簡単に再現できない。 lseek() は-1を返し errno この前にファイルは閉じられておらず、ファイルハンドル (int) はリセットされていません。

この後、別のファイルが作成されます。 open() はまた大丈夫で lseek()write() が再び動作するようになりました。

さらに悪いことに、このユーザーはもう一度完全なシーケンスを試したところ、すべてうまくいきました。

そこで質問なのですが、OSが何らかの理由でファイルハンドルを閉じてしまうことはあるのでしょうか? 何がこれを引き起こすのでしょうか?ファイル・インデクサやファイル・スキャナのようなものでしょうか?

これを解決する最良の方法は何でしょうか。この疑似コードは最良の解決策でしょうか。 (コードのレイアウトは気にしないでください。)

int fd=open(...);
if (fd>-1) {
  long result = lseek(fd,....);
  if (result == -1 && errno==9) {
      close(fd..); //make sure we try to close nicely
      fd=open(...);

      result = lseek(fd,....);
  }
}

どなたか同じような経験をお持ちの方はいらっしゃいますか?

要約: ファイルのシークと書き込みが与えられた fd に対して問題なく動作し、突然理由もなく errno=9 が返される。

解決方法は?

どのような設定をされているかわかりませんが、次のようなシナリオで、そのような効果(またはそれに似たもの)が得られると思います。 私はこれを検証するためにテストしていませんので、塩漬けにしてください。

あなたが開いているファイル/デバイスがサーバーアプリケーションとして実装されている場合(例:NFS)、サーバーアプリケーションがダウン/再起動/リブートした場合に何が起こるかを考えてみてください。 クライアント側で有効だったファイルディスクリプタが、サーバー側では有効なファイルハンドルに対応しなくなる可能性があります。 これは、クライアントがEBADFを取得する一連のイベントにつながる可能性があります。

ご参考になれば幸いです。