【问题标题】:How do I program for Linux's new `fanotify` file system monitoring feature?如何为 Linux 的新 `fanotify` 文件系统监控功能编程?
【发布时间】:2010-12-22 14:22:18
【问题描述】:

fanotify,建立在fsnotify 之上,应该替换inotify,后者替换了dnotify。是否有一些好的编程示例或现有实用程序使用fanotify 来监视文件系统中的更改? fanotify 提供了多少细节?

【问题讨论】:

标签: linux inotify fanotify


【解决方案1】:

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

【讨论】:

    【解决方案2】:
    【解决方案3】:

    我刚刚了解了 fanotify,它看起来很不错。很不错的界面!

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

    我找不到使用它的实用程序,但我想它们很快就会出现。

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

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

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

    关于细节,fanotify 提供的事件似乎比 inotify 少。我想这在未来可能会改变,但由于这是一个正在开发中的全新功能,所以我现在不能说太多。

    【讨论】:

    • 最终 fanotify 进入了 2.6.36
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-01
    • 2012-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多