| |
![]() |
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. В следующей статье будут описаны некоторые
достаточно сложные изменения в Linux системе. Почему это необходимо? Мы сделаем
все, кроме enabling devfs функционирования ядра (последний шаг самый простой).
До этого мы инсталлируем devfsd
(device management daemon)
в специальном режиме так, чтобы он поддержал возможность отката и восстановления
любых изменений в device permissions и ownership. Требуется немного изловчиться,
чтобы получить хорошо функционирующую новую систему. Как только это произойдет,
вы будете очень довольны результатом.
Первый шаг в переходе на 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,
также должна быть заблокирована.
Находясь в секции 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
(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 теперь инсталлирован,
но не в рабочем состоянии (именно то, что на данный момент и требуется).
Примечание по конфигурации.
Мы будем конфигурировать |
Теперь пришло время скомпилировать и инсталлировать ядро (которое ранее было сконфигурировано). Это ядро должно подменить ваше текущее. Оно должно загрузиться как обычное, хотя и имеет встроенную поддержку 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.
Но возможно ли это?
Одно из возможных решений - добавление специального 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.
About the author![]() Перевод: Владимир Холманов
|