Handbook:Parts/Working/Initscripts/ru

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

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

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

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

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

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

When all referenced scripts are executed, init continues with running the scripts that have a symbolic link to them in. Again, it will use the alphabetical order to decide what script to run first, unless a script has dependency information in it, in which case the order is changed to provide a valid start-up sequence. The latter is also the reason why commands used during the installation of Gentoo Linux used, as in.

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

Remember the boot sequence that was just described - init's first action is to mount all file systems. This is defined in the following line from :

This line tells init that it must run to initialize the system. The script takes care of the initialization, so one might say that init doesn't do much - it delegates the task of initializing the system to another process.

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

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

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

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

The line that defines level 3, again, uses the rc script to start the services (now with argument ). Again note that the argument of rc is the same as the subdirectory from.

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

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

In Gentoo, there are seven runlevels defined: three internal runlevels, and four user-defined runlevels. The internal runlevels are called sysinit, shutdown and reboot and do exactly what their names imply: initialize the system, powering off the system, and rebooting the system.

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

Работа со сценариями инициализации
The scripts that the rc process starts are called init scripts. Each script in can be executed with the arguments ,  ,  ,  ,  ,  ,  ,  ,  , or.

To start, stop, or restart a service (and all depending services), the,  , and   arguments should be used:

To stop a service, but not the services that depend on it, use the  option together with the   argument:

To see what status a service has (started, stopped, ...) use the  argument:

If the status information shows that the service is running, but in reality it is not, then reset the status information to "stopped" with the  argument:

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. 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 :

Наконец, можно просмотреть список служб, требующихся для данной, но отсутствующих в системе:

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

With it is possible to add and remove init scripts to a runlevel. The tool will then automatically ask the  script to rebuild the dependency tree.

Добавление и удаление служб
In earlier instructions, init scripts have already been added to the "default" runlevel. What "default" means has been explained earlier in this document. Next to the runlevel, the script requires a second argument that defines the action: ,  , or.

To add or remove an init script, just give the   or   argument, followed by the init script and the runlevel. For instance:

The command will show all the available init scripts and list at which runlevels they will execute:

It is also possible to run (without  ) to just view enabled init scripts and their runlevels.

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

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

Каталог conf.d
Gentoo provides an easy way to configure such a service: every init script that can be configured has a file in. For instance, the initscript (called ) has a configuration file called, which can contain the options to give to the Apache 2 server when it is started:

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

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

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

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

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

Зависимости
Существуют две настройки, работающие с зависимостями, которые вы можете определить, и они будут влиять на порядок запуска инициализационных скриптов: use (использую) и need (нуждаюсь). Кроме этих двух, существуют еще два влияющих на порядок загрузки метода, называющихся before (перед) и after (после). Последние два определяют не зависимости, они не заставят выдать ошибку скрипт, если тот скрипт, что в них описан вообще не должен запуститься (или не запустится).


 * Настройка use информирует систему init, что данный скрипт использует функциональность некоторого скрипта, но строго от него не зависит. Хорошим примером будет use logger или use dns. Если эти сервисы есть, они будут хорошо использоваться, но если у вас нет логгера, или DNS-сервера, сервисы все равно будут работать. Если сервисы существуют, они будут запущены до того, как запустится скрипт, использующий их.
 * Настройка need это жесткая зависимость. Она означает, что скрипт, которому нужен другой скрипт, не запустится, пока другой скрипт не запустится успешно. Также, если другой скрипт будет перезапущен, то этот тоже будет перезапущен.
 * При использовании before, данный скрипт запускается до некоторого скрипта, если выбранный скрипт это часть того же	уровня инициализации. Так, инициализационный скрипт xdm, который определен before alsasound будет запущен до скрипта alsasound, но только если alsasound запланирован запуститься на том же уровне инициализации. Если alsasound не запланирован запуститься, то эта конкретная настройка не будет иметь эффекта, и xdm запустится в тот момент времени, который система init посчитает лучшим вариантом.
 * Похожим образом, after информирует систему init, что данный скрипт нужно запустить после некоторого скрипта, если выбранный скрипт является частью того же уровня инициализации. Если нет, то настройка не имеет эффекта, и скрипт будет запущен системой init в момент времени, который, как она посчитает, будет наилучшим.

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

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

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

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

As can be seen, the postfix service:


 * Requires the (virtual) net dependency (which is provided by, for instance, ).
 * Uses the (virtual) logger dependency (which is provided by, for instance, ).
 * Uses the (virtual) dns dependency (which is provided by, for instance, ).
 * Provides the (virtual) mta dependency (which is common for all mail servers).

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

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

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

Стандартные функции
Next to the  functionality, it is also necessary to define the   function. This one contains all the commands necessary to initialize the service. It is advisable to use the  and   functions to inform the user about what is happening:

Both  and   should be used in start and stop functions. If the service does not create a pidfile, then use  if possible, though it is recommended to test this to be sure. Otherwise, don't use pidfiles. It is also possible to add  to the start-stop-daemon options, but this is not recommended unless the service is extremely verbose. Using  may hinder debugging if the service fails to start.

Another notable setting used in the above example is to check the contents of the RC_CMD variable. Unlike the previous init script system, the newer openrc system does not support script-specific restart functionality. Instead, the script needs to check the contents of the RC_CMD variable to see if a function (be it  or  ) is called as part of a restart or not.

For more examples of the  function, please read the source code of the available init scripts in the  directory.

Another function that can (but does not have to) be defined is. The init system is intelligent enough to fill in this function by itself if start-stop-daemon is used.

If the service runs some other script (for example, Bash, Python, or Perl), and this script later changes names (for example, to foo), then it is necessary to add   to start-stop-daemon. This must specify the name that the script will be changed to. In this example, a service starts, which changes names to foo:

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

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

Добавление дополнительных параметров
Если вы хотите ввести в сценарий дополнительные параметры, кроме упоминавшихся, нужно добавить к переменной extra_commands название параметра и создать функцию	с названием, соответствующим параметру. Например, для поддержки параметра restartdelay:

Переменные для настройки служб
In order to support configuration files in, no specifics need to be impleneted: when the init script is executed, the following files are automatically sourced (i.e. the variables are available to use):



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

Кто может от этого выиграть?
Many laptop users know the situation: at home they need to start net.eth0, but they don't want to start net.eth0 while on the road (as there is no network available). With Gentoo the runlevel behaviour can be altered at will.

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

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

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

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

To enable hotplugging, but only for a selected set of scripts, use the rc_hotplug variable in :

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

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