如何为Linux的新"fanotify"文件系统监视功能编程? [英] How do I program for Linux's new `fanotify` file system monitoring feature?

查看:437
本文介绍了如何为Linux的新"fanotify"文件系统监视功能编程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

fanotify应该替换inotify,而inotify替换了dnotify.是否存在一些使用fanotify来监视文件系统中的更改的良好编程示例或现有实用程序? fanotify提供多少细节?

fanotify, built on top of fsnotify, is supposed to replace inotify which replaced dnotify. Are there some good programming examples or existing utilities that use fanotify to watch for changes in a filesystem? How much detail does fanotify provide?

推荐答案

此LWN文章通常被引用为fanotify的文档来源.但是那里的描述似乎已经过时了. fanotify不再可以通过套接字连接使用.取而代之的是,有两个新的包装了syscall的libc函数,它们在sys/fanotify.h中声明.一个称为fanotify_init,另一个称为fanotify_mark.在撰写本文时,这些系统调用仍包含在缺少的手册页列表中.但是,对于这些手册页,有包含草稿的邮件.结合使用这些手册页,查看相关标题和一些反复试验,您应该能够做到这一点.

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.

似乎原本为fanotify设想的某些功能不再以这种方式提供支持.例如,LWN文章描述了FAN_GLOBAL_LISTENER标志,该标志将隐式标记整个文件系统树,除非明确地未标记部分.当前接口没有这样的规定,但是使用以下标记可以实现类似的结果:

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, "/")

在inotify事件作为事件一部分提供访问对象的路径的情况下,fanotify为它打开文件描述符.为了将此描述符转换为路径名,可以使用proc文件系统中的相应条目,如此处所述

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

这篇关于如何为Linux的新"fanotify"文件系统监视功能编程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆