joe*_*ker 17 linux inotify fanotify
fanotify
建在上面fsnotify
,应该取代inotify
被替换的dnotify
.是否有一些好的编程示例或现有实用程序fanotify
用于监视文件系统中的更改?fanotify
提供了多少细节?
MvG*_*MvG 17
This LWN article is often quoted as a source of documentation for fanotify. But the description there appears to be out of date. fanotify no longer works using a socket connection. Instead, there are two new libc functions wrapping syscalls, declared in sys/fanotify.h
. One is called fanotify_init
, the other is fanotify_mark
. At the time of this writing, these syscalls are still included in the list of missing manual pages. There is, however, a mail containing drafts for these manual pages. With a combination of these man pages, a look at the headers in question, and a bit of trial and error, you should be able to get this going.
It seems that some of the functionality originally envisioned for fanotify is no longer suipported in that fashion. For example, the LWN article describes a FAN_GLOBAL_LISTENER
flag which will implicitely mark the whole filesystem tree unless parts are explicitely unmarked. The current interface has no such provision, but a similar result can be achieved using the following mark:
fanotify_mark(fan,
FAN_MARK_ADD | FAN_MARK_MOUNT,
FAN_OPEN | FAN_EVENT_ON_CHILD,
AT_FDCWD, "/")
Run Code Online (Sandbox Code Playgroud)
Where inotify events provide the path to the accessed object as part of the event, fanotify opens a file descriptor for it. In order to turn this descriptor into a path name, the corresponding entry from the proc file system can be used, as described here.
Here is a simple example which simply prints the name of every opened file:
#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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
Tob*_*obu 12
Linux手册中提供了fanotify API的文档:
以下是一些例子,fatrace是最精细的.
Go和Python存在绑定.
我刚学会了fanotify,看起来非常好.非常好的界面!
它还没有在Linus树中,但我想它会在Linux 2.6.33和之前进行测试(我今天在LKML中发现了一些补丁).在原始补丁中,他们宣布了一个GIT树,因此您可以从那里构建测试内核.您可能还会发现测试git树.
我找不到使用它的实用程序,但我想它们很快就会到来.
这里有一个例子,在电子邮件的末尾:
http://lwn.net/Articles/339253/
如果您真的对这个新功能感兴趣,可能需要监视Linux内核邮件列表并在那里进行交互.您也可以等到实用程序发布或开发自己的实用程序.
关于细节,似乎fanotify提供的事件少于inotify.我想这可能会在未来发生变化,但由于这是开发中的一个全新功能,我现在对它的描述并不多.