SYSV init RedHat.

© Alec Voropay, FDL

    Довольно часто задаваемый вопрос : Каким образом стартует система ? Где в Linux аналог autoexec.bat ?

    Чтобы понять, как стартует система, сначала необходимо понять идею RunLevel-а.

    Для нетерпеливых - быстрый ответ.


RunLevel.

    Как написано в man init : RunLevel - это "особая конфигурация системы, при которой существуют только определенные группы процессов". Существуют RunLevel-ы от "0" до "6" и особый RunLevel "S" (single user).

    Итак, для RedHat :

    Идея RunLevel-ов пошла из системы UNIX System V и POSIX и поэтому Linux-ы (и RedHat в том числе) используют именно SYSV init. В других системах (например *BSD) используются совершенно другие понятия и процесс старта/останова системы совсем другой.

    ПРИМЕЧАНИЕ : Такая раскладка по RunLevel-ам принята именно в RedHat Linux. В других дистрибутивах может быть принята другая схема.

    ПРИМЕЧАНИЕ : В данном тексте совершенно не рассматривается вопрос, как стартует само ядро Linux (MBR, LILO/GRUB, init-rd и так далее). Считается, что ядро "как-то" загрузилось и взлетело. ;)


SYSV init.

    Процесс init - совершенно особый процесс в любой системе UNIX. Во-первых, он всегда имеет PID=1. Во-вторых, он не имеет предков и порождается совершенно "чудесным" образом прямо после старта ядра UNIX. В третьих, init - это "папа", "дедушка" или "пра-пра-дедушка" всех процессов в системе.

    Эти правила общие для любой системы UNIX, мы же будем рассматривать только SYSV init.

    Сразу после старта init читает файл /etc/inittab. Нас заинтересуют следующие строки :

id:3:initdefault:

l3:3:wait:/etc/rc.d/rc 3

    Это означает, что RunLevel по умолчанию будет 3, и для запуска его необходимо выполнить исполняемый файл /etc/rc.d/rc   с параметром "3". А если необходимо, чтобы система стартовала прямо в X-ах, можно поменять RunLevel на "5".

    В любой момент можно сменить текущий RunLevel, для этого просто нужно дать команду "init 3" или например "init 6". При каждой смене Run-Level-а исполняется файл /etc/rc.d/rc 3 (или 6).

    Файл /etc/rc.d/rc довольно интересен. Он показывает всю мощь языка shell. Ключевые строки в нем следующие :

for i in /etc/rc.d/rc$runlevel.d/K*; do
   $i stop
done

for i in /etc/rc.d/rc$runlevel.d/S*; do
   $i start
done

    Надеюсь, все понятно ? ;-) См. быстрый ответ. Но сначала рассмотрим, что такое "подсистемы".

    ПРИМЕЧАНИЕ : На самом деле можно запустить совершенно любую программу вместо init :
LILO: linux init=/bin/bash
#

Кто там спрашивал, как сломать Linux ? ;) (не забудьте mount -n -o rw,remount / )
[используйте пароль на GRUB или LILO]


Подсистемы.

    В системе RedHat все демоны (группы процессов) разделены на "подсистемы". Например sendmail, или named. Файлы для запуска "подсистем" живут в /etc/rc.d/init.d/*

    Так что если вы хотите правильно, "по-RedHat-овски" запустить или остановить какой-нибудь демон, действовать надо так :

[root@on ~]# /etc/rc.d/init.d/sendmail start
[root@on ~]# /etc/rc.d/init.d/sendmail stop

    Для облегчения жизни существует команда service :

[root@on ~]# service sendmail start
[root@on ~]# service sendmail stop

    Или проще, для перезапуска "подсистемы" :

[root@on ~]# service sendmail restart

    Кроме того, в любой момент можно узнать статус "подсистемы" :

[root@on ~]# service sendmail status
sendmail (pid 186) is running...

    Все запущенные "подсистемы" регистрируются в /var/lock/subsys/

   Документация в /usr/share/doc/initscripts/sysvinitfiles или тут.


Итого.

    В RedHat для быстрого управления RunLevel-ами существует специальная утилита : ntsysv. С ее помощью можно быстро "включать" и "отключать" различные подсистемы на разных уровнях. По умолчанию, она работает с текущим  RunLevel-ом.

    Более простая, но более широко распространенная утилита : chkconfig. Однако, только chkconfig умеет "регистрировать" новые подсистемы с помощью ключей --add --del. См. man chkconfig. Под X Window  существует утилита аналогичного назначения: tksysv.

    Чтобы понять, как это все работает на "низком уровне", заглянем в каталог /etc/rc.d/rc3.d/

[root@on ~]# cd /etc/rc.d/rc3.d/
[root@on rc3.d]# ls -l
lrwxrwxrwx 1 root root 16 Feb 7 19:30 K20rstatd -> ../init.d/rstatd
lrwxrwxrwx 1 root root 17 Feb 7 19:30 K20rusersd -> ../init.d/rusersd
lrwxrwxrwx 1 root root 15 Feb 7 19:30 K20rwhod -> ../init.d/rwhod
lrwxrwxrwx 1 root root 15 Feb 8 16:48 K45named -> ../init.d/named
lrwxrwxrwx 1 root root 16 Feb 7 19:29 K55routed -> ../init.d/routed
lrwxrwxrwx 1 root root 17 Feb 7 19:19 S10network -> ../init.d/network
lrwxrwxrwx 1 root root 16 Feb 7 19:19 S20random -> ../init.d/random
lrwxrwxrwx 1 root root 16 Feb 7 19:19 S30syslog -> ../init.d/syslog
lrwxrwxrwx 1 root root 13 Feb 7 19:20 S40atd -> ../init.d/atd
lrwxrwxrwx 1 root root 15 Feb 7 19:19 S40crond -> ../init.d/crond
lrwxrwxrwx 1 root root 14 Feb 7 19:27 S50inet -> ../init.d/inet
lrwxrwxrwx 1 root root 15 Feb 8 17:00 S55named -> ../init.d/named
lrwxrwxrwx 1 root root 18 Feb 7 19:19 S75keytable -> ../init.d/keytable
lrwxrwxrwx 1 root root 18 Feb 7 19:30 S80sendmail -> ../init.d/sendmail
lrwxrwxrwx 1 root root 13 Feb 7 19:24 S85gpm -> ../init.d/gpm
lrwxrwxrwx 1 root root 13 Feb 7 19:19 S90xfs -> ../init.d/xfs
lrwxrwxrwx 1 root root 19 Feb 7 19:26 S99linuxconf -> ../init.d/linuxconf
lrwxrwxrwx 1 root root 11 Feb 7 19:19 S99local -> ../rc.local

    Опять выполняется правило, общее для RedHat - Все живет на symlink-ах !

    Как мы выяснили ранее, выполнение скрипта  /etc/rc.d/rc 3 вызовет : для всех symlink-ов с буквой "К" вызов подсистем с параметром 'stop', а для symlink-ов с буквой "S" -- подсистем с параметром "start".

    А цифры служат для лишь для указания порядка выполнения скриптов. (А на самом деле, работает просто звездочка * из shell).

    Как несложно догадаться, RunLevel 6 /etc/rc.d/rc6.d/ (останов системы) состоит практически из одних "K*" (то есть, убивает все процессы).


Зачем все это ?

    Довольно часто задают вопрос : зачем это все так сложно ?

    Ответ обескураживает - Для простоты !

    Дело в том, что при таком раскладе можно очень просто администрировать, какие подсистемы и в каком порядке будут запущены и остановлены на каком RunLevel-е.

    Действительно, нужно лишь поставить нужный symlink, не изменяя и не редактируя никаких файлов. (Вообще говоря, утилита ntsysv именно это и делает. Только не забудьте "зарегистрировать" подсистему через chkconfig --add service).

    Например, чтобы "вручную" добиться автоматического запуска на RunLevel 3 подсистемы sshd нужно лишь поставить symlink :

/etc/rc.d/rc3.d/S75sshd --> ../init.d/sshd

    Причем, мы можем точно контролировать, когда (после каких подсистем) он запустится. Да, а на RunLevel 6 (/etc/rc.d/rc6.d/) надо не забыть поставить K25sshd.

    Однако удалять synlink-и вручную нет необходимости, поскольку с помощью утилит делать это проще и кроме того, сохраняется связность скриптов Start/Kill.

    Управлять порядком запуска/останова "подсистем" можно через ключевое слово # chkconfig: 235 94 06 в .init файлах. См. документацию тут.


Last change : 19-11-2003