Search     or:     and:
 LINUX 
 Language 
 Kernel 
 Package 
 Book 
 Test 
 OS 
 Forum 
 iakovlev.org 
 Kernels
 Boot 
 Memory 
 File system
 0.01
 1.0 
 2.0 
 2.4 
 2.6 
 3.x 
 4.x 
 5.x 
 6.x 
 Интервью 
 Kernel
 HOW-TO 1
 Ptrace
 Kernel-Rebuild-HOWTO
 Runlevel
 Linux daemons
 FAQ
NEWS
Последние статьи :
  Тренажёр 16.01   
  Эльбрус 05.12   
  Алгоритмы 12.04   
  Rust 07.11   
  Go 25.12   
  EXT4 10.11   
  FS benchmark 15.09   
  Сетунь 23.07   
  Trees 25.06   
  Apache 03.02   
 
TOP 20
 MINIX...3057 
 Solaris...2933 
 LD...2904 
 Linux Kernel 2.6...2470 
 William Gropp...2180 
 Rodriguez 6...2011 
 C++ Templates 3...1945 
 Trees...1937 
 Kamran Husain...1865 
 Secure Programming for Li...1792 
 Максвелл 5...1710 
 DevFS...1693 
 Part 3...1682 
 Stein-MacEachern-> Час...1632 
 Go Web ...1624 
 Ethreal 4...1618 
 Arrays...1607 
 Стивенс 9...1603 
 Максвелл 1...1592 
 FAQ...1538 
 
  01.01.2024 : 3621733 посещений 

iakovlev.org

Journalling and ReiserFS

Daniel Robbins (drobbins@gentoo.org)
President/CEO
June 2001



Перевод: Владимир Холманов
С выходом релиза 2.4 Linux появилась возможность использования filesystem с новыми свойствами, таких как Reiserfs, XFS, GFS и других. Эти filesystems еще не достаточно опробованы и имеются вопросы, что именно они могут делать, насколько они хороши и насколько оправдано их использование в промышленной Linux среде. Daniel Robbins отвечает на эти вопросы по ходу пояснения инсталляции этих новых продвинутых filesystems под Linux 2.4. В этой, первой статье из цикла, даются пояснения по journalling вообще и ReiserFS в частности.

Что следует ожидать от прочтения этого цикла статей.

Цель этого цикла состоит в том, чтобы дать твердое, практическое введение в новые файловые системы для Linux, такие как ReiserFS, XFS, JFS, GFS, ext3 и другие. Я хочу "вооружить" читателя практичным взглядом на эти вещи и подготовить к осознанному использованию новых файловых систем. Цель так же в том, чтобы помочь Вам (насколько это возможно) избежать многих потенциальных ловушек. Иначе, предлагается осторожный просмотр файловых систем с позиций стабильности, производительности (плюсов и минусов), любых отрицательных воздействий на приложения, анализ комбинаций kernel/patch и т.п. Рассматривайте цикл статей как "insider's guide" для файловых систем нового поколения.

Это то, что следует иметь в виду. Однако, открывая цикл, я несколько отвлекаюсь от поставленной "практической" цели и отвлекаюсь на небольшое "теоретическое" вступление. Далее будут охвачены две темы, очень важные для Linux development community - "журнализация" и "техническая" точка зрения на проект ReiserFS. Journalling - технология, которую долго ждали, и пришло время ее практического использования. На этой технологии работают ReiserFS, XFS, JFS, ext3 и GFS. Важно точно понять, что собственно делает journalling и почему Linux в ней нуждается. Даже если вам это хорошо известно, я надеюсь, что мое journalling intro Вам будет полезно. Это хорошая "рыба" для объяснения технологии другим и кое-что для практики. Часто процесс внедрения нового приходится начинать с "Linux guy/gal", убеждая других в необходимости "качественного скачка".

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

Введение в journalling: meta-data

Начнем с банального. Файловые системы существуют для того, чтобы хранить, находить и манипулировать данными. Для выполнения таких задач сама файловая система должна иметь внутреннюю "управляющую" структуру, которая позволяет все это делать. Такая внутренняя структура ("the data about the data") называется meta-data. От организации этих meta-data зависят рабочие характеристики файловых систем (и это то, чем файловые системы друг от друга отличаются).

Обычно с такими meta-data сам пользователь не взаимодействует. Вместо этого с ними работает драйвер файловой системы. Linux filesystem driver специально разработан для управления этим лабиринтом метаданных. Однако, для функционирования драйвера имеется одно важное требование; он ожидает видеть метаданные в разумном, непротиворечивом, не разрушенном состоянии. В противном случае обращение к файлам становится невозможным.

Введение в journalling: fsck

Поговорим о fsck. Где-то в начале загрузки Linux запускается fsck и начинается сканирование всех локальных файловых систем (перечислены в /etc/fstab). Делается это для того, чтобы гарантировать непротиворечивость meta-data и, в конечном счете, возможность монтирования файловой системы. Такое сканирование занимает много времени и, в целях "экономии", предполагается следующее. Если Linux завершает работу "корректно", то сброс на диск всех кэшированных данных происходит "штатно". В таком случае есть гарантия, что filesystem размонтирована "чисто" и готова к очередному монтированию. Как правило, fsck ограничивается только проверкой "флага чистого размонтирования" и, если проблем нет, делает разумное предположение, что с meta-data все OK.

Однако все мы знаем, что происходят и аварийные ситуации вследствие сбоя в питании или глубокого зависания системы. В таких ситуациях о "чистом размонтировании" со сбросом всех кэшированных данных на диск речи не идет. Если такое происходит, очередной запуск fsck обнаруживает это и делается разумный вывод, что filesystems, вероятно, не готова к взаимодействию с драйвером. Очень может быть, что meta-data находятся в противоречивом состоянии.

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

Проблемы с fsck

Нельзя сказать, что описанное - плохой подход к обеспечению целостности файловой системы, но решение не оптимально. Не оптимальность результат того, что fsck должен просканировать все метаданные файловой системы для вывода об их непротиворечивости. Выполнение полной проверки всех метаданных задача сама по себе трудоемкая. К этому следует добавить, что с увеличением размера файловой системы затраты на полное сканирование растут прогрессивно (на персональной машине это может занять несколько минут, на сервере полчаса и больше). И еще, стандартное поведение fsck предполагает периодически проверки после некоторого числа "чистых размонтирований", что не может считаться приемлемым для mission-critical datacenter, когда "время - деньги". К счастью, имеется лучшее решение.

Журнал.

Журналируемые файловые системы снимают проблему fsck через дополнительную data structure, называемую журналом. Такой журнал - on-disk structure. Прежде, чем драйвер файловой системы сделает любое изменение в meta-data, делается запись в журнал с описанием предстоящих действий. Только после этого происходит изменение самих метаданных. Таким образом, журналируемая файловая система обслуживает регистрационный файл последних модификаций метаданных. Затраты на ведение такого журнала несравненно ниже, чем сканирование всей файловой системы на предмет непротиворечивости метаданных.

Представьте себе цепочку - хранящиеся данные (stuff), "данные об этих данных" (the data about the stuff) и журнал с meta-meta-data (the data about the data about the stuff).

Journalling в действии.

А что же делает fsck на журналируемой файловой системе? Обычно - ничего. Он просто "не видит" файловую систему и разрешает ее монтирование. Реальное волшебство быстрого восстановления filesystem в непротиворечивое состояние ложится на драйвер файловой системы. Когда файловая система монтируется, Linux filesystem driver выясняет, все ли было в порядке. Если "чистого размонтирования" не было и метаданные должны быть исправлены то, вместо выполнения полного сканирования (как это делает fsck), драйвер читает журнал. Так как в журнале содержится хронология всех последних изменений метаданных, выполняется просмотр мизерной части meta-data. Вопрос о приведении файловой системы в непротиворечивое состояние решается в течение долей, максимум нескольких секунд. В отличие от традиционного (на сегодняшний день) подхода, время восстановления не зависит от размера файловой системы (зависит от интенсивности операций IO в момент, предшествующий краху). Благодаря журналу снимаются многие проблемы, ставшие препятствием на пути увеличения размеров файловых систем.

ReiserFS

Теперь перейдем к ReiserFS, первой из нескольких журналируемых файловых систем, которые планируется исследовать. ReiserFS 3.6.x (версия для Linux 2.4) разработана Hans Reiser и его командой Namesys. Hans и его команда проповедуют философию, что лучшая файловая система та, которая формирует единую общедоступную среду, или namespace. В такой среде приложения могут взаимодействовать более гибко, эффективно и мощно. Для достижения этого, файловая система должна выполнять часть работы, традиционно выполнявшуюся приложениями. При таком подходе пользователи часто могут продолжать прямое использование файловой системы вместо формирования уровней специального назначения, типа баз данных и т.п.

Работа с маленькими файлами.

Как обстоят дела с размещением в файловой системе большого числа маленьких порций информации? В Namesys решили, по крайней мере, для начала, сосредоточится на одном из аспектов работы файловой системы - работе с маленькими файлами. Строго говоря, файловые системы наподобие ext2 и ufs в этой области ведут себя неэффективно, часто вынуждая разработчиков проектировать базы данных или использовать другие "фокусы" для получения удовлетворительной производительности. Такой подход приводит к "изобретению множества велосипедов" и порождает огромное число несовместимых API узкоспециального назначения.

Разберемся, а за счет чего ext2 поощряет этот вид "велосипедного" программирования. Ext2 хороша для хранения достаточно большого числа файлов размером более двадцати килобайт каждый, но совсем не идеальна для хранения 2,000 50-байтовых файлов. Мало того, что заметно снижается производительность, но и само хранение маленьких файлов на ext2 приводит к неэффективному использованию дискового пространства, так как ext2 ассигнует под каждый файл целое число 1-2-4 KB блоков (размер блока устанавливается при формировании файловой системы).

Обычная житейская мудрость подсказывает нам отказаться от хранения многих смехотворно маленьких файлов непосредственно на файловой системе. Вместо этого возникает идея хранения информации в некоторой базе данных, работающей над filesystem. В ответ на это Hans Reiser сказал бы, что всякий раз, когда формируется уровень над filesystem, это свидетельствует лишь о том, что файловая система не отвечает нашим потребностям. Если бы она удовлетворяла, от этого можно было бы отказаться. Следовательно, хорошо спроектированная файловая система экономит время на разработку и устраняет ни с чем более не совместимый код.

Но это все теория. А как на практике ReiserFS работает с большим числом маленьких файлов? Удивительно, но очень хорошо. Фактически, ReiserFS при обработке файлов размером меньше одного K выигрывает в скорости у ext2 в восемь - пятнадцать раз! Вообще, ReiserFS превосходит по быстродействию ext2 в почти каждой области, но действительно сияет, когда сравнивается обработка маленьких файлов.

Технология ReiserFS

За счет чего ReiserFS эффективно работает с маленькими файлами? ReiserFS использует специально оптимизированные b* balanced tree (одно на filesystem) для организации всех данных файловой системы. Одно это дает большое увеличение производительности, а также снимает ряд искусственных ограничений на размещение файловой системы. Например, становится возможным иметь каталог, содержащий 100,000 других подкаталогов. Еще одна выгода от использования b*tree в том, что ReiserFS, подобно большинству других filesystems нового поколения, динамически ассигнует inodes вместо их статического набора, образующегося при создании "традиционной" файловой системы. Это дает большую гибкость и оптимальность в формировании пространства хранения.

ReiserFS также имеет ряд features, нацеленных специально для улучшения работы с маленькими файлами. ReiserFS не связана ограничением в ассигновании памяти для файла в целом числе 1-2-4 KB блоков. По необходимости для файла может ассигноваться точный размер. ReiserFS также включает некоторые виды специальной оптимизации файловых "хвостов" для хранения конечных частей файлов, меньших, чем блок filesystem. Для увеличения скорости, ReiserFS способен хранить содержимое файлов непосредственно внутри b*tree, а не в виде указателя на дисковый блок (в ext2 есть понятие fastlink, когда содержимое "мягкой" ссылки до 60 байт хранится в inode).

Тем самым достигается две вещи. Первое, сильно увеличивается производительность, так как data и stat_data (inode) информация может хранится рядом и считываться одной дисковой операцией IO. Второе, ReiserFS способен упаковать хвосты, экономя дисковое пространство. Фактически, при разрешении ReiserFS выполнять упаковку хвостов (значение по умолчанию) будет экономиться примерно шесть процентов дискового пространства (в сравнении с ext2).

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

ReiserFS - превосходная filesystem. В следующей статье будет описан процесс инсталляции ReiserFS под Linux 2.4. Будет описана процедура оптимальной настройки под требования приложений, опции ядра и другое.

Использование ReiserFS в Linux 2.4

Daniel Robbins (drobbins@gentoo.org)
President/CEO, Gentoo Technologies, Inc.
August 2001

С выходом релиза 2.4 Linux появилась возможность использования filesystem с новыми свойствами, таких как Reiserfs, XFS, GFS и других. Эти filesystems еще не достаточно опробованы и имеются вопросы, что именно они могут делать, насколько они хороши и насколько оправдано их использование в промышленной Linux среде. Daniel Robbins отвечает на эти вопросы по ходу пояснения инсталляции этих новых продвинутых filesystems под Linux 2.4. В своей предыдущей статье этой серии Daniel описал преимущества journalling и ReiserFS. В этой статье речь пойдет о процессе инсталляции rock-solid Linux 2.4-based ReiserFS системы.

В этой статье я опишу процесс установки ReiserFS с ядром 2.4. Одновременно будут затронуты "технические" аспекты, касающиеся ядра 2.4 и его сопряженности с ReiserFS, вопросы производительности и т.п. Так как инсталляция будет описана в начале, я рекомендую прежде прочесть всю статью, и лишь потом перейти к практике. Полезно сразу ознакомиться с техническими примечаниями, поскольку при установке ReiserFS на вашу систему такое знание поможет снять ряд вопросов.

Поиск подходящего ядра.

Чтобы enable ReiserFS на вашей системе, сначала потребуется найти подходящее ядро. Если вы следите за развитием ядер серии 2.4, то, наверное, знаете, что не все происходит гладко. При написании статьи последним было 2.4.6-pre2. Однако я рекомендую обратить внимание либо на 2.4.4 (a stock Linus kernel), либо на 2.4.4-ac9 (модифицированное ядро от Alan Cox) для установки ReiserFS. Тесты показали, что на 2.4.5 имеются "моменты", которые не позволяют рекомендовать это ядро для промышленного использования. Давайте надеяться, что 2.4.6 в этом плане будет лучше.

Если не хотите использовать 2.4.4 или 2.4.4-ac9 ядро для ReiserFS, прежде убедитесь, что проведены достаточные тесты по исследованию устойчивости ReiserFS на выбранном ядре. Конечно, предупреждение не распространяется для ReiserFS на тестовом сервере, где можно использовать любое ядро, если не поступало сообщений о его "проблемности".

Имеются два серьезных основания для повышенного внимания к проблемам стабильности ядра вообще и стабильности ReiserFS в частности. Первое, до сих пор ReiserFS - "экспериментальная" kernel feature и вы не должны прогнозировать, что ее реализация на более новом ядре будет работать не хуже, чем на предыдущем. Второе (в данный момент это самая большая проблема), большая часть релизов ядра 2.4 и patches были немного flaky side, что предполагает большую осторожность. Теоретически, все 2.4 релизы принадлежат stable series, так как 2.4 "по определению" считается таковой. На практике в этом возникают сомнения.

Я надеюсь, что не отговорил вас от использования ReiserFS или Linux 2.4, но предупреждение не будет лишним. Не прыгайте с одного ядра на другое только по причине его "современности". На промышленных системах такая практика ничего хорошего не сулит. Когда переходите на непроверенное ядро, вы рискуете не только зависанием системы, но и сохранностью данных. Даже если сама ReiserFS устойчива, есть вероятность, что ошибки в других частях ядра приведут к повреждению информации на файловой системе.

Если вы еще не выбрали хороший источник информации по стабильности современных ядер, я рекомендую посетить Linux Weekly News (смотри Resources ниже), чтобы быть "в курсе" kernel problems (информация обновляется каждый четверг). Теперь, когда я убедил читателей в использовании 2.4.4 или 2.4.4-ac9 для ответственных инсталляций ReiserFS, продолжим.

Подготавливаем ядро.

OK, возможны три варианта получения production-ready ReiserFS. Первый, использование простого stock 2.4.4 Linux kernel. Второй, использование 2.4.4 kernel с наложением ReiserFS bigpatch. Он, в свою очередь, содержит специальные patches для придания ReiserFS свойств quota-compatible и дополнительной совместимости с locally-running NFS сервером. Третий, использование 2.4.4 ядра с ac9 patch (что дает нам 2.4.4-ac9) как с bigpatch, так и без него. Я рекомендую использовать 2.4.4-ac9 с bigpatch, так как bigpatch не имеет отрицательных эффектов, а с ac9 ядро работает лучше. Однако, если вы испытываете неприязнь к ac ядрам, используйте простое 2.4.4. Далее описывается процесс установки 2.4.4-ac9 с bigpatch, но если у вас одна или обе patches не установлены, просто пропустите соответствующий шаг. Теперь начнем.

Получите 2.4.4 kernel sources от kernel.org и положите в /usr/src каталог. Переименуйте существовавший linux каталог или symlink на него, либо просто удалите старую symlink. Далее:


 # cd /usr/src
 # cat /path/to/linx-2.4.4.tar.bz2 | bzip2 -d | tar xvf -
 

The ac9 patch and bigpatch

Можно использовать простое 2.4.4 ядро, в нем все имеется. Однако я рекомендую применить следующие ac и bigpatch patches.

Для apply the ac9 patch, получите Alan Cox ac9 patch из kernel.org и выполните:


 # cd /usr/src/linux
 # bzip2 -dc /path/to/patch-2.4.4-ac9.bz2 | patch -p1
 

Наложив такой patch (или оставив все без изменений), получите DiCE и ReiserFS bigpatch. Опять же, этот шаг необязателен, но мною рекомендованный, особенно для NFS сервера и поддержки квот (даже если это вам не нужно, patch не навредит). Для наложения bigpatch выполните:


 # cd /usr/src/linux
 # bzip2 -dc /path/to/bigpatch-2.4.4.diff.bz2 | patch -p1
 

Выполнив один, оба или ни одного шага, вы готовы к конфигурированию ядра для ReiserFS.

Обратите внимание: если вам требуется помощь в компиляции ядра, есть хорошая, свободно распространяемая обучающая программа Compiling the Linux kernel на developerWorks. Далее очень кратко.

Kernel configuration весьма проста. Сначала выполняем "make menuconfig". В секции "Code maturity level options" убедитесь, что опция "Prompt for development and/or incomplete code/drivers" - enabled. Переходим в секцию "File systems" и enable "ReiserFS support". Вы должны конфигурировать поддержку ReiserFS для компилирования непосредственно в ядро, а не как модуль. Теперь не помешает разрешить "Have reiserFS do extra internal checking". Сохраните конфигурацию и компилируйте ядро ("make dep; make bzImage; make modules; make modules_install") и добавьте запись в ваш загрузчик для ReiserFS-enabled kernel.

Важно: никогда не удаляйте ваше текущее ядро, не убедившись в работоспособности нового.

Работа с ReiserFS

Инсталляция tools.

До перезагрузки следует инсталлировать "reiserfsprogs" tools, которые состоят из "mkreiserfs", "resize_reiserfs" (полезно, если у вас используется LVM) и "fsck.reiserfs". Получить самую последнюю версию "reiserfsprogs" (на момент написания статьи - "3.x.0j") можно от Namesys.com download page. Как только tools загружены, их можно компилировать и инсталлировать следующими командами:


 # cd /tmp
 # tar xzvf reiserfsprogs-3.x.0j.tar.gz
 # cd reiserfsprogs-3.x.0j
 # ./configure
 ./configure output will appear here
 # make
 make output will appear here
 # make install
 make install output will appear here
 

После инсталляции tools можно создавать новые partitions (используя "fdisk" или "cfdisk") либо LVM logical volumes (используя "lvcreate") по необходимости и перезагрузить систему. Когда создается standard partitions его можно маркировать как "Linux native file system" (83).

Создание и монтирование файловой системы.

После перезагрузки вы сможете создать файловую систему ReiserFS на пустом partition следующей командой:


 # mkreiserfs /dev/hdxy
 

В этом примере /dev/hdxy - device node, соответствующий свободному partition. Монтирование аналогично любой другой файловой системе:


 # mount /dev/hdxy /mnt/reiser
 

Добавить файловую систему ReiserFS в файл /etc/fstab можно при установке полей "freq" и "passno" в значение "0", например:


 /dev/hdc1       /home                   reiserfs        defaults       0 0
 

Начиная с этого момента ваша ReiserFS внешне становится тождественной ext2. Вы быстро забудете об изнурительном "fsck", а данные станут доступны быстрее, особенно из маленьких файлов.

Технические примечания по ReiserFS.

Стабильность файловой системы.

Я использовал 2.4.4 с ReiserFS на промышленном сервере в течение месяца (на cvs.gentoo.org development сервере) без каких-либо проблем. 2.4.4 и 2.4.4-ac9 зарекомендовали себя надежными. Сервер сильно загружен операциями IO, так как на нем хранятся cvs архив нашего "dev-wiki", почтовый сервер gentoo.org, списки рассылки и другое.

Ограничения ReiserFS.

Хотя ReiserFS превосходит по быстродействию практически во всех типах приложений "файловую классику" ext2, имеется ряд областей, где ReiserFS в настоящее время еще не доработан. Это не жесткие ограничения ReiserFS, а те области, до которых разработчики Namesys не имели время добраться.

No dump/restore

Да, это истина. ReiserFS не имеет "dump" и "restore" реализации. Если вы желаете использовать ReiserFS, но вам нравится "dump", придется находить иные пути backing data. В действительности это не так актуально. Ядро 2.4 несовместимо с "dump" и "restore" в принципе (а не только на ReiserFS). Для подробной информации о dump/kernel 2.4 incompatibility читайте Linus Torvalds (смотри Resources), где он говорит, "Dump была глупой программой, во-первых. Оставьте ее в прошлом."

Проблемы производительности.

Хотя ReiserFS в общем, имеет преимущество в производительности над ext2, в частностях имеются и слабости. Первая - работа с "разреженными" файлами (например, mailbox). ReiserFS заметно хуже справляется с разреженными файлами, чем ext2. Положение должно изменится, когда разработчики Namesys вернуться к оптимизации этой стороны ReiserFS (предполагается в версии 4 ReiserFS). А сейчас ext2 - лучшее решение для приложений, которые помещают информацию в разреженные файлы.

Вы можете столкнуться с проблемами при написании кода, который делает связанный вызов stat() для большого числа файлов. Одно из приложений, которое имеет проблемы (проявляется только с ReiserFS на ядрах 2.4, но не с 2.2) - mutt mailer (смотри Resources) когда он читает большие maildir-style mailboxes. Очевидно, mutt выполняет вызов stats для каждого почтового файла дважды. Это имеет тенденцию замедления работы. В команде разработчиков ReiserFS об этой специфической проблеме знают и работают над ее устранением (решение будет включено в ReiserFS 4 или раньше).

Performance tweaks

К счастью, имеется пара простых приемов, которые вы можете использовать для "купирования" проблем производительности. Первый прием - монтирование ReiserFS filesystem с опцией "noatime" (опция монтирования, доступная и для других файловых систем). Вероятно, вы знаете, что системы UNIX делают запись atime (время доступа) для каждого объекта файловой системы и этот атрибут модифицируется при каждом чтении файла. Для большинства случаев штамп atime интереса не представляет (даже не могу привести пример, когда atime требуется для "критических" приложений). По этой причине, ничем не рискуя, от его модификации можно отказаться и получить выигрыш в производительности. Можно даже сказать следующее. Если вам не известно, что штамп atime требуется для конкретного приложения, разместившего файлы на конкретной файловой системе, то вы должны монтировать ее с опцией noatime. Используйте примерно следующую запись в /etc/fstab:


 /dev/hdc1       /home                   reiserfs        noatime       0 0
 

В первой статье о ReiserFS я упомянул, что ReiserFS имеет специфическую feature, называемую "tail packing" (упаковка хвостов). А что в ReiserFS называют "хвостами"? Во-первых, файлы, размер которых меньше, чем блок файловой системы или, во-вторых, "кончики" файлов, которые не заполняют весь блок. В первом случае ReiserFS имеет превосходную производительность по причине умения "запихивать" такие "карликовые" файлы в свои b*tree (первичная организационная структура данных). При этом данные хранятся рядом со stat-data (ReiserFS эквивалент i-node). Во втором случае с производительностью иначе. Хвосты не заполняют полный блок и непроизводительно используют дисковое пространство. Для лучшего использования дискового пространства ReiserFS использует "tail packing". Считается, что такая feature позволяет экономить более 5% в сравнении с ext2.

Немного больше о notail.

Не следует думать, что упаковка хвостов больших файлов имеет одни достоинства. Один из недостатков - снижение производительности. Разработчики ReiserFS предполагали, что ряд пользователей решит не жертвовать производительностью ради 5% экономии дискового пространства. Была предусмотрена опция монтирования "notail". Когда файловая система монтируется с этой опцией, упаковка хвостов отключается, что дает прирост скорости при меньшей вместимости диска. С учетом сегодняшней стоимости дискового пространства следует рекомендовать монтирование файловой системы с опциями "notail" и "noatime":


 /dev/hdc1       /home                   reiserfs        noatime,notail       0 0
 

Даже если имеется потребность в экономии дискового пространства, может оказаться хорошей идеей временное монтирование файловой системы (пока не заполнилась) с опцией "notail". Кроме того, некоторые загрузчики имеют проблемы с загрузкой ядер, созданных на ReiserFS с tail packing enabled. Если у вас LILO старее версии 21.6, с такой проблемой вы обязательно столкнетесь. Могут быть проблемы даже с современными версиями GRUB при загрузке файлов stage1 и stage1_5, хотя на загрузку самого ядра это не влияет. Устранить проблему поможет временное монтирование ReiserFS с опцией "notail" и перемещение файлов в буферную файловую систему "туда обратно". Помните, после пересоздания файлов (инсталляция нового ядра) они снова окажутся "без хвостов". Есть возможность перемонтирования файловой системы (с новыми опциями) без ее размонтирования (подробно в части 3). Ниже показано, как перемонтировать корневую файловую систему с опцией "notail". Команда будет полезной, если для вас обычная практика - упаковка хвостов, но загрузчик "этого не любит" и требуется "распаковать" вспомогательные файлы:


 # mount / -o remount,notail
 

Примечания по Qmail.

Если вы используете qmail с ReiserFS, то имеется несколько важных замечаний. Первое - необходимо использовать специальный patch к qmail 1.03 sources. Он требуется для устранения проблемы, которая возникает в связи с несинхронными "link()" и "unlink()" вызовами (с ext2 имеется похожая проблема). Далее, можно посетить Jedi's qmail tuning page, где содержится множество хороших советов о том, как оптимизировать производительность qmail. Наконец, имеется Jedi's ReiserSMTP package. ReiserSMTP содержит GPL plug-in для SMTP части qmail. Такая модернизация от Jedi's (специально для ReiserFS) обеспечит удвоение производительности при обработке входящей почты.

Заключение.

Я нахожу, что ReiserFS очень приятная файловая система и дает выигрыш не только на маленьких, но и на больших файлах по сравнению с ext2. Благодаря ReiserFS разработчикам требуется только 15 секунд для модификации CVS Gentoo Linux, притом, что на ext2 это занимало около 2 минут. ReiserFS делает работу более комфортной и позволяет нашему cvs серверу одновременно обрабатывать большее число IO без потери интерактивности.

Притом, что она уже сегодня производит впечатление, будущее представляется еще более интересным. Hans Reiser имеет очень агрессивный творческий план относительно ReiserFS, включая использование ее как full-fledged high-performance database с полной поддержкой transaction и advanced querying features. Со временем можно ожидать, что ReiserFS станет больше чем "другая высокоэффективная файловая система". Это должно открыть новые возможности и подходы для решения традиционных проблем хранения информации. С Namesys можно связывать и будущее развитие Linux.


Использование файловой системы virtual memory (VM) и bind mounts

Daniel Robbins (drobbins@gentoo.org)
President/CEO, Gentoo Technologies, Inc.
September 2001

С выходом релиза 2.4 Linux появилась возможность использования filesystem с новыми свойствами, таких как Reiserfs, XFS, GFS и других. Эти filesystems еще не достаточно опробованы и имеются вопросы, что именно они могут делать, насколько они хороши и насколько оправдано их использование в промышленной Linux среде. В этой статье Daniel дает обзор tmpfs, файловой системы, основанной на VM, и описывает новые, ставшими доступными с переходом на ядро 2.4 возможностями "bind"-mounting abilities.

В предыдущих статьях этой серии я описал преимущества журналирования вообще и файловую систему ReiserFS в частности. Была описана процедура установки rock-solid Linux 2.4-based ReiserFS файловой системы. В данной статье обратим свое внимание на нетривиальную тему. Сначала будет рассмотрена tmpfs, еще известная как virtual memory (VM) filesystem. Tmpfs - вероятно лучшая RAM disk-like система, уже сейчас доступная для Linux через новые свойства ядра 2.4. После начального вступления рассмотрим дополнительные возможности ядра 2.4, называемые "bind mounts", которые добавляют много гибкости в монтировании файловых систем. В следующей статье мы сосредоточимся на devfs, а затем потратим время на более глубокое знакомство с новой ext3 filesystem.

Презентация tmpfs.

Если от меня потребуют объяснить в одной фразе, что такое tmpfs, я бы сказал - tmpfs подобие ramdisk, но с "изюминкой". Подобно ramdisk, tmpfs использует ОПЕРАТИВНУЮ ПАМЯТЬ, но, кроме этого, может использовать swap devices. В то время как традиционный ramdisk это блочное устройство и перед его использованием необходимо отформатировать раздел командой mkfs с опциями, то файловая система tmpfs - устройство не блочное, готовое к использованию сразу после монтирования. Такие свойства tmpfs делают ее самой привлекательной из RAM-based файловых систем, известных на сегодняшний день.

Tmpfs и VM

Давайте посмотрим на некоторые наиболее интересные свойства tmpfs. Как было отмечено выше, tmpfs может использовать и RAM, и swap. На первый взгляд, это может показаться не принципиальным, но вспомните, tmpfs еще известна как "virtual memory filesystem". Возможно, вы знаете, что ядро Linux "понимает" ресурс "виртуальная память" именно как единое - целое RAM и swap devices. Подсистема VM ядра ассигнует эти ресурсы другим подсистемам и управляет этими ресурсами behind-the-scenes (прозрачно в фоне). При этом часто без ведома "подсистемы - заказчика" перемещает страницы ОПЕРАТИВНОЙ ПАМЯТИ между swap и vice-versa.

Файловая система tmpfs запрашивает страницы у подсистемы VM для хранения файлов. При этом сама tmpfs не знает, находятся ли эти страницы в swap или в RAM; это - "проблема" VM подсистемы. Иначе, tmpfs filesystem знает лишь то, что она использует виртуальную память.

Это не блочное устройство.

Теперь о другом интересном свойстве tmpfs filesystem. В отличие от большинства "нормальных" файловых систем (например, ext3, ext2, XFS, JFS, ReiserFS) tmpfs не является "надстройкой" над блочным устройством. Поскольку tmpfs напрямую "встроена" в VM, ее можно монтировать сразу после создания командой:


 # mount tmpfs /mnt/tmpfs -t tmpfs
 

После выполнения команды вы получите новую tmpfs filesystem, смонтированную в /mnt/tmpfs и готовую к использованию. Обратите внимание, нет потребности в форматировании командой mkfs tmpfs; да это и невозможно, такой команды просто не существует. Сразу после команды mount файловая система доступна для использования и имеет тип tmpfs. Это в принципе отличается от Linux ramdisks; стандартный Linux ramdisks - block devices и требует форматирования перед размещением на нем файлов. Что имеем? Монтируй и используй!

Преимущества tmpfs.

  • Динамически изменяемый размер файловой системы.
  • Вы вероятно уже задавались вопросом, а какого размера файловую систему мы подмонтировали к /mnt/tmpfs в примере выше? Ответ неожиданный (особенно, если имели дело только с disk-based файловыми системами). /mnt/tmpfs первоначально имеет очень маленький размер, но, по мере копирования и создания файлов драйвер tmpfs ассигнует у VM дополнительную память, динамически увеличивая емкость. Справедливо и обратное, при удалении файлов из /mnt/tmpfs драйвер отдает освобождаемую память операционной системе. Теперь ясно (память достаточно ценный ресурс и ее "никогда не бывает много"), большой плюс tmpfs в том, что используется ровно столько памяти, сколько требуется. См. Resources.

  • Скорость.
  • Другое преимущество tmpfs - ее "блестящая" скорость. Поскольку файловая система tmpfs постоянно загружена в оперативную память, операции записи - чтения происходят почти мгновенно. Даже если интенсивно используется swap, скорость все равно высокая (более того, перемещение в swap означает передачу ресурсов процессам, наиболее нуждающимся в памяти, что способствует повышению общей производительности). Итог - свойство динамически изменять размер и, при необходимости, сбрасываться в swap, дает возможность операционной системе более гибко распоряжаться ресурсами. Файловая система tmpfs прекрасная альтернатива традиционному RAM disk с позиции скорости.

  • Безинерционность.
  • А вот это может считаться как плюсом, так и минусом. Как можно догадаться, данные в tmpfs после перезагрузки будут потеряны (оперативная память энергозависима по своей природе. Даже после "горячей перезагрузки", сохранившись в "физической оперативной памяти", информация станет недоступной, так как таблицы виртуальной памяти будут инициализированы иначе). Название "tmpfs" само за себя говорит. Плохо ли это? С какой стороны посмотреть. Фактически, tmpfs превосходный резервуар для хранения временных файлов. Традиционно для этих целей используется /tmp и некоторые части дерева /var. Есть даже опция - очищать /tmp при перезагрузке, на что тратится дополнительное время. В случае с tmpfs, такая "опция" - физическое свойство.

Использование tmpfs.

Все, что требуется для использования tmpfs - это ядро 2.4, скомпилированное с "Virtual memory file system support (former shm fs)" enabled; эта опция находится в подразделе "File systems" (make menuconfig). Если на вашей системе такое ядро, уже можно монтировать tmpfs filesystems. На предкомпилированных ядрах дистрибутивов это, как правило, сделано всегда. Можно не пользоваться самой tmpfs, но такая поддержка требуется для использования POSIX shared memory. Заметим, для использования System V shared memory поддержка tmpfs в ядре не требуется. POSIX shared memory широкого применения еще не получила, но это дело времени.

Уход от low VM conditions

А чего это мы все говорим о достоинствах? Фактом является то, что tmpfs динамически растет и уменьшается. Поэтому естественен провокационный вопрос. А что случится, если tmpfs filesystem разрастется так, что поглотит всю виртуальную память? Скажем так, приемлемое решение еще не найдено. С ядром 2.4.4, увы, произошло бы зависание. С ядром 2.4.6, подсистема VM имеет некоторую защиту, и авария не произойдет. Когда 2.4.6 почувствует точку, за которой ассигнование дополнительной памяти проблематично, вы просто не сможете ничего более записать в tmpfs filesystem. Кроме того, произойдут некоторые другие вещи. Сначала процессы в системе не смогут ассигновать дополнительную память; внешне система станет очень вялой. У суперпользователя есть время, чтобы предпринять шаги для выхода из low-VM condition.

Далее, ядро имеет встроенную last-ditch систему освобождения памяти при ее исчерпании; она находит процесс, который наиболее "жадно" потребляет VM ресурсы и уничтожает его. К сожалению, такое "kill a process" решение имеет неприятные последствия, особенно, если в истощении памяти виновата tmpfs. Причина вот в чем. Сама tmpfs уничтожена быть не может, так как она - часть ядра, а не пользовательский процесс. Кроме того, специфика tmpfs такова, что для ядра не существует простого способа выяснить, какой именно процесс "затопляет" tmpfs. В таких случаях ядро ("вот разберусь до конца и накажу, кого попало") по ошибке "убивает" самый большой VM-hog процесс, которым обычно является ваш X server. Определить, что истинной причиной "падения" X было low-VM condition (tmpfs) очень сложно.

Решение для Low VM

К счастью, tmpfs позволяет указать максимальный размер filesystem при ее монтировании или перемонтировании. Фактически, с ядром 2.4.6 и util-linux-2.11g, такие параметры можно установить только при монтировании, но не перемонтировании (в следующих версиях ядер это может быть уже решено). Установка оптимального лимита на размер tmpfs зависит от ресурсов и режима использования Linux box; идея в том, чтобы предотвратить возможность со стороны tmpfs filesystem истощения ресурсов виртуальной памяти и предотвратить low-VM conditions, о чем говорилось ранее. Хороший способ найти приемлемый tmpfs upper-bound состоит в использовании top монитора для наблюдения за swap в момент пиковых нагрузок. Установите tmpfs upper-bound немного меньше, чем сумма свободной swap и RAM при пиковой нагрузке.

Создать tmpfs filesystem с лимитом на максимальный размер достаточно просто. Например:


 # mount tmpfs /dev/shm -t tmpfs -o size=32m
 

В этом примере монтирование новой tmpfs происходит не к точке /mnt/tmpfs, а к специально созданному /dev/shm. Это каталог, который является "official" mountpoint для tmpfs. Если вы используете devfs, этот каталог будет создан автоматически.

Если требуется ограничить размер filesystem 512 КБ или 1 GB, можно соответственно указать size=512k или size=1g. В дополнение к ограничению размера можно лимитировать число inodes (filesystem objects) через параметр nr_inodes=x. Где x - целое число, возможно, с суффиксом k, m или g для обозначения тысяч, миллионов или миллиардов inodes.

Для автоматического монтирования при загрузке системы допустимо сделать запись в файле /etc/fstab. Например:


 tmpfs   /dev/shm        tmpfs   size=32m        0       0
 

Монтирование поверх занятой mountpoints

При использовании ядер 2.2 любая попытка монтирования к уже используемой mountpoint приводила к ошибке. После переписи кода ядра повторное монтирование к занятой точке перестало быть проблемой. Такой пример: при загрузке системы монтируется "реальный" раздел диска к точке /tmp. Принимается оперативное решение использовать tmpfs. В старое время потребовалось бы размонтировать /tmp и повторно смонтировать tmpfs в /tmp:


 #  umount /tmp
 #  mount tmpfs /tmp -t tmpfs -o size=64m
 

Однако не всегда это возможно. Если есть процессы с открытыми в /tmp файлами будет выдана следующая ошибка:


 umount: /tmp: device is busy
 

На последних 2.4 ядрах можно перемонтировать /tmp filesystem без получения ошибки "device is busy":


 # mount tmpfs /tmp -t tmpfs -o size=64m
 

Единственной командой ваша новая tmpfs filesystem монтируется к /tmp поверх ранее смонтированного partition. При этом все новые файлы будут открываться на tmpfs, а процессы, которые имели открытые файлы на "оригинальной" filesystem, так и будут продолжать работать с ними! Если размонтировать tmpfs-based /tmp, "оригинальная" /tmp появится, как и прежде. Фактически, можно монтировать любое число файловых систем на одну mountpoint, и mountpoint будет действовать подобно стеку.

Bind mounts

Используя bind mount, мы можем монтировать всю или только часть уже смонтированной filesystem к другой точке и иметь filesystem, доступную от обеих mountpoints одновременно! Например, можно использовать bind mounts для монтирования root filesystem к /home/drobbins/nifty:


 #  mount --bind / /home/drobbins/nifty
 

Теперь, если зайти в /home/drobbins/nifty, вы увидите вашу root filesystem (/home/drobbins/nifty/etc, /home/drobbins/nifty/opt и т.д.). Если модифицируется файл на root filesystem, все изменения будут видны и в /home/drobbins/nifty. Так происходит потому, что это одни и те же разделы диска, просто ядро отображает filesystem в двух разных mountpoints. Обратите внимание, когда происходит монтирование файловой системы к новой точке через bind-mounted, все файловые системы, которые были примонтированы к "оригинальной", в новой позиции отображены не будут. Другими словами, если /usr создан на отдельном partition, после выполнения bind-mounted подкаталог /home/drobbins/nifty/usr окажется пустым. Потребуется дополнительное bind mount, чтобы просмотреть содержимое /usr в /home/drobbins/nifty/usr:


 #  mount --bind /usr /home/drobbins/nifty/usr
 

Bind mounting для части файловой системы.

Bind mounting делает возможными еще более "тонкие" вещи. Например, вы монтируете tmpfs к /dev/shm, его "традиционной" точке, но одновременно хотите использовать tmpfs для /tmp. Вместо монтирования еще одной tmpfs к /tmp (что возможно), вы решаете share новый /tmp с /dev/shm. Но, bind mount /dev/shm к /tmp нужно сделать так, чтобы каталоги из /dev/shm не были видны в /tmp. Как это сделать? Пример:


 # mkdir /dev/shm/tmp
 # chmod 1777 /dev/shm/tmp
 # mount --bind /dev/shm/tmp /tmp
 

В этом примере сначала создается каталог /dev/shm/tmp и назначаются права доступа 1777 (обычные для /tmp). Далее можно монтировать только отдельный /dev/shm/tmp. После этого файл /tmp/foo будет дополнительно виден как /dev/shm/tmp/foo, но файл /dev/shm/bar в каталоге /tmp отображен не будет.

Примечание переводчика. Здесь очень быстро "пролистали" тонкие вещи. chmod 1777 /dev/shm/tmp устанавливает наследование прав в "стиле Беркли" (единичка в аргументах). Если этого не сделать, например, X server после перезагрузки "грохнется на старте". Второй момент - "аномальное" наследование при монтировании. Родительский каталог (точка монтирования /tmp) наследует свойства от дочернего каталога (/dev/shm/tmp). "Не логично", и "по незнанию" может стать причиной проблем.

Как следует из примера, bind mounts очень сильное средство и может помочь в проектировании файловой системы сложной архитектуры. Следующая статья будет посвящена devfs; а пока можно посмотреть следующие ресурсы.

Введение в devfs

Daniel Robbins (drobbins@gentoo.org)
President/CEO, Gentoo Technologies, Inc.
September 2001

С выходом релиза 2.4 Linux появилась возможность использования filesystem с новыми свойствами, таких как Reiserfs, XFS, GFS и других. Эти filesystems еще не достаточно опробованы и имеются вопросы, что именно они могут делать, насколько они хороши и насколько оправдано их использование в промышленной Linux среде. В этой статье Daniel объясняет назначение и преимущества использования devfs, файловой системы управления устройствами и подготавливает к пониманию своей следующей статьи, где будет рассказано об оптимальной установке devfs на вашей системе.

Презентация devfs

Устройства, устройства повсюду.

Devfs, или Device Filesystem, разработана с единственной целью предоставления нового (более "нормального") способа управления всеми блочными и символьными устройствами, заполнившими каталог /dev. Вероятно, вам известно, что обычное /dev дерево содержит сотни блочных и символьных специальных файлов-устройств, которые располагаются на корневой файловой системе. Каждый такой специальный файл доступен для user-space процессов и обеспечивает легкость взаимодействия с kernel devices. Выполняя операции с такими специальными файлами, X server способен обращаться к video hardware, fsck способен выполнять filesystem checks, а lpd передает данные через параллельный порт на принтер и т.д.

Фактически, одна из "приятных" черт Linux и Unix заключается в том, что devices не скрыты за некоторым непонятным и специфическим API, а сосуществуют на файловой системе рядом с "нормальными" файлами, каталогами и символическими ссылками. Поскольку символьные и блочные devices отображаются в привычное filesystem namespace, имеется дополнительная возможность более простого взаимодействия с hardware через стандартные Unix команды, например cat или dd. И это не просто фокус. "Стандартное" взаимодействие более выразительно и способствует быстрому освоению нового оборудования.

Проблемы управления.

В то время как сама идея отображения устройств как специальных файлов хороша, следует заметить, что обычные Linux системы управляют ими далеко не оптимальным и громоздким способом. В наши дни в Linux поддерживается много самого разного hardware. При "классическом" подходе это означает, что в каталоге /dev "обитают" сотни специальных файлов для "презентации" соответствующих hardware. Большинство таких специальных файлов "don't even map" на реально существующее на вашей машине устройство (но в каталоге /dev такой специальный файл все равно должен присутствовать на случай добавления нового hardware/drivers). Такой подход вносит много путаницы.

Только одного такого аргумента достаточно, чтобы осознать необходимость "перестройки" каталога /dev, конечно, при соблюдении принципа "обратной совместимости". Чтобы хорошо понять, как именно devfs решает большинство проблем связанных с "классическим" каталогом /dev, посмотрим на devfs с позиции разработки нового драйвера для устройства.

Внутренняя организация device management

Чтобы получить ясное представление о devfs, давайте разберемся, как devfs меняет традиционный подход для случая добавления нового драйвера. Традиционный (без devfs) kernel-based device driver "прописывает" устройство в остальной части системы через системные вызовы register_blkdev() или register_chrdev() (зависит от того, регистрируется блочное или символьное устройство).

Major номер (unsigned 8-bit integer) передается как параметр либо register_blkdev(), либо register_chrdev(). После регистрации устройства ядро знает, что этот конкретный major номер соответствует конкретному драйверу для устройства, которое выполнило вызов register_???dev().

Вопрос, а какой major номер разработчик драйвера должен использовать для передачи с запросом register_???dev()? Проблемы нет, если developer драйвера не планирует его использования "внешним миром". В этом случае сгодится любой major номер, лишь бы он не конфликтовал с другими major номерами, используемыми в конкретном частном случае. Как альтернатива, разработчик может "динамически" ассигновать major номер перед register_???dev(). Однако, "по большому счету", такое решение приемлемо только в случае, если драйвер не предназначен для широкого использования.

Получение номера.

Если developer хочет предложить свой драйвер для широкого использования (а большинство Linux developers имеет тенденцию делать именно так), то использование major номера "от балды" или даже вариант с его динамическим ассигнованием "не пройдет". В таких случаях разработчик драйвера должен войти в контакт с Linux kernel developers и получить для своего специфического устройства "официальный" major номер. После этого, для всех Linux пользователей это устройство (и только оно) будет связано с таким major номером.

Важно иметь "официальный" major номер, так как для взаимодействия с этим специфическим устройством, администратор должен в каталоге /dev создать специальный файл. Когда device node (специальный файл) создается, он должен получить тот же major, как зарегистрирован во внутренних структурах ядра. После этого, когда пользовательский процесс выполняет операцию над файлом-устройством, ядро знает, с каким драйвером нужно связаться. Иначе, mapping от специального файла на kernel driver сделано по major номером, а не по именам устройств. Такое "непонимание" device name - особенность non-devfs систем.

Как только device driver получает официальный major, он может использоваться публично, а device node можно включать в дерево /dev разных дистрибутивов через официальный сценарий /dev/MAKEDEV. Такой сценарий помогает суперпользователю автоматизировать процесс создания device nodes с правильными major и minor номерами, правами и владельцами.

Традиционные проблемы.

К сожалению, при таком подходе имеется много проблем. У разработчика драйвера появляется "головная боль" от необходимости согласования действий с kernel developers для получения "официального" major. То же относится к самим kernel developers. Возникает потребность отслеживания процедуры ассигнования всех major номеров. Во многом это похоже на проблемы системного администратора при использовании статического ассигнования IP адресов в локальной сети, когда сеть начинает "разрастаться". Точно так же, как системный администратор может "разрубить узел", воспользовавшись DHCP, можно было бы использовать подобный подход для регистрации devices.

Проблема не только в этом. Linux подошел к границе, когда все "официальные" major и minor номера будут исчерпаны. Конечно, можно просто увеличить разрядность номеров, но при этом станет еще сложнее отслеживать уникальность major для драйверов. Имеется и более радикальный способ решения проблемы. Это переход на devfs.

Подход devfs. devfs_register()

Имеется быстрое описание того, как devfs функционирует и снимает многие проблемы. После правильного конфигурирования devfs, что подразумевает добавление поддержки devfs в ядро и выполнение множества достаточно хитрых изменений в сценариях запуска, суперпользователь перезагружает систему. Стартует ядро и device drivers начинают регистрировать свои устройства для остальной части системы. Если это non-devfs система, как и ранее, выполняются системные вызовы register_blkdev() и register_chrdev() (вместе с сопровождающими вызовы major номерами). Однако, если enabled devfs, то device drivers для регистрации своих устройств используют новый, улучшенный kernel call, называемый devfs_register().

Об этом devfs_register() вызове можно много рассказать. Хотя можно указать major и minor номера для обратной совместимости, жесткого требования, делать именно так, не существует. Вместо этого вызов devfs_register() передает path на устройство как параметр, и именно так оно впоследствии появиться под /dev. Например, драйвер устройства foo регистрирует свое устройство в devfs. При этом драйвер передает параметр foo0 с вызовом devfs_register(), сообщая ядру, что в корне devfs namespace должен быть создан новый файл-устройство foo0. В ответ на вызов devfs_register() добавляется foo0 device node к корню devfs namespace и запись о том, что этот новый foo0 node должен отобразится на foo device driver в ядре.

Devfs в действии.

После того, как все device drivers стартовали и зарегистрировали соответствующие им устройства в ядре, ядро запускает /sbin/init и начинается отработка сценариев системной инициализации. На ранней фазе процесса начальной загрузки (еще до filesystem checks), из rc scripts монтируется devfs filesystem к точке /dev, которая содержит representation для devfs namespace. После такого монтирования ко всем зарегистрированным устройствам (например, /dev/foo0) можно обращаться как на обычной non-devfs системе. Отличие в том, что при обращении к устройствам, kernel maps на соответствующий device driver devfs отрабатываются по именам устройств, а не по major номерам.

Красота такого подхода в том, что все требующиеся device nodes (и ничего лишнего) создаются автоматически ядром. Соответственно, отпадает необходимость в погоне за последним сценарием MAKEDEV (так как все зарегистрированные устройства сами "по волшебству" появляются в /dev). Еще сие означает, что каталог /dev не загроможден сотнями "фиктивных" device nodes. Фактически, используя devfs, можно зайти в /dev и узнать, какие устройства у вас "реально" присутствуют. Например, если у вас laptop с поддержкой "горячей" замены hardware, то устройства будут появляться и исчезать в /dev по мере того, как вы вставляете или удаляете PC Cards. Это делает devfs очень "чистым" и "функциональным" после всего того, что когда-то было.

Красота devfs

Devfs делает многие вещи проще. Рассмотрим старт Linux bootable CD-ROM, который состоит из boot loader, initrd, ядра и loopback filesystem на CD. Когда BIOS передает управление CD, boot loader грузит ядро и initrd, а затем стартует /linuxrc script из "развернувшегося" initrd. Первоочередная задача /linuxrc заключается в том, чтобы смонтировать CD таким образом, чтобы loopback filesystem могла самостоятельно mounted и accessed.

Без devfs сценарий /linuxrc должен опробовать множество специальных файлов в /dev, которые либо "представляют", либо "не представляют" реальное hardware в системе. Например, /linuxrc должен просканировать /dev/hdc, /dev/scd0, /dev/hdb и прочие для обнаружения "живого" устройства CD-ROM. По мере сканирования будут впустую опробованы несколько "фиктивных" device nodes.

В том случае, если используется devfs, сценарий /linuxrc просто заходит в /dev/cdroms, в котором находятся все специальные файлы, ассоциированные с "реальными" для данной машины CD-ROM, причем независимо, IDE или SCSI. Благодаря такому devfs соглашению, выбор очень конкретный; в подкаталоге перечислены только активные устройства, а "исследующему коду" даже не требуется знать о подробностях основного CDROM, например, сидит он на IDE channel или использует SCSI ID. Фактически, это уже другое достоинство devfs. Как будет видно из следующей статьи этого цикла, devfs имеет совершенно иные, заданные по умолчанию местоположения для устройств в /dev.

Если необходимо обратится к конкретному блочному устройству (диск, partition, CD-ROM и т.д), доступ можно сделать через несколько специальных файлов. Например, на моем сервере имеется единственный SCSI CD-ROM. При devfs enabled, я могу работать с ним переместившись либо в /dev/cdroms/cdrom0, либо в /dev/scsi/host0/bus0/target4/lun0/cd. При этом доступ произойдет к одному и тому же устройству. Просто у меня есть выбор, через какой именно файл я это сделаю. Кроме этого, как альтернатива, к своему CD-ROM я могу получить доступ "в старом стиле" как /dev/sr0, если мне так хочется и инсталлирована удобная и небольшая программка devfsd. Версии devfsd меняются очень быстро, но, в общем, это программа, которая заботится об "обратной совместимости" специальных файлов и позволяет настраивать /dev разными способами. Программа devfsd будет рассмотрена в следующей статье при описании процесса перехода на devfs в вашей системе. А теперь некоторые ресурсы по devfs:

Установка devfs

Daniel Robbins (drobbins@gentoo.org)
President/CEO, Gentoo Technologies, Inc.
October 2001

С выходом релиза 2.4 Linux появилась возможность использования filesystem с новыми свойствами, таких как Reiserfs, XFS, GFS и других. Эти filesystems еще не достаточно опробованы и имеются вопросы, что именно они могут делать, насколько они хороши и насколько оправдано их использование в промышленной Linux среде. В этой статье Daniel проведет вас через процесс подготовки системы к использованию devfs. Описание процесса завершается, когда ваша система полностью готова к использованию devfs. И, конечно, предполагается еще одна статья, в которой Daniel опишет заключительную фазу установки devfs.

В предыдущей статье (часть 4) было описание того, чем является devfs и как она решает многие проблемы управления устройствами. Теперь наступило время практической реализации devfs на вашей системе. В этой статье будет описана вся подготовительная работа для devfs-ready, а в следующей - конвертация на devfs. Можно безболезненно выполнить все практические шаги из этой статьи еще до прочтения следующей, так как в результате система будет функционировать "по старому", но в полной готовности к решающему действию.

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

Требования.

Чтобы иметь работающую devfs требуется Linux 2.4 (статья ориентирована на 2.4.6 или 2.4.8) и glibc 2.1.3 или современней. Рекомендуется Xfree86 не ниже 4.0 и будет не лишним сначала модернизироваться до Xfree86 версии 4.1.

Необходимая предосторожность - освойте bash rescue.

В этой статье предлагается внести изменения в boot-critical части Linux системы. Любые ошибки, скажем, по обычной невнимательности, в таких вещах могут приводить к невозможности загрузки системы в "штатном режиме". Я обязан начать статью с пояснения, как в неприятной ситуации загрузить bash shell. Надеюсь, этого не потребуется и все же... Если система не загружается из-за проблемы в init scripts или даже непосредственно в /sbin/init, повода для волнений еще нет.

Самый простой способ выполнить emergency boot - передать опцию init=/bin/bash ядру в паузе boot-time, сделанных GRUB или LILO. В случае с GRUB вы должны передавать эту опцию, в интерактивном режиме нажав "e", и редактируя запись menu в реальном времени. В случае с LILO есть выбор. Можно ввести параметр интерактивно в паузе загрузки или создать "стационарную" запись для "emergency" в /etc/lilo.conf, не забыв выполнить lilo.

Процедура восстановления.

Процедура "rescue" выглядит так. Сначала передается init =/bin/bash ядру в качестве опции начальной загрузки. В процессе начальной загрузки вместо обычного первого процесса /sbin/init будет запущен /bin/bash. Вы увидите bash root prompt без всякого log in:


 #
 

При этом, несмотря на наличие root bash prompt, смонтирована только файловая система root, и та в режиме read-only. От этого пункта двигаемся дальше. Если файловые системы не размонтированы чисто, требуется сначала прогнать fsck. Начните с fsck -a на root файловой системе, а затем fsck -R -A -a на всех остальных:


 # fsck -a /dev/hda1
 # fsck -R -A -a
 

Теперь, когда метаданные на ваших файловых системах находятся в непротиворечивом состоянии (либо предыдущий шаг был пропущен вследствие предшествовавшего "чистого размонтирования" или использования журналируемых файловых систем), можно перемонтировать root файловую систему в read-write и монтировать /proc:


 # mount / -o remount,rw
 # mount /proc
 

После этого монтируйте остальные требующиеся деревья файловой системы, находящиеся на отдельных partitions. Например, для монтирования /usr:


 # mount /usr
 

Может оказаться полезным активизировать swap, если планируется делать что-нибудь большее, чем запуск текстового редактора. Впрочем, даже использование emacs, может потребовать наличия swap:


 # swapon -a
 

Пришло время запустить любимый редактор и устранить проблему с начальной загрузкой. Повторно перемонтируйте partitions в режим read-only, способом, аналогичным их монтированию. Например, если /usr находится на отдельном partition, то, для приведения файловой системы в непротиворечивое состояние перед перезагрузкой, выполните:


 # mount /usr -o remount,ro
 # mount / -o remount,ro
 

Теперь перезагрузка произойдет без запуска fsck. Если с помощью редактора вы правильно решили проблему, LILO или GRUB отработают "штатно":


 # /sbin/reboot -nfi
 

Готовимся к переходу на devfs

Devfs конфигурация.

Теперь, зная действия при возникновении критической ситуации, можно подготовить систему к переходу на devfs. В следующей статье будут описаны некоторые достаточно сложные изменения в Linux системе. Почему это необходимо? Мы сделаем все, кроме enabling devfs функционирования ядра (последний шаг самый простой). До этого мы инсталлируем devfsd (device management daemon) в специальном режиме так, чтобы он поддержал возможность отката и восстановления любых изменений в device permissions и ownership. Требуется немного изловчиться, чтобы получить хорошо функционирующую новую систему. Как только это произойдет, вы будете очень довольны результатом.

Devfs kernel support

Первый шаг в переходе на devfs достаточно прост: требуется enable devfs support в ядре. Ядро должно быть серии 2.4. Войдите в каталог с исходниками ядра и выполните make menuconfig или make xconfig (по вкусу). В секции Code maturity level options проверьте, что Prompt for development and/or incomplete code/drivers enabled. В секции File systems находим /dev file system support (EXPERIMENTAL). Согласитесь с этим пунктом. Откроются еще две дополнительные опции. Первая указывает, будет ли devfs монтироваться автоматически к /dev в процессе начальной загрузки. От этого необходимо отказаться, мы будим монтировать /dev вручную, используя специальный сценарий. Вторая опция, Debug devfs, также должна быть заблокирована.

Отключение /dev/pts

Находясь в секции File systems, отключите поддержку /dev/pts file system for Unix98 PTYs, если это еще не заблокировано. Devfs сама обеспечивает подобные функциональные возможности, а devpts в дальнейшем не потребуется. Сохраните конфигурацию, но пока не компилируйте и не инсталлируйте новое ядро. Перед переходом к следующему шагу убедитесь, что при наличии записи о /dev/pts в /etc/fstab она должна быть закомментирована, чтобы впредь, при перезагрузках, больше не монтировалась.

О конфигурационных фокусах.

Загрузите в редактор файл /etc/securetty. Этот файл используется login и позволяет перечислить allows tty's, т.е. разрешенные для входа в систему пользователем root. В нем обычно перечислены устройства от tty1 до tty12, по одному на строку. Чтобы файл подготовить для devfs, необходимо добавить devfs-style имена для своих tty's, сохранив старые на случай загрузки с devfs disabled. Добавьте следующие строки после старых записей в /etc/securetty.


 vc/1
 vc/2
 vc/3
 vc/4
 vc/5
 vc/6
 vc/7
 vc/8
 vc/9
 vc/10
 vc/11
 vc/12
 

Инсталляция devfsd

Следующим шагом инсталлируем в системе devfsd (devfs helper daemon). Devfsd позаботиться о создании "old-style" compatibility device nodes, автоматизации действий, связанных с registered/unregistered драйверов, запоминания изменений в правах и владельцах специальных файлов на файловой системе root и т.п. В данный момент требуется только сама инсталляция, а в следующей статье научимся ее использовать вместе с devfs. Загрузим с ftp самую современную версию devfsd tarball (см. Resources). На момент написания статьи это была 1.3.16. Выполним следующее:


 # tar xzvf devfsd-1.3.16.tar.gz
 # cd devfsd
 # make
 

Devfsd откомпилирован и готов к инсталляции. Если man pages хранятся в /usr/man, выполните make install, а если используете FHS-compliant и man pages находятся в /usr/share/man, то выполните make mandir=/usr/share/man install. Devfsd теперь инсталлирован, но не в рабочем состоянии (именно то, что на данный момент и требуется).

Примечание по конфигурации.

Мы будем конфигурировать devfsd так, чтобы иметь полную поддержку для compatibility devices, то есть записи tty? будут понятными системе. Лучше перестраховаться, чем впоследствии столкнуться с ситуацией, когда login для суперпользователя невозможен. При описываемом подходе, даже если имеется проблема и devfsd не стартует, суперпользователь все равно может войти в систему. Приглашение командной строки можно получить как обычно, даже если devfs enabled.

Новое ядро.

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

Подходы к конфигурированию devfs.

Теперь система готова к конвертированию devfs, что является темой следующей статьи. Но, сначала, познакомимся с самим подходом к конвертированию. Как будет показано, devfs-enabling дистрибутив может быть очень хитрым, особенно, если есть желание использовать удобные features, например, persistent permissions и ownership.

Проблемы с kernel automounting

Имеется несколько способов devfs-enable. Первый - иметь ядро с поддержкой автоматического монтирования devfs к /dev в процессе начальной загрузки (помните? Мы отказались от этой опции). На первый взгляд, такой подход наиболее предпочтителен, так как гарантирует, что все devfs-style devices доступны всем процессам, включая /sbin/init. Однако при таком подходе имеются и проблемы. Если devfs обеспечивает все "new-style" devices, то old-style device nodes создаются devfsd daemon. Devfsd не запускается ядром, и, если мы имеем kernel mount devfs at boot, мы окажемся с не смонтированными device nodes ко времени запуска /sbin/init. Из этого следует, что, отработав до system initializations scripts, процесс загрузки потребует старта devfsd одним из первых. Хитрость не только в этом (требуется детальное понимание взаимодействия startup scripts на конкретной системе). Такой подход порождает другие проблемы.

Основная проблема с kernel mounting состоит в том, что devfsd оптимизирован для работы, когда он имеет доступ к содержимому "оригинального" old-style on-disk /dev каталогу. Обычное решение - allow access к "оригинальным" old-style devices через bind-mounting /dev к другой точке (обычно /dev-state) до того, как devfs монтируется к /dev.

Такое решение гарантирует, что содержимое старого каталога /dev все еще доступно в /dev-state после монтирования devfs. При таком подходе devfsd может использовать этот каталог для persistent device storage. Важно понять, что без bind mount старое содержимое /dev становится недоступным сразу после монтирования devfs к /dev. В этом суть проблемы при использовании kernel mount devfs. Если ядро монтирует файловую систему devfs к /dev до старта любого процесса, способного выполнить bind mount, то содержимое "оригинального" /dev становится полностью недоступным. Неприятность, не так ли? (О bind mounts было рассказано в части 3 этого цикла.)

Лучшее решение.

В идеале хотелось бы иметь полный набор device nodes (new-style и old-style для обратной совместимости) еще до старта /sbin/init, а также возможность выполнить bind mount /dev к другой точке перед монтированием devfs. Но возможно ли это?

The init wrapper

Одно из возможных решений - добавление специального kernel patch, чтобы выполнить bind mount от /dev к /dev-state. Но, при таком решении проблемы загрузки, создаются неудобства, связанные с необходимостью вручную править исходники каждого нового Linux ядра перед его компиляцией и инсталляцией. Имеется альтернативный (по мнению автора - лучший) способ решения проблемы "курица или яйцо" для devfs, через использование init wrapper. Для этого конкретного случая init wrapper реализован как bash script, который "подставляется" вместо /sbin/init (а реальный init переименовывается в /sbin/init.system). Коротко о том, что делает init wrapper:


 #!/bin/bash
 mkdir -f /dev-state
 mount --bind /dev /dev-state
 mount -t devfs none /dev
 devfsd /dev
 exec /sbin/init.system
 

Первое, wrapper гарантирует, что /dev-state существует. Второе, /dev tree через bind mount перемонтируется к /dev-state для доступности содержимого /dev из каталога /dev-state. Третье, монтируется файловая система devfs к вершине /dev, и, четвертое, стартует devfsd так, что old-style устройства автоматически регистрируются одновременно с devfs. Последнее, через команду exec стартует "оригинальный" /sbin/init, который заблаговременно был переименован в /sbin/init.system. Команда exec осуществляет "обратную подмену" bash script на init.system. Из этого следует, что bash script завершается, а его идентификатор (ID 1) наследуется init.system (идентификатор, требуемый для процесса init). Когда /sbin/init.system запускается, начальная загрузка системы происходит как обычно за исключением того, что devfs уже полностью в рабочем состоянии. Использование init wrapper позволило отказаться от kernel patch или иметь дело с devfs системой, имеющей ограниченную обратную совместимость (kernel devfs automount).

В следующей статье будет описание процесса получения full версии init wrapper и примеры использования преимуществ многих мощных devfsd's features.

Переход на devfs (с использованием init wrapper)

Daniel Robbins (drobbins@gentoo.org)
President/CEO, Gentoo Technologies, Inc.
October 2001

С выходом релиза 2.4 Linux появилась возможность использования filesystem с новыми свойствами, таких как Reiserfs, XFS, GFS и других. Эти filesystems еще не достаточно опробованы и имеются вопросы, что именно они могут делать, насколько они хороши и насколько оправдано их использование в промышленной Linux среде. В этой статье Daniel демонстрирует использование init wrapper и конвертацию системы на использование "devfs mode".

А все ли у вас подготовлено?

Эта статья завершает описание конвертации Linux под использование devfs или Device Filesystem. Для тех, кто только что начал чтение, будут полезны ссылки. В части 4 этой серии статей объяснялось, как devfs решает проблему регистрации устройств на уровне ядра. В части 5 я описал все шаги, необходимые для придания вашей Linux системе свойства devfs-совместимости (без этого переход на devfs невозможен).

Если вы не читали часть 5, очень важно сделать это теперь, прежде чем выполнить описанные ниже команды. Если не сделать предварительную подготовку, есть гарантия, что init wrapper, который будет инсталлирован, правильно работать не сможет. В таком случае вы останетесь с системой, которая не может загружаться и требует больших усилий для своей "реанимации". Однако если вы прочли и сделали все, о чем писалось в части 5, можно двигаться дальше.

The init wrapper

Первые строки.

Часть 5 этой серии статей завершилась описанием концепции init wrapper с объяснением, почему именно таким способом удобно решать проблему инициализации devfs. Без углубления в детали, все же по шагам "пройдемся" по полной версии init wrapper и "вникнем" в ее части. Начнем с вершины:

The init wrapper, top portion


 #!/bin/bash
 # Copyright 2001 Daniel Robbins <drobbins@gentoo.org>, Gentoo Technologies, Inc.
 # Distributed under the GNU General Public License, version 2.0 or later.
 
 trap ":" INT QUIT TSTP
 export PATH=/sbin:/bin:/usr/sbin:/usr/bin
 umask 022
 
 if [ $$ -ne 1 ]
 then
     exec /sbin/init.system $*
 fi
 

Как можно заметить, init wrapper - "правильный" bash script, что следует из "магической" первой строки #!/bin/bash. Самое время заметить, что этот init wrapper требует версию bash 2.0 или современней. Введите /bin/bash --version, чтобы узнать, какая версия инсталлирована на вашей системе. В системе может быть установлено несколько версий интерпретатора. При этом может иметься отдельный исполняемый файл /bin/bash2. В таком случае скорректируйте первую строку сценария.

Теперь смотрим ниже. Команда trap защищает сценарий от прерывания пользователем (например, комбинации CRTL-C в процессе начальной загрузки), если его выполнение уже началось. Далее, экспортируется path по умолчанию и устанавливается (по умолчанию) umask 022. Явное назначение umask для использования в процессе начальной загрузки не помешает, тем более что на ранних ядрах серии 2.4 имелся дефект, приводивший к установке по умолчанию umask 0.

Ниже - первая условная инструкция, if [ $$ -ne 1 ]. Интерпретатор разворачивает $$ в process ID (текущего процесса). Инструкция читается как "отличается ли ИДЕНТИФИКАТОР текущего процесса от 1?" Что за этим скрывается? Первый процесс, запущенный ядром при загрузке, всегда получает PID 1. Именно этот номер зарезервирован для процесса init. Если PID не равен 1, можно уверенно сказать, что сценарий запущен из командной строки уже после загрузки системы. Заметим, второе вполне нормально, так как команда /sbin/init имеет двойное назначение и при запуске суперпользователем на загруженной машине используется для смены runlevel. Во втором случае сценарий просто запустит через exec оригинальный /sbin/init, на нашей системе переименованный в /sbin/init.system. Используя переменную $* можно любой из параметров, введенный в командной строке, передать программе init.system.

Kernel boot options

В случае, когда wrapper запускается ядром при начальной загрузке, сценарий получает PID равный 1. Первая условная конструкция будет пропущена, а bash продолжит выполнение wrapper. Просмотрим следующие строки:

More of the init wrapper


 mount -n /proc
 devfs="yes"
 for copt in `cat /proc/cmdline`
 do
     if [ "${copt%=*}" = "wrapper" ]
     then
             parms=${copt##*=}
             #parse wrapper option
             if [ "${parms/nodevfs//}" != "${parms}" ]
             then
                 devfs="no"
             fi
     fi
 done
 

Если отрабатывается эта часть кода, значит, идет процесс начальной загрузки. Первое действие - монтирование /proc к файловой системе root, которая все еще установлена в режиме read-only. После этого следует большой и сложный кусок bash кода, который использует выгоды одной очень удобной особенности Linux. Вы могли этого и не знать, но ядро позволяет увидеть, какие опции были ему переданы через LILO или GRUB по содержимому /proc/cmdline. На моем development box содержимое /proc/cmdline следующее:

Contents of /proc/cmdline


 # cat /proc/cmdline
 root=/dev/hda6 hda=89355,16,63 mem=524224K
 

Мы воспользуемся преимуществом существования /proc/cmdline, сканируя этот файл для поиска опции начальной загрузки с именем wrapper. Если среди kernel boot options появится wrapper=nodevfs, то сценарий не станет делать enabled devfs. В случае если такая переменная отсутствует в /proc/cmdline, то wrapper bash script продолжит devfs инициализацию. Мораль этой истории - вы можете легко отключать инициализацию devfs, передав ядру в паузе LILO или GRUB параметр wrapper=nodevfs. Если сделано так, сценарий переопределит значение переменной devfs в no, иначе - оставит yes.

Wrapping как он есть.

Теперь оставшаяся часть wrapper:

Rest of the init wrapper


 if [ "$devfs" = "yes" ]
 then
  if [ -e /dev/.devfsd ]
  then
     clear
     echo
     echo "The init wrapper has detected that /dev has been automatically mounted by"
     echo "the kernel. This will prevent devfs from automatically saving and"
     echo "restoring device permissions. While not optimal, your system will still"
     echo "be able to boot, but any perm/ownership changes or creation of new compat."
     echo "device nodes will not be persistent across reboots until you fix this"
     echo "problem."
     echo
     echo "Fortunately, the fix for this problem is quite simple; all you need to"
     echo "do is pass the \"devfs=nomount\" boot option to the kernel (via GRUB"
     echo "or LILO) the next time you boot.  Then /dev will not be auto-mounted."
     echo "The next time you compile your kernel, be sure that you do not"
     echo "enable the \"Automatically mount filesystem at boot\" devfs kernel"
     echo "configuration option.  Then the \"devfs=nomount\" hack will no longer be"
     echo "needed."
     echo
     read -t 15 -p "(hit Enter to continue or wait 15 seconds...)"
  else
     mount -n /dev /dev-state -o bind
     mount -n -t devfs none /dev
     if [ -d /dev-state/compat ]
     then
         echo Copying devices from /dev-state/compat to /dev
         cp -ax /dev-state/compat/* /dev
     fi
  fi
  /sbin/devfsd /dev >/dev/null 2>&1;
 fi
 
 exec /sbin/init.system $*
 

Перед нами большая условная инструкция, которая выполняется только тогда, когда переменная devfs установлена в yes. Иначе, инициализация devfs пропускается полностью, а devfs не пытается монтироваться. В таком случае произойдет традиционная non-devfs boot.

Однако если выбрана установка devfs, сценарий входит внутрь условного выражения. В этой инструкции выясняется, была ли devfs уже смонтирована ядром. Делается это через простой "визуальный" контроль наличия символьного устройства /dev/.devfsd. При монтировании devfs ядром это устройство создается автоматически, а будущий devfsd процесс будет использовать его для связи с ядром. Если devfs уже смонтирована (пользователь выбрал опцию "Automatically mount devfs at boot" перед компиляцией ядра), происходит распечатка информационного сообщения. В сообщении говорится, что невозможно повторно установить features of devfs, так как сделать это можно через wrapper только тогда, когда это еще не сделано самим ядром.

Device persistence

Если все OK, мы выполняем установку devfs, которая была описана в конце прошлой статьи. При этом /dev is bind-mounted к /dev-state, а файловая система devfs монтируется к /dev. Теперь о том, что было пропущено в прошлой статье. Мы проверяем существование каталога /dev-state/compat и рекурсивно копируем его содержимое в /dev. Такая процедура может показаться избыточной (мы ведь собираемся пользоваться преимуществами devfsd, не так ли?), но как выясняется необходимая и полезная. Причина, по которой необходим каталог compat в том, что devfsd's persistence features работают только с devfs-enabled drivers.

Что случиться, если в системе используется non-devfs kernel module? Казалось бы, достаточно создать device node в /dev вручную. Проблема в том, что созданный вручную new device node будет проигнорирован devfsd, а это означает, что после очередной перезагрузки он исчезнет и его придется "пересоздавать". Решение проблемы в том, чтобы иметь каталог /dev-state/compat. Если имеется non-devfs module, просто создаете old-style device nodes в /dev-state/compat, и они будут добавлены к devfs при начальной загрузке. Все это благодаря "внимательности" нашего init wrapper.

Осталось запустить devfsd и выйти из условного выражения. Как последний штрих, через exec запускается реальный init, или, как он теперь называется, /sbin/init.system. Происходит стандартный процесс загрузки системы. Ну, не совсем стандартный. Мы теперь имеем devfs-enabled system!

Инсталляция init wrapper.

Теперь приступим к инсталляции init wrapper. Сначала напишите исходный wrapper.sh и сохраните его где-нибудь в вашей системе. Сделайте следующее:

Installing the init wrapper


 # cd /sbin
 # cp init init.system
 # cp /path/to/wrapper.sh init
 # chmod +x init

Теперь init wrapper на месте.

Tweaking umount

Используя init wrapper, мы уходим от использования сложного компилированного initscript. Однако полностью избежать всех проблем нам не удастся. Если не предпринять дополнительных мер, то rc scripts будут очень много времени тратить на размонтирование корневой файловой системы (после инсталляции devfs). Имеется простое решение проблемы. Профильтруйте через grep ваши rc scripts на наличие команд umount, например, cd /etc/rc.d; grep -r umount *, или cd /etc/init.d; grep -r umount * (в зависимости, где инсталлированы ваши rc scripts). Далее, в каждом сценарии, где имеется команда umount, убедитесь, что она вызывается с ключом -r.

Ключ -r для umount выполняет remount в режим read-only (при повторной попытке), если unmounting завершился неудачей. Это достаточно для приведения корневой файловой системы в непротиворечивое состояние, после чего перезагрузка произойдет без проблем. "Чистое" размонтирование может не произойти из-за существующего монтирования к /dev, а /dev, в свою очередь, может оказаться не размонтированным, если открыт какой-либо device node.

Теперь перезагрузка практически подготовлена. Но, прежде, посмотрим на devfsd и /etc/devfsd.conf с позиции, чтобы compatibility devices и device persistence были enabled. Не волнуйтесь, мы всего лишь в одном шаге от завершения перехода на devfs.

devfsd.conf

Загрузите /etc/devfsd.conf в ваш любимый редактор. Посмотрите на первые четыре строки рекомендованного мною devfsd.conf:

devfsd.conf, top portion


 REGISTER        .*              MKOLDCOMPAT
 UNREGISTER      .*              RMOLDCOMPAT
 REGISTER        .*              MKNEWCOMPAT
 UNREGISTER      .*              RMNEWCOMPAT
 

Каждая из этих четырех строк состоит из event (REGISTER или UNREGISTER), регулярного выражения (.*) и action (строки *COMPAT). Что они означают? Первая строка указывает devfsd исполнять MKOLDCOMPAT action, когда любое устройство регистрируется в ядре (регулярное выражение .* match любому устройству). MKOLDCOMPAT action встроенная функция devfsd и означает "создавать любые old compatibility devices, соответствующие регулярному выражению, при его регистрации через devfs". Как несложно догадаться, RM*COMPAT actions работают при device unregistration, заставляя эти special compatibility devices волшебно исчезать. В целом, эти четыре строки указывают devfsd создавать compatibility devices (if any) когда устройство регистрируется и удалять compatibility devices при unregistered. Благодаря таким строкам, когда регистрируется драйвер IDE device как /dev/ide/host0/bus0/target0/lun0/disc (в devfs-style) самой системой, то devfs автоматически создает соответствующее /dev/hda compatibility-style device. Это очень полезно для таких команд, как mount и fsck, которые могут читать /etc/fstab, содержащий имена old-style device. Вообще, создание compatibility devices делает переход на devfs "бес проблемным". Следующая строка из моего devfsd.conf:

Module auto-loading

devfsd.conf, continued


 LOOKUP          .*              MODLOAD
 

Эта запись сообщает devfsd выполнять MODLOAD action всякий раз, когда любое устройство (смотри на регулярное выражение) "looked up". Такое случается, когда приложение ищет конкретное device node. MODLOAD action заставит выполнить команду modprobe /dev/mydev (/dev/mydev - имя устройства, которое внешний процесс пытается найти). Благодаря этой feature (в сочетании с правильно конфигурированным /etc/modules.conf), становится возможной автозагрузка драйверов по требованию, например, звуковой карточки, и другие подобные вещи.

Device persistence

Продолжим разбор строк из devfsd.conf:

devfsd.conf, continued


 REGISTER        ^pt[sy]/.*      IGNORE
 CHANGE          ^pt[sy]/.*      IGNORE
 REGISTER        .*              COPY    /dev-state/$devname $devpath
 CHANGE          .*              COPY    $devpath /dev-state/$devname
 CREATE          .*              COPY    $devpath /dev-state/$devname
 

В этих нескольких строках предписывается devfsd использование /dev-state как архива для любых device permission или ownership изменений, а также любых new compatibility devices, которые пользователь может создать. В двух первых строках явно сообщается devfsd не выполнять специальных действий при регистрации или смены атрибутов для любых pseudo-terminal devices. Если такие строки не использовать, то permissions и ownership таких pseudo-terminals сохранялись бы после перезагрузок. Это не оптимально, так как мы всегда должны устанавливать новые значения perms для pseudo-terminal devices после загрузки системы.

Следующие три строки включают /dev-state persistence для всех остальных устройств. Восстановятся любые атрибуты из /dev-state, когда устройство регистрируется или стартует сам devfsd (а также копирование атрибутов для любых совместимых устройств). Кроме этого, будут немедленно копироваться любые изменения в атрибутах, а также любые записи для только что созданных совместимых устройств к /dev-state.

CFUNCTION and symlinks

Заканчивается мой devfsd.conf следующими строками:

devfsd.conf, end


 REGISTER        ^cdrom/cdrom0$          CFUNCTION GLOBAL symlink cdroms/cdrom0 cdrom
 UNREGISTER      ^cdrom/cdrom0$          CFUNCTION GLOBAL unlink cdrom
 REGISTER        ^misc/psaux$            CFUNCTION GLOBAL symlink misc/psaux mouse
 UNREGISTER      ^misc/psaux$            CFUNCTION GLOBAL unlink mouse
 

Эти четыре строки необязательные, но они достойны упоминания. В то время как /dev-state persistence работает чудесно для device nodes, к символическим ссылкам это не относится. Возникает вопрос: как обеспечить, чтобы символические ссылки, например /dev/mouse или /dev/cdrom, не просто существовали, но и автоматически "воссоздавались" после перезагрузок? В конфигурациях devfsd такая возможность предусмотрена. Последние четыре строки (или подобные, все зависит от специфики настраиваемой системы) решают проблему. Первые две указывают devfsd создавать символическую ссылку /dev/cdrom, когда регистрируется устройство /dev/cdrom/cdrom0. Реализовано это через dynamic call функций libc, которые в данном случае специфицированы как symlink() и unlink(). Последние две строки конфигурационного файла используют аналогичный подход для создания символических ссылок /dev/mouse, когда устройство /dev/misc/psaux (в этом примере PS/2 мышь) регистрируется в devfs. "Подгоните" строки к вашей системе и сохраните конфигурационный файл devfsd.conf.

Предупреждение перед перезагрузкой.

Перед перезагрузкой можно посмотреть Richard Gooch's devfs FAQ. По этой ссылке можно найти информацию о devfs naming scheme, особенно полезную, когда вы только знакомитесь с именами устройств нового стиля (смотри Resources ниже). Я также рекомендую распечатать на принтере из части 5 порядок действий при "emergency bash rescue", если это для вас новость. Помните, если по каким то причинам init wrapper script создаст проблему, вы всегда можете удалить его следующей последовательностью спасательных команд. Загрузитесь "emergency bash rescue", выполните remounting корневой файловой системы в режим read-write и последовательно сделайте:

Откат к статусу pre-wrapper, если необходимо.


 # cd /sbin
 # mv init wrapper.sh
 # mv init.system init
 

Выполнив эти команды, перемонтируйте файловую систему в режим read-only и перезагрузите систему. Система откатится в pre-wrapper state. Исправьте ошибки, снова перезагрузитесь и наслаждайтесь devfs!


Презентация ext3

Daniel Robbins (drobbins@gentoo.org)
President/CEO, Gentoo Technologies, Inc.
November 2001

С выходом релиза 2.4 Linux появилась возможность использования filesystem с новыми свойствами, таких как Reiserfs, XFS, GFS и других. Эти filesystems еще не достаточно опробованы и имеются вопросы, что именно они могут делать, насколько они хороши и насколько оправдано их использование в промышленной Linux среде. Daniel Robbins отвечает на эти вопросы по ходу пояснения инсталляции этих новых продвинутых filesystems под Linux 2.4. По большей части статья основана на ext3 - новой улучшенной версии ext2 с возможностями journaling.

В прошлых статьях имелся обзор non-traditional filesystems типа tmpfs и devfs. Теперь пришло время вернуться к disk-based filesystems, и это делается на примере ext3. Ext3 filesystem, разработанная Dr. Stephen Tweedie, сформирована на структурах существующей ext2 filesystem; фактически, ext3 очень похожа на ext2 за исключением маленького (но важного) отличия - она поддерживает journaling. После такого "маленького" добавления в ext3 появились некоторые удивительные и интригующие возможности. В этой статье дается сравнение ext3 с другими journaling filesystems, доступными для использования уже сегодня. Планируется выход еще одной статьи об использовании ext3.

Пояснения к Ext3

Что собой представляет ext3 в сравнении с ReiserFS? В предыдущих статьях отмечалось, насколько хорошо ReiserFS подходит для работы с маленькими файлами (до 4КБ), и в отдельных случаях работа с такими файлами в ReiserFS в десять - пятнадцать раз эффективней, чем в ext2 (и ext3). Однако, кроме достоинств, ReiserFS имеет и свои слабости. В текущем релизе ReiserFS (версия 3.6) некоторые виды доступа к файлу фактически приводят к заметному снижению производительности в сравнении с ext2 и ext3 (особенно при чтении больших почтовых каталогов). Кроме того, ReiserFS не имеет хорошей совместимости с NFS и имеет проблемы с производительностью при дефиците свободного дискового пространства. Напротив, ext3 с этими задачами справляется великолепно. Она во многом подобна ext2; не ставит рекордов при обработке маленьких файлов, но хорошо прогнозируемая и не боится работы при ограниченных дисковых ресурсах.

Еще одно достоинство ext3 происходит из того, что она основана на коде ext2. Дисковый формат ext2 и ext3 идентичен; из этого следует, что при необходимости ext3 filesystem можно монтировать как ext2 без каких либо проблем. И это еще не все. Благодаря факту, что ext2 и ext3 используют идентичные метаданные, имеется возможность оперативного обновления ext2 в ext3. Именно так. Имеется ряд системных утилит, работающих с современными 2.4 ядрами (например, tune2fs) позволяющих конвертировать имеющуюся ext2 в journaling ext3. Удивительно, но сделать это можно даже на смонтированной ext2 filesystems. Переход безопасен, обратим и сравнительно легок (в отличие от конвертирования к XFS, JFS или ReiserFS - какого либо копирования данных на другой раздел не требуется). Теперь представьте на мгновение тысячи промышленных ext2 серверов (уже работающих), для которых обновление до ext3 минутное дело; можно получить хорошее представление о перспективности ext3's в Linux семействе.

Если от меня потребуют дать характеристику ext3 в одном слове, я бы сказал - удобная. Это действительно удобно как следствие насколько только возможной совместимости ext3 с существующей ext2. После обновления вам не придется сталкиваться с любыми неожиданностями. Есть еще одна характеристика, положительно отличающая ext3 от остальных journaled filesystems под Linux - высокая надежность, но об этом ниже.

Надежность Ext3

В дополнение к ext2-compatible, ext3 наследует другие преимущества общего формата metadata. Пользователи ext3 имеют в своем распоряжении годами проверенный fsck tool. Конечно, основная причина перехода на journaling filesystem - отказ от необходимости периодических и долгих проверок непротиворечивости метаданных на диске. Однако "журналирование" не способно защитить от сбоев ядра или повреждения поверхности диска (или кое-чего подобного). В аварийной ситуации вы оцените факт преемственности ext3 от ext2 с ее fsck. Напротив, ReiserFS fsck еще находится в младенчестве и устранение нарушений в метаданных может стать трудным и опасным процессом.

Metadata-only journaling

Интересно то, что ext3 выполняет journaling совсем иначе, чем ReiserFS и другие journaling filesystems. В ReiserFS, XFS и JFS filesystem журналируются метаданные привода и не предусмотрено какое либо журналирование самих данных. При metadata-only journaling метаданные хранятся так надежно, что, скорее всего вам не придется пользоваться fsck. Однако, неожиданные перезагрузки и сбои в электропитании могут приводить к утере данных, которые в момент сбоя записывались на диск. Ext3 использует несколько творческих решений для избежания таких проблем.

Сначала поясним ситуацию с metadata-only journaling. Например, вы редактировали файл /tmp/myfile.txt в момент, когда машина неожиданно блокировалась. В случае с metadata-only journaling filesystem (например, ReiserFS, XFS или JFS) ваши filesystem метаданные утрачены не будут и запуска fsck не потребуется.

Однако, в случае такого сбоя имеется высокая вероятность, что в файле /tmp/myfile.txt останется один мусор, а то и просто он станет нечитабельным.

Причина в следующем. "Обычные" journaled filesystems, подобные ReiserFS, XFS и JFS опекают метаданные, но для повышения производительности заботу о данных не проявляют. В нашем примере происходила модификация некоторых filesystem блоков и соответствующих им метаданных, но синхронизация была неожиданно прервана. "Непротиворечивость" файловых блоков будет восстановлена, чего нельзя сказать об их "наполнении".

Журнализация в ext3

Теперь, когда имеется общее понимание проблемы, посмотрим, как ext3 осуществляет journaling. В коде журнализации для ext3 используется специальный API, называемый Journaling Block Device layer или JBD. JBD был разработан для журнализации на любых block device. Ext3 привязана к JBD API. При этом код ext3 filesystem сообщает JBD о необходимости проведения модификации и запрашивает у JBD разрешение на ее проведение. Журналом управляет JBD от имени драйвера ext3 filesystem. Такое соглашение очень удобно, так как JBD развивается как отдельный, универсальный объект и может использоваться в будущем для журналирования в других filesystems.

Имеется два важных момента в JBD-managed ext3 journal, вытекающих из хранения журнала в inode файле (в базовом варианте). Первое, в зависимости от ключей монтирования ext3 filesystem, этот файл можно "видеть" или "не видеть" (расположен в /.journal). Второе, такое хранение журнала делает возможным переход к ext3 через простое добавление единственного файла (и замену драйвера) без использования несовместимых расширений к ext2 метаданным. Это ключ к пониманию "обратной совместимости" ext3 filesystem с ext2 метаданными и "прямой совместимости" ext2 с ext3 драйвером.

Различные подходы к journaling

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

JBD использует иной подход. Вместо регистрации промежуточных байтов сохраняются полностью измененные блоки файловой системы. Драйвер Ext3, аналогично, хранит полные точные копии модифицируемых блоков (1КБ, 2КБ или 4КБ) в памяти до завершения операции IO. Это может показаться расточительным. Полные блоки содержат не только изменившиеся данные, но и не модифицированные.

Подход, используемый JBD, называется "физическим журналированием", что отражает использование JBD "физических блоков" как основную единицу ведения журнала. Подход, когда хранятся только изменяемые байты, а не целые блоки, называется "логическим журналированием" (используется XFS). Поскольку ext3 использует "физическое журналирование", журнал в ext3 имеет размер больший, чем в XFS. За счет использования в ext3 полных блоков, как драйвером, так и подсистемой журналирования нет сложностей, которые возникают при "логическом журналировании". Кроме того, использование полных блоков позволяет исполнение некоторой дополнительной оптимизации, например "squishing" нескольких ожидающих обработки операции IO в пределах моноблока в одной структуре оперативной памяти. Это позволяет ext3 записывать на диск несколько смежных модификаций одной операцией. Как дополнение, при операциях записи существенно сокращается нагрузка на CPU.

Защита данных в Ext3

Теперь можно поговорить о том, как ext3 filesystem обеспечивает журнализацию и data, и metadata. Фактически в ext3 имеются два метода гарантирования непротиворечивости.

Первоначально ext3 разрабатывалась для журналирования full data и metadata. В этом режиме (называется "data=journal" mode), JBD журналирует все изменения в filesystem, связанные как с data, так и с metadata. При этом JBD может использовать журнал для отката и восстановления metadata и data. Недостаток "полного" журналирования в достаточно низкой производительности и расходе большого объема дискового пространства под журнал.

Недавно для ext3 был добавлен новый режим журналирования, который сочетает высокую производительность и гарантию непротиворечивости структуры файловой системы после сбоя (как у "обычных" журналируемых файловых систем). Новый режим работы обслуживает только metadata. Однако драйвер ext3 filesystem по-прежнему отслеживает обработку целых блоков данных (если они связаны с модификацией метаданных), и группирует их в отдельный объект, называемый transaction. Транзакция будет завершена только после записи на диск всех данных. "Побочный" эффект такой "грубой" методики (называемой "data=ordered" mode) - ext3 обеспечивает более высокую вероятность сохранности данных (по сравнению с "продвинутыми" журналируемыми файловыми системами) при гарантии непротиворечивости metadata. При этом происходит журналирование изменений только структуры файловой системы. Ext3 использует этот режим по умолчанию.

Заключение

В настоящее время многие пытаются определиться, какая из поддержанных в Linux журналируемых filesystem является "лучшей". По большому счету, все определяется тем, для каких целей и каких приложений файловую систему планируется использовать; каждая имеет свои достоинства и недостатки. Безусловное преимущество пользователей Linux - возможность выбора между файловыми системами нового поколения. Вместо приклеивания ярлыка "лучшей" файловой системы, следует понять силу и слабость каждой и принять обоснованное решение.

Ext3 имеет множество преимуществ. Она разработана для максимальной простоты развертывания. Она основана на годами проверенном коде ext2 и получила "по наследству" замечательный fsck tool. Ext3 в первую очередь предназначена для приложений, не имеющих встроенных возможностей по гарантированию сохранности данных. В целом, ext3 - замечательная файловая система и достойное продолжение ext2. В моей следующей статье будет описана установка и работа с ext3. До этого можете посмотреть некоторые ресурсы.


Неожиданности от ext3.

Daniel Robbins (drobbins@gentoo.org)
President/CEO, Gentoo Technologies, Inc.
December 2001

С выходом релиза 2.4 Linux появилась возможность использования filesystem с новыми свойствами, таких как Reiserfs, XFS, GFS и других. Эти filesystems еще не достаточно опробованы и имеются вопросы, что именно они могут делать, насколько они хороши и насколько оправдано их использование в промышленной Linux среде. В этой статье Daniel продолжает рассматривать ext3, новую улучшенную версию файловой системы ext2 с возможностью journaling. В статье вы найдете описание режимов ext3 и демонстрацию некоторых неожиданных ext3 data=journal показателей интерактивной производительности.

Я хочу быть честным. В этой статье я планировал описать установку и настройку ext3 на вашей системе. Хотя такая цель была обозначена, это не совсем то, о чем пойдет разговор. У Andrew Morton's имеется превосходная "Using the ext3 filesystem in 2.4 kernels" страница (смотри Resources далее), что делает простое объяснение перехода на ext3-enable излишним (зачем повторять то, что прекрасно описано у других). Вместо этого я собираюсь обратить ваше внимание на неожиданные стороны использования ext3 и, думаю, это будет полезным для вас. После прочтения этой статьи вы будете готовы к более осознанному переходу на ext3, чем в случае "пересказа" Andrew's page. По крайней мере, я на это надеюсь.

Новые модификации ядра 2.4.

Давайте начнем с ядра. Я обсуждал стабильную 2.4 ветку, когда описывал ReiserFS. При написании той (часть 2) статьи я рекомендовал остановиться на одной из последних к тому времени 2.4.4-ac9 версии ядра. В то время эту версию можно было рекомендовать как наиболее приемлемую для использования ReiserFS в промышленной среде. Поскольку с того времени утекло много воды и 2.4.4-ac9 уже не новость, пришло время сказать несколько слов о более современных версиях.

С появлением 2.4.10 серия 2.4 вышла на новый уровень производительности и универсальности (а вопросы были). Что же такое принципиальное случилось, что позволило Linux 2.4 выйти из кризиса? В акрониме к VM Linus признал, что серия 2.4 не оправдала надежд, и, прежде всего, из-за проблематичного кода VM. Первоначальный код поменяли на неотработанную и среднюю VM реализацию от Andrea Archangeli. Новая VM реализация от Andrea (впервые появилась в 2.4.10) стала действительно большим шагом вперед. Производительность ядра реально увеличилось, а система стала более чувствительной. 2.4.10 определенно поворотный пункт в развитии ядра 2.4 Linux. До этого момента оптимизм понемногу таял, и возникали вопросы, а не примкнуть ли к команде FreeBSD developers. Нужно отдать должное Linus за его решительность к таким серьезным (но необходимым) изменениям в стабильной ветке.

После такого поворота событий и включения нового VM кода от Andrea требуется немало времени для "затирания швов" (вопросы стабильности вышли на первый план). Используйте ядра 2.4.13+, а лучше 2.4.16+ (но не между ними) для rock-solid ext3. Код был интегрирован в ядро (без patch) начиная с версии 2.4.15-pre2. Нет оснований избегать использования 2.4.16+ ядра, с ним реализация ext3 будет полной. Когда будете читать Andrew's page (смотри Resources дальше), имейте в виду, начиная с 2.4.16 нет надобности накладывать patch на ядро (это уже сделано).

Обратите внимание, я рекомендую использовать 2.4.16+ (даже 2.4.13+), но не 2.4.15+. На это есть серьезные основания. В релизе 2.4.15-pre9 был обнаружен ugly filesystem corruption bug. Выбор 2.4.16+ ядра избавит вас от возможных проблем.

Предостережение пользователям laptops.

Ext3 имеет твердую репутацию rock-solid filesystem, и я с удивлением узнал, что у нескольких пользователей laptop возникли проблемы при переходе на ext3. Был соблазн, как реакция на подобные сообщения, отказаться от использования ext3. Однако, разбираясь в причинах таких явлений, я обнаружил, что проблемы не связаны непосредственно с ext3, а были вызваны laptop hard drives.

Кэш записи.

Вы можете этого и не знать, но самые современные hard drives имеет нечто, называемое "write cache". Он используется hard drive для сбора ожидающих обработки операций записи. Помещая ожидающие обработку записи в кэш, hard drive firmware может переупорядочивать и группировать их так, чтобы они были записаны на диск самым быстрым из возможных способов. Кэш записи с такой позиции очень полезная вещь (читайте объяснение Линуса и его мнение о write caching в разделе Resources).

К сожалению, некоторые laptop hard drives имеют сомнительную возможность игнорирования любого "официального" ATA request с требованием сброса на диск их write cache. Возразить нечего, такая "замечательная" feature до недавнего времени не была запрещена ATA спецификацией. При взаимодействии с такими типами дисков у ядра нет возможности гарантировать, что специфический блок был "фактически" сброшен на диск. Хотя это необходимая причина вдруг возникшей проблемы с нарушением целостности данных, но еще не достаточная.

Ситуация оказалась еще хуже. Некоторые современные laptop hard drives имеют еще более "вредную" привычку без команды сбрасывать свой write cache, когда система перезагружается или "засыпает". Если hard drive наделен обеими features, а файловая система поддерживает журнализацию, происходит периодическое разрушение данных и нельзя ничего предпринять для предотвращения этого.

Где решение? Если вы имеете laptop, действуйте осторожно. Сохраните важные файлы перед внесением больших изменений в файловую систему. Если возникнут проблемы с нарушением целостности данных после перехода на ext3, возможно причина в "продвинутости" вашего диска. В таком случае можно войти в контакт с изготовителем вашего laptop hard drive по вопросу о его замене. Есть надежда, что уже в ближайшее время эти диски уйдут с рынка (или переместятся на рынки третьих стран - прим. переводчика) и о проблеме можно будет забыть.

Теперь, после испуга, вы готовы к обсуждению различных ext3 опций journaling данных.

Опции journaling и производительность.

Ext3 предлагает на выбор три режима journaling при монтировании файловой системы: data=writeback, data=ordered и data=journal.

Для указания journal mode можно добавить соответствующую строку (например, data=journal) в поле опций записи в /etc/fstab или непосредственно в командной строке указать -o data=journal при вводе команды mount. Для указания метода journaling на root файловой системе (по умолчанию data=ordered) можно использовать специальную kernel boot option, называемую rootflags. Например, для указания монтирования корневой файловой системы в режим full data journaling, добавьте rootflags=data=journal к kernel boot options.

data=writeback mode

В режиме data=writeback, файловая система ext3 не выполняет какого либо журналирования data. С подобным видом журналирования вы имеете дело в файловых системах XFS, JFS и ReiserFS (metadata only). Как объяснялось в предыдущих статьях, это не защитит от разрушения данные в обновляемых файлах в случае неожиданной перезагрузки. Несмотря на этот недостаток, режим data=writeback обеспечивает самую высокую производительность ext3 при всех условиях.

data=ordered mode

В режиме data=ordered файловая система ext3 "официально" журналирует только метаданные, но логически metadata и data блоки группируются в единый модуль, называемый transaction. Перед записью новых метаданных на диск, связанные data блоки записываются первыми. Режим data=ordered эффективно (хотя без гарантии) решает проблему c разрушением данных, свойственную режиму data=writeback и большинству других journaled файловых систем. Заметьте, делается это без full data journaling. По производительности следует заметить, что data=ordered в ext3 работает несколько медленнее data=writeback, но заметно быстрее full data journaling.

Что касается гарантии от разрушения данных. При добавлении данных в конец файла режим data=ordered гарантированно обеспечивает целостность (как при full data journaling mode). Однако если данные в файл пишутся поверх существующих, то есть вероятность перемешивания "оригинальных" блоков с модифицированными. Это результат того, что data=ordered не отслеживает записи, при которых новый блок ложится поверх существующего и не вызывает модификации метаданных. В режиме data=ordered порядок записи отслеживается только до попадания в hard drive's write cache. Такое ограничение не должно огорчать пользователей, так как операция добавления в конец файла более обычна, чем наложение записи. По этой причине режим data=ordered хорошая альтернатива для full data journaling.

data=journal mode

Режим data=journal обеспечивает полное журналирование и метаданных, и самих данных. Все новые данные сначала пишутся в журнал и только после этого переносятся на свое постоянное место. В случае аварийного отказа журнал можно повторно перечитать, приведя данные и метаданные в непротиворечивое состояние.

Теоретически, режим data=journal самый медленный из всех journaling режимов, так как данные записываются на диск два раза. Однако было доказано, что в отдельных случаях режим data=journal показывает неплохие результаты. Andrew Morton, после знакомства с отчетами LKML о том, что в ext3 data=journal иногда неожиданно выдает высокую производительность, решил провести небольшое тестирование. Сначала он написал простой shell script, предназначенный для записи данных на тестируемую файловую систему с максимально возможной скоростью:

Быстрая запись.

 while true
 do
         dd if=/dev/zero of=largefile bs=16384 count=131072
 done
 

Одновременно с записью данных на тестируемую файловую систему, он попытался прочесть 16Mb данных с другой ext2 файловой системы того же диска, подсчитав результаты:

Чтение 16Mb файла.

 time cat 16-meg-file > /dev/null
 

Результат оказался поразительным. Режим data=journal позволил прочесть 16Mb файл в 9 - 13 раз быстрее, чем при других ext3 режимах, ReiserFS и даже ext2 (в которой журналирование вообще отсутствует):

Written-to-filesystem 16-meg-read-time (seconds) ext2 78 ReiserFS 67 ext3 data=ordered 93 ext3 data=writeback 74 ext3 data=journal 7

Эндрю повторил тестирование, изменив условия. Чтение 16Mb файла происходило с тестируемой файловой системы. Результат оказался аналогичным. Что из этого следует? Так или иначе, но режим data=journal очень хорошо подходит для случаев, когда данные должны одновременно читаться и записываться. Поэтому режим data=journal, который теоретически считался самым медленным, оказывается, имеет преимущество в среде, сильно нагруженной интерактивными операциями IO. По крайней мере, режим data=journal не настолько вял, как казалось бы!

Andrew еще не нашел объяснений, почему так происходит. Возможно, ответ на этот вопрос поможет в совершенствовании ext3 так, чтобы режимы data=writeback и data=ordered стали более производительными.

data=journal tweaks

Сообщалось о специфической проблеме при использовании ext3 в режиме data=journal на нагруженных серверах и нагруженных NFS серверах в частности. Каждые тридцать секунд сервер испытывает "шторм записей" на диск, прекращая реагировать на все остальное. Если вы столкнулись с такой проблемой, ее можно устранить. Введите следующую команду (с привилегиями root) для "подстегивания" Linux's dirty buffer-flushing algorithm:

Tweaking bdflush

 echo 40 0 0 0 60 300 60 0 0 > /proc/sys/vm/bdflush
 

Такая настройка bdflush заставит kupdate выполняться каждые 0.6 секунд, а не через 5 секунд (по умолчанию). Кроме того, ядру сообщается необходимость сброса на диск dirty буфера через 3 секунды, а не через 30 (значение по умолчанию). Регулярно и часто сбрасывая на диск недавно измененные данные, можно избежать затяжных "штормов записи". Помните, это снизит эффективность работы (особенно при небольшой загрузке системы), так как у ядра будет меньше возможностей для объединения операций записи. Нагруженному серверу снижение эффективности не грозит, а интерактивность будет улучшена.

Заключение.


Презентация XFS.

Daniel Robbins (drobbins@gentoo.org)
President/CEO, Gentoo Technologies, Inc.
January 2002

С выходом релиза 2.4 Linux появилась возможность использования filesystem с новыми свойствами, таких как Reiserfs, XFS, GFS и других. Эти filesystems еще не достаточно опробованы и имеются вопросы, что именно они могут делать, насколько они хороши и насколько оправдано их использование в промышленной Linux среде. Daniel Robbins отвечает на эти вопросы по ходу пояснения инсталляции этих новых продвинутых filesystems под Linux 2.4. В этой статье Daniel представляет XFS, SGI's free enterprise-class файловую систему, ставшую доступной для Linux.

В этой статье мы познакомимся с XFS, SGI's free, 64-bit, высокопроизводительной файловой системой для Linux. Сначала будет проведено сравнение XFS с ext3 и ReiserFS и описаны некоторые из технологий, которые используют внутренние структуры XFS. В следующей статье будет описан процесс инсталляции XFS на вашей системе и даны несколько советов по настройке XFS и ее полезных features, например ACL (access control lists) и поддержки extended attribute.

Презентация XFS.

Файловая система XFS первоначально была разработана Silicon Graphics, Inc. в начале 90-х годов. В то время в SGI пришли к выводу, что их "базовая" файловая система (EFS) по скорости перестала соответствовать современным требованиям. Изучив проблему, в SGI пришли к выводу, что лучше "с нуля" спроектировать новую высокопроизводительную 64-bit файловую систему, чем попытаться модернизировать EFS. Рождение XFS произошло в релизе IRIX 5.3 в 1994. С этого времени именно эта файловая система становится базовой для всех SGI's IRIX-based продуктов для workstations на основе supercomputers. Совсем недавно XFS стала доступна и для Linux. Появление поддержки XFS в Linux событие значимое. Теперь Linux community обладает устойчивой, современной файловой системой с богатым набором feature, масштабной и удовлетворяющей самым высоким требованиям к хранилищам данных.

Сравнение производительности XFS с ReiserFS и ext3.

До недавнего времени выбор файловой системы для Linux был ободряюще прямым. Те, кому требовалась высокая производительность, склонялись к ReiserFS, а те, кого волновала целостность данных, предпочитали ext3. С появлением поддержки XFS для Linux выбор стал не столь прямолинеен. В частности, большой вопрос, а действительно ли ReiserFS при всех условиях является лидером по производительности?

Недавно мной было проведено тестирование с целью сравнения XFS, ReiserFS и ext3 в отношении raw performance. Но, прежде всего я замечу, что результаты отражают только общую тенденцию зависимости производительности файловых систем от нагрузки на однопроцессорной системе. Тесты, не претендуя на "абсолютную" истинность результатов, тем не менее, могут помочь в ответе на вопрос: для какой специфической задачи какой файловой системе следует отдавать предпочтение. И еще раз, результаты моего тестирования не рассматривайте как заключительные. В любом случае, для ответственного выбора следует проводить тестирование на конкретных приложениях.

Результаты.

Тестирование показало, что XFS очень быстрая файловая система. XFS постоянный лидер в тестах с манипуляциями большими файлами. Собственно такой результат вполне предсказуемый (она и проектировалась именно под это). Была замечена одна "причуда" в производительности - относительно медленные операции удаления файлов. В этом вопросе она проиграла и ReiserFS, и ext3. По замечанию Steve Lord (Principal Engineer по файловым системам в SGI) недавно был написан patch, решающий эту проблему (будет доступен в ближайшее время).

В других тестах производительность XFS была близка к таковой у ReiserFS и всегда превосходила ext3. Приятная особенность XFS - она не генерит (впрочем, как и ReiserFS) излишнюю дисковую активность. XFS пытается кэшировать как можно больше данных и "основанием" для сброса на диск является заполнение памяти, а не интервал времени. Когда происходит сброс данных на диск, это не оказывает заметного влияния на другие IO операции. Как противоположность - в ext3 (режим "data=ordered") периодический сброс данных на диск порождает проблемы с интерактивностью и, при высокой интенсивности операций IO, даже disk thrashing.

Следующие тесты на производительность и адаптацию к внешним факторам сосредоточились вокруг распаковки kernel source tarball на RAM disk и последующее рекурсивное копирование source tree в новый каталог на той же файловой системе. XFS справлялась с такой задачей хорошо, но проигрывала ReiserFS. Однако, после повторного mkfs.xfs и игры с опциями mount, XFS смогла немного "обойти" по скорости ReiserFS даже при обработке файлов среднего размера, характерных для kernel source tree. Словом, преимущество почти во всем, кроме маленькой детали - удаления старых файлов, "неудобной" для XFS операции (ReiserFS и ext3 удаляют файлы быстрее, чем XFS).

Выводы по производительности.

Сказанного достаточно для понимания общей идеи относительно ожиданий производительности от XFS. Результаты тестирования подтвердили, что XFS лучший выбор среди файловых систем, если требуются манипуляции с большими файлами. При работе с файлами среднего размера XFS вполне конкурентоспособна, а в ряде случаев даже немного быстрее ReiserFS. Последнее справедливо, если создавать и монтировать XFS с некоторыми performance-enhancing опциями. Ext3 в режиме "data=journal" показывает сравнительно неплохую производительность с учетом гарантии целостности данных (а не только метаданных). Однако дать по настоящему высокую оценку ext3 мешают проблемы при сбросе данных на диск.

Проект XFS.

В документе "Scalability in the XFS Filesystem" (смотри Resources) представленном в USENIX '96, инженеры SGI поясняют, что XFS была разработана под девизом "думайте о большем". И действительно, XFS снимает некоторые ограничения, присущие традиционным файловым системам. Остановимся на некоторых интригующих features проекта XFS.

Презентация allocation groups.

При создании файловой системы XFS основное block device разбивается на восемь или больше равных по размеру линейных областей. Их можно было бы назвать "chunks" или "linear ranges", но в терминологии XFS они именуются "allocation group". Уникальность allocation group в том, что каждая группа управляет своими собственными inodes и free space, что превращает группы в своего рода автономные sub-filesystem, сосуществующие в рамках общей XFS.

Allocation groups и масштабность.

А зачем разработчики XFS решили использовать allocation groups? В первую очередь это сделано для эффективной параллельной обработки операций IO. Поскольку каждая allocation group это эффективно управляемый автономный объект, ядро может распределять нагрузку между несколькими allocation groups. Без allocation groups код файловой системы XFS стал бы "узким горлом" для производительности, вынуждая IO-hungry процессы "выстраиваться в цепочку" для модификации inode и выполнения других операций над метаданными. Благодаря allocation groups код XFS допускает multiple threads, а процессы могут работать параллельно, даже при сложных IO операциях на одной файловой системе. Если у вас работает XFS, то ограничения по скорости, даже на high-end hardware, не будут определяться кодом файловой системы. Allocation groups в еще большей степени способствуют оптимизации параллельных IO операций на многопроцессорных системах, так как "in transit" одновременно могут находиться несколько модификаций метаданных.

B+ trees повсюду.

Внутренне, allocation groups используют эффективные B+ trees для отслеживания важных данных, например, диапазонов [ranges] (еще называются "extents") свободного дискового пространства и, конечно, inodes. Фактически, каждая allocation group имеет три B+ trees, при этом для отслеживания free space используются два. Одно дерево индексирует extents свободного дискового пространства по размеру, а второе - по начальной физической location на блочном устройстве. Способность быстро находить подходящие regions в free space - критическое условие для maximizing операций записи (то, что положительно отличает XFS от других файловых систем).

В XFS очень эффективно организовано управление inodes. Каждая allocation group ассигнует inodes как ей это удобно в группы по 64. Каждая allocation group хранит свои inodes, используя B+ tree, и каждый конкретный inode number может быть быстро найден на диске. Можно сказать, что XFS использует B+ trees где это только возможно, что и способствует повышению производительности.

Journaling.

Разумеется, как и большинство современных файловых систем, XFS поддерживает журналирование метаданных для быстрого восстановления в случае аварийной перезагрузки. Подобно ReiserFS, в XFS используется логическое журналирование. Иначе, журнал ведется не файловыми блоками (как в ext3), а в эффективном дисковом формате с регистрацией только изменяемых метаданных. Для XFS логическое журналирование особенно "показано". На high-end hardware (что обычно для XFS) журнал наиболее спорный ресурс. Использование space-efficient logical journal минимизирует непроизводительное расходование ресурсов. Кроме того, XFS допускает хранение журнала на другом блочном устройстве (partition, скажем так, на "дешевом" диске). Эта feature не только экономит дорогие ресурсы, но в еще большей степени "работает" на увеличение скорости XFS.

Как и ReiserFS, XFS журналирует только метаданные и не делает это для самих данных. Из этого следует, что в XFS (как и в ReiserFS) возможна потеря данных, измененных перед аварийной перезагрузкой. Но, у журнала XFS имеется два свойства, снижающих вероятность потери данных по сравнению с ReiserFS.

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

Теперь непосредственно о проблеме потери данных. Такая проблема в XFS минимизируется вследствие того, что операция сброса на диск ожидающих обработки модификаций метаданных в XFS происходит чаще, чем это происходит в ReiserFS (особенно при высокой интенсивности операций IO). Как следствие, после аварии в XFS потерь будет меньше, чем при тех же условиях в ReiserFS. Заметьте, сама по себе более частая запись метаданных не "купирует" проблему, а лишь провоцирует более частый сброс на диск и самих данных.

Delayed allocation.

Этот краткий технический обзор XFS завершается описанием delayed allocation, еще одной feature, уникальной среди файловых систем. Определимся с терминами. Понятие allocation относится к процессу обнаружения областей free space для записи новых данных.

XFS выполняет allocation, разделяя, казалось бы, неделимый процесс на два шага. Сначала, когда XFS получает данные для записи, выполняется запись ждущей транзакции [pending transaction] в RAM и просто резервируется соответствующее количество пространства на основной файловой системе. При этом, резервируя "количество пространства" для новых данных, XFS не решает, какие именно блоки файловой системы эту информацию будут хранить. XFS откладывает принятие окончательного решения до самого последнего момента, когда данные фактически сбрасываются на диск.

Через delaying allocation файловая система XFS получает дополнительные возможности оптимизации скорости. Когда наступает момент фактического сброса данных на диск, XFS может быстро и интеллектуально ассигновать free space под оптимизацию производительности. В частности, если новые данные добавляются в конец одного файла, XFS может ассигновать смежные region на диске. Если бы XFS не задерживала "до последнего" принятие решения по ассигнованию физических блоков, возможно, данные были бы "размазаны" по множеству несмежных участков. Благодаря задержке "физического" ассигнования, XFS способна делать запись одной операцией, повышая производительность и снижая фрагментацию.

Delayed allocation имеет еще один положительный эффект. Если создается много временных файлов с "маленьким временем жизни", XFS вообще не будет сбрасывать их на диск (ну и что, не только XFS). А теперь внимание, поскольку физические блоки не allocated, отсутствует необходимость в их последующей deallocate. Иначе, не пишутся на диск не только данные, но и не изменяются метаданные файловой системы (а вот это уже кое-то, по сравнению с другими FS).


Развертывание XFS.

Daniel Robbins (drobbins@gentoo.org)
President/CEO, Gentoo Technologies, Inc.
April 2002

С выходом релиза 2.4 Linux появилась возможность использования filesystem с новыми свойствами, таких как Reiserfs, XFS, GFS и других. Эти filesystems еще не достаточно опробованы и имеются вопросы, что именно они могут делать, насколько они хороши и насколько оправдано их использование в промышленной Linux среде. Daniel Robbins отвечает на эти вопросы по ходу пояснения инсталляции этих новых продвинутых filesystems под Linux 2.4. В этой статье Daniel описывает, как добавить XFS к вашей системе и исследует отдельные, более "продвинутые" features XFS.

В этой статье будет показано, как добавить поддержку XFS к вашей системе. Но сначала посетите и исследуйте SGI XFS Project page (смотри Resources далее). Если проследуете по download link, вы найдете patches, tools и даже Red Hat XFS-enabled kernels.

Но не торопитесь. Конечно, можно инсталлировать XFS используя pre-rolled, т.е. официальные релизы. Но в данном случае я не рекомендую такой подход. При написании этой статьи самый последним из официальных релизов XFS был 1.0.2, созданный еще в ноябре 2001. С того времени было внесено множество уточнений к XFS и, чтобы извлечь из этого выгоду, воспользуемся современными sources из XFS CVS tree. Developers и users, сделавшие выбор в пользу Gentoo Linux и воспользовавшиеся XFS из CVS, получили от XFS много больше.

Использование CVS.

Если вы раньше не пользовались CVS, можете воспользоваться моей tutorial - CVS для developer и любителей (смотри Resources). Даже если вы имеете самое общее представление о CVS, этого будет достаточно. Убедитесь только, что на вашей системе имеется инсталлированный CVS package и вам доступна команда cvs.

Описание CVS instructions, которые будут использоваться далее, можно также найти на SGI's site (смотри Resources). После grabbing исходников через cvs, вы получите новый каталог, содержащий up-to-date XFS-enabled kernel sources и самые современные XFS tools. Для grab the sources от XFS CVS сначала установите переменную окружения CVSROOT в требуемое значение. Например, по bash prompt введите:


 $ export CVSROOT=':pserver:cvs@oss.sgi.com:/cvs'
 

Теперь перейдите в каталог, где вы желаете разместить XFS directory tree, и выполните:


 $ cvs login
 

По запросу пароля введите cvs. Теперь вы подключились к public CVS repository. Получите самые последние XFS sources, введя:


 $ cvs -z3 checkout linux-2.4-xfs
 

Запустится процесс checkout. Это займет некоторое время, так как файлы, которые вы grabbing, включают полное Linux source tree. Через некоторое время, когда команда cvs checkout завершится, вы будете иметь новое linux-2.4-xfs directory tree в текущем рабочем каталоге. Рекомендация на будущее: если вам потребуется модернизировать source tree, просто внутри linux-2.4-xfs каталога введите:


 $ cvs -z3q update -dP
 

Работа с деревом.

Имеется два важных каталога внутри нового linux-2.4-xfs. Первый называется linux и содержит XFS-enabled kernel source tree, а второй называется cmd и содержит sources для различных XFS userspace программ. Чтобы воспользоваться kernel sources, можно либо скопировать linux каталог в /usr/src, либо компилировать новое ядро "на месте".

Теперь о том, как получить работающее ядро. Войдите в linux каталог и загрузите Makefile в ваш любимый редактор. В начале файла вы увидите несколько строк, которые выглядят примерно так:


 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 17
 EXTRAVERSION = -xfs
 

Эти строки сообщают Makefile компилировать ядро с официальным именем 2.4.17-xfs. Некоторые предпочитают иметь ядро без -xfs в официальном имени. Если вы один из таких людей, измените строку, которая будет читаться:


 EXTRAVERSION =
 

Теперь о kernel configuration. Для enable XFS, после make menuconfig перейдите в секцию File systems. Там вы увидите следующую опцию:


 < > SGI XFS filesystem support
 

Разрешите ее (рекомендуется статически компилировать в ядро). Введите "y" и появятся еще три под опции:


 [ ]   Enable XFS Realtime support  
 [ ]   Enable XFS Quota 
 < >   Enable XFS DMAPI
 

Опция "XFS Realtime" разрешает поддержку realtime subvolume в XFS, что позволит в дальнейшем конфигурировать области памяти, обеспечивающие deterministic performance для приложений реального времени. Опция "XFS Quota" позволит, как нетрудно догадаться, поддержку лимитов на размер доступного дискового пространства для пользователей и групп. Опция "XFS DMAPI", если помечена, разрешит специальный API, предназначенный для management приложений. В настоящее время под Linux еще нет tools, которые пользуются преимуществами DMAPI (имеются у Sistina's LVM и "родные" SGI XFS utilities). Однако некоторые DMAPI-enabled приложения для Linux уже находятся в разработке у SGI и IBM.

После выбора "SGI XFS filesystem support" и конфигурирования остальной части ядра по вашему вкусу, вы готовы ввести make dep && make && make bzImage && make modules && make modules_install, инсталлировать новое ядро и перезагрузиться. .

Инсталляция tools.

Теперь, когда вы работаете на XFS-enabled kernel, можно создать и инсталлировать различные XFS tools. Одна из хороших новостей относительно XFS - она поставляется с полным набором инструментов поддержки и утилит. Войдите в каталог linux-2.4-xfs/cmd и запустите (с правами root) следующий shell script:


 # for x in attr acl xfsprogs dmapi xfsdump
 do
 cd $x
 autoconf
 /configure --prefix=/usr
 make
 make install
 cd ..
 done
 
 

Не забудьте о переводе строки после done. Наш специальный build script начнет работу, и все XFS tools будут инсталлированы. После финиша добавим несколько developer-related файлов, которые не инсталлированы предыдущей командой make installl:


 # for x in attr dmapi xfsprogs
 do
 cd $x
 make install-dev
 cd ..
 done
 
 

Создание и монтирование файловой системы.

После отработки script все XFS-related программы будут инсталлированы и готовы к использованию. Можно создать тестовую XFS и попытаться достигнуть оптимальной производительности.

Если XFS создается поверх ReiserFS, потребуется небольшая уловка. По bash prompt введите следующую команду для "обнуления" начального участка block device, на котором хранилась ReiserFS, а теперь вы собираетесь инициализировать новую XFS filesystem:


 # dd if=/dev/zero of=/dev/hdc9
 

Такой шаг необходим для wipe out хранящихся ReiserFS метаданных. Иначе, команда mount может "запутаться" и случайно смонтировать новую XFS filesystem как дефектную ReiserFS! Достаточно позволить dd отработать 10 секунд и прервать комбинацией CTRL-C. При этом все "критические" части ранее существовавшей ReiserFS будут заполнены нулями, а код авто-детектирования типа файловой системы "путаться" больше не будет.

Пришло время create новую файловую систему. Для этого можно воспользоваться командой mkfs.xfs следующим образом:


 # mkfs.xfs /dev/hdc9
 

Такая команда сделает все необходимое, но имеется пара опций, позволяющих mkfs.xfs сконфигурировать новую XFS под максимальную производительность.

Первая из таких опций -l size=32m, что сообщит mkfs.xfs сконфигурировать файловую систему так, чтобы журнал метаданных имел размер 32 Mb. Это повысит производительность, сделав маловероятным переполнение журнала при высоких нагрузках.

Вторая опция позволяет поднять производительность новой файловой системы, сообщив mkfs.xfs минимизировать число allocation groups. Обычно, mkfs.xfs выбирает число allocation groups автоматически. Но опыт показывает, выбирается число несколько большее, чем требуется для оптимальной производительности однопроцессорных Linux workstations и серверов. Если вы повторно перечитаете мою предыдущую статью, allocation groups позволяют XFS выполнять операции над метаданными параллельно. Это очень удобно для high-end серверов, но слишком много allocation groups добавляют работы. Вместо того чтобы разрешить mkfs.xfs автоматически выбрать число allocation groups для вашей файловой системы, сделайте это "вручную", используя -d agcount=x. Выберите x минимальным, например, 4, 6 или 8. Расчет достаточно прост, необходимо иметь, по крайней мере, одну allocation group на каждые 4 GB в target block device. Две описанные опции позволят создать "оптимизированную" XFS filesystem следующей командой:


 # mkfs.xfs -d agcount=4 -l size=32m /dev/hdc9
 

Теперь, после created файловой системы, ее можно монтировать. При этом можно воспользоваться некоторыми performance-enhancing опциями монтирования, чтобы "выжать" максимум из новой файловой системы:


 # mount /dev/hdc9 /mnt -o noatime,nodiratime,osyncisdsync
 

Первые две опции монтирования выключают модификацию atime, что практически никогда и не требуется, но способствует деградации производительности. Опция osyncisdsync добивается такого sync/async поведения XFS, чтобы максимально соответствовать таковому в ext3. Благодаря таким mkfs.xfs и mount ваша новая XFS будет иметь скорость немного выше, чем при умолчании.

Положительные герои.

Одна из хороших вещей в XFS - она имеет много goodies. Одной из таких специальных функциональных возможностей являются "access control lists" или ACL. Сейчас это поддерживается в XFS по умолчанию. Списки контроля доступа позволяют определять fine-grained разрешения на файлы. Например, вместо ограниченного "rwx" для владельца, группы и других, становится возможным добавлять любое число дополнительных пользователей или групп и определять "rwx" permissions и для них.

Полное описание access control lists - вне контекста этой статьи. Если вам это интересно, посмотрите большое введение в ACL на bestbits site (Resources), особенно, если посетить страничку "Why you may want Access Control Lists (ACLs)". Обратите внимание, большая часть технической информации этого сайта связана с поддержкой ACL под ext2 и ext3 (но ничего дополнительного не требуется для ACL под XFS).

XFS имеет еще одну feature, называемую "extended attributes". Такие extended attributes позволяют вам associate user-defined данные с объектами файловой системы. Например, если вы имеете графический файл по имени mygraphic.png, можно attach к нему атрибут, называемый "thumbnail", содержащий маленькую версию image. Эти данные не будут viewable обычными IO файловыми операциями, но к ним можно обращаться из программ, использующих special extended attributes API. По своей сути, extended attributes похожи на "resource fork", существующие на MacOS системах.

Имеется пример использования extended attributes через команду attr из командной строки. Скажем, я желаю добавить description attribute к моему home каталогу. Я ввожу:


 $ attr -s description -V "Home of Daniel Robbins" /home/drobbins
 Attribute "description" set to a 22 byte value for /home/drobbins:
 Home of Daniel Robbins
 

После этого, чтобы видеть список атрибутов, ассоциированных с /home/drobbins, можно ввести:


 $ attr -l /home/drobbins
 Attribute "description" has a 22 byte value for /home/drobbins/
 

А чтобы просмотреть содержание description attribute, я ввожу:


 $ attr -q -g description /home/drobbins/
 Home of Daniel Robbins
 

Extended attributes просты и забавны в использовании. Вы можете узнать о них больше, прочитав man attr. XFS включает также API C для взаимодействия с extended attributes. Если вы интересуетесь работой с C++ IOStream интерфейсом к extended attributes, можете посмотреть libferris на SourceForge (Resources).

Конечно, extended attributes и ACL открывают интересные возможности, но будьте осторожны. Большинство backup программ в настоящее время еще "не понимают" ни EA, ни ACL. Известные мне исключения - xfsdump и xfsrestore, поставляемые с XFS distribution. Если используете другую backup программу, проведите сначала интенсивное тестирование на поддержку EA и ACL.


Совершенствование файловых систем.




Перевод: Владимир Холманов

Daniel Robbins (drobbins@gentoo.org)
President/CEO, Gentoo Technologies, Inc.
June 2002

В серии "Advanced filesystem implementor's guide" Daniel Robbins описывает современные технологии, применяемые в файловых системах под Linux 2.4. В руководстве даются ценные практические советы по их применению, информация о производительности и технические примечания. Это способствует созданию хороших условий для их освоения и накопления опыта работы с ними. В новой статье Daniel расскажет об изменениях в XFS, ReiserFS и ext3 произошедших к настоящему времени, теперь уже имея статус Главного Архитектора Gentoo Linux. Помимо прочего, уделяется внимание тем направлениям, по которым продолжится совершенствование этих файловых систем в ближайшие пол года.

Просматривая свои прошлые статьи из серии "Руководство по "продвинутым" файловым системам" для себя я отметил, что со времени первой публикации прошел почти год! Не волнуйтесь, эта серия скоро пополнится новым содержанием, поскольку я собираюсь приступить к описанию Linux технологий JFS и EVMS (enterprise volume management) от IBM. Поскольку площадкой для публикаций является сайт IBM, я решил, что описание технологий от IBM уместно сделать после всех остальных файловых систем для Linux.

Но, прежде чем приступить к JFS и EVMS, я отвлекусь на вопросы update текущего состояния файловых систем в мире Linux. Мы опробовали большое число ядер серии 2.4. Одни из них были оценены как "приличные", о других такого не говорили. Не только ядро, но и XFS, ext3 и ReiserFS находились в состоянии активного развития. При этом, большое число пользователей Gentoo Linux использовали самые разные комбинации файловых систем XFS, ext3 и ReiserFS и с разными результами. Когда кто либо из пользователей Gentoo Linux имеет проблему с журналируемой файловой системой, обычно я об этом узнаю. Итак, какие файловые системы стали наиболее популярными? Какие из их числа наиболее надежны? В этой статье я воспользуюсь результатами обратной связи с пользователями и информацией от development команд ReiserFS, ext3 и XFS.

Что можно сказать об XFS?

За прошедшие несколько месяцев XFS стала самой популярной файловой системой для Linux. Такой вывод следует из обратной связи с пользователями Gentoo Linux. Тенденция выбора в пользу XFS сложилась из-за ее хороших рабочих характеристик. Однако, в релизах 1.0.x XFS страдала одной серьезной проблемой. Давайте повторимся. "Metadata only" журналируемые файловые системы, которыми являются XFS и ReiserFS, допускают нарушение целостности самих данных. Такое происходит когда метаданные о файле модифицируются перед непредвиденным обстоятельством (аварийным отказом). Но, если у ReiserFS попавший под разрушение файл будет содержать старые (а при некоторых обстоятельствах "мусорные") блоки данных, то в случае с XFS блоки заполняются двоичными нулями. Было замечено, что XFS 1.0.x имеет плохую тенденцию обнулять слишком много модифицируемых файлов при зависании сервера или нарушении электропитания. Те, кто использовал XFS на надежном сервере с источником бесперебойного питания, чуствовали себя прекрасно. У тех, кто устанавливал XFS на системе с низкой стабильностью из за программных или аппаратных проблем, возникал большой риск накопления потерянных данных.

К счастью, разработчики SGI XFS существенно снизили такую тенденцию в релизе 1.1 XFS. Проблема проявлялась более заметно в XFS 1.0 по причине того, что слишком многие виды модификаций метаданных требовали журналирования строго в порядке их следования. Такие in-order metadata updates, еще называемые "синхронными" модификациями, оказывают эффект форсированной записи всех предшествующих (отложенных) модификаций. Здесь и возникала проблема. Вынужденно ранняя запись метаданных на диск (а за каждой такой операцией стоят свои блоки с данными) приводил к накапливанию блоков, которые ожидали свою запись на диск еще около 30 секунд после обновления метаданных о них. То есть, создавалось относительно большое окно для возможной утери данных.

Техническое примечание.

В релизе 1.1 XFS метаданные файловой системы модифицируются синхронно только в двух случаях:

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

К счастью, подавляющее большинство операций обычного сервера асинхронны по своей природе.

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

Эта проблема особенно неприятна в ситуациях, когда файлы регулярно переписываются "поверх" новыми данными. В таком случае раннее сбрасывание метаданных на диск создает большое окно, что может привести к потере содержимого всего файла при зависании системы в неудачное время. Именно такой сценарий сработал некоторое время назад на сервере gentoo.org. Так как наше mailman mailing list software каждые несколько минут переписывало поверх собственный конфигурационный файл, оно и стало главным кандидатом в жертвы описанному сценарию.

Вывод из ситуации следующий: парни из SGI существенно улучшили ситуацию в релизе 1.1 XFS. Если вы имеете 1.0 XFS, то должны в самое ближайшее время спланировать переход на XFS 1.1. В XFS 1.1 сделано множество и других исправлений. Как только в SGI уменьшили зависимость XFS от синхронных модификаций это оказало положительный эффект на "неудобную" в XFS 1.0.x операцию удаления файлов. Yay!

Что в ближайшей перспективе? Мы можем ожидать выхода нового релиза XFS, который лучше адаптирован под платформу Itanium (Intel). Сейчас XFS для Linux требует, чтобы у XFS размер блока файловой системы точно совпадал с размером страницы оперативной памяти платформы. Становится невозможным просто взять и переставить диск из системы x86 на Itanium, так как в Itanium размер страницы 64 K, а на x86 аппаратно поддержана страница 4 K. Размер файлового блока в 64 K близок к оптимальному значению для многих задач и используется на Itanium системах. Когда проблема жесткой привязки размеров блока и страницы будет решена, это не только облегчит перенос дисков с файловой системой XFS между платформами x86 и ia64, но и даст дополнительные удобства системным администраторам в выборе наиболее оптимального размера блока для решаемых задач.

ReiserFS

Файловая система ReiserFS, возможно, наиболее честолюбивый проект развития журналируемых файловых систем. Это не портирование существующей файловой системы на Linux ядро (подобно XFS, JFS) и не развитие уже существующей файловой системы, как ext3. Нет, ReiserFS стартовала с пустого места и гордится некоторыми впечатляющими показателями качества, скажем, обработкой маленьких файлов. Но, а как показала себя ReiserFS в терминах стабильности и наличия ошибок после ее переноса на ядра серии 2.4?

С самого начала ReiserFS имела необычно много проблем с разрушениями и стабильностью. Имеется несколько ядер, которые стали полным кошмаром для пользователей ReiserFS, включая 2.4.3, 2.4.9 и даже относительно недавнее 2.4.16. В то время как некоторые из этих проблем были вызваны ошибками непосредственно в коде файловой системы ReiserFS, имелись нежелательные побочные эффекты, вызываемые изменениями в других частях ядра. Одна неприятная вещь в процессе развития Linux ядра заключается в том, что независимо от того, насколько тщательно проверен ваш собственный код, возможны такие изменения у другого разработчика, которые приведут к ломке вашего кода. Слишком часто нежелательные побочные эффекты выявляются уже после того, как вышел релиз для неподозревающей Linux публики. Следует сказать, что немало пользователей ReiserFS были приведены в уныние такой ситуацией.

Но имеются и хорошие новости. За последние несколько месяцев ReiserFS стала смотреться намного лучше. Одной причиной стала стабилизация kernel sources после релиза 2.4.17. Кроме того, парни из Namesys (разработчики ReiserFS) устранили несколько неявных ошибок в своем коде. Как результат, сложилось мнение, что ядро 2.4.18 имеет очень твердую ReiserFS реализацию. А ведь 2.4.18 это не весенний цыпленок [spring chicken] - во время написания этой статьи на протяжении почти 3 месяцев так и небыло найдено существенных проблем. Фактически, из-за прекращения потока сообщений об ошибках, Namesys переорентировали Release Manager на новые задания по улучшению производительности ReiserFS.

Очень похоже, что ReiserFS и ядро 2.4 "разрулили" свои противоречия. Лично для меня это хорошая новость. Имею желание вновь начать использовать ReiserFS в качестве корневой файловой системы, как только придет время переустановки моей development workstation. Я уверен, что имеются много других экс-ReiserFS-пользователей, которые вернутся обратно, так как пришло спокойствие на "ядерную землю". И в самом деле, трудна жизнь без ReiserFS когда уже знаешь, как благоприятно влияет на некоторые приложения увеличение performance на маленьких файлах.

А что мы можем ожидать от ReiserFS в ближайшем будущем? Согласно Hans Reiser и его команды, на очереди некоторые очень хорошие усовершенствования, намеченые к выходу ядра 2.4.20_pre1. Следует выделить data journaling от Chris Mason (аналог режима "data=journal" в ext3) и новый код ассигнования блоков, который лучше масштабируется и немного повышает peformance на большых файлах (до 15 % на операциях чтения с IDE дисков). Кроме этих ближайших и существенных изменений мы, вероятно увидим, что ReiserFS поддерживает эквивалент режима "data=ordered" из ext3. То есть, ReiserFS предлагает эквивалент режима data integrity, реализованного в файловой системе ext3. Я очень счастлив видить, что команда разработчиков ReiserFS придает такой высокий приоритет проблеме целостности данных (а не только метаданных).

Ext3

А что относительно ext3? В общем, ext3 характеризуется как устойчивая и не страдающая серьезными проблемами файловая система. У некоторых она может вызывать "раздражение", поскольку не имеет никаких серьезных усовершенствований по сравнению с ext2, за исключением хорошей реализации журналирования. Подобное "раздражение" в мире файловых систем скорее плюс. Это значит, что файловая система выполняет свои функции без суеты и инцидентов. Кроме того, несмотря на меньшую "продвинутость" ext3 (по отношению к ResierFS, XFS и JFS), она достаточно быстра и имеет хорошие настройки для типичных файловых операций большинства серверов и рабочих станций. Ясно, что разработчики ext3 имели целью создание высококачественной журналируемой системы, на которую Linux пользователи могут смело переходить.

На ядре 2.4.19_pre5 синхронное монтирование ext3 и "chattr +S" файлов стало происходить приблизительно в десять раз быстрее. В самом ближайшем будущем ожидается добавление опции для синхронных модификаций в целых деревьях каталогов, что непременно найдет использование в почтовых программах. Следует ожидать исправлений мелких ошибок и повышения производительности. И ничего мажорного. Код ext3 уже совершенен и находится в эксплуатационном режиме.

Благодарю за чтение этой статьи и приглашаю к знакомству с JFS!

Resources

About the author

author Residing in Albuquerque, New Mexico, Daniel Robbins is the President/CEO of Gentoo Technologies, Inc., and the creator of Gentoo Linux, an advanced Linux for the PC, and the Portage system, a next-generation ports system for Linux. He has also served as a contributing author for the Macmillan books Caldera OpenLinux Unleashed, SuSE Linux Unleashed, and Samba Unleashed. Daniel has been involved with computers in some fashion since the second grade, when he was first exposed to the Logo programming language as well as a potentially dangerous dose of Pac Man. This probably explains why he has since served as a Lead Graphic Artist at SONY Electronic Publishing/Psygnosis. Daniel enjoys spending time with his wife, Mary, and his new baby daughter, Hadassah. You can contact Daniel at drobbins@gentoo.org.
Оставьте свой комментарий !

Ваше имя:
Комментарий:
Оба поля являются обязательными

 Автор  Комментарий к данной статье