Сценарии запуска и останова


Сценарии запуска и останова находятся в каталоге /etc/rc и называются rc-сценариями. Такой сценарий управляет загрузкой системы в многопользовательском режиме и процессом ее останова. Основные сценарии запуска располагаются в каталоге /etc/rc.d, сценарии из других каталогов управляют дополнительным программным обеспечением. Сценарии запуска устанавливаются из «портов» и пакетов, но если вы устанавливаете собственное программное обеспечение, то вам потребуется самостоятельно создать сценарии запуска. Этот раздел предполагает базовое понимание сценариев на языке командного интерпретатора. Если вы никогда их не видели и не применяли, изучите примеры очень внимательно. Создавать командные сценарии нетрудно, и лучший способ научиться этому состоит в том, чтобы изучать примеры и приспосабливать их под свои нужды. Кроме того, для изменения процесса запуска или останова необходимо понимать, как работают сценарии запуска.

В ходе начальной загрузки операционная система FreeBSD проверяет каталог /usr/local/etc/rc.d на наличие дополнительных сценариев командного интерпретатора, чтобы использовать их в процессе запуска/останова. (С помощью параметра local_startup в файле rc.conf можно определить дополнительные каталоги, но сейчас мы будем полагать, что в системе имеется единственный каталог, используемый по умолчанию.) В процессе запуска производится поиск исполняемых сценариев командного интерпретатора и предполагается, что все найденные сценарии являются сценариями запуска. Система выполняет такие сценарии с аргументом start. При останове система FreeBSD запускает те же сценарии с аргументом stop. Предполагается, что сценарии принимают эти аргументы и выполняют соответствующие действия.

Порядок запуска rc-сценариев

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

# rcorder /etc/rc.d/* /usr/local/etc/rc.d/*
rcorder: Circular dependency on provision 'mountcritremote' in file 'archdep'.
(Перевод: Циклическая зависимость от 'mountcritremote' в файле 'archdep') rcorder: requirement 'usbd' in file '/usr/local/etc/rc.d/hald' has no providers.
(Перевод: 'usbd', требуемый в файле'/usr/local/etc/rc.d/hald', отсутствует)
dumpon
initrandom
geli
gbde
encswap
...

В данном случае утилита rcorder(8) отсортировала все сценарии в каталогах /etc/rc.d и /usr/local/etc/rc.d в порядке, в каком они будут запускаться во время загрузки системы. В первую очередь мы видим предупреждения: дело в том, что некоторые сценарии имеют циклические ссылки. Наличие таких конфликтов необязательно означает что-то ужасное, потому что не каждый сценарий всегда запускается во всех системах. В данном примере сценарий mountcritremote требует, чтобы перед ним был запущен сценарий archdep, но сценарий archdep, в свою очередь, должен запускаться после того, как отработает сценарий mountcritremote. В этом конфликте нет ничего страшного, потому что несмотря на него моя система все-таки загружается. Эта система не монтирует удаленные файловые системы, поэтому сценарий mountcritremote фактически ничего не делает, выдавая бессмысленное сообщение об ошибке. Точно так же сценарий hald требует, чтобы перед ним был запущен несуществующий сценарий usbd. В версии FreeBSD 7.0 отсутствует демон usbd(8), но он имеется в более старых версиях операционной системы, которые поддерживаются деревом «портов». Система запуска достаточно интеллектуальна, чтобы перескочить эти ошибки.

Упорядочивание сценариев запуска производится на основе маркеров, расположенных внутри самих сценариев.

Типичный сценарий запуска

Система запуска постоянно развивается. Поэтому, прежде чем приступать к созданию собственного сценария, загляните сначала в один из простых сценариев в каталоге /etc/rc.d, чтобы убедиться в том, что мои слова все еще соответствуют действительности. Типичный сценарий запуска должен выглядеть примерно так, как показано ниже, хотя вы можете заметить незначительные отличия:

Метка PROVIDE (1) сообщает утилите rcorder(8) официальное название сценария. Если какой-то другой сценарий потребует предварительно запустить rpcbind(8), этот сценарий будет перечислен в списке зависимостей. Подобным образом метка REQUIRE (2) перечисляет сценарии, которые должны быть запущены перед этим сценарием. Данный сценарий должен запускаться после сценариев NETWORKING, ntpdate, syslogd и named.

Чтобы использовать механизм самоупорядочения сценариев запуска, необходимо подключить к rc-сценарию инфраструктуру /etc/rc.subr (3). Ваш сценарий должен определить имя команды (4), как указано в /etc/rc.conf.

Выражение rcvar (5) — это наследие тех времен, когда FreeBSD и OpenBSD использовали единую систему сценариев запуска, но система запуска по-прежнему предполагает наличие этого выражения. Вам также необходимо указать точную команду, которая должна быть запущена (6), — в принципе, в системе может быть несколько одноименных команд, если они находятся в разных каталогах. Далее выполняется загрузка конфигурации для этой команды из /etc/rc.conf (7). И, наконец, можно выполнить фактическую команду (8).

Хотя все это может испугать, в действительности здесь нет ничего сложного. Для начала просто создайте копию одного из существующих сценариев. Впишите имя вашей команды и соответствующим образом измените путь. Выясните, какие сценарии должны запускаться перед ним: может быть, для запуска сценария требуется подключение к сети? Должны ли быть прежде запущены какие-то демоны или нужно, чтобы ваша программа запускалась перед какими-то демонами? Если это пока неизвестно, сделайте так, чтобы последним запускался ваш сценарий, скопировав содержимое метки REQUIRE из сценария, который запускается последним. Ознакомившись с содержимым других сценариев запуска, реализующих подобные функции, вы узнаете практически все, что нужно для создания сценария запуска.

С помощью этого простого сценария вы сможете разрешать или запрещать запуск своей программы, а также настраивать ее, добавляя параметры настройки в /etc/rc.conf. Допустим, если вы дали своему демону имя tracker, ваш сценарий будет отыскивать переменные tracker_enable и tracker_flags в /etc/rc.conf и использовать их каждый раз при выполнении сценария.

Специальные значения в метке PROVIDE

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

Значение FILESYSTEMS гарантирует, что к моменту запуска будут смонтированы все локальные файловые системы, перечисленные в /etc/fstab.

Значение NETWORKING гарантирует, что будут сконфигурированы все сетевые функции, включая настройку IP-адресов на сетевых интерфейсах, настройку фильтра пакетов PF и т. д.

Значение SERVER гарантирует готовность системы к запуску таких основных серверов, как named(8), и программ поддержки NFS. К этому моменту удаленные файловые системы еще не смонтированы.

Значение DAEMON гарантирует, что к моменту запуска будут смонтированы все локальные и удаленные файловые системы, включая NFS и CIFS, и что будут запущены расширенные сетевые службы, такие как DNS.

Значение LOGIN соответствует состоянию, когда все сетевые службы системы уже запущены и FreeBSD приступает к запуску служб поддержки входа пользователя через консоль, FTP, SSH и других.

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

Применение сценариев для управления запущенными программами

Те из вас, кто имел дело со сценариями командного интерпретатора, могли заметить, что приведенный выше сценарий фактически не включает ничего, что отвечало бы за запуск, перезапуск, остановку и получение информации о состоянии программы. Все это реализует rcNG.* Нужно перезапустить демона? Просто выполните команду:

# /usr/local/etc/rc.d/customscript restart

а все остальное сделает rcNG.

Читатели, обладающие некоторым опытом работы с UNIX, могут подумать: «Зачем тогда вообще создавать сценарий, если я просто могу использовать командную строку?» Если вы знакомы с программой, вы наверняка знаете, какую команду следует выполнить, чтобы запустить или остановить ее. Все так, но это не самый лучший выход, потому что тогда системный администратор рабочего сервера должен будет запускать и останавливать каждую программу строго определенным способом. При использовании инфраструктуры rcNG вы уверены, что в любое время программа будет запущена именно таким способом, как во время загрузки системы. Подобным образом, каждый раз программа будет останавливаться точно так же, как во время останова системы. Можно выучить все аргументы командной строки для каждого демона в системе и гордиться этим, но осознать необходимость единообразия запуска и останова и всегда применять обеспечивающие его системные инструменты — значит понимать разницу между знанием системы UNIX и знакомством с ней.

Сценарии запуска/останова сторонних производителей

Представьте, что вы устанавливаете сложный программный продукт, разработчик которого не поддерживает систему запуска FreeBSD. Для нас это не проблема. В большинстве случаев разработчики поставляют сценарии, принимающие единственный аргумент, например stop или start. He забывайте, что во время загрузки FreeBSD запускает rc-сценарии без аргумента start, а во время останова — без аргумента stop. Добавив операторы PROVIDE и REQUIRE в виде комментариев, вы сможете организовать запуск сценария в соответствующее время на этапе загрузки и останова системы. Учет особенностей системы запуска в управлении сценариями не является обязательным требованием.

Отладка своих сценариев запуска

Локальные сценарии, например те, что устанавливаются системой «портов», запускаются с помощью /etc/rc.d/localpkg. Если ваш собственный сценарий вызывает проблемы, можно попробовать запустить сценарий localpkg в режиме отладки и посмотреть, как ваш сценарий взаимодействует с системой запуска. Лучший способ заключается в использовании режима отладки.

# /bin/sh -х /etc/rc.d/localpkg start

При этом будет выполнена попытка запустить все локальные демоны на сервере, в рабочей системе это не всегда желательно. Попробуйте сначала выполнить отладку на тестовой системе. Кроме того, следует помнить, что ключ включения режима отладки -x не передается дочерним сценариям — в режиме отладки будет работать только сценарий /etc/rc.d/localpkg.

Комментарии запрещены.