【问题标题】:how come osx kernel get so many times of file operationsosx内核怎么会有这么多次文件操作
【发布时间】:2013-09-02 02:39:10
【问题描述】:

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

【问题讨论】:

  • 您是在编写内核扩展来接收通知,还是只是附加到更高级别的东西?
  • 是的,我们需要知道您如何接收这些通知的确切机制。另外,您确定通知都是针对该特定文件的吗?
  • @Merlin069 是的,我正在编写一个基于 kauth 的 kext 以在 KAUTH_SCOPE_FILEOP 范围内监听
  • @pmjordan 是的,我确信它发生在同一个文件上。当你打开一个文件并修改一个存在的文件时,它也会导致很多打开/写入操作。:(

标签: macos events notifications filesystemwatcher kernel-extension


【解决方案1】:

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

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

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

【讨论】:

  • 虽然我还没有验证,但我认为这是一个合理的解释。谢谢。
【解决方案2】:

如果您查看 VNode 范围内发生的事情,它提供了更多细节,您会发现在使用触摸时发生了很多事情。这是基于 Singh 的“Mac OSX Internals”的 VNode 监视器的程序的输出,当我创建一个名为“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}

有趣的是,您可以看到 WRITE_DATAACCESS 出现了 3 次。请注意,这是两个标志;写入数据和访问。

因此,根据这些数据,在我看来,这 3 个打开与您所看到的内容相关,但您可能在某个地方错过了一个打开,或者由于某种原因,它没有通知您其中一个。

【讨论】:

    【解决方案3】:

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

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

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

    1. 进程打开一个文件。
    2. 进程分叉。 IE。 child 继承打开文件的文件描述符。
    3. 父进程和子进程最终都会关闭描述符(通过close() 显式关闭或在进程终止时隐式关闭)

    【讨论】:

      猜你喜欢
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-17
      • 2011-07-20
      • 2019-03-13
      • 1970-01-01
      相关资源
      最近更新 更多