fanotify_mark(2)
| 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 — битовая маска, описывающая выполняемое изменение. Она должна содержать только одно значение из:
- 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 не проверяется на корректность.
СМОТРИТЕ ТАКЖЕ
| 2019-08-02 | Linux |
