FANOTIFY_MARK(2) Руководство программиста Linux FANOTIFY_MARK(2)

ИМЯ

fanotify_mark - добавляет, удаляет или изменяет метку fanotify для объекта файловой системы

ОБЗОР

#include <sys/fanotify.h>
int fanotify_mark(int fanotify_fd, unsigned int flags,
                  uint64_t mask, int dirfd, const char *pathname);

ОПИСАНИЕ

Обзор программного интерфейса fanotify смотрите в fanotify(7).

Системный вызов fanotify_mark() добавляет, удаляет или изменяет метку fanotify для объекта файловой системы. Вызывающий должен иметь право на чтение помеченного объекта файловой системы.

Аргумент fanotify_fd — файловый дескриптор, возвращаемый fanotify_init(2).

Аргумент flags — битовая маска, описывающая выполняемое изменение. Она должна содержать только одно значение из:

События в mask будут добавлены в маску меток (или в маску игнорирования). Если значение mask пусто, то возвращается ошибка EINVAL.
События в mask будут удалены из маски меток (или маски игнорирования). Если значение mask пусто, то возвращается ошибка EINVAL.
Удалить все метки файловых систем, все метки монтирований или все метки каталогов и файлов из группы fanotify. Если в flags содержится FAN_MARK_MOUNT, то все метки монтирований удаляются из группы. Если в flags содержится FAN_MARK_FILESYSTEM, то все метки файловых систем удаляются из группы. В противном случае удаляются все метки и каталогов и файлов. Вместе с FAN_MARK_FLUSH может быть указан только либо FAN_MARK_MOUNT, либо FAN_MARK_FILESYSTEM.Значение mask игнорируется.

Если не задано ни одно из этих значений, или указано больше одного, то вызов завершается с ошибкой EINVAL.

Кроме этого в flags могут быть указаны (побитовым сложением):

Если pathname — символьная ссылка, то помечается сама ссылка, а не файл, на который она ссылается (по умолчанию fanotify_mark() разыменовывает pathname, если это символьная ссылка).
Если объект файловой системы для пометки не является каталогом, то возвращается ошибка ENOTDIR.
Пометить точку монтирования, заданную в pathname. Если само значение pathname не является точкой монтирования, то будет помечена точка монтирования, которая содержит pathname. Будут отслеживаться все каталоги, подкаталоги и содержащиеся в точке монтирования файлы.
Пометить файловую систему, заданную в pathname. Будет помечена файловая система, содержащая pathname. Будут отслеживаться все файлы и каталоги файловой системы любой точки монтирования.
События в mask должны быть добавлены или удалены из маски игнорирования.
Маска игнорирования должна остаться неизменной при событиях изменения. Если этот флаг не указан, то маска игнорирования очищается при появлении событий изменения игнорируемого файла или каталога.

В mask указывается какие события должны прослушиваться (или игнорироваться). Данная битовая маска состоит из следующих значений:

Создать событие при доступе (для чтения) к файлу или каталогу (но смотрите ДЕФЕКТЫ).
Создать событие при изменении (при записи) файла.
Создать событие при закрытии файла, открытого на запись.
Создать событие при закрытии файла или каталога, открытого только для чтения.
Создать событие при открытии файла или каталога.
Создать событие, когда файл открыт для начала выполнения. Подробней об этом в ЗАМЕЧАНИЯХ.
Создать событие при переполнении очереди сообщений. Размер очереди сообщений ограничен 16384 элементами, если в fanotify_init(2) не указан FAN_UNLIMITED_QUEUE.
Создать событие при запросе открытия файла или каталога. Требуется файловый дескриптор fanotify, созданный с FAN_CLASS_PRE_CONTENT или FAN_CLASS_CONTENT.
Создать событие при запросе открытия файла или каталога на выполнение. Требуется файловый дескриптор fanotify, созданный с FAN_CLASS_PRE_CONTENT или FAN_CLASS_CONTENT. Дополнительная информация представлена в ЗАМЕЧАНИЯХ.
Создать событие при запросе чтения файла или каталога. Требуется файловый дескриптор fanotify, созданный с FAN_CLASS_PRE_CONTENT или FAN_CLASS_CONTENT.
Создать события для каталогов, например при вызове opendir(3), readdir(3) (но смотрите ДЕФЕКТЫ) и closedir(3). Без этого флага будут создаваться события только для файлов.
Должны создаваться события для прямых потомков помеченных каталогов. Флаг не влияет на помеченные точки монтирования и файловые системы. Заметим, что события не генерируются для потомков подкаталогов помеченных каталогов. Для слежения за всем деревом каталогов нужно пометить соответствующую точку монтирования.

Определены следующие составные значения:

Файл закрыт (FAN_CLOSE_WRITE|FAN_CLOSE_NOWRITE).

Объект файловой системы для пометки задаётся файловым дескриптором dirfd и путём, указанным в pathname:

  • Если значение pathname равно NULL, то в dirfd указан объект файловой системы для пометки.
  • Если значение pathname равно NULL и dirfd равно специальному значению AT_FDCWD, то помечается текущий рабочий каталог.
  • Если в pathname задан абсолютный путь, то им определяется объект файловой системы для пометки, а dirfd игнорируется.
  • Если в pathname задан относительный путь и dirfd не равно AT_FDCWD, то помечаемый объект файловой системы определяется из pathname относительно каталога, заданного в dirfd.
  • Если в pathname задан относительный путь и dirfd равно AT_FDCWD, то помечаемый объект файловой системы определяется из pathname относительно текущего рабочего каталога.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

При успешном выполнении fanotify_mark() возвращает 0; при ошибке возвращается -1, а в errno задаётся причина ошибки.

ОШИБКИ

В fanotify_fd передан некорректный файловый дескриптор.
В flags или mask указано некорректное значение, или в fanotify_fd не файловый дескриптор fanotify.
Файловые дескриптор fanotify был открыт с FAN_CLASS_NOTIF и маска содержит флаг для событий доступа (FAN_OPEN_PERM или FAN_ACCESS_PERM).
Объект файловой системы, указанный в dirfd и pathname, не существует. Эта ошибка также возникает при попытке удаления метки с не помеченного объекта.
Невозможно выделить необходимую память.
Количество меток превышает ограничение в 8192 и флаг FAN_UNLIMITED_MARKS не был указан при создании файлового дескриптора fanotify с помощью fanotify_init(2).
В этом ядре не реализован fanotify_mark(). Программный интерфейс fanotify доступен только, если ядро было собрано с параметром CONFIG_FANOTIFY.
В значении flags содержится FAN_MARK_ONLYDIR, а в dirfd и pathname указан не каталог.

ВЕРСИИ

Вызов fanotify_mark() появился в версии 2.6.36 ядра Linux и был включён в версии 2.6.37.

СООТВЕТСТВИЕ СТАНДАРТАМ

Данный системный вызов есть только в Linux.

ЗАМЕЧАНИЯ

При использовании FAN_OPEN_EXEC или FAN_OPEN_EXEC_PERM в mask события этих типов будут возвращаться только, когда происходит непосредственное выполнение программы. Точнее говоря, события этих типов будут сгенерированы для файлов, которые открываются с помощью execve(2), execveat(2) или uselib(2). События данных типов не будут возникать в ситуации, когда интерпретатору передаётся (или он читает) файл интерпретируемого сценария.

Также, если метка помещается на динамический компоновщик Linux, то пользователь должен также ожидать приём сообщения, когда он открывает объект ELF с помощью execve(2) или execveat(2).

Например, если вызывается следующий двоичный ELF и меткой FAN_OPEN_EXEC отмечен /:

$ /bin/echo foo

Слушающее приложение в этом случае получило бы события FAN_OPEN_EXEC для исполняемого файла ELF и интерпретатора, соответственно:

/bin/echo
/lib64/ld-linux-x86-64.so.2

ДЕФЕКТЫ

В ядрах Linux до версии 3.16 существуют следующие дефекты:

  • Если flags содержит FAN_MARK_FLUSH, то dirfd и pathname должны задавать корректный объект файловой системы, даже если этот объект не используется.
  • Вызов readdir(2) не генерирует событие FAN_ACCESS.
  • Если fanotify_mark() вызван с FAN_MARK_FLUSH, то значение flags не проверяется на корректность.

СМОТРИТЕ ТАКЖЕ

fanotify_init(2), fanotify(7)

2019-03-06 Linux