Linux 目录通知¶
Stephen Rothwell <sfr@canb.auug.org.au>
目录通知的目的是允许用户应用程序在目录或目录中的任何文件发生更改时收到通知。基本机制包括应用程序使用 fcntl(2) 调用注册对目录的通知,并且通知本身使用信号传递。
应用程序决定它希望收到哪些“事件”的通知。当前定义的事件是
DN_ACCESS
目录中的文件被访问(读取)
DN_MODIFY
目录中的文件被修改(写入,截断)
DN_CREATE
在目录中创建了一个文件
DN_DELETE
一个文件从目录中取消链接
DN_RENAME
目录中的一个文件被重命名
DN_ATTRIB
目录中的一个文件的属性被更改(chmod,chown)
通常,应用程序必须在每次通知后重新注册,但如果 DN_MULTISHOT 与事件掩码进行“或”运算,则注册将保持有效,直到显式删除(通过注册不接收任何事件)。
默认情况下,SIGIO 将传递给进程,而不包含其他有用的信息。但是,如果使用 F_SETSIG fcntl(2) 调用通知内核要传递哪个信号,则 siginfo 结构将传递给信号处理程序,并且该结构的 si_fd 成员将包含与发生事件的目录关联的文件描述符。
最好,应用程序将选择一个实时信号(SIGRTMIN + <n>),以便可以对通知进行排队。如果指定了 DN_MULTISHOT,这一点尤其重要。请注意,SIGRTMIN 通常被阻止,因此最好使用(至少)SIGRTMIN + 1。
实现预期(特性和错误 :-))¶
通知应适用于对文件的任何本地访问,即使实际文件系统位于远程服务器上也是如此。这意味着应该通知对本地用户模式服务器提供的文件的远程访问。此外,应通知对本地内核 NFS 服务器提供的文件的远程访问。
为了尽可能减小对文件系统代码的影响,忽略了指向文件的硬链接问题。因此,如果文件 (x) 存在于两个目录(a 和 b)中,则使用名称“a/x”对文件进行的更改应通知到期望目录“a”上通知的程序,但不会通知到期望目录“b”上通知的程序。
此外,即使取消链接的文件仍会在它们链接到的最后一个目录中产生通知。
配置¶
Dnotify 通过 CONFIG_DNOTIFY 配置选项控制。禁用时,fcntl(fd, F_NOTIFY, ...) 将返回 -EINVAL。
示例¶
有关示例,请参见 tools/testing/selftests/filesystems/dnotify_test.c。
注意¶
从 Linux 2.6.13 开始,dnotify 已被 inotify 取代。有关其详细信息,请参见Inotify - 一个强大而简单的文件更改通知系统。