How do I program for Linux's new `fanotify` fi

2019-01-22 08:20发布

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?

3条回答
ら.Afraid
2楼-- · 2019-01-22 08:48

The documentation for the fanotify API is available in the Linux manpages:


Here are some examples, fatrace being the most elaborate.

Bindings exist for Go and Python.

查看更多
淡お忘
3楼-- · 2019-01-22 08:59

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

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);
    }
  }
}
查看更多
女痞
4楼-- · 2019-01-22 09:00

I just learned about fanotify and it seems very nice. Very nice interface!

It is not in the Linus tree yet but I guess it will get there for Linux 2.6.33 and before for testing (I noticed some patches today in LKML). In the original patch they announce a GIT tree thus you might be able to build a testing kernel from there. You might also find testing git trees.

I couldn't find utilities that use it but I guess they'll come soon.

There is an example here, at the end of the email:

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

If you are really interested in this new feature you might want to monitor the Linux Kernel Mailing List and interact there. You can also wait until the utilities are released or develop your own.

About the detail, it seems fanotify provides less events than inotify. I guess this might change in the future but since this is a brand new feature in development there is not much I can say about it now.

查看更多
登录 后发表回答