linux - 如何针对 Linux 的新 `fanotify` 文件系统监控功能进行编程?

标签 linux inotify fanotify

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

最佳答案

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

似乎不再支持最初为 fanotify 设想的某些功能。例如,LWN 文章描述了一个 FAN_GLOBAL_LISTENER 标志,它将隐含地标记整个文件系统树,除非部分被明确地取消标记。目前的接口(interface)没有这样的规定,但是使用下面的标记可以达到类似的效果:

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

关于linux - 如何针对 Linux 的新 `fanotify` 文件系统监控功能进行编程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1835947/

相关文章:

go - 将字节数组转换为 Golang 中的 syscall.InotifyEvent 结构

用于文件夹列表的 Python Inotify

linux - 执行已知已安装的可执行文件时遇到问题

linux - curl 或读取每一行 url 文本文件,然后将每一行输出到标记为连续数字的单独文件 - 1 2 3 等

Linux 用户空间应用程序编译错误

c++ - 如果我使用 fanotify 控制对文件的访问的正在运行的守护进程重新启动或关闭,系统会卡住

c++ - fanotify - 内核 5.1 中引入的新标志的问题

c - timer_create 在 i386 系统上导致段错误,但在 x86_64 系统(linux)上没有

linux - 如何在 Linux 中监视完整的目录树的更改?

c++ - 如何使用FAN_DENY? (法诺菲)