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 — битовая маска, описывающая выполняемое изменение. Она должна содержать только одно значение из:

FAN_MARK_ADD
    События в mask будут добавлены в маску меток (или в маску игнорирования). Если значение mask пусто, то возвращается ошибка EINVAL.

FAN_MARK_REMOVE
    События в mask будут удалены из маски меток (или маски игнорирования). Если значение mask пусто, то возвращается ошибка EINVAL.

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

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

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

FAN_MARK_DONT_FOLLOW
    Если pathname — символьная ссылка, то помечается сама ссылка, а не файл, на который она ссылается (по умолчанию fanotify_mark() разыменовывает pathname, если это символьная ссылка).

FAN_MARK_ONLYDIR
    Если объект файловой системы для пометки не является каталогом, то возвращается ошибка ENOTDIR.

FAN_MARK_MOUNT
    Пометить точку монтирования, заданную в pathname. Если само значение pathname не является точкой монтирования, то будет помечена точка монтирования, которая содержит pathname. Будут отслеживаться все каталоги, подкаталоги и содержащиеся в точке монтирования файлы. Это значение нельзя использовать, если файловый дескриптор fanotify_fd инициализирован с флагом FAN_REPORT_FID или если в качестве маски mask указано любое событие изменения нового каталога. Результатом попытки это сделать будет возврат ошибки EINVAL.

FAN_MARK_FILESYSTEM (начиная с Linux 4.20)
    Пометить файловую систему, заданную в pathname. Будет помечена файловая система, содержащая pathname. Будут отслеживаться все файлы и каталоги файловой системы любой точки монтирования.

FAN_MARK_IGNORED_MASK
    События в mask должны быть добавлены или удалены из маски игнорирования.

FAN_MARK_IGNORED_SURV_MODIFY
    Маска игнорирования должна остаться неизменной при событиях изменения. Если этот флаг не указан, то маска игнорирования очищается при появлении событий изменения игнорируемого файла или каталога.

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

FAN_ACCESS
    Создать событие при доступе (для чтения) к файлу или каталогу (но смотрите ДЕФЕКТЫ).

FAN_MODIFY
    Создать событие при изменении (при записи) файла.

FAN_CLOSE_WRITE
    Создать событие при закрытии файла, открытого на запись.

FAN_CLOSE_NOWRITE
    Создать событие при закрытии файла или каталога, открытого только для чтения.

FAN_OPEN
    Создать событие при открытии файла или каталога.

FAN_OPEN_EXEC (начиная с Linux 5.0)
    Создать событие при открытии файла для начала выполнения. Подробней об этом в ЗАМЕЧАНИЯХ.

FAN_ATTRIB (начиная с Linux 5.1)
    Создать событие при изменении метаданных файла или каталога.

FAN_CREATE (начиная с Linux 5.1)
    Создать событие при создании файла или каталога в помеченном родительском каталоге.

FAN_DELETE (начиная с Linux 5.1)
    Создать событие при удалении файла или каталога в помеченном родительском каталоге.

FAN_DELETE_SELF (начиная с Linux 5.1)
    Создать событие при удалении самого помеченного файла или каталога.

FAN_MOVED_FROM (начиная с Linux 5.1)
    Создать событие при перемещении файла или каталога из помеченного родительского каталога.

FAN_MOVED_TO (начиная с Linux 5.1)
    Создать событие при перемещении файла или каталога в помеченный родительский каталог.

FAN_MOVE_SELF (начиная с Linux 5.1)
    Создать событие при перемещении самого помеченного файла или каталога.

FAN_Q_OVERFLOW
    Создать событие при переполнении очереди сообщений. Размер очереди сообщений ограничен 16384 элементами, если в fanotify_init(2) не указан FAN_UNLIMITED_QUEUE.

FAN_OPEN_PERM
    Создать событие при запросе открытия файла или каталога. Требуется файловый дескриптор fanotify, созданный с FAN_CLASS_PRE_CONTENT или FAN_CLASS_CONTENT.

FAN_OPEN_EXEC_PERM (начиная с Linux 5.0)
    Создать событие при запросе открытия файла или каталога на выполнение. Требуется файловый дескриптор fanotify, созданный с FAN_CLASS_PRE_CONTENT или FAN_CLASS_CONTENT. Дополнительная информация представлена в ЗАМЕЧАНИЯХ.

FAN_ACCESS_PERM
    Создать событие при запросе чтения файла или каталога. Требуется файловый дескриптор fanotify, созданный с FAN_CLASS_PRE_CONTENT или FAN_CLASS_CONTENT.

FAN_ONDIR
    Создать события для каталогов, например, когда вызывается opendir(3), readdir(3) (но смотрите ДЕФЕКТЫ) и closedir(3). Без этого флага события создаются только для файлов. Флаг FAN_ONDIR возвращается в маске событий только, если файловый дескриптор fanotify_fd инициализирован с флагом FAN_REPORT_FID. В контексте события элементов каталога, например таких как FAN_CREATE, FAN_DELETE, FAN_MOVED_FROMи FAN_MOVED_TO, требуется задавать флаг FAN_ONDIR для создания событий, когда изменяются элементы подкаталогов (т. е., mkdir(2)/ rmdir(2)). События изменения элемента подкаталога никогда не будут объединены с с событиями изменений элементов не подкаталога. Этот флаг никогда не возвращается один в событии и всегда задаётся вместе с другим типом события.

FAN_EVENT_ON_CHILD
    Должны создаваться события для прямых потомков помеченных каталогов. Флаг не влияет на помеченные точки монтирования и файловые системы. Заметим, что события не генерируются для потомков подкаталогов помеченных каталогов. Для слежения за всем деревом каталогов нужно пометить соответствующую точку монтирования.

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

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

FAN_MOVE
    Файл или каталог был перемещён (FAN_MOVED_FROM|FAN_MOVED_TO).

Объект файловой системы для пометки задаётся файловым дескриптором 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 задаётся причина ошибки.

ОШИБКИ

EBADF
    В fanotify_fd передан некорректный файловый дескриптор.

EINVAL
    В flags или mask указано некорректное значение, или в fanotify_fd не файловый дескриптор fanotify.

EINVAL
    Файловый дескриптор fanotify был открыт с FAN_CLASS_NOTIF или FAN_REPORT_FID и маска содержит флаг для событий доступа (FAN_OPEN_PERM или FAN_ACCESS_PERM).

ENODEV
    Объект файловой системы, указанный в pathname, не связан с файловой системой, которая поддерживает fsid (например, tmpfs(5)). Эта ошибка может вернуться только, когда файловый дескриптор fanotify, возвращаемый fanotify_init(2), был создан с флагом FAN_REPORT_FID.

ENOENT
    Объект файловой системы, указанный в dirfd и pathname, не существует. Эта ошибка также возникает при попытке удаления метки с не помеченного объекта.

ENOMEM
    Невозможно выделить необходимую память.

ENOSPC
    Количество меток превышает ограничение в 8192 и флаг FAN_UNLIMITED_MARKS не был указан при создании файлового дескриптора fanotify с помощью fanotify_init(2).

ENOSYS
    В этом ядре не реализован fanotify_mark(). Программный интерфейс fanotify доступен только, если ядро было собрано с параметром CONFIG_FANOTIFY.

ENOTDIR
    В значении flags содержится FAN_MARK_ONLYDIR, а в dirfd и pathname указан не каталог.

EOPNOTSUPP
    Объект, указанный в pathname, связан с файловой системой, которая не поддерживает кодирование файловых описателей. Эта ошибка может вернуться только, когда файловый дескриптор fanotify, возвращаемый fanotify_init(2), был создан с флагом FAN_REPORT_FID.

EXDEV
    Объект файловой системы, указанный в pathname, располагается в подтоме файловой системы (например, btrfs(5)), которая использует fsid отличный от используемого в её корневом суперблоке. Эта ошибка может вернуться только, когда файловый дескриптор fanotify, возвращаемый fanotify_init(2), был создан с флагом FAN_REPORT_FID.

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

СООТВЕТСТВИЕ СТАНДАРТАМ
Данный системный вызов есть только в Linux.

ЗАМЕЧАНИЯ

  FAN_OPEN_EXEC и FAN_OPEN_EXEC_PERM
При использовании 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)