Handbook:Parts/Working/Initscripts/ru

Процесс загрузки системы
Когда загружается система по экрану пробегает много текста. Если присмотреться, заметно, что этот текст (обычно) не меняется от загрузки к загрузке. Последовательность всех этих действий называется последовательностью загрузки и в той или иной степени постоянна.

Во-первых, загрузчик размещает в памяти образ ядра, который указан в файле его конфигурации загрузчика. После этого загрузчик просит процессор запустить ядро. Когда ядро загружено и запущено, оно инициализирует относящиеся к ядру структуры и задания, и запускает процесс init.

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

И, наконец, когда все скрипты выполнены, init подключает терминалы (чаще всего просто виртуальные консоли, которые видны при нажатии +, + и так далее), прикрепляя к каждой консоли специальный процесс под названием. Этот процесс впоследствии обеспечивает возможность входа в систему через эти терминалы с помощью login.

Init-скрипты
Сейчас процесс init запускает скрипты из каталога не просто в случайном порядке. Более того, запускаются не все скрипты из, а только те, которые предписано исполнять. Решение о запуске скрипта принимается в результате просмотра каталога.

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

Когда все скрипты, указанные в, будут выполнены, init переходит к запуску скриптов, на которые есть символьные ссылки из. И снова запуск происходит в алфавитном порядке, пока в скрипте не встретится информация о зависимостях; тогда порядок изменяется для обеспечения правильного порядка запуска. Именно по данной причине команды, используемые во время установки Gentoo Linux, используют, как в команде.

Как работает init
Конечно, init не принимает решений сам по себе. Ему необходим конфигурационный файл, где описаны необходимые действия. Этот файл -.

Если запомнили последовательность загрузки, описанную чуть ранее, вы вспомните, что первое действие init - это монтирование всех файловых систем. Это определяется в следующей строке файла :

Этой строкой процессу init предписывается выполнить для инициализации системы. Самой инициализацией занимается скрипт, так что можно сказать, что init делает не слишком много - он просто делегирует задачу по инициализации системы другому процессу.

Во-вторых, init выполняет все скрипты, на которые есть символьные ссылки из. Это определяется следующей строкой:

И снова все необходимые действия выполняются скриптом openrc. Заметьте, что параметр, переданный openrc (boot), совпадает с названием используемого подкаталога в.

Теперь init проверяет свой конфигурационный файл, чтобы определить, какой уровень запуска нужно запустить. Для этого из считывается строка:

В приведенном примере (который подходит для подавляющего большинства пользователей Gentoo) номер уровня запуска - 3. Пользуясь этой информацией, init проверяет, что нужно выполнить для запуска уровня запуска 3:

В строке, определяющей уровень 3, для запуска сервисов снова используется скрипт openrc (на этот раз с аргументом ). Опять-таки, обратите внимание, что аргумент, передаваемый скрипту openrc, совпадает с названием подкаталога из.

По окончании работы openrc, init принимает решение о том, какие виртуальные консоли включить и какие команды выполнить в каждой из них:

Существующие уровни запуска
В предыдущем разделе мы увидели, что init применяет нумерацию для определения уровня запуска, который надо использовать. Уровень запуска - это то состояние, в котором запущена система, он содержит набор скриптов (скрипты уровня запуска или init-скрипты), которые следует выполнять, при входе и выходе из определенного уровня запуска.

В Gentoo определено семь уровней запуска: три служебных и четыре определяемых пользователем. Служебные называются sysinit, shutdown и reboot. Действия, совершаемые ими, в точности соответствуют их названиям: инициализация системы, выключение системы и ее перезагрузка.

Определяемые пользователем уровни - это те, которым соответствуют подкаталоги в : boot, default, nonetwork и single. Уровень boot запускает все службы, необходимые системе и используемые всеми остальными уровнями. Остальные уровни отличаются друг от друга запускаемыми службами: default используется для повседневной работы, nonetwork - для тех случаев, когда не требуется сеть, а single используется при необходимости восстановления системы.

Работа с init-скриптами
Скрипты, запускаемые процессом openrc, называются init-скриптами. Каждый скрипт из может запускаться с аргументами ,  ,  ,  ,  ,  ,  ,  ,  ,   или.

Для запуска, остановки или перезапуска службы (и всех, зависящих от нее) следует использовать,   и  :

Если вы хотите остановить службу, но оставить зависимые от нее работающими, можно использовать опцию  вместе с аргументом stop:

Чтобы узнать текущее состояние службы (запущена, остановлена, и т.д.), можно использовать аргумент :

Если указано, что служба работает, но вы знаете, что это не так, можно сбросить состояние на stopped , используя аргумент :

To also ask what dependencies the service has, use,   or. With  it is possible to see the services that are really necessary for the correct functioning of the service. or, on the other hand, shows the services that can be used by the service, but are not necessary for the correct functioning.

Similarly, it is possible to ask what services require the service or can use it (  or  ):

rc-update
Система инициализации Gentoo использует дерево зависимостей для определения служб, которые запускаются в первую очередь. Так как это очень утомительное занятие, и мы бы не хотели, чтобы пользователь занимался этим вручную, мы разработали утилиты, упрощающие управление уровнями запуска и init-скриптами.

Используя, можно включать и исключать init-скрипты из уровней запуска. Из автоматически запускается скрипт  для перестроения дерева зависимостей.

Добавление и удаление служб
В процессе установки Gentoo вы уже добавляли init-скрипты в уровень запуска default. Ранее в данном документе было объяснено, что означает default. Кроме уровня запуска, скрипту требуется второй аргумент, определяющий действие:   (добавить),   (удалить) или   (показать).

Для того, чтобы добавить или удалить init-скрипт, просто введите с аргументом   или , затем название init-скрипта и уровня запуска. Например:

По команде выводится список всех доступных init-скриптов с указанием списка уровней запуска, на которых они будут выполняться:

Вы также можете запустить (без  ) чтобы просто просмотреть включенные инициализационные скрипты и их уровни запуска.

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

Вторая причина, по которой настройки хранятся отдельно от самого init-скрипта - это возможность обновления скрипта без опасения, что все пользовательские настройки будут утеряны.

Каталог conf.d
В Gentoo предусмотрен очень простой способ настройки сервисов: для каждого init-скрипта, предполагающего настройку, в каталоге есть конфигурационный файл. Например, у скрипта, запускающего (под названием ) есть настроечный файл, где могут храниться нужные параметры, передаваемые серверу Apache 2 при запуске:

Такие файлы настроек содержат только переменные (наподобие ), облегчая настройку служб. Это также позволяет нам давать больше информации о переменных (в комментариях).

Это необходимо?
Нет, написание init-скриптов обычно не требуется, так как Gentoo содержит готовые скрипты для всех предоставляемых сервисов. Однако, некоторые пользователи могут установить какой-либо сервис, не используя систему Portage; в таком случае, вероятно, придется создавать init-скрипт самостоятельно.

Не используйте init-скрипт, идущий с сервисом, если он не написан специально для Gentoo: init-скрипты Gentoo не совместимы со скриптами, используемыми в других дистрибутивах! То есть, если другой дистрибутив не использует OpenRC!

Структура
Основная структура init-скрипта показана ниже.

Every init script requires the  function or   variable to be defined. All other sections are optional.

Зависимости
There are three dependency-alike settings that can be defined which influence the start-up or sequencing of init scripts:,   and. Next to these, there are also two order-influencing methods called  and. These last two are no dependencies per se - they do not make the original init script fail if the selected one isn't scheduled to start (or fails to start).


 * The  settings informs the init system that this script uses functionality offered by the selected script, but does not directly depend on it. A good example would be   or  . If those services are available, they will be put in good use, but if the system does not have a logger or DNS server the services will still work. If the services exist, then they are started before the script that uses them.
 * The  setting is similar to   with one exception.    only considers services which were added to an init level.   will try to start any available service even if not added to an init level.
 * The  setting is a hard dependency. It means that the script that is needing another script will not start before the other script is launched successfully. Also, if that other script is restarted, then this one will be restarted as well.
 * When using, then the given script is launched before the selected one if the selected one is part of the init level. So an init script xdm that defines   will start before the alsasound script, but only if alsasound is scheduled to start as well in the same init level. If alsasound is not scheduled to start too, then this particular setting has no effect and xdm will be started when the init system deems it most appropriate.
 * Similarly,  informs the init system that the given script should be launched after the selected one if the selected one is part of the init level. If not, then the setting has no effect and the script will be launched by the init system when it deems it most appropriate.

Из вышенаписанного должно быть ясно, что  это единственная действительная настройка зависимостей, так как она влияет на то, будет ли запущен скрипт или нет. Все остальные являются больше указателями системе init, говорящими в каком порядке скрипты могут (или должны) запускаться.

Теперь, если вы посмотрите на многие из существующих инициализационных скриптов Gentoo, вы заметите, что некоторые из них имеют зависимости от вещей, которые не являются инициализационными скриптами. Эти вещи мы называем виртуальными.

Виртуальная зависимость - это зависимость от функций, предоставляемых сервисом, но не каким-то единственным сервисом. Init-скрипт может зависеть от сервиса системного журнала, но таких достаточно много (metalogd, syslog-ng, sysklogd и тому подобное). Поскольку нельзя нуждаться в каждой из них (ни в одной вразумительной системе они не запущены все сразу), мы обеспечили предоставление виртуальной зависимости всеми этими сервисам.

Например, давайте взглянем на информацию о зависимостях postfix.

Как можно увидеть, сервис postfix:


 * требует сеть (net): виртуальная зависимость, удовлетворяемая, например,
 * использует журнал (logger): виртуальная зависимость, удовлетворяемая, например,
 * использует (dns): виртуальная зависимость, удовлетворяемая, например,
 * предоставляет почтовый агент (mta): виртуальная зависимость, общая для всех программ - почтовых серверов

Порядок запуска
Как мы описали в предыдущем разделе, можно сказать системе init, в каком порядке она должна запускать (или останавливать) скрипты. Этот порядок поддерживается как через настройки зависимостей use и need, так и через настройки порядка before и after. Так как мы описали их ранее, давайте посмотрим на сервис Portmap, как на пример такого init-скрипта.

Также можно использовать знак "*", чтобы охватить все службы данного уровня запуска, хотя это не рекомендуется.

Если сервис должен писать на локальные диски, он должен потребовать localmount. Если он что-либо поместит в, например, pid-файл, он должен запускаться после bootmisc:

Стандартные функции
Следом за разделом  потребуется определить функцию. В ней содержатся все команды, необходимые для запуска сервиса. Рекомендуется применять функции  и   для сообщений пользователю о том, что происходит:

Как, так и   должны использоваться в функциях start и stop. Если сервис не создает pid-файл, тогда используйте, если возможно, хотя лучше протестировать это, чтобы быть уверенным. Иначе, не используйте pid-файлы. Можно добавить  к опциям start-stop-daemon, но это не рекомендуется, если только сервис не очень многословный. Использование  может скрыть информацию если сервис не сможет запуститься.

Другой интересной настройкой, используемой в вышеприведенном примере является проверка содержимого переменной RC_CMD. В отличие от предыдущей инициализационной системы, новая система OpenRC не поддерживает отдельную функциональность restart для каждого скрипта. Вместо этого, скрипт должен проверить содержимое переменной RC_CMD, чтобы проверить, вызывается ли функция (как , так и  ) как часть restart, или нет.

Если нужны дополнительные примеры функции, пожалуйста, прочитайте исходный код init-скриптов, находящихся в каталоге.

Еще одной функцией, которую можно определить (но не обязательно это делать), является. Система init, применяемая нами, достаточно развита и в состоянии самостоятельно заполнить эту функцию, если используется start-stop-daemon.

Если сервис запускает некоторый другой скрипт (например, на Bash, Python или Perl), и этот скрипт позднее изменяет имя (например, с на foo), тогда нужно добавить   к start-stop-daemon. Нужно определить имя, на которое скрипт изменит свое имя. В приведенном примере, сервис запускает, а потом это имя меняется на foo:

У start-stop-daemon есть отличная man-страница, которую можно посмотреть, если нужна дополнительная информация.

Синтаксис init-скриптов, применяемых в Gentoo, основан на оболочке POSIX, поэтому можно свободно использовать внутри своих скриптов sh-совместимые конструкции. Остальные конструкции, вроде тех, которые	специфичны только для bash, выносите за пределы init-скриптов, чтобы быть уверенным, что скрипты будут работать независимо от того, что Gentoo может сделать со своей системой init.

Добавление дополнительных параметров
If the initscript needs to support more options than the ones we have already encountered, then add the option to one of the following variables, and create a function with the same name as the option. For instance, to support an option called :


 * extra_commands - Command is available with the service in any state
 * extra_started_commands - Command is available when the service is started
 * extra_stopped_commands - Command is available when the service is stopped

Переменные для настройки сервисов
Для поддержки настроечных файлов из каталога ничего дополнительно делать не нужно: при запуске init-скрипта автоматически подключаются следующие файлы (т.е., переменные из них становятся доступны):



Кроме того, если init-скрипт предоставляет виртуальную зависимость (например, net), то также подключается файл, соответствующий этой зависимости (например, ).

Кто может выиграть?
Большинству пользователей ноутбуков знакома ситуация: дома нужен запуск net.eth0, и наоборот, в дороге запуск net.eth0 не нужен (так как сеть недоступна). В Gentoo можно изменять поведение уровней запуска по своему усмотрению.

Например можно создать второй загружаемый уровень запуска default, в котором будут другие init-скрипты. Затем, при загрузке, можно выбрать, какой из уровней default следует использовать.

Использование программного уровня (softlevel)
Прежде всего, создайте каталог для второго уровня запуска default. Например, создадим уровень запуска offline:

Добавьте необходимые init-скрипты в только что созданный уровень запуска. Например, чтобы получить точную копию уровня default, за исключением net.eth0:

Даже несмотря на то, что net.eth0 был удален с уровня запуска offline, udev может попытаться запустить любые устройства, которые найдет, и запустить соответствующие сервисы. Данная функциональность называется hotplugging. По умолчанию, Gentoo отключает hotplugging.

Чтобы включить hotplugging, но только для конкретного набора скриптов, используйте переменную rc_hotplug в :

Теперь необходимо отредактировать конфигурацию загрузчика, добавив новую запись для уровня запуска offline. В данной записи добавьте  в качестве параметра загрузки.

Использование загрузочного уровня (bootlevel)
Использование загрузочного уровня полностью аналогично использованию программного уровня. Единственная разница состоит в том, что определяется второй уровень boot вместо второго уровня default.