11 окт. 2011 г.

Upstart и init в Ubuntu



Источники:

Дополнительно:

http://habrahabr.ru/post/113350/ 
Несколько слов о классической схеме загрузки пользовательских процессов в Linux. На определенном этапе загрузки системы, запускается первый пользовательский процесс init, который читает конфигурационный файл /etc/inittab
В нем прописаны основные параметры запуска системы, в частности уровень запуска (runlevel) по умолчанию и представленные ниже строки:
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
Каждый такой скрипт, которому в качестве параметра передается номер уровня запуска, начинает останавливать/запускать скрипты из каталога /etc/rcN.d/, где N - это номер уровня запуска. Подробнее об этом можно прочесть в влекции по управлению демонами.
Основной недостаток этого подхода - это то, что запуск процессов (демонов), происходит последовательно, один за другим. В то же время загрузка многих демонов не зависит друг от друга, и их можно было бы запускать параллельно, ускоряя запуск операционной системы. Второй недостаток - необходимоcть самостоятельно писать управляющие скрипты, которые находятся в каталоге /etc/init.d/. Управляющие скрипты должны уметь как минимум запускать и останавливать демон, а также реализовать обработку возможных нестандартных ситуаций. Вероятно, существуют и другие недостатки, но эти два фигурируют как основные.
Проект upstart создан с целью заменить традиционный способ загрузки пользовательских процессов в Linux, а также способ управления ими. Информации об upstart пока не очень много в русскоязычном интернете, поэтому большая ее часть взята с сайта проекта, а также из справочной информации операционной системы Ubuntu. Практические испытания также проводились в операционной системе Ubuntu 9.10.
Как и в классическом варианте - upstart имеет главный процесс, который отвечает за загрузку и управление демонами. Называется он также как и в классическом варианте - init. Чтобы понять “кто есть кто” посмотрите отсутствует ли в системе файл /etc/inittab и присутствует ли каталог /etc/init/ или /etc/event.d/. Если это так, значит у вас установлен upstart. Сейчас в своей ubuntu 9.10 я вижу только каталог /etc/init, хотя в предыдущих версиях был и каталог /etc/event.d.
Далее по тексту, чтобы отличать классический процесс init от процесса init в upstart, я буду употреблять для последнего выражение upstart init.
В upstart ввели такое понятие как “задание” (jobs). Если во время запуска процесс init читает конфигурацию из файла/etc/inittab, то процесс upstart init читает конфигурацию из файлов каталога /etc/init/. Эти файлы и являютсяфайлами-заданиями (jobs). Каждый файл в каталоге /etc/init/ отвечает за запуск отдельного демона или сервиса и должен заканчиваться на .conf. Также допускается, создавать подкаталоги в которых могут находится файлы-задания.
Синтаксис файлов-заданий несложный. Большую часть времени при дальнейшем изучении вопроса, займет разбор событий который понимает upstart init. Поэтому пока только в общих чертах. В файлах-заданиях обязательно содержится информация когда задание должно стартовать (определение start on), когда останавливаться (stop on) и, что запускать (ключевые слова exec или script).
Итак, когда же задание сработает? Вот здесь и есть первое основное отличие которое решает проблему последовательного запуска скриптов. upstart - это подсистема которая реагирует на события. Поэтому после ключевых слов start on или stop on, обязательно указывается событие (event), при наступлении которого начинает выполняться запуск или остановка задания. Например, задание failsafe-x.conf будет выполнено в том случае когда некорректно остановится менеджер gdm (start on stopped gdm EXIT_STATUS=[!0]).
Если рассматривать события наиболее часто употребляемые в файлах заданий, то это startuprunlevelstopped иstartedstartup - это самое первое событие, которое распознается подсистемой upstart на самом раннем этапе загрузки операционной системы. Событие runlevel (с указанием целевого уровня), как следует из названия генерируется при смене уровня запуска. Событие stopped генерируется после остановки указанного задания, а started послезавершения старта задания. Просмотрев файлы-задания в каталоге /etc/init/ можно найти и другие события.
Таким образом если необходимо создать задание которое будет запускать тестовый демон test на 2-м и 3-м уровне запуска и останавливать на остальных уровнях, достаточно создать файл test.conf в котором написать:
1
2
3
4
start on runlevel [23]
stop on runlevel [!23]

exec test
Подсистема upstart решает и вторую проблему - она самостоятельно занимается запуском и завершением работы демонов. Строки start on runlevel [23] в одном только файле /etc/init/test.conf, достаточно для запуска демонаtest. Подсистема upstart освобождает нас от процедуры описания КАК запустить демон и позволяет сосредоточиться только на том ЧТО необходимо запустить.
Для ручного запуска или остановки заданий в upstart предусмотрены команды start и stop, расположенные, как правило, в каталоге /sbin. Чтобы в Ubuntu остановить демон cron достаточно ввести команду sudo stop cron:
1
2
igor@adm-ubuntu:/etc/event.d$ sudo stop cron
cron stop/waiting
Чтобы запустить cron набираем sudo start cron:
1
2
igor@adm-ubuntu:/etc/event.d$ sudo start cron
cron start/running, process 6874
Из других команд управления можно отметить команду status, которая показывает в каком состоянии (останова или работы) находится задание (а соответственно и демон):
1
2
igor@adm-ubuntu:/etc/event.d$ status cron
cron start/running, process 6874
Также следует отдельно упомянуть команду initctl. Эта команда как следует из ее названия (сокращенное от init control), позволяет управлять демоном upstart init. Команда initctl тоже умеет останавливать (initctl stop) и запускать (initctl start) задания, а также проверять их статусы (initctl status). Если нужно посмотреть статус всех заданий есть команда initctl list:
1
2
3
4
5
6
7
8
igor@adm-ubuntu:/etc/event.d$ initctl list
avahi-daemon start/running, process 836
mountall-net stop/waiting
...
...
dmesg stop/waiting
networking stop/waiting
tty6 stop/waiting
Узнать версию установленной подсистемы upstart можно по команде initctl version:
1
2
igor@adm-ubuntu:/etc/event.d$ initctl version
init (upstart 0.6.3)
В завершении пример запуска своего демона с помощью upstart. Вместо громоздкого скрипта timeconsole, достаточно создать файл /etc/init/showtime.conf следующего содержимого:
1
2
3
4
5
6
7
8
start on runlevel [2] #Запускать на втором уровне
stop on [!2] #Завершать на уровне запуска отличном от второго

post-stop script #секция позволяет задать дополнительные действия после остановки демона
clear > /dev/tty8 #очищаем консоль на которую выводилось время
end script

exec /usr/sbin/showtime #запуск демона
Для ручного управления используем команды start и stop:
1
2
3
4
5
6
igor@ubuntu:~$ sudo start showtime
showtime start/running, process 6214
igor@ubuntu:~$ sudo stop showtime
showtime stop/waiting
igor@ubuntu:~$ status showtime
showtime stop/waiting
Можно также проверить, что демон автоматически запускается при переходе на второй runlevel, набрав команду sudo telinit 2. Проверял - работает.
На этом пока все. Как всегда - приветствуются комментарии к статье, замечания, вопросы и предложения.




В статье upstart в Ubuntu я постарался разложить для себя по полочкам работу системы upstart, на примере таковой в операционной системе Ubuntu 9.10. Об основных особенностях upstart я упомянул, но забыл о такой вещи как совместимость со старой схемой запуска - когда используются скрипты написанные для традиционного демона init. Поэтому здесь небольшое дополнение на эту тему. Если вы только знакомитесь с upstart, рекомендую прочесть сначала статью upstart в Ubuntu.
Многие классические демоны, запускаются скриптами расположенными в каталоге /etc/init.d/. То есть при установке такого демона, управляющий скрипт копируется в каталог /etc/init.d/ и в в соответствующих каталогах /etc/rcX.d/прописываются символические ссылки для запуска демона на соответствующих уровнях запуска.
Upstart просматривает и выполняет только файлы-задания расположенные в каталоге /etc/init/, поэтому для того, чтобы выполнялись скрипты из каталогов /etc/rcX.d/, необходимо “сказать” об этом upstart. Для этой цели в каталоге/etc/init/ находится файл-задание rc.conf. Именно благодаря этому файлу и просисходит просмотр и запуск скриптов для стандартного init из каталога /etc/rcX.d/. Вот текст rc.conf:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# rc - System V runlevel compatibility
#
# This task runs the old System V-style rc script when changing between
# runlevels.

description     "System V runlevel compatibility"
author          "Scott James Remnant "

start on runlevel [0123456]
stop on runlevel [!$RUNLEVEL]

export RUNLEVEL
export PREVLEVEL

console output
env INIT_VERBOSE

task

exec /etc/init.d/rc $RUNLEVEL
Выполняя этот файл-задание, upstart запускает скрипт /etc/init.d/rc с передачей ему уровня запуска ($RUNLEVEL). Эта запись фактически реализует блок из файла /etc/inittab, который является основным конфигурационным файлом для классического демона init:
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
А дальше уже по классической схеме - скрипт rc начинает выполнять скрипты из соответствующего каталога/etc/rcX.d/.
Примерно, так. Если где ошибся - поправляйте.


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

Отправить комментарий