Подтвердить что ты не робот

Как я могу запрограммировать для Linux новую функцию мониторинга файловой системы `fanotify`?

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

4b9b3361

Ответ 1

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

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

Ответ 2

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


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

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

Ответ 3

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

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

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

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

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

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

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