4

ドライブをリカバリ モードでマウントし、再起動時にストリームにゼロの fsevents を取得する FSEvents で奇妙な動作が見られます。私は次のことを行います:

  1. 定期的に起動
  2. FSEventsGetCurrentEventId() で現在のイベントを記録する
  3. 回復モードで起動し、監視パス内のファイルを変更します
  4. システムを再起動します

これが発生すると、fsevents API を使用してもイベントがまったく取得されません。通常のOSで他の変更を行った場合でも、kFSEventStreamEventFlagHistoryDoneセンチネルで送信する唯一のフラグ。

このars technicaのレビューは、他のデバイスにマウントするときにkFSEventStreamEventFlagMustScanSubDirsフラグを取得する必要があることを暗示しているようですが、その動作は見られません. 誰もこれに遭遇したことがありますか?OSがオフのときにドライブが別の場所にマウントされた場合を検出して処理するより良い方法はありますか?

更新:Linuxから起動してファイルシステムを変更するのと同じことを試みました。何があっても 0 イベントという同じ奇妙な動作は発生しませんでしたが、変更したディレクトリまたは MustScanSubdirs フラグからのイベントも取得しませんでした。

更新 2:このスレッドで受け入れられた応答は、これが発生すると、上記の状況でログが古くなっていることをタイム マシンが検出することを示しています。ログが古くなっているかどうかを検出する方法を知っている人はいますか? この日付は、フラグの代わりに使用できます。

4

1 に答える 1

2

手順 2 で FSEvents データベースの UUID も保存し、手順 4 で確認する必要があると思います。

この動作は、Apple のドキュメントで漠然と言及されています(強調を追加)。

注:ディスクは以前のバージョンの OS X (または他のオペレーティング システム) を実行しているコンピューターによって変更される可能性があるため、イベント リストは、ボリュームに対するすべての変更の決定的なリストではなく、助言として扱う必要があります。以前のバージョンの OS X を実行しているコンピューターによってディスクが変更された場合、履歴ログは破棄されます。

たとえば、バックアップ ソフトウェアは定期的にボリュームの完全なスイープを実行して、変更が見過ごされないようにする必要があります。

破棄されている履歴ログについて少し注意してから、参照を見てください(強調を追加):

FSEventStreamGetLatestEventId() -> 最初に、ストリームが作成されたときに指定された sinceWhen 値を返します。その後、クライアントのコールバックを呼び出す直前に、現在のイベントのバッチで言及されている最大番号のイベント ID で更新されます。クライアントは、デバイスの UUID (FSEventsCopyUUIDForDevice() で取得)も格納している限り、この値を永続的に格納できます。UUID が保存したものと一致する限り、クライアントは後でこのイベント ID を sinceWhen パラメータとして FSEventStreamCreateRelativeToDevice() に提供できます。これが機能するのは、FSEvents サービスが永続的なボリュームごとのデータベースにイベントを格納するためです。この点で、イベント ID のストリームは、グローバルなシステム全体のクロックのように機能しますが、特定のタイムベースとは関係ありません。

FSEventsCopyUUIDForDevice() -> そのボリュームの FSEvents データベースを一意に識別する UUID を取得します。データベースが破棄された場合、クライアントがこの状況を検出し、FSEventStreamCreate...() 関数への sinceWhen パラメータとして保存したイベント ID を使用しようとすることを回避できるように、その代わりに別の UUID が割り当てられます。

UUID はデバイスごとであることに注意してください。そのため、ディレクトリ ツリー内にマウントされているファイル システムがある場合は、おそらくそれぞれの UUID を取得する必要があります。

幸運を!

于 2012-09-05T01:29:34.383 に答える