Sysfs linux что это
Виртуальные файловые системы в Linux: зачем они нужны и как они работают? Часть 1
Всем привет! Мы продолжаем запуски новых потоков по уже полюбившимся вам курсам и сейчас спешим сообщить о том, что у нас стартует новый набор по курсу «Администратор Linux», который запустится в конце апреля. К этому событию и будет приурочена новая публикация. С оригиналом материала можно ознакомиться тут.
Виртуальные файловые системы выполняют роль некой волшебной абстракции, которая позволяет философии Linux говорить, что «всё является файлом».
Что такое файловая система? Опираясь на слова одного из первых контрибьюторов и авторов Linux Робера Лава, «Файловая система – это иерархическое хранилище данных, собранное в соответствии с определенной структурой». Как бы то ни было, это определение в равной мере хорошо подходит для VFAT (Virtual File Allocation Table), Git и Cassandra (база данных NoSQL). Так что именно определяет такое понятие, как «файловая система»?
Основы файловой системы
Если мы можем открывать, читать и записывать в сущность, то эта сущность считается файлом, как мы видим из примера в консоли сверху.
Феномен VFS лишь подчеркивает наблюдение, характерное для Unix-подобных систем, которое гласит, что «всё является файлом». Подумайте, насколько странно, что тот маленький пример сверху с /dev/console показывает, как на самом деле работает консоль. На картинке изображена интерактивная Bash сессия. Отправка строки в консоль (virtual console device) отображает ее на виртуальном экране. VFS имеет другие, еще более странные свойства. Например, она дает возможность осуществлять поиск по ним.
Знакомые нам системы, такие как ext4, NFS и /proc имеют три важные функции в структуре данных С, которая называется file_operations. Кроме того, определенные файловые системы расширяют и переопределяют функции VFS привычным объектно-ориентированным способом. Как отмечает Роберт Лав, абстракция VFS позволяет пользователям Linux беспечно копировать файлы в или из сторонних операционных систем или абстрактных сущностей, таких как pipes, не беспокоясь об их внутреннем формате данных. Со стороны пользователя (userspace) с помощью системного вызова процесс может копировать из файла в структуры данных ядра с помощью метода read() одной файловой системы, а затем использовать метод write() другой файловой системы для вывода данных.
/tmp: Простая подсказка
Все знают, что хранение /tmp на физическом носителе – безумие! Источник.
Почему нежелательно хранить /tmp на физическом носителе? Потому что файлы в /tmp являются временными, а устройства хранения медленнее, чем память, где создается tmpfs. Более того, физические носители более подвержены износу при перезаписи, чем память. Наконец, файлы в /tmp могут содержать конфиденциальную информацию, поэтому их исчезновение при каждой перезагрузке является неотъемлемой функцией.
Здесь /proc/meminfo — это пустой файл, который тем не менее содержит ценную информацию.
Файлы в sysfs описывают одно конкретное свойство для каждой сущности и могут быть читаемыми, перезаписываемыми или и то и другое сразу. «0» в файле говорит о том, что SSD не может быть удален.
Вторую часть перевода начнем с того, как наблюдать за VFS с помощью инструментов eBPF и bcc, а сейчас ждем ваши комментарии и традиционно приглашаем на открытый вебинар, который уже 9 апреля проведет наш преподаватель — Владимир Дроздецкий.
Национальная библиотека им. Н. Э. Баумана
Bauman National Library
Персональные инструменты
sysfs
sysfs – виртуальная файловая система операционной системы Linux, которая экспортирует в пространство пользователя через виртуальные файлы информацию о различных подсистемах ядра, подключенных устройствах и соответствующих им драйверах. В дополнение к экспорту информации о различных устройствах и подсистемах виртуальные файлы используются для их конфигурации.
Содержание
История
К тому времени новая модель драйверов была объединена в версии ядра 2.5.1 и получила название driverfs, которое лучше отражало ее функциональность. В течение следующего года разработки версии 2.5, инфраструктурные возможности модели driverfs стали казаться полезными для других подсистем. Для центрального управления объектами был разработан механизм kobjects, а driverfs преобразовался в sysfs.
Монтирование sysfs
sysfs монтируется как любая другая файловая система в оперативной памяти:
Нужно иметь ввиду, что sysfs монтируется в директорию /sys по-умолчанию.
Навигация в sysfs
Поскольку sysfs это просто набор директорий, файлов и символических ссылок, она легко управляется с помощью обычных утилит оболочки (рекомендуется использовать tree(1)).
На верхнем уровне монтирования sysfs находится число директорий. Эти директории представляют основные подсистемы, зарегистрированные с помощью sysfs. Директории создаются во время запуска системы, когда происходит регистрация подсистем ядром kobject. После инициализации, они начинают открывать объекты, зарегистрированные в рамках соответствующих директорий.
block
Директория block содержит поддиректории для каждого блока устройства, которое было обнаружено в системе. В директории каждого блока устройства находятся атрибуты, описывающие множество параметров, включая размер устройства и соответствующий ему номер dev_t. Там же находится символическая ссылка, которой сопоставляется соответствующее устройство из физического дерева устройств. Так же, существует директория представляющая интерфейс планировщика ввода/вывода. Этот интерфейс обеспечивает статистическими данными о очереди запросов устройств и некоторые перестраиваемые функции, которые пользователь или администратор могут использовать для оптимизации производительности. Каждый раздел каждого блока устройства представлен как поддиректория блока устройства. Атрибуты в этих директориях только для чтения.
Директория bus содержит поддиректории для каждого типа физической шины, которые поддерживают регистрацию в ядре (либо статически скомпилированы, либо загружаются через модуль).
Директория drivers содержит директории для драйверов каждого устройства, зарегистрированного на этом типе шины. Внутри каждой директории драйверов атрибуты позволяют просматривать и управлять параметрами драйвера и символическими ссылками, к которым привязаны драйвера соответствующих устройств из физического дерева устройств.
class
Директория class содержит представления каждого класса устройств, зарегистрированного в ядре. Класс устройства описывает функциональный тип устройства.
Каждый класс устройства содержит поддиректории для каждого класса объекта, который определен и зарегистрирован с этим классом устройства. Для большинства классов объектов устройств, их директории содержат символические ссылки на директории устройства и драйвера. Физическое устройство может содержать несколько объектов класса, которые выполняют разные логические функции. Каждый класс устройства и класс объекта может содержать атрибуты с параметрами, которые описывают или контролируют класс объекта.
devices
Директория devices представляет собой глобальную иерархию устройств. Она содержит все физические устройства, которые были обнаружены шинами, типы которых зарегистрированы в ядре. Родственные устройства представляют собой цепочку устройств, где каждое последующее устройство физически или электрически подчиняется предыдущему. Но существует два типа устройств, являющихся исключениями: платформенные устройства и системные устройства. Платформенные устройства это периферийные устройства, присущие данной платформе. Обычно они имеют порты вводы/вывода или MMIO, которые находятся в определенном месте. Системные устройства не принадлежат к периферийным, но являются неотъемлемой частью системы. Во многом, они не имеют ничего общего с другими устройствами. Они имеют доступ к аппаратной конфигурации, но не имеют возможности передавать данные. Обычно, системные устройства не привязаны к драйверам, но, по-крайней мере для представленных в sysfs, имеется конкретный архитектурный код, который настраивает их и обрабатывает в качестве объекта экспорта.
firmware
Директория firmware содержит интерфейсы для просмотра и управления определенными объектами прошивки и их атрибутами. Прошивка, в этом случае, ссылается на платформо-ориентированный код, который исполняется при запуске системы. Каждая директория содержит множество объектов и атрибутов специфичных для прошивки.
module
power
Интерфейс ядра
Функции sysfs видимые для ядра разделяются на три категории, зависящие от типа объекта, который они экспортируют в пользовательское пространство:
Также есть две подкатегории экспорта, атрибуты которых были разработаны для пользователей нуждающихся в экспорте других файлов, в частности ASCII файлов:
В файловой системе результаты экспорта обеих этих категорий представлены в виде файлов.
Первый параметр всех функций sysfs это kobject, с которым проводится манипуляции. Ядро sysfs предполагает, что этот kobject будет валидным на протяжении времени работы функции. Вызывающий всегда несет ответственность за обеспечение валидности и неизменности объекта в течение всего вызова sysfs. Все функции sysfs должны вызываться из контекста процесса. Они также не должны вызваться с какими-либо спинлоками, так как большинство из них напрямую принимают семафоры и все вызовы функций виртуальной файловой системы, которые также принимают семафоры и могут стать причиной остановки процесса.
Объекты ядра
Объекты ядра экспортируются как директории через sysfs. Функции для работы с объектами ядра:
Объявление функции | Назначение |
---|---|
int sysfs_create_dir(struct kobject ∗ k); | Создание директории |
void sysfs_remove_dir(struct kobject ∗ k); | Удаление директории |
int sysfs_rename_dir(struct kobject ∗, const char ∗new_name); | Изменение имени директории |
У параметра kobject существует два основных поля, за валидностью которых и нужно следить:
При создании директории, эти параметры контролируют где будет создана директория и что запустило создание этой директории. Расположение новой директории определяется по параметру k->parent ; она создается как ее поддиректория. Если параметр k->parent пуст, то директория создастся на самом верхнем уровне иерархии. Во всех случаях, подсистема (кроме драйвера низкого уровня) сама заполнит эту область информацией известной об объекте, если объект зарегистрирован в подсистеме. Это обеспечивает простой механизм создания пользовательского представления внутреннего дерева объектов.
В случае удаления директории, также удалятся все объекты, принадлежащие данной директории, в том числе и файлы.
При вызове функции изменения имени директории, sysfs выделяет новый объект dentry для kobject и вызывает процедуру koject для изменения имени объекта. Если переименование прошло успешно функция вернет 0. В других случаях, функция возвращает отрицательное значение, соответствующее идентификатору ошибки.
Объекты атрибутов
Объявление функции | Назначение |
---|---|
int sysfs_create_file(struct kobject ∗, const struct attribute ∗); | Создание файла |
void sysfs_remove_file(struct kobject ∗, const struct attribute ∗); | Удаление файла |
int sysfs_update_file(struct kobject ∗, const struct attribute ∗); | Обновление файла |
При создании атрибута, для определения его имени используется поле name структуры и поле mode для установки режима доступа к файлу. Директория создания файла определяется локацией kobject. Поле owner структуры используется как счетчик ссылок для того, чтобы знать когда файл доступен. Файловые операции над атрибутами, которые вызывает виртуальная файловая система устанавливаются sysfs. Это позволяет sysfs ловить каждый запрос доступа и выполнить необходимые действия. Когда файл открыт, sysfs инкрементирует счетчик ссылок и kobject, представленного директорией где расположен атрибут, и модуля, содержащего код атрибута.
Если данные атрибута изменены, ядро может сообщить процессу, что пользовательское пространство может ждать обновления, путем изменения временную отметку файла используя функцию обновления.
Объекты отношений
Отношение между двумя объектами в sysfs может быть выражено символической ссылкой. Функции для работы с символическими ссылками:
Объявление функции | Назначение |
---|---|
int sysfs_create_link(struct kobject ∗kobj, struct kobject ∗target,char ∗name); | Создание символической ссылки |
void sysfs_remove_link(struct kobject ∗, char ∗name); | Удаление символической ссылки |
Группы атрибутов
Интерфейс группы атрибутов это простой интерфейс для добавления и удаления атрибутов за один вызов. Работа с группой атрибутов обеспечивается struct attribute_group с набором методов:
Объявление функции | Назначение |
---|---|
int sysfs_create_group(struct kobject ∗, const struct attribute_group ∗); | Создание группы атрибутов |
void sysfs_remove_group(struct kobject ∗, const struct attribute_group ∗); | Удаление группы атрибутов |
Группа атрибутов представляет собой простой массив атрибутов, определенный полем attrs. sysfs может создать поддиректорию для хранения группы атрибутов. При добавлении атрибутов, значение возвращаемого результата функции зависит от каждого. Если добавление хотя бы одного атрибута нарушится, предыдущие добавленные атрибуты удалятся и вернется код ошибки. При удалении группы атрибутов, все внутренние атрибуты также будут удалены. Если для хранения группы sysfs создала поддиректорию, то она также будет удалена.
Бинарные файлы
Бинарные файлы это специальный класс файлов, которые могут быть экспортированы через sysfs, используя struct bin_attribute и ее методы:
Объявление функции | Назначение |
---|---|
int sysfs_create_bin_file(struct kobject ∗ kobj, struct bin_attribute ∗ attr); | Создание бинарного файла |
int sysfs_remove_bin_file(struct kobject ∗ kobj, struct bin_attribute ∗ attr); | Удаление бинарного файла |
Структура нужна, чтобы экспортировать бинарные данные, которые легче форматировать и обрабатывать в более гибкой среде, такой как контекст процесса пользовательского пространства, так как они имеют известный заданный формат.
Записки дебианщика
В этом блоге публикуются заметки и решения, найденные в процессе работы, освоения и жизни в дистрибутиве Debian GNU/Linux.
Вглубь синтетических джунглей файловой системы sysfs в Linux
Зачем нужна /sys, когда есть /proc?
Основной лейтмотив создания /sys было навести некоторый порядок в том бардаке, который являет из себя /proc и выделить информацию о структурах ядра в отдельную директорию.
Sysfs это файловая система, находящаяся в памяти (in-memory), основана первоначально на Ramfs, которая в свою очередь была написана во время перехода на ядро 2.4.0. Как говорит один из авторов [1], «это было упражнение в элегантности, имевшее целью показать, насколько легко написать простую файловую систему, если использовать новый на тот момент слой VFS». Из-за простоты и использования VFS, это дало здоровую основу для создания других in-memory файловых систем.
При этом sysfs может быть смонтирована, как и любая другая файловая система из пространства пользователя. Большинство дистрибутивов делают это автоматически при старте системы, добавляя соотвутствующую строчку в /etc/fstab.
Что внутри /sys?
Sysfs является каналом распространения информации между ядром и пространством пользователя. Например, есть возможность смены планировщика ввода/вывода или изменения параметров Udev программы. В каталоге /sys находится несколько подкаталогов, представляющих ряд основных подсистем, которые зарегистрированы в Sysfs:
Внутри /sys/block
Каталог /sys/ block содержит подкаталоги для каждого блочного устройства, которое было обнаружено в системе. Там хранятся параметры, которые описывают такие свойства блочных устройств, как размер устройства, его партиции, планировщик ввода-вывода и другие.
Зайдя туда, мы обнаруживаем кучу блочных устройств, среди которых можно найти рабочий винчестер, подключённые флешки и внешние жёсткие диски. Вот что автор этих строк нашёл про свой жёсткий диск, на котором установлен евонный Дебиан:
Статистика ввода-вывода
Интерфейс /sys/block/sdX/stat даёт некоторые статистические данные о производительности ввода-вывода ядра. Эти данные пользователь или администратор может использовать для оптимизации производительности, если знает, что они значат.
Например, если дать команду:
Мы увидим что-то типа:
186908 41568 6033917 2408504 91198 509600 4882200 9406764 0 1161304 11848624
Эти сакрально-литургические знаки означают следующее:
Смена планировщика ввода-вывода на лету
Как нам намекает документация, планировщик ввода-вывода может быть изменён в любое время на лету, хотя может быть небольшая задержка из-за того, что все запросы предыдущего планировщика должны быть обработаны прежде, чем запустится новый. Чтобы узнать, какой планировщик стоит сейчас, даём команду:
Сменить планировщик можно на лету:
# echo «deadline» > /sys/block/sda/queue/scheduler
После этого планировщик для данного диска будет изменён.
И другие каталоги.
Содержимое других каталогов будет интереснее разработчикам, а не пользователям, и может сильно меняться от версии ядра Linux.
/sys/bus
Это структура шин данных в системе, которая показывает, какая шина куда подключена (например, контроллер USB может быть подключен к шине PCI), и какие устройства в каждой шине потенциально может поддерживать (наряду с соответствующими драйверами), и какие устройства существуют. Здесь есть символической ссылки, которые указывают на директории устройства в глобальном дереве устройств. Каждый тип шины данных представлен двумя подкаталогами: устройств и драйверов.
/sys/class
Хранит все классы устройств, зарегистрированные ядром. Используется для описания функционального типа устройств. Большинство подкаталогов содержат символические ссылки на каталоги device и driver. Например, физическое устройство типа мышь может ссылаться на объект ядра «мышь», на устройство input event и input debug. Классы могут включать в себя диски, разделы, последовательные порты, и т.д.
/sys/devices
Содержит глобальную иерархию устройств: каждое физическое устройство, которые было обнаружено и зарегистрировано ядром.
Например, автор этих строк нашёл:
Platform devices это периферия (подключаемые устройства), присущие конкретной платформе (порты ввода-вывода, legacy-устройства типа последовательного контроллера или контроллера дискет [floppy controller]).
System devices это устройства, интергрированные в платформу, например аппаратные регистры для доступа к конфигурированию, которые не имеют возможностей обмениваться данными. Обычно для них нет драйверов (процессор, таймеры и другое).
/sys/firmware
Cодержит интерфейсы для просмотра и манипулирования firmware-специфичными объектами и их параметрами. Как правило, это платформо-зависимый код, который выполняется в системе при включении, например BIOS.
/sys/module
Cодержит подкаталоги для каждого загруженного модуля ядра. Имя каталога отражает имя модуля. Ядро имеет глобальное пространство имён для всех модулей. Подкаталоги содержат параметры, специфичные для каждого загруженного модуля. Эта информация используется для отладки и простым смертным не будет интересна.
/sys/power
Это скорее заделка на будущее. Может содержать название состояния, которое позволит процессу переходить в режим пониженного энергопотребления.
В зависимости от версии ядра, в /sys могут появляться и другие каталоги.
Ссылки
Есть любопытный документец [1] The sysfs Filesystem, OLS’05 на 14 страниц, написанная тем водянистым и пустозвонным стилем, коий так не переваривает автор этих строк. Документация к ядру тоже не особенно жаждет подробно рассказать о том, что означают все эти переменные и отгораживается вот этим:
Виртуальные файловые системы в Linux: зачем они нужны и как они работают? Часть 2
Всем привет, делимся с вами второй частью публикации «Виртуальные файловые системы в Linux: зачем они нужны и как они работают?» Первую часть можно прочитать тут. Напомним, данная серия публикаций приурочена к запуску нового потока по курсу «Администратор Linux», который стартует уже совсем скоро.
Как наблюдать за VFS с помощью инструментов eBPF и bcc
Самый простой способ понять, как ядро оперирует файлами sysfs – это посмотреть за этим на практике, а самый простой способ понаблюдать за ARM64 – это использовать eBPF. eBPF (сокращение от Berkeley Packet Filter) состоит из виртуальной машины, запущенной в ядре, которую привилегированные пользователи могут запрашивать ( query ) из командной строки. Исходники ядра сообщают читателю, что может сделать ядро; запуск инструментов eBPF в загруженной системе показывает, что на самом деле делает ядро.
К счастью, начать использовать eBPF достаточно легко с помощью инструментов bcc, которые доступны в качестве пакетов из общего дистрибутива Linux и подробно задокументированы Бернардом Греггом. Инструменты bcc – это скрипты на Python с маленькими вставками кода на С, это означает, что каждый, кто знаком с обоими языками может с легкостью их модифицировать. В bcc/tools есть 80 Python скриптов, а это значит, что скорее всего разработчик или системный администратор сможет подобрать себе что-нибудь подходящее для решения задачи.
vfsstat.py – это скрипт на Python, со вставками С кода, который просто считает вызовы функций VFS.
Приведем более тривиальный пример и посмотрим, что бывает, когда мы вставляем USB-флеш накопитель в компьютер и его обнаруживает система.
Корневые файловые системы только для чтения делают возможными встроенные устройства
Конечно, никто не выключает сервер или свой компьютер, вытаскивая вилку из розетки. Но почему? А все потому что смонтированные файловые системы на физических устройствах хранения могут иметь отложенные записи, а структуры данных, записывающие их состояние, могут не синхронизироваться с записями в хранилище. Когда это случается, владельцам системы приходится ждать следующей загрузки для запуска утилиты fsck filesystem-recovery и, в худшем случае, потерять данные.
Связываемые и накладываемые маунты, использование их контейнерами
Выполнение команды man mount – лучший способ узнать про связываемые и накладываемые маунты, которые дают разработчикам и системным администраторам возможность создавать файловую систему по одному пути, а затем предоставлять ее приложениям в другом. Для встроенных систем это означает возможность хранить файлы в /var на флеш-накопителе, доступном только для чтения, но накладываемое или связываемое монтирование пути из tmpfs в /var при загрузке позволит приложениям записывать туда заметки (scrawl). При следующем включении изменения в /var будут утеряны. Накладываемое монтирование создает объединение между tmpfs и нижележащей файловой системой и позволяет делать якобы изменения существующих файлов в ro-tootf тогда как связываемое монтирование может сделать новые пустые tmpfs папки видимыми как доступные для записи в ro-rootfs путях. В то время как overlayfs это правильный ( proper ) тип файловой системы, связываемое монтирование реализовано в пространстве имен VFS.
Посмотрим, что получилось:
Запуск mountsnoop во время «загрузки» контейнера показывает, что среда выполнения контейнера сильно зависит от связываемого монтирования (Отображается только начало длинного вывода).
Друзья, напишите была ли эта статья полезной для вас? Возможно у вас есть какие-то комментарии или замечания? А тех, кому интересен курс «Администратор Linux», приглашаем на день открытых дверей, который пройдёт 18 апреля.