0

我在用户空间中创建了一个文件(使用 touch 命令),我希望只看到一个 OPEN 和一个 CLOSE 文件操作,但是,我从内核通知中获得了 2 个 OPEN 和 3 个 CLOSE 操作。操作顺序是这样的:打开 --> 关闭 --> 打开 --> 关闭 ---> 关闭....有人可以给我一些提示吗?提前致谢。

4

3 回答 3

2

Kauth vnode 和 fileop 侦听器对我来说效果很好。如果您收到对您没有意义的事件通知,我建议使用内核调试器在您的 kauth 侦听器回调中放置一个断点并查看回溯。xnu 源代码是可用的,因此您应该能够从中找出原因以及您收到相关通知的回溯。

我知道如果一个文件有多个句柄,您可以获得额外的关闭通知。因此,如果您打开文件、dup()文件描述符,然后关闭两个句柄,您将获得一个打开和 2 个关闭。就是这样,恐怕。没有公共内核 API 可用于确定进程是否具有特定文件的剩余句柄。

至于为什么您会收到 2 个打开的通知 - 这可能与touch编写方式有关,也可能与外壳有关。通常,打开通知确实对应于open()系统调用。如果有疑问,请编写您自己的“触摸”工具,该工具只调用一次打开和关闭来测试您是否获得了正确的事件。如果您需要,也可以使用 Apple 触摸命令的源代码。

于 2013-09-05T12:22:30.540 回答
1

If you look at what happens in the VNode scope, which gives more detail, you'll see that quite a lot occurs when you use touch. This is the output from a program based on the VNode monitor of Singh's "Mac OSX Internals", when I create a file called 'testtouch': -

09:00:51.262 Pid: 49 (fseventsd) "/Users/user/testtouch" VREG VT_HFS {READ_ATTRIBUTESREAD_SECURITY} 09:00:51.263 Pid: 49 (fseventsd) "/Users/user/testtouch" VREG VT_HFS {READ_ATTRIBUTESREAD_SECURITY} 09:00:51.278 Pid: 40 (mds) "/Users/user/testtouch" VREG VT_HFS {READ_ATTRIBUTES} 09:00:51.278 Pid: 40 (mds) "/Users/user/testtouch" VREG VT_HFS {WRITE_DATAACCESS} 09:00:51.278 Pid: 40 (mds) "/Users/user/testtouch" VREG VT_HFS {READ_DATAACCESS} 09:00:51.279 Pid: 40 (mds) "/Users/user/testtouch" VREG VT_HFS {EXECUTEACCESS} 09:00:51.279 Pid: 559 (mdworker) "/Users/user/testtouch" VREG VT_HFS {READ_DATA} 09:00:51.279 Pid: 559 (mdworker) "/Users/user/testtouch" VREG VT_HFS {READ_ATTRIBUTES} 09:00:51.280 Pid: 559 (mdworker) "/Users/user/testtouch" VREG VT_HFS {WRITE_DATAACCESS} 09:00:51.280 Pid: 559 (mdworker) "/Users/user/testtouch" VREG VT_HFS {READ_DATAACCESS} 09:00:51.280 Pid: 559 (mdworker) "/Users/user/testtouch" VREG VT_HFS {EXECUTEACCESS} 09:00:51.281 Pid: 559 (mdworker) "/Users/user/testtouch" VREG VT_HFS {READ_ATTRIBUTES} 09:00:51.286 Pid: 559 (mdworker) "/Users/user/testtouch" VREG VT_HFS {READ_EXTATTRIBUTES} 09:00:51.286 Pid: 559 (mdworker) "/Users/user/testtouch" VREG VT_HFS {READ_ATTRIBUTESREAD_SECURITY} 09:00:51.287 Pid: 559 (mdworker) "/Users/user/testtouch" VREG VT_HFS {READ_ATTRIBUTES} 09:00:51.287 Pid: 559 (mdworker) "/Users/user/testtouch" VREG VT_HFS {READ_ATTRIBUTES} 09:00:51.288 Pid: 559 (mdworker) "/Users/user/testtouch" VREG VT_HFS {WRITE_DATAACCESS} 09:00:51.288 Pid: 559 (mdworker) "/Users/user/testtouch" VREG VT_HFS {READ_DATAACCESS} 09:00:51.288 Pid: 559 (mdworker) "/Users/user/testtouch" VREG VT_HFS {EXECUTEACCESS} 09:00:51.289 Pid: 40 (mds) "/Users/user/testtouch" VREG VT_HFS {READ_ATTRIBUTES}

Interestingly, you can see that WRITE_DATAACCESS occurs 3 times. Note that this is two flags; WRITEDATA and ACCESS.

So from this data, it looks to me as the 3 opens correlate with what you're seeing, but you may have missed an open somewhere, or for some reason, it fails to notify you of one of them.

于 2013-09-09T08:11:38.097 回答
0

MacOS X 包含许多可以打开文件的东西。考虑 Spotlight 的索引。每当您修改文件(即打开它然后关闭它)时,Spotlight 最终都会想要索引它。这可以解释为什么您会看到多个打开/关闭事件。

您可以通过使用 proc_selfpid() 分析来验证这一点,它将告诉您导致事件的进程的 PID。(这是有效的,因为 KAuth 回调是直接从属于进程的线程调用的,forKAUTH_SCOPE_FILEOPKAUTH_SCOPE_VNODE.)

另外我猜打开和关闭事件计数之间的差异可能是由进程分叉引起的。考虑这种情况:

  1. 进程打开一个文件。
  2. 进程分叉。即子继承打开文件的文件描述符。
  3. 父进程和子进程最终都会关闭描述符(close()在进程终止时显式或隐式)
于 2013-10-16T13:32:17.127 回答