sysfs

sysfs – виртуальная файловая система операционной системы Linux, которая экспортирует в пространство пользователя через виртуальные файлы информацию о различных подсистемах ядра, подключенных устройствах и соответствующих им драйверах. В дополнение к экспорту информации о различных устройствах и подсистемах виртуальные файлы используются для их конфигурации.

sysfs обеспечивает похожую функциональность, что и sysctl в системах типа BSD. Различие состоит в том, что sysfs - виртуальная файловая система, а sysctl является механизмом встроенным в ядро.

История

sysfs - файловая система в оперативной памяти, разработанная Патриком Мошелом, первоначально основанная на ramfs. sysfs первоначально назывался ddfs (Device Driver Filesystem) и была написана для отладки новой модели драйверов. Механизм использовал procfs для экспорта информации из дерева устройств, но под строгими указаниями Линуса Торвальда, был преобразован под использование новой файловой системы основанной на ramfs.

К тому времени новая модель драйверов была объединена в версии ядра 2.5.1 и получила название driverfs, которое лучше отражало ее функциональность. В течение следующего года разработки версии 2.5, инфраструктурные возможности модели driverfs стали казаться полезными для других подсистем. Для центрального управления объектами был разработан механизм kobjects, а driverfs преобразовался в sysfs.

Монтирование sysfs

sysfs монтируется как любая другая файловая система в оперативной памяти:

mount -t sysfs sysfs /sys

Также, sysfs может быть смонтирована автоматически при загрузке, используя файл /etc/fstab. Большинство дистрибьютов, поддерживающих ядро версии 2.6, имеют записи для sysfs в /etc/fstab.

Нужно иметь ввиду, что sysfs монтируется в директорию /sys по-умолчанию.

Навигация в sysfs

Поскольку sysfs это просто набор директорий, файлов и символических ссылок, она легко управляется с помощью обычных утилит оболочки (рекомендуется использовать tree(1)).

На верхнем уровне монтирования sysfs находится число директорий. Эти директории представляют основные подсистемы, зарегистрированные с помощью sysfs. Директории создаются во время запуска системы, когда происходит регистрация подсистем ядром kobject. После инициализации, они начинают открывать объекты, зарегистрированные в рамках соответствующих директорий.

block

Директория block содержит поддиректории для каждого блока устройства, которое было обнаружено в системе. В директории каждого блока устройства находятся атрибуты, описывающие множество параметров, включая размер устройства и соответствующий ему номер dev_t. Там же находится символическая ссылка, которой сопоставляется соответствующее устройство из физического дерева устройств. Так же, существует директория представляющая интерфейс планировщика ввода/вывода. Этот интерфейс обеспечивает статистическими данными о очереди запросов устройств и некоторые перестраиваемые функции, которые пользователь или администратор могут использовать для оптимизации производительности. Каждый раздел каждого блока устройства представлен как поддиректория блока устройства. Атрибуты в этих директориях только для чтения.

bus

Директория bus содержит поддиректории для каждого типа физической шины, которые поддерживают регистрацию в ядре (либо статически скомпилированы, либо загружаются через модуль).

Каждый тип шины представлен двумя поддиректориями: devices и drivers. Директория devices содержит список устройств, обнаруженных на этом типе шины во всей системе. В списке состоит из символических ссылок, которым соответствуют устройства из физического дерева устройств.

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

class

Директория class содержит представления каждого класса устройств, зарегистрированного в ядре. Класс устройства описывает функциональный тип устройства.

Каждый класс устройства содержит поддиректории для каждого класса объекта, который определен и зарегистрирован с этим классом устройства. Для большинства классов объектов устройств, их директории содержат символические ссылки на директории устройства и драйвера. Физическое устройство может содержать несколько объектов класса, которые выполняют разные логические функции. Каждый класс устройства и класс объекта может содержать атрибуты с параметрами, которые описывают или контролируют класс объекта.

devices

Директория devices представляет собой глобальную иерархию устройств. Она содержит все физические устройства, которые были обнаружены шинами, типы которых зарегистрированы в ядре. Родственные устройства представляют собой цепочку устройств, где каждое последующее устройство физически или электрически подчиняется предыдущему. Но существует два типа устройств, являющихся исключениями: платформенные устройства и системные устройства. Платформенные устройства это периферийные устройства, присущие данной платформе. Обычно они имеют порты вводы/вывода или MMIO, которые находятся в определенном месте. Системные устройства не принадлежат к периферийным, но являются неотъемлемой частью системы. Во многом, они не имеют ничего общего с другими устройствами. Они имеют доступ к аппаратной конфигурации, но не имеют возможности передавать данные. Обычно, системные устройства не привязаны к драйверам, но, по-крайней мере для представленных в sysfs, имеется конкретный архитектурный код, который настраивает их и обрабатывает в качестве объекта экспорта.

firmware

Директория firmware содержит интерфейсы для просмотра и управления определенными объектами прошивки и их атрибутами. Прошивка, в этом случае, ссылается на платформо-ориентированный код, который исполняется при запуске системы. Каждая директория содержит множество объектов и атрибутов специфичных для прошивки.

module

Директория module содержит поддиректории для каждого модуля загруженного в ядро. Имя каждой директории - объединение имени файла объекта модуля и внутреннего имени модуля. Каждый модуль представлен здесь, независимо от того как подсистема зарегистрировала его и присущие ему объекты. Ядро имеет глобальное пространство имен для всех модулей.

Внутри каждой директории находятся поддиректории, называемые секциями. Поддиректории содержат атрибуты секции модуля, которые используются для отладки. Каждая директория модуля содержит хотя бы один атрибут: refcnt. Этот атрибут показывает текущий показатель счетчика ссылок или число пользователей модуля. Это значение аналогично значению четвертой колонки команды lsmod(8).

power

Директория power представляет подсистемы, частично использующие питание. Директория содержит два атрибута: disk, который управляет механизмом остановки диска; state, который позволяет процессу ввести состояние низкого энергопотребления.

Интерфейс ядра

Функции 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-> name

При создании директории, эти параметры контролируют где будет создана директория и что запустило создание этой директории. Расположение новой директории определяется по параметру k->parent; она создается как ее поддиректория. Если параметр k->parent пуст, то директория создастся на самом верхнем уровне иерархии. Во всех случаях, подсистема (кроме драйвера низкого уровня) сама заполнит эту область информацией известной об объекте, если объект зарегистрирован в подсистеме. Это обеспечивает простой механизм создания пользовательского представления внутреннего дерева объектов.

В случае удаления директории, также удалятся все объекты, принадлежащие данной директории, в том числе и файлы.

При вызове функции изменения имени директории, sysfs выделяет новый объект dentry для kobject и вызывает процедуру koject для изменения имени объекта. Если переименование прошло успешно функция вернет 0. В других случаях, функция возвращает отрицательное значение, соответствующее идентификатору ошибки.

Объекты атрибутов

Объекты атрибутов могут быть переданы через sysfs как обычные файлы, используя struct attribute, с соответствующими методами:

Объявление функции Назначение
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); Удаление символической ссылки

Отношение внутри ядра может быть просто указателем между двумя разными объектами. Если оба объекта представлены в sysfs как директории, тогда символическая ссылка между ними может быть создана для предотвращения возникновения избыточной информации. При создании символической ссылки между двумя объектами первый аргумент функции kobject является объектом откуда идет ссылка, то есть директория, где ссылка была создана. Второй аргумент - директория куда указывает ссылка. Третий - имя ссылки в системе.

Группы атрибутов

Интерфейс группы атрибутов это простой интерфейс для добавления и удаления атрибутов за один вызов. Работа с группой атрибутов обеспечивается 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); Удаление бинарного файла

Структура нужна, чтобы экспортировать бинарные данные, которые легче форматировать и обрабатывать в более гибкой среде, такой как контекст процесса пользовательского пространства, так как они имеют известный заданный формат.

Источники