Наши партнеры








Книги по Linux (с отзывами читателей)

Библиотека сайта rus-linux.net

Руководство по "продвинутым" файловым системам, часть 5


Первоисточник : http://www-106.ibm.com/developerworks/library/l-fs5.html


Установка 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.

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.

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