LXF109:DRBruan3
(Новая: ==Юный выскочка== : ''init'' малость устарел; пришло время нового демона запуска системы. Много лет в Linux ис...) |
(→Поэкспериментируем) |
||
Строка 73: | Строка 73: | ||
tty5 (start) running, process 2123 | tty5 (start) running, process 2123 | ||
tty6 (start) running, process 2127 | tty6 (start) running, process 2127 | ||
− | + | ||
+ | Вызовем событие ‘'''greet'''’ с помощью ''initctl'' таким образом: | ||
+ | |||
# initctl emit greet ellie | # initctl emit greet ellie | ||
greet ellie | greet ellie |
Текущая версия на 10:07, 11 ноября 2009
|
|
|
Содержание |
[править] Юный выскочка
- init малость устарел; пришло время нового демона запуска системы.
Много лет в Linux использовалась схема управления запуском сервисов во время загрузки, которая появилась в System V Unix еще в 1983 году. За эти годы системные администраторы подружились со структурой System V и уровнями выполнения. Они знают и о скриптах запуска сервисов в /etc/init.d, и обо всех этих символических ссылках с названиями на ‘S’ и ‘K’, и о процессе init с его файлом конфигурации /etc/inittab.
Поэтому исчезновение inittab в некоторых последних дистрибутивах Linux немного шокирует, как и замена почтенного init на upstart. Первым дистрибутивом, выполнившим ее, был Ubuntu (еще в Edgy Eft более полутора лет назад). В Fedora 9 также используется upstart (это позволяет предположить, что за ним со временем последует Red Hat Enterprise Linux), а разработчики OpenSUSE 11.0 предпочли остаться со старым добрым init.
Upstart – это основанная на событиях замена init; управляет запуском задач и сервисов во время загрузки и их остановкой во время выключения системы и наблюдает за ними во время работы. Демон upstart, для обратной совместимости (и для вящей путаницы) названный init, управляется «событиями», формируемыми D-BUS. У события есть простое текстовое имя, например, ‘startup’, ‘control-alt-delete’ или ‘runlevel’.
При запуске демон читает все файлы в /etc/event.d/. Каждый из них определяет задание, которым будет управлять upstart. Имя задания совпадает с именем файла. Эти файлы устанавливают, какие события вызовут запуск (или останов) задания и что делать, когда происходит событие. Вот простой пример – файл события Ctrl+Alt+Delete из Fedora 9 (обе его строки!):
start on control-alt-delete exec /sbin/shutdown -r now “Control-Alt-Delete pressed”
Когда задание активизируется, оно проходит через серию состояний: ожидание, запуск, выполнение, остановка и т.д. Эти изменения состояний сами порождают события: «запускается», «запущено», «останавливается» и «остановлен». Поэтому можно определить задание, запускаемое по окончании другого. Вот файл события prefdm – он отвечает за запуск графического экрана входа в систему сразу после перехода на уровень выполнения 5 (т.е. после завершения задания ‘rc5’):
start on stopped rc5 stop on runlevel [!5] console output respawn respawn limit 10 120 exec /etc/X11/prefdm -nodaemon
Директивы respawn в этом файле говорят, что upstart должен перезапустить программу после ее завершения, но не более 10 раз каждые 120 секунд. Механизм обработки событий upstart предоставляет большую гибкость в определении того, что должно произойти при выполнении заданных условий; можно, например, потребовать «смонтировать USB-брелок, когда он обнаружен». Впрочем, ни в Ubuntu, ни в Fedora я не увидел подтверждения тому, что upstart настроен на такие штуки.
Upstart поставляется с утилитой initctl, позволяющей получить список заданий, показать все сгенерированные события и переходы и даже вызвать собственные события вручную. Есть и утилита telinit, предоставленная для обратной совместимости, хотя, насколько я могу судить, она просто вызывает событие подходящего уровня выполнения.
[править] Поэкспериментируем
Понять, как работает upstart, поможет простой эксперимент. (Я проводил его на Fedora 9, но все должно работать точно так же на Ubuntu.) Начнем с создания файла sayhello в каталоге /etc/event.d с таким содержимым:
start on greet console output script echo “hello $1” at $(date) > /tmp/upstart-test end script
Затем просигнализируем upstart перечитать файлы событий. Как и у старины init, у демона upstart идентификатор процесса равен 1:
# kill -HUP 1
Теперь проверим, что upstart знает о нашем задании, с помощью команды:
# initctl list control-alt-delete (stop) waiting logd (stop) waiting prefdm (start) running, process 2119 rc0 (stop) waiting ... кое-что опущено ... sayhello (stop) waiting ... опущено еще больше ... tty5 (start) running, process 2123 tty6 (start) running, process 2127
Вызовем событие ‘greet’ с помощью initctl таким образом:
# initctl emit greet ellie greet ellie sayhello (start) waiting sayhello (start) starting sayhello (start) pre-start sayhello (start) spawned, process 9333 sayhello (start) post-start, (main) process 9333 sayhello (start) running, process 9333 sayhello (stop) running sayhello (stop) stopping sayhello (stop) killed sayhello (stop) post-stop sayhello (stop) waiting
Вывод команды ясно показывает изменения состояний, порождаемые нашим заданием ‘sayhello’. А проверка содержимого файла /tmp/upstart-test должна дать соответственно:
# cat /tmp/upstart-test hello ellie at Mon Jun 2 06:45:36 BST 2008
Чтобы продвинуться на этап вперед, определим второе задание ‘saygoodbye’ в файле /etc/event.d. Оно будет запускаться после завершения ‘sayhello’:
start on stopped sayhello console output script echo “goodbye world” >> /tmp/upstart-test end script
Конечно, будет нужно велеть upstart перечитать файлы. Теперь откройте второе окно терминала. Выполните в нем следующую команду:
# initctl events
Она останется работать в фоне и сообщит обо всех событиях.
Вернитесь в первое окно и сгенерируйте другое событие ‘greet’:
# initctl emit greet taylor
потом вернитесь во второе, чтобы посмотреть, какие события были сгенерированы:
greet taylor starting sayhello started sayhello stopping sayhello ok stopped sayhello ok starting saygoodbye started saygoodbye stopping saygoodbye ok stopped saygoodbye ok
и в завершение эксперимента снова проверьте содержимое файла /tmp/upstart-test, чтобы убедиться в том, что задание ‘saygoodbye’ запускалось:
# cat /tmp/upstart-test hello taylor at Mon Jun 2 07:01:45 BST 2008 goodbye world
Ну да, пример игрушечный. Но я надеюсь, что он помогает почувствовать, как работает механизм обработки событий upstart, и показывает некоторые его возможности. Он мог бы заменить, например, запуск задач по расписанию, который сейчас выполняется Cron. Однако его главная цель на данный момент – просто заместить init как средство запуска сервисов во время загрузки. В самом upstart нет уровней выполнения, но просмотрев файлы событий в /etc/event.d, можно увидеть, что конфигурация эмулирует прежнее поведение. Все начинается с события startup, активизирующего задание rcS, которое выполняет традиционный низкоуровневый скрипт инициализации /etc/init.d/rcS (в Ubuntu) или /etc/rc.d/rc.sysinit (в Fedora). Что произойдет дальше, зависит от конкретного дистрибутива.
[править] Потенциал
В Fedora 9 задание rcS запускает скрипт ‘post-stop’ – он вытаскивает уровень выполнения по умолчанию из /etc/inittab и вызывает telinit с этим уровнем выполнения как аргументом. Версия telinit в upstart нужна только для обратной совместимости, она просто генерирует событие ‘runlevel 3’, которое в свою очередь активизирует задание rc3, запускающее традиционный скрипт /etc/rc.d/rc3 для перехода на желаемый уровень выполнения.
Чтобы разобраться с Ubuntu, потребовалось чуть больше времени, но я в конце концов заметил файл rc-default, запускаемый по завершению задания rcS (он содержит строку ‘start on stopped rcS’). Этот файл также пытается получить уровень выполнения по умолчанию из /etc/inittab, а если такого файла нет (кстати, в установке по умолчанию его и нет), то переходит на уровень выполнения 2 путем вызова telinit. Но и в Ubuntu, и в Fedora все заканчивается вызовом обычного стартового сценария, который запускает скрипты S* из каталога с соответствующим уровнем выполнения. Другими словами, методы взаимодействия с сервисами времени загрузки не изменились. (Например, для управления ссылками S* и K* все еще используется chkconfig.) В обоих случаях ссылка на /etc/inittab – это лишь мимолетный кивок в сторону обратной совместимости; в этом файле всего одна строка ‘initdefault’, она задает начальный уровень выполнения. В самом upstart нет уровней выполнения, они лишь результат настройки upstart, заботящейся об обратной совместимости.
Вообще-то в Ubuntu от идеи уровней выполнения почти отказались, так как их всего два: single-user и 2. Кажется, мы возвращаемся ко временам BSD Unix, где были только уровни выполнения single-user и multi-user, и даже я смог понять, что происходит.
Документация по upstart довольно скупа. В частности, в Ubuntu даже нет раздела man, где описывался бы формат файлов событий, хотя такой раздел имеется в Fedora. Неплохое обсуждение есть в блоге Скотта Джеймса Ремнанта [Scott James Remnant] (http://www.netsplit.com), но как-то странно искать документацию по фундаментальным вопросам в подобных местах. LXF
[править] Не цитируйте меня…
Мой коллега, преподаватель по Linux, как-то спросил меня: «Чем различаются теория и практика?» Как, наверное, требует профессиональная этика в такие моменты, я ответил: «Не знаю, а чем?» «Ну, – сказал он, – в теории разницы нет, а на практике есть».
Компьютерщики привыкли присваивать слова: ремешок ботинка (начальная загрузка – bootstrap), семафор, сигнал, молотить (thrash), мышь, печенье (cookie – куки), пламя (flame – флейм), мясные консервы (spam – спам), вилка (fork) и т.д. – и это напоминает мне наблюдение Шалтая-Болтая из «Алисы в Зазеркалье» Льюиса Кэрролла. Он сказал: «Когда я употребляю слово, оно означает только то, что я хочу, чтобы оно означало – ни больше, ни меньше». Вот моя любимая цитата из Ларри Уолла [Larry Wall]: «Скажем, вы вернулись в прошлое к Аде Лавлейс [Ada Lovelace, дочь поэта Байрона; считается самым первым программистом, – прим. ред.] и спросили бы ее, в чем разница между скриптом [сценарием] и программой. Она бы, наверное, улыбнулась и сказала что-то типа: “Ну, сценарий дают актерам, а программку – публике”».
И моя самая любимая, из Роберта Ферта [Robert Firth]: «Одной из главных причин падения Римской Империи было отсутствие нуля в нумерации: не было способа узнать, что их программы на C успешно завершились».
[править] Это терминал
Заметили, как трудно стало встретить добрую старую командную строку? Раньше вы просто загрузили бы компьютер и сразу ее увидели, но в современных дистрибутивах, чтобы до нее добраться, нужно пройти через три уровня меню. В Vista – четыре. В поисках этой подсказки я теперь начинаю чувствовать себя изгоем, вынужденным мокнуть под дождем на заднем дворе, чтобы выкурить сигарету. Итак, вот мое «впечатление художника» о том, как найти командную строку в Intrepid Ibex.