web-dev-qa-db-ja.com

NFSでinotify

最近、inotifyを使用して、特定のディレクトリで作成されたファイルを監視するDropboxシステムを作成しました。私が見ているディレクトリはNFSサーバーからマウントされており、inotifyの動作は予想とは異なります。 inotifyスクリプトがマシンAで実行され、/ some/nfs/dir/also/visible/to/Bを監視する次のシナリオを考えます。

-マシンAを使用して/ some/nfs/dir/also/visible/to/Bにファイルを作成すると、スクリプトは期待どおりに動作します。マシンBを使用して同じアクションを実行すると、ディレクトリにドロップされた新しいファイルについてスクリプトに通知されません。
-NFSサーバーでスクリプトを実行すると、マシンAとマシンBの両方からファイルが作成されたときに通知されます。

これは、私がinotofyにアクセスするために使用しているパッケージのバグのバグですか、またはこれは予想される動作ですか?

57
ajwood

inotifyが機能するには、カーネルのサポートが必要です。アプリケーションがディレクトリを追跡すると、それらの変更が発生したときにカーネルに通知するようカーネルに要求します。変更が発生すると、それらの変更をディスクに書き込むことに加えて、カーネルは監視プロセスにも通知します。

リモートNFSマシンでは、変更はカーネルには見えません。完全にリモートで発生します。 NFSはinotifyよりも前のものであり、NFSでのネットワークレベルのサポートはありません。

これを回避したい場合は、ストレージマシン上でサービスを実行し(カーネルは常にファイルシステムの変更を確認するため)、リモートマシンへのリクエストを仲介し、データをリモートクライアントに転送できます。

編集:[〜#〜] nfs [〜#〜] が不足していると非難されるべきだと思うinotifyのサポート。

ネットワークファイルシステム(NFS)は、1984年にSun Microsystemsによって開発された分散ファイルシステムプロトコルですwikipediaの記事

しかしながら:

Inotify(inode notify)はLinuxカーネルサブシステムであり、ファイルシステムの変更を通知するためにファイルシステムを拡張する働きをします。 [...]リリース2.6.13からメインラインLinuxカーネルに含まれています(6月18日、2005)[...]。 ウィキペディアの記事

ポータブルネットワークプロトコル/アプリケーションが、異なるオペレーティングシステム用に開発された特定のカーネル機能をサポートし、20年以上後に現れたを期待するのは困難です。didに拡張機能が含まれていても、他のオペレーティングシステムでは使用できず、有用でもありません。

*すべての場合の強調鉱山


これに関する別の問題。ネットワークをまったく使用していないと仮定します。代わりに、適切なinotifyサポートを備えたローカルファイルシステムを使用します。ext3(/mnt/foo)。しかし、実際のディスクの代わりに、ファイルシステムはループバックデバイスからマウントされます。そして、基礎となるファイルは、vfsの別の場所でアクセス可能です(たとえば、/var/images/foo.img)。

これで、マウントされたext3ファイルシステムを変更することは想定されていませんが、メタデータではなくファイルの内容を変更する場合は、それでもかなり安全です。

そのため、賢いユーザーがファイルシステムイメージ(/var/images/foo.img)16進エディタで、ファイルの内容を他のデータに置き換え、同時にinotifyウォッチがマウントされたファイルシステム上の同じファイルを監視している。

Inotifyがこの種の変更を監視プロセスに常に通知するように手配できる合理的な方法はありません。おそらくext3に通知して変更を尊重するために取ることができる回転がいくつかあるかもしれませんが、それ以外はたとえばxfs drtiverには当てはまりません。

それもするべきではありません。不正行為です! inotifyは、監視対象の実際のマウントポイントでvfsを介して発生した変更のみを通知できます。基礎となるデータの変更のために、そのVFSの外部で変更が発生した場合、inotifyは役に立たず、その問題を解決するようには設計されていません。

ネットワーク通知にメッセージキューを使用することを検討しましたか?

SGI [〜#〜] fam [〜#〜] を見つけました。監視デーモンを使用してファイルの変更を監視します。 NFSをサポートしており、 wiki でいくつかの説明を見ることができます。

6
cmchao

Dockerのバインドマウントがホストディレクトリからのファイル変更を検出しない理由の答えを探してこの質問に出くわした人(アプリのホットリロード用)は、ホストとコンテナ間のファイル変更の伝播がそうではないためですコンテナカーネルと通信します。

コンテナ自体からの変更のみがカーネルに伝達されます。これに対する解決策は、fsnotifyを使用する代わりに、ライブリロードユーティリティで「ポーリングモード」を有効にすることです。

3
Derian Tungka

@SingleNegationEliminationを2回目にします。

また、 notify-forwarder を試すこともできます。

  • マシンAはローカルのinotifyイベントを監視し、それらをマシンUDPに転送します(UDP経由)。
  • マシンBはイベントを再生しません(できませんか?)が、変更されたファイルに対してATTRIBイベントを発生させます。

Vagrantを使用する場合は、 vagrant-notify-forwarder を使用します。

0
jchook

SingleNegationEliminationの説明に同意し、iSCSIターゲットはカーネルに警告するため、iSCSIターゲットが機能することを追加したいと思います。

そのため、「システム」に関連する「実際の」ファイルシステム上のものがInotifyのアラートをトリガーします。 Rsyncのように、マウントされたパーティションに何かをネットキャッチします。

Inotify経由で通知を取得する必要がある場合(またはinotifyを使用する必要がある場合)、ファイルシステムにcronをrsync -avz経由で作成できます。もちろん欠点は、実際のシステムのhddスペースを使用していることです。

0
Richard Tang