Опубликован: 22.06.2005 | Уровень: для всех | Доступ: свободно | ВУЗ: Компания IBM
Лекция 10:

Этапы загрузки системы

< Лекция 9 || Лекция 10: 123456 || Лекция 11 >

Запуск системных служб

Полноценно загруженная Linux-система - не только login на виртуальной консоли. Системе есть чем заняться и помимо идентификации пользователей. Даже если компьютер не работает WWW-, FTP- или почтовым сервером для "внешнего мира", себе самой и своим пользователям система предоставляет множество услуг: отсылка заданий на печать и обеспечение их очереди, запуск заданий по расписанию, проверка целостности и т.п. Набор утилит и системных программ, предназначенных для предоставления таких услуг, принято называть подсистемами или службами.

Чему служат демоны?

Как правило, системная служба организована так. Во время начальной загрузки запускается в фоновом режиме программа, которая на протяжении работы системы находится в таблице процессов, однако большей частью бездействует, ожидая, когда ее о чем-нибудь попросят. Для того чтобы попросить эту программу об услуге, которую она предоставляет, используются утилиты, взаимодействующие с ней по специальному протоколу. По аналогии с сократовским "даймонионом", который незримо присутствует, по своей инициативе не делает ничего, не дает совершать плохое и способствует хорошему, такую программу стали называть " daemon ". Не знакомые с творчеством Платона программисты-любители частенько переименовывали ее в " demon " ( демон ); к сожалению, именно в такой, слегка инфернальной форме, daemon и вошел в русскоязычную терминологию. Выходит, что в Linux услуги пользователям предоставляют... демоны!

Демон. Запускаемая в фоне программа, длительное время пребывающая в таблице процессов. Обычно демон активизируется по запросу пользовательской программы, по сетевому запросу или по наступлению какого-либо системного события.

В ранних версиях UNIX все, что нужно было запускать при старте системы, вписывалось в inittab. Было довольно удобно в одном файле указывать, какие именно демоны должны работать в системе, и в каком порядке их запускать. Само поведение демона при запуске явно рассчитано на использование в inittab по методу " wait ": классический демон запускается интерактивно, проверяя правильность конфигурационных файлов и прочие условия работы, а затем самостоятельно уходит в фон (попросту делая fork() и завершая родительский процесс). Таким образом, init ждет, пока демон работает интерактивно, а когда служба, возглавляемая этим демоном, готова к работе, переходит к следующей строке inittab. Однако часто бывает так, что автор демона знать не знает, какие именно условия разработчики той или иной версии Linux сочтут пригодными для запуска. Для этого ими создается стартовый сценарий, в котором запрограммирована логика запуска и останова службы. Кроме того, если на каждом из уровней выполнения запускается много различных служб, попытка записывать их запуск в inittab делает его громоздким и совсем неочевидным.

Гуревич посоветовал Мефодию отложить на время изучение загрузки системы, а сначала посмотреть, как управлять стартовыми сценариями.

Стартовый сценарий системной службы

Стартовый сценарий - программа (обычно написанная на shell), управляющая включением или выключением какого-нибудь свойства системы. Это может быть запуск и остановка HTTP-сервера, активизация и деактивизация сетевых настроек, загрузка модулей и настройка звуковой подсистемы и т.п. Простейший стартовый сценарий обязан принимать один параметр, значение которого может быть словом "start" для запуска (включения) и "stop" для остановки (выключения). Если в определенном дистрибутиве Linux принято решение, что стартовые сценарии должны понимать и другие параметры, например "restart" (обычно "stop"+"start", но не всегда) и "status" (для опроса состояния), это требование распространяется на все стартовые сценарии. Единообразие позволяет, например, без труда запускать и останавливать демоны, не выясняя, каков PID останавливаемого процесса и какой именно сигнал ему следует послать. Достаточно запуск написать так, чтобы PID процесса откладывался в специальный файл (обычно /var/run/имя_службы ), а в остановку вписать что-то вроде kill -правильный_сигнал `cat /var/run/имя_службы`.

Все стартовые сценарии служб, которыми может воспользоваться система, принято хранить в каталоге /etc/rc.d/init.d (в некоторых дистрибутивах, для совместимости со старыми версиями UNIX, используется /etc/init.d, иногда это просто символьная ссылка на /etc/rc.d/init.d ). Запустить или остановить службу можно, просто вызвав соответствующий сценарий с параметром "start" или "stop". Часто ту же самую задачу выполняет и специальная команда service, которая проверяет, есть ли указанный стартовый сценарий, и запускает его9В некоторых дистрибутивах Linux такая команда может называться invoke-rc.d, а команда, аналогичная описанному ниже chkconfig - update-rc.d . :

[root@localhost root]# lsmod > old
[root@localhost root]# /etc/rc.d/init.d/sound stop
 Saving OSS mixer settings: [ DONE ]
 Unloading sound module (es1371): [ DONE ]
[root@localhost root]# lsmod > nosound
[root@localhost root]# service sound start
 Loading sound module (es1371): [ DONE ]
 Loading OSS mixer settings: [ DONE ]
[root@localhost root]# lsmod > new
[root@localhost root]# diff3 old new nosound
 ====3
 1:2,5c
 2:2,5c
 es1371           25608   0
 ac97_codec       11880   0 [es1371]
 soundcore         3652   4 [es1371]
 gameport          1628   0 [es1371]
 3:1a
Пример 10.6. Перезапуск звуковой подсистемы

Здесь Мефодий сначала остановил, а потом снова активизировал звуковую подсистему. Остановка привела к выгрузке звуковых модулей, а повторный запуск - к загрузке, полностью аналогичной исходной. В этом Мефодий убедился, сравнив с помощью утилиты diff3 три списка модулей: old (до остановки звуковой подсистемы), new (после повторного запуска) и nosound (между остановкой и повторным запуском). Файлы old и new одинаковы, а от nosound оба отличаются тем, что со второй строки по пятую содержат названия тех самых модулей ядра (в том числе gameport, отвечающий за джойстик).

Схема ".d"

Итак, существует способ единообразно и гибко управлять запуском и остановкой каждой системной службы в отдельности (или включением и выключением одного свойства системы). Однако задача целиком организовать загрузку системы, от запуска init до полноценной работы, этим еще не исчерпывается. Первая из возникающих задач такова: чаще всего нужно загружать не все из размещенных в /etc/rc.d/init.d сценариев, потому что некоторые из установленных в системе служб администратор решил не использовать. Удалять оттуда не используемые при загрузке сценарии - значит, лишать администратора возможности запускать эти сценарии вручную.

Создателям ранних версий UNIX пришла в голову простая мысль: написать один большой сценарий по имени /etc/rc, в который и заносить только нужные для запуска команды вида /etc/init.d/сценарий start. Можно даже занести туда все имеющиеся стартовые сценарии, но строки, запускающие те, что не используются, закомментировать. Такая (монолитная) схема имела существенный недостаток: добавление и удаление службы в систему (например, добавление и удаление пакета, содержащего исполняемые файлы службы) требовало редактирования этого файла. Если учесть, что порядок запуска служб весьма важен (например, бессмысленно запускать сетевые демоны до активизации сетевых настроек), становится ясно, что автоматическое изменение такого файла не может гарантировать нормальную загрузку системы, а значит, недопустимо.

На помощь пришла тактика, известная как "схема .d ". Суть ее в следующем. Пусть некоторый процесс управляется конфигурационным файлом, содержимое которого зависит от наличия и активации других служб системы (таким процессом может быть демон централизованного журналирования syslogd, ведущий журнал всех событий системы, или сетевой метадемон inetd, принимающий сетевые запросы и превращающий сетевой поток данных в обыкновенный посимвольный ввод-вывод). Тогда, чтобы избежать постоянного редактирования конфигурационного файла, его превращают в каталог (например, вдобавок к файлу /etc/syslog.conf заводится каталог /etc/syslog.d ). Каждый файл в таком каталоге соответствует настройке одной службы: при добавлении ее в систему файл появляется, при удалении - исчезает. Остается только обучить тот же syslog читать настройки не только из одного syslog.conf, но и из всех файлов в syslog.d, и задача решена.

На случай запускаемых сценариев схема " .d " распространяется с двумя дополнениями. Во-первых, как уже было сказано, стартовые сценарии можно запускать, а можно и не запускать. Поэтому сам init.d на роль " .d "-каталога не годится. Впрочем, достаточно организовать еще один каталог, скажем, rc.d, и создать там ссылки (для наглядности лучше символьные) на те сценарии из init.d, которые планируется запускать при старте системы. Общий стартовый сценарий rc как раз и будет заниматься запуском стартовых сценариев из rc.d.

Во-вторых, необходимо обеспечить строгий порядок запуска этих сценариев. Теоретически это совсем просто: отсортировать их по алфавиту, как это делает ls, и запускать подряд. Практически же такое требование накладывает ограничение на имя ссылки в " .d "-каталоге, поэтому принято, чтобы в начале имени стояло двузначное число. Тогда, запуская подряд все сценарии, отсортированные по алфавиту, rc будет в первую очередь руководствоваться этим номером, а уж потом - названием службы, которое после него стоит.

< Лекция 9 || Лекция 10: 123456 || Лекция 11 >
Аягоз Имансакипова
Аягоз Имансакипова
Тимур Булатов
Тимур Булатов

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