Лекция №25 - Управление демонами

Сегодня мы поговорим о процессах Linux, которые носят называние - демоны, а также посмотрим каким образом происходит управление демонами (или службами, если проводить параллель с Windows). Основное отличие процесса-демона от обычного пользовательского процесса, в том, что демон не имеет управляющего терминала, а соответственно взаимодействовать с ним пользователь может только посредством других программ или управляющих скриптов. Итак, в простейшем случае демон - это исполняемый файл или скрипт, который работает в фоновом режиме. Очень часто такие файлы заканчиваются на букву d (от daemon): sshd, httpd, cupsd - хотя это не обязательно.

Для того чтобы управлять демоном существует управляющий скрипт для каждого демона. Расположены такие скрипты, как правило, в каталоге /etc/init.d/. Именуются такие скрипты так как и сам демон (только без буквы d в конце), хотя это не является незыблемым правилом. Например, скрипт /etc/init.d/ssh управляет демоном sshd, который расположен в каталоге /usr/sbin/.

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

start - запуск демона
stop - останов демона
restart - перезапуск демона
reload - перезагрузка (перечитывание конфигурационных файлов) параметров демона
force-reload - принудительная перезагрузка параметров демона

Если вы сами будете писать подобный управляющий скрипт, то должны помнить, что он должен обрабатывать как минимум два параметра: start и stop. Можете открыть любой скрипт из директории /etc/init.d/ и увидеть, как посредством конструкции case реализована обработка управляющих параметров.

Итак, давайте попробуем остановить и запустить демон cron. Для этого в каталоге /etc/init.d/ находится управляющий скрипт /etc/init.d/cron:

1
2
3
4
5
6
7
8
9
debian:/home/igor# /etc/init.d/cron
Usage: /etc/init.d/cron {start|stop|restart|reload|force-reload}.
debian:/home/igor# /etc/init.d/cron stop
Stopping periodic command scheduler: crond.
debian:/home/igor# ps ax | grep [c]ron
debian:/home/igor# /etc/init.d/cron start
Starting periodic command scheduler: crond.
debian:/home/igor# ps ax | grep [c]ron
 6524 ?        Ss     0:00 /usr/sbin/cron

Если запустить его без параметров (строка 1), то увидим подсказку какие параметры необходимо передавать этому скрипту (строка 2). Пробуем запустить с параметром stop (строка 3) и проверяем, что демон остановлен (строка 5). Затем запускаем демон (строка 6) и проверяем (строка 8). Таким же образом происходит управление другими демонами.

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

В каталоге /etc есть каталоги с именем rcN.d, где N - это символ указывающий на runlevel к которому относится каталог. То есть имеем такие каталоги: rc0.d, rc1.d, rc2.d, rc3.d, rc4.d, rc5.d, rc6.d и rcS.d. Если посмотреть содержимое каталогов, то можно увидеть, что в них содержатся символические линки на скрипты из каталога /etc/init.d/:

1
2
3
4
5
6
7
8
9
10
11
12
debian:/home/igor# ls -l /etc/rc6.d/
lrwxrwxrwx 1 root root  13 2008-09-05 17:20 K01gdm -> ../init.d/gdm
lrwxrwxrwx 1 root root  17 2009-02-23 16:09 K09apache2 -> ../init.d/apache2
lrwxrwxrwx 1 root root  17 2008-09-05 16:48 K11anacron -> ../init.d/anacron
lrwxrwxrwx 1 root root  13 2008-09-05 17:08 K11atd -> ../init.d/atd
lrwxrwxrwx 1 root root  14 2008-09-05 14:44 K11cron -> ../init.d/cron
lrwxrwxrwx 1 root root  15 2008-09-05 17:18 K19hplip -> ../init.d/hplip
...
...
lrwxrwxrwx 1 root root  18 2008-09-05 14:43 S40umountfs -> ../init.d/umountfs
lrwxrwxrwx 1 root root  20 2008-09-05 14:43 S60umountroot -> ../init.d/umountroot
lrwxrwxrwx 1 root root  16 2008-09-05 14:43 S90reboot -> ../init.d/reboot

Символические линки именуются в соответствии со следующим правилом: сначала идет латинская большая буква S или K, затем двузначное число и после этого точное называние скрипта на который ссылается символический линк. Буква K в имени линка означает, что скрипт на который он ссылается должен быть выполнен с параметром stop. То есть K11cron (строка 6) означает, что будет выполнена команда /etc/init.d/cron stop. То есть будет остановлен демон cron. Соответственно буква S означает, что скрипт на который указывает линк должен выполнится с параметром start. Двузначное число определяет порядок выполнения скриптов, а соответственно порядок запуска или завершения демонов. Первыми запускаются скрипты с меньшими номерами. Таким образом реализуется разрешение зависимостей скриптов (демонов). Например, демон cron должен быть остановлен только после того как будет остановлен демон apache2 (строки 6 и 3). Если у символических линков одинаковый номер, то это означает, что демоны не зависят друг от друга и скрипты могут выполняться в любом порядке. Также нужно отметить, что сначала выполняются все скрипты с буквой K, а затем только все скрипты с буквой S.

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

1
2
3
4
5
6
7
l0:0:wait:/etc/init.d/rc 0
l1:1:wait:/etc/init.d/rc 1
l2:2:wait:/etc/init.d/rc 2
l3:3:wait:/etc/init.d/rc 3
l4:4:wait:/etc/init.d/rc 4
l5:5:wait:/etc/init.d/rc 5
l6:6:wait:/etc/init.d/rc 6

Когда системы переходит на какой либо runlevel, например, на шестой, то выполняется скрипт /etc/init.d/rc, которому в качестве параметра передается номер уровня запуска - 6. В результате своей работы скрипт /etc/init.d/rc начинает выполнять в соответствии с вышеописанными правилами все скрипты на которые есть символические ссылки в каталоге /etc/rc6.d/. Если упрощенно, то имя каждого символического линка преобразуется из вида K01gdm в /etc/init.d/gdm stop, а S10sysklogd в /etc/init.d/sysklogd start.

Таким образом если вы хотите, чтобы какой-то демон запускался (или останавливался) на нужном вам уровне вам нужно создать соответствующий символический линк в соответствующем каталоге /etc/rcN.d/. Например, если вы не хотите, чтобы демон cron запускался на всех уровнях значит из всех каталогов /etc/rcN.d/ необходимо удалить линк вида S80cron.

Если у вас есть свой собственный демон (например mydaemon c управляющим скриптом mydaemon) и вы хотите его запускать на 5-м уровне запуска значит в каталоге /etc/rc5.d/ вам необходимо создать символический линк:

1
igor@adm-ubuntu:~/linux$ sudo ln -s /etc/init.d/mydaemon /etc/rc5.d/S99mydaemon

Управляющий скрипт естественно должен находится в каталоге /etc/init.d/.

Удаляя и добавляя символические линки в каталоги /etc/rcN.d/ можно настроить запуск и останов демонов на соответствующих уровнях запуска.

Во многих дистрибутивах присутствуют утилиты, которые позволяют ускорить процесс управления запуска демонов для разных runlevel. Для Rad Hat дистрибутивов это утилита chkconfig, для debian-дистрибутивов это update-rc.d или sysv-rc-conf. Также существуют подобные программы и с графическим интерфейсом, например, KSysV. Для утилит наподобие chkconfig в управляющих скриптах принято также писать информацию с параметрами по умолчанию. Эта информация задается в виде комментариев в самом начале скрипта. Вот пример:

1
2
3
4
5
6
7
8
### BEGIN INIT INFO
# Provides:          apache2
# Required-Start:    $local_fs $remote_fs $network $syslog
# Required-Stop:     $local_fs $remote_fs $network $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start/stop apache2 web server
### END INIT INFO

Если выполнить команду chkconfig без дополнительных параметров, то будут созданы символические линки с буквой S в каталогах /etc/rcN.d для уровней запуска - 2 3 4 5, а с буквой K в каталогах /etc/rcN.d для уровней запуска 0 1 6.

Читать другие лекции по курсу Администратор ПК с Linux

Статьи и новости схожей тематики:

Комментариев: 11

  1. sergkarpenko:

    а про freebsd нет такой же информации?

    Ответить

    Igorka Reply:

    Про freebsd я ничего не могу сказать. А зачем тебе?

    Ответить

    sergkarpenko Reply:

    изучаю на досуге, она быстрее и ресурсов меньше ест (как это не прискорбно)

    Ответить

  2. Александр:

    во фре этими скриптами управляет файл
    /etc/rc.conf
    сами скрипты старта/останова демонов лежат в /usr/local/etc/rc.d
    например, чтобы apache22 запускался при старте системы, нужно добавить такую строчку в файл /etc/rc.conf
    apache22_enable=”YES”, для того, чтобы отключить автозапуск apache22 при загрузке ситемы, строчку нужно удалить.
    автору огромное спасибо за статью, изучаю линукс на примере убунты, до этого, 1.5 года работал только с freebsd. Igorka выручил ты меня:)

    Ответить

    Igorka Reply:

    Всегда пожалуйста :) И тебе тоже спасибо. Хочу еще уточнить на всякий случай, что в Ubuntu применяется еще такая штука как upstart. Упоминал о ней здесь http://igorka.com.ua/2009/09/18/upstart-alternativa-init/ В ближайшее время постараюсь более подробно расписать. Не хотел с ней связываться пока традиционный способ загрузки не разберу, а теперь уже можно :)

    Ответить

  3. valeraorg.pp.ua:

    Еще не мешало бы упоминуть про работу с сервисами в Fedora|RH|CentOS
    Там есть утилита service
    Пример service httpd restart
    Так вот в ubuntu и debian ее очень нехватает (по дефолту ее там нет)
    Ставится так #aptitude install sysvconfig

    Я ее применяю когда например программа из пакетов неподходит, приходиться компилить, а при этом скрипта перезапуска нет в /etc/init.d/
    к примеру так компилится proftpd. Только так и могу его перезапусткать.

    Кстати это одновременно вопрос. А как вы поступаете в таком случае, так как неуверен что я прав.

    Ответить

    Igorka Reply:

    Валерий, спасибо за замечание. Об утилите service лектор упоминал, но вижу, что я пропустил ее и не упомянул в лекции. В ближайшее время исправлю.
    По поводу того, что там нет скрипта… Может я неправильно понял (я ведь только учусь), но как правило скрипт должен быть. Может в нем не реализован параметр restart, но stop, start должны быть. А значит можно поправить скрипт дописав в case - restart в котором будет вызов сначала stop, а затем start. К тому же в ubuntu сейчас есть upstart, что накладывает свои особенности.

    Ответить

  4. юотыч:

    Есть в убунте service, по крайней мере в 9.10 службами gdm networking я управлял им.

    Ответить

  5. Iceman:

    Спасибо за статью, посмотрите, не опечатка ли? Вы пишете:
    “Когда системы переходит на какой либо runlevel, например, на шестой, то выполняется скрипт /etc/init.d/rc, которому в качестве параметра передается номер уровня запуска - 6. В результате своей работы скрипт /etc/init.d/rc начинает выполнять в соответствии с вышеописанными правилами все скрипты на которые есть символические ссылки в каталоге /etc/rc5.d/.”

    Возможно имелось в виду “/etc/rc6.d/” ?

    Ответить

    Igorka Reply:

    Спасибо, что отписались.
    Действительно опечатка. Уже поправил.

    Ответить

  6. Constructed:

    Огромное спасибо за статью! Очень познавательно :)

    Ответить

Оставьте свой отзыв