Обработка FSEvents диска, измененного другой ОС

Я наблюдаю странное поведение на FSEvents, когда я монтирую свой диск в режиме восстановления, а при перезагрузке получаю ноль fsevents в своем потоке. Я делаю следующее:

  1. Регулярно загружайтесь
  2. Запишите текущее событие с помощью FSEventsGetCurrentEventId()
  3. Загрузитесь в режиме восстановления и измените файл в отслеживаемом пути
  4. Перезагрузите систему

Когда это происходит, я вообще не получаю никаких событий, когда использую fsevents API. Единственный флаг, который он отправляет в дозорном kFSEventStreamEventFlagHistoryDone, даже если я сделал другие изменения в обычной ОС.

Этот обзор ars technica, кажется, подразумевает, что когда вы монтируете на какое-то другое устройство, вы должны получить флаг kFSEventStreamEventFlagMustScanSubDirs, но я не вижу такого поведения. Кто-нибудь сталкивался с этим раньше? Есть ли лучший способ обнаружить и устранить случай, когда диск был смонтирован где-то еще, когда ОС была выключена?

Обновление: я попробовал то же самое, загрузившись из Linux и изменив файловую систему. Я не получил такого же странного поведения 0 событий, несмотря ни на что, но я также не получил событие из каталога, который я изменил, или флаг MustScanSubdirs.

Обновление 2: в этой теме принятый ответ говорит, что когда это происходит , машина времени обнаруживает, что журналы устарели в описанных выше ситуациях. Кто-нибудь знает, как определить, устарели ли журналы? Эту дату можно было бы использовать вместо флага.


person Kat    schedule 02.09.2012    source источник


Ответы (1)


Я думаю, вам также нужно сохранить UUID базы данных FSEvents на шаге № 2 и проверить его на шаге № 4.

Такое поведение расплывчато упоминается в документации Apple (выделено мной):

Примечание. Поскольку диски могут быть изменены компьютерами с более ранними версиями OS X (или потенциально другими операционными системами), вы должны рассматривать список событий как рекомендательный, а не как окончательный список всех изменений тома. Если диск изменен компьютером с предыдущей версией OS X, исторический журнал удаляется.

Например, программное обеспечение для резервного копирования должно периодически выполнять полную проверку любого тома, чтобы гарантировать, что никакие изменения не будут потеряны.

Обратите внимание на то, что исторический журнал удаляется, а затем посмотрите на ссылка (выделено мной):

FSEventStreamGetLatestEventId() -> Первоначально это возвращает значение с тех пор, когда оно было предоставлено при создании потока; после этого он обновляется идентификатором события с наибольшим номером, упомянутым в текущем пакете событий непосредственно перед вызовом обратного вызова клиента. Клиенты могут хранить это значение постоянно, пока они также сохраняют UUID для устройства (полученный с помощью FSEventsCopyUUIDForDevice()). Позже клиенты могут предоставить этот идентификатор события в качестве параметра с тех пор, как функция FSEventStreamCreateRelativeToDevice(), если его UUID соответствует тому, что вы сохранили. Это работает, потому что служба FSEvents хранит события в постоянной базе данных для каждого тома. В этом отношении поток идентификаторов событий действует как глобальные общесистемные часы, но не имеет отношения к какой-либо конкретной временной шкале.

FSEventsCopyUUIDForDevice() -> Получает UUID, который однозначно идентифицирует базу данных FSEvents для этого тома. Если база данных будет удалена, ее замена будет иметь другой UUID, чтобы клиенты могли обнаружить эту ситуацию и избежать попыток использовать идентификаторы событий, которые они сохранили в качестве параметра с тех пор, для функций FSEventStreamCreate...().

Обратите внимание, что UUID относится к каждому устройству, поэтому, если у вас есть какие-либо файловые системы, смонтированные внутри вашего дерева каталогов, вам, вероятно, потребуется получить UUID каждой из них.

Удачи!

person dlitz    schedule 05.09.2012