如何为Linux的新`fanotify`文件系统监控功能编程?

时间:2009-12-02 21:29:51

标签: linux inotify fanotify

构建在fanotify之上的

fsnotify应该替换替换inotify的{​​{1}}。是否有一些好的编程示例或现有实用程序使用dnotify来监视文件系统中的更改? fanotify提供了多少详细信息?

3 个答案:

答案 0 :(得分:17)

This LWN article经常被引用为fanotify的文档来源。但那里的描述似乎已经过时了。 fanotify不再使用套接字连接。相反,有两个新的libc函数包装系统调用,在sys/fanotify.h中声明。一个叫fanotify_init,另一个叫fanotify_mark。在撰写本文时,这些系统调用仍包含在list of missing manual pages中。但是,这些手册页有mail containing drafts。通过这些手册页的组合,查看有问题的标题,以及一些试验和错误,您应该能够实现这一目标。

似乎最初为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文件系统中的相应条目,如here所述。

这是一个简单的例子,它只打印每个打开文件的名称:

#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);
    }
  }
}

答案 1 :(得分:12)

答案 2 :(得分:6)

我刚学会了fanotify,看起来非常好。非常好的界面!

它还没有在Linus树中,但我想它会在Linux 2.6.33之前和之前进行测试(我今天在LKML中发现了一些补丁)。在原始补丁中,他们宣布了一个GIT树,因此您可以从那里构建测试内核。您可能还会发现测试git树。

我找不到使用它的实用工具,但我想它们很快就会到来。

这里有一个例子,在电子邮件的末尾:

http://lwn.net/Articles/339253/

如果您对此新功能非常感兴趣,可能需要监控Linux内核邮件列表并在那里进行交互。您也可以等到实用程序发布或开发自己的实用程序。

关于细节,似乎fanotify提供的事件少于inotify。我想这可能会在未来发生变化,但由于这是开发中的一个全新功能,我现在对它的描述并不多。