inotifyは、書き込みの開始時または完了時に通知を起動しますか?


12

ext3 fs上の通常のファイルを介して通信する2つのプロセス、リーダーとライターを想像してください。Reader IN_MODIFYにはファイルのinotify ウォッチがあります。ライターは、1回のwrite()呼び出しでファイルに1000バイトを書き込みます。Readerはinotifyイベントを取得fstatし、ファイルを呼び出します。リーダーには何が見えますか?

  1. Readerがst_sizeファイルに対して少なくとも1000を取得するという保証はありますか?私の実験から、そうではないようです。

  2. Readerが実際にread()1000バイトできるという保証はありますか?

これは、真剣にI / Oバウンドボックスで発生しています。たとえばsar、約1秒の待機時間を示します。私の場合、リーダーはを呼び出す前にinotifyイベントを取得してから10秒待ってから、stat結果が小さすぎます。

私が期待していたのは、ファイルの準備が整うまでinotifyイベントが配信されないことでした。私が実際に起こっていると思うのwrite()は、ライターでの呼び出し中にinotifyイベントが発生し、データが準備ができたときにシステム上の他のプロセスで実際に利用できることです。この場合、10秒では十分ではありません。

私は、カーネルが実際に私が推測している方法を実装していることの確認を探しているだけだと思います。また、おそらく、この動作を変更するオプションがありますか?

最後に-この振る舞いを考えると、inotifyのポイントは何ですか?とにかく、イベントを取得した後、データが実際に利用可能になるまで、ファイル/ディレクトリをポーリングすることになります。それをずっとやっていて、inotifyを忘れることもあります。

*** 編集 ** * * さて、よくあることですが、私が実際にやっていることが理解できたので、私が見ている行動は実際に理にかなっています。^ _ ^

私は実際に、ファイルが存在するディレクトリのIN_CREATEイベントに応答しています。したがって、実際には、ファイルの作成に応答してファイルをstat()しています。必ずしもIN_MODIFYイベントではなく、後で到着する可能性があります。

コードを変更して、IN_CREATEイベントを取得したら、ファイル自体でIN_MODIFYにサブスクライブし、IN_MODIFYイベントを取得するまで実際にファイルを読み取ろうとしないようにします。ファイルへの書き込みを見逃す可能性のある小さなウィンドウがあることを認識していますが、最悪の場合、最大秒数後にファイルが閉じられるため、これは私のアプリケーションでは受け入れられます。


ファイルの代わりにパイプを使用できます。
マンノックを

2つのプロセスの間に数テラバイトのバッファーを確保するには、通常のファイルを使用する必要があります。また、再起動後もバッファ内のデータを保持します。
トッド解放

回答:


5

カーネルソースで見たものから、inotifyは書き込みが完了した後にのみ起動します(つまり、推測が間違っています)。通知がトリガーされた後、syscall sys_writeを実装する関数では、さらに2つのことが発生しwriteます。いくつかのスケジューラーパラメーターの設定と、ファイル記述子の位置の更新です。このコードは、2.6.14までさかのぼります。通知が発生する頃には、ファイルはすでに新しいサイズになっています。

問題が発生する可能性のあるものを確認します。

  • 読者は以前の記事から古い通知を受け取っているかもしれません。
  • 読者が電話をかけstatてから電話をかける、readまたはその逆の場合、間に何かが起こる可能性があります。ファイルに追加し続ける場合、stat最初に呼び出すと、そこまで読むことができることが保証されますがread、まだinotify通知を受け取っていなくても、リーダーが呼び出すまでにさらにデータが書き込まれている可能性があります。
  • ライターが呼び出したからといっwriteて、カーネルが要求された数の文字を書き込むとは限りません。アトミック書き込みが任意のサイズまで保証される状況はほとんどありません。writeただし、各呼び出しはアトミックに保証されています。ある時点で、データはまだ書き込まれておらず、突然nバイトが書き込まれています。ここで、nwrite呼び出しの戻り値です。部分的に書き込まれたファイルを観察する場合、それはwriteそのサイズ引数よりも小さい値を返したことを意味します。

何が起こっているかを調査するための便利なツールには次のものがあります。

  • strace -tt
  • 監査サブシステム

アイデアをありがとう。私はコードをレビューしましたが、実際には、エラーの場合の書き込みからの戻り値として-1のみをチェックしています。したがって、すべてのデータが書き込まれたことを示す書き込みからの戻り値を取得していない可能性があります。それでも、事実を追ってファイルを見ると、「1000」バイトのすべてが実際に書き込まれていることがわかります。これは、ファイルが良好な状態にある、つまり、一貫性のあるレコード全体で構成されているためです。したがって、最初のレコードは部分的に書き込まれていません。
トッド解放
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.