fanotify
,建立在fsnotify
之上,应该取代inotify
,后者取代了dnotify
。是否有一些好的编程示例或现有实用程序使用 fanotify
来监视文件系统中的更改? fanotify
提供了多少细节?
这篇 LWN 文章 经常被引用作为 fanotify 的文档来源。但那里的描述似乎已经过时了。 fanotify 不再使用套接字连接工作。相反,有两个新的 libc 函数包装了系统调用,在
sys/fanotify.h
中声明。一个叫fanotify_init
,另一个叫fanotify_mark
。在这里您可以找到文档。通过结合这些手册页,查看相关标题,并进行一些尝试和错误,您应该能够实现这一目标。
最初为 fanotify 设想的一些功能似乎不再以这种方式支持。例如,LWN 文章描述了一个
FAN_GLOBAL_LISTENER
标志,它将隐式标记整个文件系统树,除非明确未标记某些部分。目前的接口没有这样的规定,但是使用以下标记可以达到类似的结果:
fanotify_mark(fan,
FAN_MARK_ADD | FAN_MARK_MOUNT,
FAN_OPEN | FAN_EVENT_ON_CHILD,
AT_FDCWD, "/")
inotify 事件作为事件的一部分提供访问对象的路径,而 fanotify 为其打开一个文件描述符。为了将此描述符转换为路径名,可以使用 proc 文件系统中的相应条目,如此处所述。
这是一个简单的示例,它只是打印每个打开的文件的名称:
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/fanotify.h>
#include <sys/stat.h>
#include <sys/types.h>
#define CHK(expr, errcode) if((expr)==errcode) perror(#expr), exit(EXIT_FAILURE)
int main(int argc, char** argv) {
int fan;
char buf[4096];
char fdpath[32];
char path[PATH_MAX + 1];
ssize_t buflen, linklen;
struct fanotify_event_metadata *metadata;
CHK(fan = fanotify_init(FAN_CLASS_NOTIF, O_RDONLY), -1);
CHK(fanotify_mark(fan, FAN_MARK_ADD | FAN_MARK_MOUNT,
FAN_OPEN | FAN_EVENT_ON_CHILD, AT_FDCWD, "/"), -1);
for (;;) {
CHK(buflen = read(fan, buf, sizeof(buf)), -1);
metadata = (struct fanotify_event_metadata*)&buf;
while(FAN_EVENT_OK(metadata, buflen)) {
if (metadata->mask & FAN_Q_OVERFLOW) {
printf("Queue overflow!\n");
continue;
}
sprintf(fdpath, "/proc/self/fd/%d", metadata->fd);
CHK(linklen = readlink(fdpath, path, sizeof(path) - 1), -1);
path[linklen] = '\0';
printf("%s opened by process %d.\n", path, (int)metadata->pid);
close(metadata->fd);
metadata = FAN_EVENT_NEXT(metadata, buflen);
}
}
}
fanotify API 的文档可在 Linux 手册页中找到:
以下是一些示例,其中 fatrace 是最详细的。
Go 和 Python 存在绑定。
我刚刚了解了fanotify,它看起来非常好。非常好的界面!
它还没有在 Linus 树中,但我想它会在 Linux 2.6.33 及之前的版本中到达那里进行测试(我今天在 LKML 中注意到了一些补丁)。在原始补丁中,他们宣布了一个 GIT 树,因此您可以从那里构建一个测试内核。您可能还会发现测试 git 树。
我找不到使用它的实用程序,但我想它们很快就会出现。
电子邮件末尾有一个示例:
http://lwn.net/Articles/339253/
如果您真的对这个新功能感兴趣,您可能想要监视 Linux 内核邮件列表并在那里进行交互。您也可以等到实用程序发布或开发自己的实用程序。
从细节上看,fanotify 提供的事件似乎比 inotify 少。我想这将来可能会改变,但由于这是正在开发中的全新功能,所以我现在对此无话可说。