Zenbook. Инициализация системы

Автор: Алексей Федорчук

После завершения загрузки ядра, обеспечением которой мы занимались в прошлой главе, наступает время инициализации системы. Она начинается запуском процесса init, что осуществляется исполнением одноименного файла /sbin/init. Рассмотрим его штатные задачи.

Первой из таких задач, как по времени исполнения, так и по значению, является проверка целостности наличных файловых систем. Для начала каждая из них проверяется на наличие бита «чистого размонтирования» (clean byte), который автоматически устанавливается в ходе правильного завершения предыдущего сеанса работы. Если такой бит обнаруживается на каждой файловой системе — все хорошо, дело движется дальше. Если нет — запускается принудительная проверка некорректно размонтированной файловой системы.

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

А следующая задача процесса init — это вызов и отработка сценариев инициализации, или стартовых скриптов, собранных в каталоге /etc и его подкаталогах. Это обычные сценарии оболочки, рассчитанные на исполнение стандартным шеллом (в Linux — /bin/bash). Они включают в себя последовательности команд, призванные монтировать файловые системы, активизировать область своппинга, устанавливать системные часы, запускать те или иные службы и демоны, включая сетевые соединения.

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

Например, обязательная процедура на стадии отработки сценариев инициализации — монтирование (и перемонтирование) необходимых файловых систем в режиме чтения/записи — ведь, как мы помним из предыдущей главы, при загрузке ядра несущая его корневая файловая система монтируется в режиме «только для чтения». Это выполняется прямой директивой

# /sbin/mount -a

предписывающей смонтировать все файловые системы, и входящей в состав одного из стартовых сценариев. В какой именно — зависит от системы, и со временем мы разберёмся, где она находится в нашем случае). А вот что понимается под словом «все» (имя опции -a — от all) — то есть список аргументов (устройств и точек монтирования), а также опций, с которыми должна быть смонтирована та или иная файловая система, — и составляет содержание конфигурационного файла /etc/fstab.

Это — очень простая база данных, каждая запись которой соответствует подлежащей монтированию файловой системе, а поля, разделителем которых являются символы пробела (пробелов) или табуляции, следующие:

  • имя файла устройства, несущего файловую систему;
  • точка монтирования — каталог в файловой иерархии;
  • тип файловой системы;
  • опции монтирования (часто имеет значение default).

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

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

Наконец, третья непременная задача процесса init — обеспечение регистрации пользователя в системе, каковая также может осуществляться различными способами: в текстовой консоли или через графические менеджеры сеансов.

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

Ошибки при отработке скриптов инициализации обычно приводят к тому, что сервис, при выполнении сценария запуска которого произошёл сбой, просто не будет доступным после загрузки системы.

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

Впрочем, оснований для паники нет ни в одном из указанных случаев — даже при впадении в панику ядра. Все возможные при инициализации системы ошибки исправимы тем или иным способом. Ибо легкий флирт, в том числе и с операционной системой, подобно насморку, переносится на ногах, и постельный режим необходим лишь в тяжелых случаях. В одних ситуациях достаточно завершить процесс загрузки и чуть  изменить настройки, в других — загрузиться в однопользовательском режиме, в третьих придется грузиться с rescue-носителя (например, LiveCD). А вот хирургического вмешательства, сиречь полной переустановки системы, скорее всего, не потребуется никогда.

Оборотная сторона инициализации системы — это ее останов или рестарт, различий между этими процессами практически нет. И отвечает за него команда shutdown, которая может быть дана от лица суперпользователя или члена группы operator. С опцией -h она вызывает останов машины, с опцией -r — ее перезагрузку. И еще команде этой требуется аргумент — время, когда останов или рестарт должны произойти. Впрочем, есть способ и мгновенного останова или рестарта:

# shutdown -h now

или

# shutdown -r now

соответственно. Именно последняя команда отрабатывается при перезагрузке машины с клавиатуры посредством «Салюта из трёх пальцев», по выражению Патрика Фолькердинга.

Кроме того, существуют также команды halt и reboot того же назначения. Однако самостоятельной роли они не играют, просто вызывая команду shutdown с опцией останова и перезагрузки, соответственно.

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

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

На протяжении многих лет одним из первых правил техники безопасности был запрет останавливать простым отключением питания. И действительно, до недавнего времени это было чревато разными неприятностями.

Однако в современном ядре Linux реализована поддержка управления питанием стандарта ACPI (Advanced Configuration and Power Interface). Она делает допустим останов системы простым отключением питания машины — на нажатие кнопки Power на корпусе компьютера (но ни в коем случае не на переключение тумблера блока питания или выдёргивание силового кабеля) система реагирует точно так же, как и на команду shutdown -h now. В частности, в Zenwalk’е эта процедура выполняется абсолютно безболезненно. Разумеется, на мало-мальски современном «железе».

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

Вызов определённого runlevel, то есть такой взаимосвязанной группы сценариев, осуществляется при инициализации системы программой /sbin/init. А сами эти группы описаны в главном её конфигурационном файле — /etc/inittab, описывающем весь ход процесса init — от проверки файловых систем до подготовки к регистрации.

Теоретически процесс init предусматривает вызов семи runlevels — от нулевого до шестого, хотя, кажется, ни в одном дистрибутиве они не задействуются все. За тремя из них зафиксированы группы сценариев определенного назначения:

  • 0 — halt, то есть останов системы;
  • 1 — single user mode, сиречь однопользовательский режим;
  • 6 — reboot (перезагрузка системы).

Использование остальных отдано на откуп создателям дистрибутивов. В чём мы сейчас и убедимся на примере нашего героя, дистрибутива Zenwalk. Для чего внимательно рассмотрим устройство его файла /etc/inittab.

В нем после всякого рода копирайтов для начала перечисляются все runlevels и поясняется их значение для дистрибутива  Slackware, поскольку в Zenwalk’е, его прямом потомке, они отличаются лишь в деталях. Так что вот на этих деталях мы и заострим внимание:

  • 0 = останов системы;
  • 1 = однопользовательский режим;
  • 2 = не используется, но сконфигурирован аналогично runlevel 3;
  • 3 = многопользовательский текстовый режим;
  • 4 = многопользовательский графический режим с авторизацией через менеджер сессий GDM;
  • 5 = не используется, но сконфигурирован аналогично runlevel 3;
  • 6 = перезагрузка системы.

Все эти строки закрыты комментариями, то есть приводятся только для справки. А теперь начинаются строки, собственно и определяющие конфигурацию. Формат любой из строк в /etc/inittab следующий:

идентификатор:runlevel:действие:запускаемый процесс

Не во всех строках значения присвоены каждому полю.

Для начала определяется runlevels по умолчанию. В Zenwalk’е, в отличие от Slackware, «умолчальным» уровнем по умолчанию является 4-й, что описывается такой строкой:

id:4:initdefault:

Если необходимо перейти на загрузку в текстовом режиме (это может случиться при сбоях графической системы), её следует заменить строкой

id:3:initdefault:

Далее следует серия строк, описывающих, какие сценарии должны запускаться при каждом из задействованных runlevels и некоторых других событиях, как то:

  • старте системы (выполняется в любом случае, независимо от runlevel по умолчанию);
  • загрузке в однопользовательском режиме или переходе в него из любого многопользовательского;
  • загрузке в любом из многопользовательских режимов;
  • «комбинации из трёх пальцев» (Three Finger Salute, по выражению Патрика Фолькрдинга);
  • обычном останове системы;
  • обычной программной перезагрузке;
  • аварийном отключении питания;
  • восстановлении  питания после сбоя.

Сами по себе сценарии эти мы рассмотрим в одной из последующих глав, посвящённых собственно настройке системы, тем более, что здесь менять, скорее всего, ничего не придётся.

А пока, слову скажу, что переход с одного runlevels на другой осуществляется командой

# /sbin/init #

где # — требуемый runlevel. Например:

# /sbin/init  0

вызовет останов системы, аналогично команде

# shutdown -h now

команда

# /sbin/init 6

её перезагрузку, как при команде

# shutdown -r now

а команда

# /sbin/init 1

переход в однопользовательский режим — ситуация, к которой на практике иногда приходится прибегать. Впрочем, это не какая-то особенность Zenwalk’а, а общее свойство всех Linux-систем.

Далее идут строки, описывающие виртуальные терминалы, доступные по завершению инициализации:

c1:1235:respawn:/sbin/agetty 38400 tty1 linux
c2:12345:respawn:/sbin/agetty 38400 tty2 linux
c3:12345:respawn:/sbin/agetty 38400 tty3 linux
c4:12345:respawn:/sbin/agetty 38400 tty4 linux
c5:12345:respawn:/sbin/agetty 38400 tty5 linux
c6:12345:respawn:/sbin/agetty 38400 tty6 linux

Таковых по умолчанию как бы шесть. Почему «как бы» — сейчас увидим: в поле runlevels всех строк перечислены все доступные пользователям уровни, и лишь в первой из них пропущен runlevel 4. А ведь именно он является умолчальным в Zenwalk’е. Это вызвано тем, что первый виртуальный терминал зарезервирован для запуска X-сервера и менеджера сессий. Так что в обычной жизни пользователю доступны только 5 виртуальных терминалов.

Впрочем, поскольку Zenwalk  ориентирован на работу в графическом режиме, этого вполне достаточно. Более того, число виртуальных терминалов можно и сократить: для этого достаточно закрыть комментариями соответствующие строки.

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

Еще обратим внимание на поле действия: значение respawn, что означает автоматический перезапуск процесса в случае его завершения. То есть: по завершении сеанса пользователя на любой консоли тут же появляется приглашение в авторизации.

Далее идёт несколько закрытых комментариями строк, посвященных терминальному доступу по COM-порту и модему (к модемному выходу в Интернет это не имеет ни малейшего отношения). Нас они не интересуют.

Последняя строка определяет сценарий при запуске графического режима:

x1:45:respawn:/etc/rc.d/rc.4

Можно видеть, что он приурочен к уровням 4 и 5, и также влечёт «самовосстановление» по завершении сеанса.

На этом рассмотрение инициализации системы можно считать законченным. Если чего упустил — буду признателен на указание пробелов. Добавлю только, что этот вопрос подробно освещён в статье Владмира Попова Init et cetera или О стилях загрузки Linux. Дата её смущать не должна — ничего принципиально нового в дистрибутивах, не использующих upstart или initng, не изменилось.


[Назад] [Главная] [Вперёд]