Главная » Ядро Linux » Файловая система sysfs

0

 — это виртуальная файловая система, которая существует  только в  оперативной памяти и позволяет просматривать иерархию объектов kobject . Она позволяет пользопателям просматривать топологию устройств операционной системы в  виде простой файловой системы. Атрибуты объектов kobjec t могут экспортироваться  в  виде файлов, которые позволяют считывать значения переменных ядра, а также опционально записывать их.

Хотя изначально целью создания  модели представления устройств было описание топологии устройств системы для управления электропитанием,  файловая система sysfs  стала удачным продолжением этой идеи. Для того чтобы упростить отладку, разработчик унифицированной модели устройств решил экспортировать дерево устройств в  виде файловой системы. Такое решение показало свою полезность вначале в качестве замены файлов, связанных с устройствами, которые раньше экспортировались через файловую систему /ргос,  а  позже в  качестве мощного инструмента  просмотра информации о  системной иерархии объектов. Вначале, до  появления объектов kobject , файловая система sysfs  называлась  driverfs. Позже  стало ясно — новая объектная модель была бы  очень кстати, и в  результате этого появилась концепция объектов kobject . Сегодня каждая система, на которой работает ядро 2.6, имеет поддержку файловой системы sysfs,  и практически во  всех случаях эта файловая система монтируется.

Основная идея работы файловой системы sysfs  — это привязка объектов kobjec t к структуре каталогов с  помощью поля dentry , которое есть в  структуре kobject . Вспомните из материала главы 12, "Виртуальная файловая система", что   структура dentr y  используется для представления элементов каталогов. Связывание объектов с  элементами каталогов проявляется в том, что   каждый объект просто видится как каталог файловой системы. Экспортирование  объектов kobjec t в  виде файловой системы выполняется путем построения дерева элементов каталогов в  оперативной памяти. Но обратите внимание,  объекты kobjec t уже   образуют древовидную структуру  — нашу модель устройств!  Поэтому простое назначение каждому объекту иерархии, которые уже   образуют дерево в  памяти,  соответствующего элемента каталога позволяет легко построить файловую систему sysfs.

На рис. 17.2 показан частичный вид файловой системы sysfs,  которая смонтирована на каталог /sys.

Корневой каталог файлопой системы sysfs  содержит семь подкаталогов: block, bus, class , devices ,  firmware, module и power. В  каталоге bloc k  содержатся каталоги для каждого зарегистрированного в  системе устройства блочного ввода-вывода.

/sys

block/ fd0 hda dev

device-> . ./. ./devices/psi0000:00/0000:00:1f.1/ide/0.0 hda1

hda2 hda3 hda4 hda5 hda6

dev size start star

bus/

queue

lidc hdd loop0 loop1

Ioop2

Ioop3

Ioop4

Ioop5

Ioop6

Ioop7 md0

class/ devices/ firmware/ power

Рис. 17.2. Содержимое части каталога /sys

Каждый из  каталогов в свою  очередь  содержит подкаталоги, соответствующие разделам блочного устройства. Каталог bu s  позволяет просматривать информацию  о системных шинах. В каталоге clas s представлена информация о системных устройствах, которая организована в соответствии с высокоуровневыми функциями этих устройств. Каталог device s содержит информацию о топологии устройств в системе. Она  отображается непосредственно на иерархию структур  устройств ядра. Каталог firmware  содержит специфичное для данной системы дерево  низкоуровневых подсистем, таких как ACPI, EDD, EFT и т.д. В каталоге power содержатся данные по управлению электропитанием всех устройств системы.

Наиболее важным является каталог  devices , который экспортирует модель устройств ядра  во  внешний мир.   Структура каталога соответствует топологии устройств в системе. Большинство информации,  которая содержится в других каталогах, — это  просто  другое  представление данных  каталога devices . Например, в каталоге  /sys/class/net / информация представлена в соответствии с высокоуровневым представлением зарегистрированных сетевых устройств. В этом каталоге может  содержаться подкаталог eth0, который содержит символьную ссылку  device на соответствующее устройство каталога devices .

Посмотрите на  содержимое каталога /sy s той  системы Linux, к которой вы имеете  доступ.  Такое  представление системных устройств является очень  четким и ясным. Оно  показывает взаимосвязь между высокоуровневым представлением информации в каталоге class , низкоуровневым представлением в каталоге device s

и драйверами устройств — в каталоге bus. Такое представление взаимосвязи между устройствами очень информативно. Оно становится еще более ценным, если осознать, что все эти данные свободно доступны и описывают все то, что происходит внутри ядра1.

Добавление и удаление объектов на файловой системе sysfs

Инициализированные объекты kobjec t автоматически не экспортируются через файловую систему sysfs. Для того чтобы сделать объект видимым через sysfs, необходимо использовать функцию kobject_add() .

int kobject_add(struct kobject *kobj);

Положение объекта на файловой системе sysfs  зависит от его положения в объектной иерархии. Если установлен указатель paren t объекта, то объект будет отображен внутри каталога, соответствующего объекту, на который указывает указатель parent . Если указатель paren t не установлен, то объект будет отображен в каталоге, соответствующем значению переменной kset->kobj . Если для некоторого объекта не установлены ни значение поля parent , ни значение поля kset, то считается, что данный объект не имеет родительского и будет отображаться в корневом каталоге файловой системы sysfs. Такое поведение практически всегда соответствует тому, что нужно. Поэтому одно из полей paren t или kse t (или оба) должно быть установлено правильным образом перед вызовом функции kobject_ad d () . Имя каталога, который представляет объект kobjec t в файловой системе sysfs, будет определяться значением поля kobj->name.

Вместо того чтобы последовательно вызывать функции  kobject_ini t ()  и kobject_add() , можно вызвать функцию kobject_registe r () .

int kobject_register(struct kobject *kobj);

Удаление объекта из файловой системы sysfs  выполняется с помощью функции kobject_del() .

void kobject_del(struct kobject *kobj);

Функция  kob j е c t u n r e g i s  t er ()   сочетает в себе выполнение функций kobject_del( )  и kobject_put() .

void kobject_unregister(struct kobject * kobj);

Все эти четыре функции  определены в файле lib/kobject. с и объявлены в файле <linux/kobject.h> .

1Если вас заинтересовала  информаци я о файлово й системе sysfs,  то, вероятно , вам будет интересн о также ознакомиться с HAL, hardware  abstraction layer (уровень абстракции аппаратного обеспечения) ,  информаци я  о которо м доступна по адресу http://hal.freedesktop.org/  .  Подсистема HAL позволяет создать в оперативно й памят и базу данных  на основани и  информаци и файлово й системы sysfs,  объединяя вместе поняти я классов, устройств и драйверов.  На основании этих данных уровень HAL предоставляет  API, которо е позволяе т разрабатыват ь  более интеллектуальные программы.

Добавление файлов на файловой системе sysfs

Объекты kobjec t отображаются на каталоги, и такое отображение выполняется естественным образом. А как насчет создания файлов? — это не что иное, как дерево каталогов без файлов.

Атрибуты, используемые по умолчанию

Набор файлов, которые создаются в каталоге по умолчанию, определяется с помощью поля ktype объектов kobjec t и множеств kset . Следовательно, все объекты kobjec t одного типа имеют один и тот же  набор файлов в  каталогах, которые этим объектам  соответствуют.  Структура  kobject_typ e   содержит  поле  default_attrs , которое представляет собой массив структур attribute . Атрибуты отображают данные ядра на файлы в файловой системе sysfs.

Структура  attribute s  определена в  файле <linux/sysfs.h> .

/*   структура  attribut e    атрибуты позволяют отобразить данные  ядра на файлы файловой  системы sysfs   */

struct attribute {

char

*name;

/* имя атрибута */

struct module

mode_t

*owner;

mode;

/* модуль, если есть, которому принадлежат данные */

/* права доступа к файлу */

};

Поле name содержит имя атрибута. Такое же  имя будет иметь и соответствующий файл на файловой системе sysfs. Поле owner — это указатель на структуру module, которая представляет загружаемый модуль, содержащий соответствующие данные. Если такого модуля не существует, то значение поля равно NULL.  Поле mode имеет тип mode_t и указывает права доступа к файлу на файловой системе sysfs. Если атрибут  предназначен для чтения всеми, то флаг прав доступа доллсен быть установлен в  значение S_IRUGO,  если атрибут имеет право на чтение только для владельца, то права доступа устанавливаются в  значение S_IRUSR. Атрибуты с правом на запись, скорее всего, будут иметь права доступа S_IRUGO    |  S_IWUSR.  Все файлы и каталоги на файловой системе sysfs  принадлежат пользователю с идентификаторами пользователя и группы равными нулю.

Структура  attribut e   используется для представления атрибутов, а  структура sysfs_op s    описывает, как эти атрибуты использовать. Поле sysfs_op s — это указатель на одноименную  структуру, которая определена в  файле <linux/sysfs.h > следующим образом.

struct sysfs_ops {

/* метод вызывается при чтении файла на файловой системе sysfs */

ssize_t (*show) (struct kobject *kobj, struct attribute *attr, char *buffer);

/* метод вызывается при записи файла на файловой системе sysfs */

ssize_t (*store) (struct kobject *kobj, struct attribute *attr, const char *buffer, size_t size);

};

Метод show() вызывается при чтении файла. Он должен выполнить копирование значения атрибута, который передается в  качестве параметра attr , в  буфер, на который указывает параметр buffer . Размер буфера равен PAGE_SIZE  байт. Для аппаратной платформы значение PAGE_SIZE  равно 4096 байтов. Функция должна возвратить количество байтов данных, которые записаны в  буфер в  случае успешного завершения, и отрицательный код ошибки, если такая ошибка возникает.

Метод store( )  вызывается при записи. Он должен скопировать siz e  байт данных из буфера buffe r в  атрибут  attr . Размер буфера всегда равен PAGE_SIZE  или меньше. Функция должна возвратить количество байтов данных, которые прочитаны из буфера при успешном выполнении, и отрицательный код ошибки в случае неудачного завершения.

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

Создание нового атрибута

Обычно атрибутов, которые используются по умолчанию и предоставляются типом ktype, связанным с  объектом kobject , оказывается достаточно. Действительно, все объекты  kobjec t одного типа должны быть чём-то  похожи друг на друга или даже быть идентичными по своей природе. Например,  для всех разделов жестких дисков один и тот же  набор атрибутов должен подходить для всех объектов kobject. Это не просто упрощает жизнь, но и позволяет упорядочить код и получить одинаковый способ доступа ко всем каталогам файловой системы sysfs, связанным  с  родственными объектами.

Тем не менее иногда требуется, чтобы определенный экземпляр объекта kobjec t имел некоторые специфические свойства. Для таких объектоп может оказаться желательным (или необходимым) создать атрибут, которого нет у общего типа данного объекта. Для такого случая ядро предоставляет функцию  sysf   s_create_fil e  ()  для добавления атрибута к существующему объекту.

int sysfs_create_file(struct kobject *kobj, const struct attribute *attr);

Эта функция  позволяет привязать структуру  attribute ,  на которую  указывает параметр  attr ,  к объекту  kobject ,  на который указывает параметр kobj . Перед тем как вызвать эту функцию,  необходимо установить значение атрибута (заполнить поля структуры). Эта функция возвращает значение нуль в  случае успеха и отрицательное значение в случае ошибки.

Обратите внимание,  что для обработки указанного атрибута используется структура sysfs_ops, соответствующая типу ktype объекта.  Иными  словами,  существующие функции show ()  и stor e {),  которые используются для объекта по умолчанию, должны иметь возможность обработать вновь созданный атрибут.

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

int sysfs_create_link(struct  kobject *kobj,

struct kobject *target, char *name);

Эта  функция создает  символьную ссылку  с именем name  в каталоге объекта, соответствующего  параметру  kobj , на  каталог,  соответствующий параметру  target .  Эта функция возвращает нулевое  значение в случае  успеха  и отрицательный код  ошибки в противном случае.

Удаление созданного атрибута

Удаляется атрибут с помощью вызова функции  sysfs_remove_f il e ().

void sysfs_remove_file(struct kobject *kobj, const struct attribute *attr);

После возврата из этой функции указанный атрибут больше не отображается в каталоге объекта.

Символьная ссылка, созданная с помощью функции sysfs_create_lin k (), может быть удалена с  помощью функции sysfs_remove_link().

void  sysfs_remove_link  (struc t  kobject *kobj, char *name) ;

После возврата из функции символьная ссылка с именем name удаляется из каталога, на который отображается объект kobj.

Все эти четыре функции объявлены в  файле  <linux/kobject.h> . Функции sysfs_create_file( )   и    sysfs_remove_file() определены в  файле  fs/sysfs/ file.с , а  функции  sysfs_create_link( )   и  sysfs_remove_link( )  —  в  файле fs/sysfs/symlink.c.

Соглашения по файловой системе sysfs

Файловая  система sysfs — это  место, где  должна  реализовываться  функциональность, для  которой раньше использовался  системный  вызов   ioctl( )   для  специальных  файлов устройств, или  файловая система procfs.  Сегодня модно   выполнять такие   вещи   через   атрибуты файловой  системы  sysfs  в  соответствующем  каталоге. Например,  вместо  того  чтобы  реализовать новую  директиву ioctl( )  для  специального  файла  устройства, лучше  добавить соответствующий  атрибут  в каталоге файловой  системы  sysfs,  который  относится  к  этому  устройству. Такой  подход  позволяет избежать использования небезопасных, из-за отсутствия проверки типов  аргументов, директив ioct l () , а также  файловой системы  /рrо с  с ее бессистемным расположением  файлов и каталогов.

Однако чтобы  файловая  система sysfs оставалась четко  организованной и  интуитивно  понятной,  разработчики должны придерживаться определенных соглашений.

Во-первых,  каждый атрибут   sysfs должен   экспортировать  значение  одной   переменной на  файл.   Значения должны быть  в  текстовом  формате  и  соответствовать простым типам  языка программирования С.  Целью  такого  представления является  необходимость избежать чрезвычайно  запутанного  и  плохо   структурированного представления информации,  которое мы сегодня имеем  на файловой системе /ргос . Использование одной  переменной на  файл  позволяет легко  считывать и записывать данные из  командной строки, а также  просто  работать  через  файловую систему  sysfs с  данными ядра  в программах, написанных на  языке  С.  В случаях, когда  одно  значение  на  файл  приводит к  неэффективному представлению информации,  допустимо использование файлов, в которых хранится несколько значений одного  типа.  Эти данные необходимо четко  разделять.  Наиболее предпочтительным  разделителем является  символ пробела. При  разработке кода  ядра  необходимо всегда  помнить,  что

файлы файловой системы sysfs являются представлениями переменных ядра, и ориентироваться на доступ к ним  из пространства пользователя, в частности из командной строки.

Во-вторых, данные  файловой системы sysfs должны  быть  организованы в виде четкой  иерархии. Для  этого  необходимо правильно разрабатывать связи  "родительпотомок" объектов kobject .  Связывать атрибуты  с объектами kobjec t  необходимо с учетом того, что эта иерархия объектов существует  не только  в ядре, но и экспортируется  в пространство пользователя. Структуру  файловой системы sysfs необходимо поддерживать в четком  виде!

Наконец,  необходимо помнить,  что  файловая система  sysfs является службой ядра  и в некотором роде интерфейсом ядра к прикладным программам (Application Binary Interface, ABT). Пользовательские программы должны  разрабатываться в соответствии  с наличием, положением, содержимым и поведением каталогов и файлов на файловой системе  sysfs. Изменение положения существующих файлов крайне не рекомендуется, а изменение поведения атрибутов, без изменения их имени или положения, может привести к серьезным проблемам.

Эти  простые соглашения позволяют с помощью файловой системы sysfs обеспечить в пространстве пользователя интерфейс ядра с широкими возможностями. При правильном использовании файловой системы sysfs разработчики прикладных программ не будут вас ругать и будут вам благодарны за хороший код.

Источник: Лав,  Роберт. Разработка ядра  Linux, 2-е  издание. : Пер.  с англ.  — М.  : ООО  «И.Д.  Вильяме» 2006. — 448 с. : ил. — Парал. тит. англ.

По теме:

  • Комментарии