Пользовательские программы взаимодействуют с ядром с помощью системных вызовов.
Системные вызовы – сервис, предоставляемый ядром ОС.
open() - открывает и возможно создаёт файл (если выставлен флаг O_CREATE), возвращает файловый дескриптор типа int и создает новый файловый дескриптор открытого файла struct file в системной таблице открытых файлов.
Системный вызов делается одним из следующих методов:
- через программное прерывание (в процессе выполнения программы, когда процессу нужно обслуживание со стороны ОС),
- через инструкцию sysenter (чуть быстрее, опускаются проверки на валидность дескрипторов и проверки, зависящие от уровня привилегии),
- через инструкцию syscall.
ЛАБОРАТОРНАЯ РАБОТА
Системный вызов open() является оберткой функции ядра ksys_open(), которая вызывает функцию do_sys_open().
O_DIRECTORY - Если pathname не является каталогом, вызвать ошибку открытия.
O_NOFOLLOW - если pathname - это символьная ссылка, то open содержит код ошибки
O_CLOEXEC - Устанавливает флаг close-on-exec (Когда этот флаг установлен, система автоматически закрывает файл, когда процесс осуществляет exec) на новом файловом дескрипторе
O_PATH - получить файловый дескриптор, который можно использовать для двух целей:
- указать местоположение в дереве каталогов ФС
- выполнить операции, которые действуют исключительно на уровне файлового дескриптора.
O_TMPFILE - создать неназванный временный обычный файл. Аргумент pathname указывает каталог; безымянный индекс будет создан в ФС этого каталога. Все, что записано в результирующий файл, будет потеряно при закрытии последнего дескриптора файла, если файлу не присвоено имя.
O_CREATE - если файл не существует, то он будет создан
Подсистема аудита предназначена для отслеживания критичных с точки зрения безопасности системных событий.
Действия __alloc_fd() выполняются в режиме монопольного доступа с использованием спин-блокировок.
Структура struct nameidata содержит путь к файлу/корневую директорию/флаги/указатель на структуру filename/inode (path.dentry.d_inode)
RCU-walk(read-copy-update) - это алгоритм выполнения поиска по пути в Linux. Существенным отличием RCU-обхода является то, что он допускает возможность одновременного доступа. Если возникает ситуация, которую rcu-walk не может обработать, возвращается - ECHILD, и будет выполнен вызов в режиме ref-walk.
После того, как была выделена новая структура для открытого файла struct file, вызываются функции do_tmpfile или do_o_path в случае если были установлены флаги O_TMPFILE|O_CREATE или O_PATH при вызове системного вызова open()
Когда O_TMPFILE и O_PATH не установлены, то есть открываем существующий файл
link_path_walk() выполняет определение положения имен (элемента каталога) в дереве каталогов или, другими словами, эта функция запускает процесс прохода по заданному пути. Он обрабатывает pathname шаг за шагом, кроме последнего компонента пути к файлу. Эта обработка включает в себя проверку прав доступа и получение файлового компонента. После выполнения link_path_walk() функция do_last() заполняет файловую структуру на основе результата, полученного с помощью функции link_path_walk().