Как мне запрограммировать для новой функции Linux `fanotify` мониторинг файловой системы? - PullRequest
17 голосов
/ 03 декабря 2009

fanotify, построенный поверх fsnotify, должен заменить inotify, который заменил dnotify. Есть ли хорошие примеры программирования или существующие утилиты, которые используют fanotify для отслеживания изменений в файловой системе? Сколько деталей fanotify предоставляет?

Ответы [ 3 ]

17 голосов
/ 15 ноября 2012

Эта статья LWN часто цитируется как источник документации для fanotify. Но описание там, кажется, устарело. fanotify больше не работает с использованием сокета. Вместо этого есть две новые функции libc, обертывающие системные вызовы, объявленные в sys/fanotify.h. Один называется fanotify_init, другой - fanotify_mark. На момент написания этой статьи эти системные вызовы все еще были включены в список отсутствующих справочных страниц . Однако для этих справочных страниц существует письмо , содержащее черновики . Сочетая эти справочные страницы, взглянув на рассматриваемые заголовки и немного проб и ошибок, вы сможете добиться успеха.

Похоже, что некоторые функции, изначально предусмотренные для 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, как описано здесь .

Вот простой пример, который просто печатает имя каждого открытого файла:

#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);
    }
  }
}
12 голосов
/ 29 ноября 2012

Документация по API fanotify доступна на страницах руководства Linux:


Вот несколько примеров, фатрас - самый сложный.

Привязки существуют для Go и Python.

6 голосов
/ 04 декабря 2009

Я только что узнал о fanotify, и это кажется очень хорошим. Очень красивый интерфейс!

Пока его нет в дереве Linus, но я думаю, что он попадет туда для Linux 2.6.33 и до тестирования (сегодня я заметил некоторые исправления в LKML). В оригинальном патче они объявляют дерево GIT, поэтому вы можете построить тестовое ядро ​​оттуда. Вы также можете найти тестовые деревья git.

Я не смог найти утилиты, которые его используют, но я думаю, они скоро появятся.

Вот пример, в конце письма:

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

Если вы действительно заинтересованы в этой новой функции, вы можете отслеживать список рассылки ядра Linux и взаимодействовать там. Вы также можете подождать, пока утилиты не будут выпущены, или разработать свою собственную.

Что касается деталей, кажется, что fanotify предоставляет меньше событий, чем inotify. Я думаю, что это может измениться в будущем, но, поскольку это совершенно новая функция в разработке, я не могу сказать об этом сейчас.

...