macos – 由其他操作系统更改的磁盘的FSEvents处理

我在FSEvents上看到奇怪的行为,我将驱动器安装在恢复模式下,并在重新启动时在我的流中获得零fsevents.

我做以下事情:

>定期开机
>使用FSEventsGetCurrentEventId()记录当前事件
>在恢复模式下启动并修改监视路径中的文件
>重新启动系统

发生这种情况时,我使用fsevents API时根本没有事件.它在kFSEventStreamEventFlagHistoryDone sentinel中发送的唯一标志,即使我在常规操作系统上进行了其他更改.

这个ars technica review似乎意味着当你在其他设备上挂载时,你应该得到kFSEventStreamEventFlagMustScanSubDirs标志,但我没有看到这种行为.以前有人遇到过这个吗?是否有更好的方法来检测和处理在操作系统关闭时驱动器已安装在其他位置的情况?

更新:我尝试从linux启动并修改文件系统.无论如何我没有得到0事件的同样奇怪的行为,但我也没有从我更改的目录或MustScanSubdirs标志中获取事件.

更新2:在this thread,接受的响应表明,当发生这种情况时,时间机器检测到在上述情况下日志已过期.有人知道如何检测日志是否过时?可以使用此日期而不是标志.

最佳答案 我认为您还需要在步骤#2中存储FSEvents数据库的UUID,并在步骤#4中检查它.

此行为是vaguely mentioned in Apple’s documentation(强调添加):

Note: Because disks can be modified by computers running earlier versions of OS X (or potentially other operating systems), you should treat the events list as advisory rather than a definitive list of all changes to the volume. If a disk is modified by a computer running a previous version of OS X, the historical log is discarded.

For example, backup software should still periodically perform a full sweep of any volume to ensure that no changes fall through the cracks.

注意关于被丢弃的历史日志的位,然后查看reference(强调添加):

FSEventStreamGetLatestEventId() -> Initially, this returns the
sinceWhen value supplied when the stream was created; thereafter, it
is updated with the highest-numbered event ID mentioned in the current
batch of events just before invoking the client’s callback. Clients
can store this value persistently as long as they also store the UUID
for the device
(obtained via FSEventsCopyUUIDForDevice()). Clients can
then later supply this event ID as the sinceWhen parameter to
FSEventStreamCreateRelativeToDevice(), as long as its UUID matches
what you stored. This works because the FSEvents service stores events
in a persistent, per-volume database. In this regard,the stream of
event IDs acts like a global, system-wide clock, but bears no relation
to any particular timebase.

FSEventsCopyUUIDForDevice() -> Gets a UUID that uniquely identifies
the FSEvents database for that volume. If the database gets discarded
then its replacement will have a different UUID so that clients will
be able to detect this situation and avoid trying to use event IDs
that they stored as the sinceWhen parameter to the
FSEventStreamCreate…() functions.

请注意,UUID是每个设备,因此如果您在目录树中安装了任何文件系统,则可能需要获取每个文件系统的UUID.

祝好运!

点赞