Init

Материал из Wiki Open book
Перейти к: навигация, поиск

Оглавление | Система инициализации

Содержание

Программа init

Как уже говорилось, самым первым процессом является программа init. И от того, каким образом она сконфигурирована, зависит дальнейшая загрузка системы.

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

Процесс запуска init каждый, кто знаком с языком программирования C, может посмотреть в исходных кодах ядра, в файле init/main.c, для остальных (а также просто ленивых) скажу, что:

  • когда наступает время породить первый процесс, то первым делом ядро пытается запустить программу, указанную опцией rdinit=;
  • если таковой опции ядру передано не было, то будет запущен /init;
  • если ничего не вышло с /init, то ядро пытается запустить программу, указанную опцией init=;
  • если это не получилось, то ядро пытается запустить /sbin/init;
  • если возникли проблемы с /sbin/init, то ядро пытается запустить /etc/init;
  • если не удалось запустить /etc/init, то ядро пытается запустить /bin/init;
  • если невозможно запустить /bin/init, то ядро пытается запустить /bin/sh;
  • ну а если даже и /bin/sh подвёл, то ядро паникует с сообщением
No init found.  Try passing init= option to kernel.
Внимание! Никогда не выносите в отдельный раздел директории /bin, /sbin, /etc, /dev. Файлы находящиеся в них могут потребоваться при старте системы. Ярким примером являются программа init и ее конфигурационный файл /etc/inittab.

Уровни выполнения

В Linux существует такое понятие как уровень выполнения (run level). Уровень выполнения обозначается числами от 0 до 9.

Система в определенный момент времени находится на соответствующем уровне выполнения. Вы, как администратор системы можете переводить ее с одного уровня выполнения на другой. Это делается при помощи программы init (или telinit). Для этого программе в качестве аргумента передается число соответствующее уровню выполнения. Например, что бы перевести систему на 3-й уровень выполнения, необходимо запустить init следующим образом:

init 3

В различных дистрибутивах Linux уровни выполнения используются для различных целей.

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

  • 0 — выполняются действия по выключению системы.
  • 1 — однопользовательский режим (single user mode). Предназначен для различных административных действий по восстановлению системы. По своему смыслу аналогичен Safe Mode Windows, но полностью его не повторяет. На этом уровне выполнения система полностью сконфигурирована, но не запущен ни один сервис, а из пользователей может работать только один root.
  • 2 — не используется, но сконфигурирован как уровень выполнения 3. В RedHat и SuSE Linux, сконфигурирован, как уровень выполнения 3, но без поддержки сетевых файловых систем. В Debian используется как многопользовательский режим.
  • 3 — многопользовательский режим (multiuser mode). Нормальный режим работы сервера.
  • 4 — В Slackware Linux используется для графического входа в систему. В RedHat и SuSE Linux не сконфигурирован.
  • 5 — В RedHat и SuSE Linux используется для графического входа в систему. В Slackware Linux не сконфигурирован.
  • 6 — выполняются действия по перезагрузке системы.

Суперпользователь может остановить систему, переведя её на нулевой уровень:

init 0

Или перегрузить систему:

init 6

Формат файла /etc/inittab

Конфигурационный файл программы init — это текстовый файл. Символ комментария — #. Файл состоит из строк следующего формата:

id:run_level:action:process
  • id — идентификатор, один или два символа. Поле должно быть уникальным. Никак не влияет на работу современной версии программы init.
  • run_level — список уровней выполнения, на которых будет выполняться программа. Поле может быть пустым.
  • action — определяет особенности выполнения программы. В этом поле можно писать только заранее определенные слова.
  • process — программа, которая будет выполняться.

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

init 3

Программа начнет выполнять только те строки, в поле run_level которых будет присутствовать цифра 3. То есть, будут запускаться программы, описанные в поле process, но с некоторыми оговорками, определяемые полем action.

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

Давайте рассмотрим конфигурационный файл inittab на примере дистрибутива Slackware Linux. Ниже показано содержимое этого файла, за исключением комментариев и пустых строк.

id:3:initdefault:
si:S:sysinit:/etc/rc.d/rc.S
su:1S:wait:/etc/rc.d/rc.K
rc:2345:wait:/etc/rc.d/rc.M
ca::ctrlaltdel:/sbin/shutdown -t5 -r now
l0:0:wait:/etc/rc.d/rc.0
l6:6:wait:/etc/rc.d/rc.6
pf::powerfail:/sbin/genpowerfail start
pg::powerokwait:/sbin/genpowerfail stop
c1:1235:respawn:/sbin/agetty 38400 tty1 linux
c2:1235:respawn:/sbin/agetty 38400 tty2 linux
c3:1235:respawn:/sbin/agetty 38400 tty3 linux
c4:1235:respawn:/sbin/agetty 38400 tty4 linux
c5:1235:respawn:/sbin/agetty 38400 tty5 linux
c6:12345:respawn:/sbin/agetty 38400 tty6 linux
x1:4:wait:/etc/rc.d/rc.4

При старте системы ядро запускает программу init без указания уровня выполнения. То есть, просто

init

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

id:3:initdefault:

Это первое исключение из общего правила. Как видите поле process пустое. В поле action написано ключевое слово initdefault, которое означает, что в поле run_level написан уровень выполнения используемый по умолчанию.

Дальше мы будем рассматривать файл с учетом того, что система стартует на третьем уровне выполнения.

В следующей строке нас ждет сразу два исключения из общего правила!

si:S:sysinit:/etc/rc.d/rc.S

Во первых, в поле run_level стоит буква S, да и action sysinit, не просто так тут написана.

Начнем с буквы S. Когда ядру при загрузке передается параметр single, ядро запускает программу init таким образом, что она перестает реагировать на все строки, кроме тех, в поле run_level которых стоит буква S. Обычно дистрибутивы сконфигурированы таким образом, что бы в этом случае система запускалась на уровне выполнения 1 (single user mode).

Действие sysinit означает, что программа, описанная в поле process будет выполняться только при старте системы, и init будет ожидать ее завершения, прежде чем начнет выполнять следующие строки. Таким образом, программа /etc/rc.d/rc.S будет выполняться только при старте системы. При переходе с одного уровня выполнения на другой она запускаться не будет.

su:1S:wait:/etc/rc.d/rc.K

Строка на третьем уровне выполнения работать не будет, мы ее пропустим.

rc:2345:wait:/etc/rc.d/rc.M

В поле run_level присутствует цифра три, поэтому программа /etc/rc.d/rc.M будет запущена. Действие wait означает, что init будет ожидать завершение выполнения программы, прежде, чем начнет выполнять следующие строки из файла inittab. Таким образом, второй при старте системы будет запущена программа rc.M.

ca::ctrlaltdel:/sbin/shutdown -t5 -r now

В поле run_level этой строки нет ни одной цифры, значит она не будет выполняться при старте системы. Как то странно при старте сразу запускать программу shutdown. Но в поле действие присутствует интересный параметр: ctrlaltdel. Он заставляет init следить за нажатием комбинации клавиш Ctrl(левый)+Alt(левый)+Del. И если кто то их нажмет, выполнит программу, указанную в поле process.

Внимание! Обратите внимание на то, что не имеет значения, залогинился пользователь в систему или нет. Любой проходящий мимо человек может нажать эту комбинацию клавиш и система будет перезагружена.
l0:0:wait:/etc/rc.d/rc.0
l6:6:wait:/etc/rc.d/rc.6

Эти две строки никакого отношения к третьему уровню выполнения не имеют, поэтому мы их пропускаем.

pf::powerfail:/sbin/genpowerfail start
pg::powerokwait:/sbin/genpowerfail stop

Поле run_level в этих строках пустое, поэтому при старте системы они работать не будут. Но, init их запомнит. Для того, что бы эти строки заработали, необходимо, что бы у вас был интеллектуальный UPS, подключенный к вашей машине. А так же запущена программа, которая понимает команды UPS (обычно используют программу genpowerd).

Если питание пропадет, то UPS сообщит об этом программе, а та в свою очередь передаст информацию init, который обработает действие powerfail. Если питание восстановится, будет обработано действие powerokwait.

Программа genpowerfail — это обыкновенный скрипт. Если его запустить с параметром start, то будет запущена программа shutdown. В зависимости от состояния UPS, процедура остановки системы будет произведена сразу или с задержкой на одну или две минуты. Если скрипт запустить с параметром stop, то процедура остановки системы будет отменена (shutdown -c).

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

После выполнения программ rc.S и rc.M, init запускает программу agetty. В других дистрибутивах может быть другая версия программы. Например, в SuSE Linux используется mingetty. Задача программы — инициализировать консоль на последовательном устройстве. В нашем случае, инициализируются консоли на виртуальных терминалах с 1-го по 6-й.

Внимание! Обратите внимание на то, что в Slackware Liniux, на 4-м уровне выполнения (графический вход в систему) консоль инициализируется только на 6-м виртуальном терминале.

Согласно действия respawn, init запускает программу и не ожидая ее завершения выполняет следующие строки. Но он не забывает о запущенных программах, он за ними следит. Если программа завершит свою работу — init запускает ее снова. Именно поэтому, после выхода из системы на экране терминала появляется приглашение входа в систему.

x1:4:wait:/etc/rc.d/rc.4

Эта строка будет выполняться только на 4-м уровне выполнения.

Действия

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

initdefault Определяет уровень выполнения по умолчанию во время загрузки системы.
sysinit Программа будет выполняться при запуске системы самой первой. init будет ожидать её завершение, прежде чем начнет выполнение следующих в списке программ.
wait Программа запускается один раз. init будет ожидать ее завершение, прежде чем начнет выполнение следующих в списке программы.
once Программа запускается один раз. init не ждет её завершения.
ctrlaltdel Определяет программу, которая будет запущена при нажатии на клавиши "Ctrl+Alt+Del".
powerfail Определяет программу, которая будет запущена при получении процессом init сигнала сбоя питания.
powerokwait Определяет программу, которая будет запущена при получении процессом init сигнала восстановления питания.
respawn Процесс будет запущен. init не будет ожидать окончания процесса и начнет обрабатывать следующие в списке строки. Если процесс завершит свою работу – init запустит его снова.

Из конфигурационного файла можно сделать вывод, что в Slackware Linux на уровне выполнения 3, init запускает следующие программы:

  • /etc/rc.d/rc.S
  • /etc/rc.d/rc.M
  • /sbin/agetty для каждой виртуальной консоли.

Что делают эти программы описано в разделе Система инициализации Slackware Linux.

Оглавление | Система инициализации

Источник — «http://wiki.kryukov.biz/wiki/Init»
Инструменты
    
Личные инструменты