Введение в POSIX'ивизм

       

Виртуальные файловые системы


До сих пор речь шла о файловых системах, размещаемых на блочных устройствах (block devices based) или, иначе говоря, "реальных". Однако POSIX-совместимые операционки поддерживают еще и несколько типов виртуальных файловых систем. Они не занимают места на диске (или - почти не занимают), располагаясь в оперативной памяти, и служат для специальных целей.

Исторически первой из таких виртуальных файловых систем была файловая система процессов - procfs. Как можно догадаться из названия, она представляет протекающие в системе процессы в виде файлов каталога /proc, откуда и получают информацию о процессах команды типа ps и top. Однако и пользователь может извлечь оттуда немало полезной для себя информации.

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

Множество важной информации содержится в файлах корня /proc. Из них обычными командами просмотра можно извлечь сведения о процессоре (/proc/cpuinfo), текущей конфигурации ядра системы (/proc/config.gz), загруженных его модулях (/proc/modules), устройстах, подсоединенных к шине PCI (/proc/pci) - в частности, иногда только тут можно узнать подробности о своей сетевой карте и внутреннем модеме, необходимые для правильной их настройки.

Следующей виртуальной файловой системой является файловая система устройств - devfs. Она по умолчанию задействована во FreeBSD 5-й ветки и во многих (хотя и далеко не всех) современных дистрибутивах Linux. Чтобы понять ее назначение, нужно вспомнить, как происходило обращение с файлами устройств ранее.

А происходило оно так. Некий набор файлов устройств генерировался при начальной установке системы. Каждый файл устройства характеризовался своим старшим (major) и младшим (minor) номерами.
Первый определял класс устройств, например, диски, терминалы и псевдотерминалы, параллельные или последовательные порты, и так далее. Младший же номер был идентификатором конкретного устройства в данном классе. Очевидно, что сочетание старшего и младшего номеров должно быть уникальным.

Файлы устройств генерировались в некотором соответствии с реальностью, но по принципу явной избыточности. Например, при наличии IDE-контроллера, поддерживающего до 4-х устройств, создавались файлы для всех теоретически подключаемых к нему дисков, даже если в наличии имелся только один. То же и с псевдотерминалами - файлов вида pty* в каталоге /dev можно было обнаружить немерянно (и понятно, почему - ведь каждый запущенный в X-сессии экземпляр эмулятора терминала вроде xtrem требовал своего такого устройства). В результате каталог /dev приобретал объем просто необозримый.

И тем не менее, подчас наличных файлов оказывалось недостаточно для представления всех нужных устройств. И тогда пользователю приходилось их создавать самостоятельно. Файлы для большинства распространенных устройств можно было создать с помощью специально предназначенного сценария /dev/MAKEDEV. Однако иногда он оказывался бессильным (особенно для новых устройств, сценарием еще неучтенных), и приходилось прибегать к чисто ручному созданию файлов устройств командой mknod. Что было не так уж и трудно само по себе, но требовало знания старшего номера создаваемого устройства (младший при этом вычислялся легко).

Появление devfs избавило пользователя от этих забот. Отныне файлы устройств пересоздаются автоматически при старте системы - и только в соответствие с наличным (и поддерживаемым текущей конфигурацией ядра) железом, определяемым в ходе загрузки. Если же в ходе работы какого-либо устройства из числа поддерживаемых недостанет - соответствующий ему файл будет создан сам собой.

Более того, devfs сделала очень легким "горячее" подключение устройств (типа карт PCMCIA, USB-накопителей, цифровых камер и сканеров с этим интерфейсом).




Достаточно воткнуть USB-драйв в соответствующий разъем - и в каталоге / dev можно будут наблюдать появление соответствующего ему файла.

В настоящее время в Linux файловая система устройств постепенно заменяется системой поддержки динамического именования устройств - udev, однако использование ее не стало еще общепризнанным.

В отличие от devfs, udev - не новая поддерживаемая ядром файловая система, пусть и виртуальная, а обычная пользовательская программа (входящая в одноименный пакет). Более того, при ее использовании необходимость в поддержке devfs отпадает вообще.

Правда, для своего функционирования udev нуждается в еще одной виртуальной файловой системе - sysfs, но ее поддержка в ядрах серии 3.6.X осуществляется автоматически (а сама эта файловая система монтируется по умолчанию в каталог /sys). Основываясь на информации из которой, udev и присваивает имена всяческим устройствам (в том числе и при горячем их подключении).

Как уже говорилось, любой POSIX-системе имена файлов конкретных устройств более или менее безразличны, так как оперирует она не с ними, а с их идентификаторами. Ранее в качестве таковых выступали старший и младший номера устройства, определяющие их класс и конкретный экземпляр его. В udev же в ход пошли непосредственные идентификаторы устройств - сериальный номер винчестера, его положение на канале IDE-шины, и так далее, сочетание которых для каждого диска (раздела, и так далее) оказывается уникальным. Программа udev извлекает эти сведения из файловой системы sysfs и, руководствуясь определенными правилами, ставит им в соответствие "человеческие" имена (вроде /dev/hda и так далее).

Во FreeBSD и многих дистрибутивах Linux используется также файловая система в оперативной памяти, именуемая mfs в первом случае и tmpfs - во втором. Реализованы они по разному, но с точки зрения пользователя выглядят почти одинаково - как дисковые разделы, смонтированные в некоторые каталоги. И на самом деле они заменяют собой блочные устройства там, где требуется быстрая, но не обязательно долговременная, запись.


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

В отличие от "нормальных" файловых систем для хранения данных, mfs и tmpfs не нуждаются в создании: для ее использования достаточно факта поддержки ядром (непосредственно или в виде модуля) и монтирования в какой-либо каталог. Обычно таким каталогом выступает /tmp, содержимое которого не должно сохраняться после рестарта системы. В BSD-системах в некоторых случаях целесообразно монтирование mfs в каталог /usr/obj, предназначенный для промежуточных продуктов компиляции при сборке ядра и базовых компонентов. А в Linux одно из штатных мест монтирования tmpfs - каталог /dev/sh. В Source Based дистрибутивах имеет смысл размещать на tmpfs также каталоги для продуктов промежуточной сборки из портообразных систем.

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

Итак, ранее неоднократно упоминалось о разделе, предназначенном для своппинга - то есть области диска, куда может выгружаться часть содержимого оперативной памяти. В Linux и BSD механизм свопирования несколько различен. В первой системе освобождение оперативной памяти происходит при ее переполнении. В системах же BSD-семейства на своп-раздел помещаются фрагменты ОЗУ, не использовавшиеся в течении определенного времени.

С точки зрения программ (и их пользователя) физическая память и раздел своппинга представляют собой единое пространство виртуальной памяти. Что особенно четко выражено в BSD, где ОЗУ может рассматриваться как своего рода кэш по отношению к виртуальной памяти.

Для того, чтобы использовать область подкачки, нужно для создать соответствующий раздел (первичный или логический - без разницы, главное - с соответствующим идентификатором, каковой для Linux swap будет 82). В BSD-системах под своппинг отводится подраздел (subpartition) внутри слайса.



Рекомендованный размер раздела подкачки во всех системах - удвоенный объем оперативной памяти. Что нынче может показаться излишеством: в машинах типичных современных конфигураций (с ОЗУ минимум 256, а то и 512 Мбайт) под Linux раздел подкачки в ходе обычной пользовательской работы практически не задействуется, а в BSD-системах используется лишь ничтожная его доля.

Тем не менее, большие объемы swap-раздела целесообразны при активном использовании временных систем в оперативной памяти - tmpfs и mfs. В этом случае при заполнении ОЗУ эти файловые системы автоматически могут быть расширены за счет раздела подкачки. Казалось бы, это - смена шила на мыло: какой смысл подменять disk based файловую систему на систему, частично размещаемую на своп-разделе (то есть также на диске)? Однако некоторый резон к тому есть: ибо в область своппинга попадают наименее используемые части ОЗУ, так что некоторый выигрыш в быстродействии операций с временными файлами сохраняется. Правда, не стоит обольщаться - выигрыш этот не очень велик, и в наиболее благоприятных условиях не превысит 10%.

Кроме выделения раздела под своппинг, требуется явным образом определить его в этом качестве и активизировать специальными командами. Поддержка виртуальной памяти - одна из жестких функций ядра и Linux, и BSD-систем. Единственное, в чем оно еще нуждается - это в указании дискового раздела в файле /etc/fstab. Впрочем, это будет темой .


Содержание раздела