Стартовые скрипты FreeBSD::Журнал СА 7.2003
www.samag.ru
     
Поиск   
              
 www.samag.ru    Web  0 товаров , сумма 0 руб.
E-mail
Пароль  
 Запомнить меня
Регистрация | Забыли пароль?
Журнал "Системный администратор"
Журнал «БИТ»
Наука и технологии
Подписка
Где купить
Авторам
Рекламодателям
Магазин
Архив номеров
Вакансии
Контакты
   

  Опросы

Какие курсы вы бы выбрали для себя?  

Очные
Онлайновые
Платные
Бесплатные
Я и так все знаю

 Читать далее...

1001 и 1 книга  
20.12.2019г.
Просмотров: 4899
Комментарии: 0
Dr.Web: всё под контролем

 Читать далее...

04.12.2019г.
Просмотров: 6151
Комментарии: 0
Особенности сертификаций по этичному хакингу

 Читать далее...

28.05.2019г.
Просмотров: 7389
Комментарии: 2
Анализ вредоносных программ

 Читать далее...

28.05.2019г.
Просмотров: 7733
Комментарии: 1
Микросервисы и контейнеры Docker

 Читать далее...

28.05.2019г.
Просмотров: 6785
Комментарии: 0
Django 2 в примерах

 Читать далее...

Друзья сайта  

Форум системных администраторов  

sysadmins.ru

 Стартовые скрипты FreeBSD

Архив номеров / 2003 / Выпуск №7 (8) / Стартовые скрипты FreeBSD

Рубрика: Администрирование /  Продукты и решения

ДЕНИС ПЕПЛИН

Стартовые скрипты в FreeBSD

Знакомство с системой зачастую начинается с ее установки и настройки, причем эти два процесса обычно совмещены. Для систем UNIX настройка сводится к созданию текстовых файлов конфигурации. В FreeBSD основная работа идет над файлом /etc/rc.conf, который является частью системы стартовых скриптов /etc/rc*.

Настроить систему после установки можно путем запуска /stand/sysinstall или вручную. Оба способа хороши, а первый к тому же лишен недостатка большинства программ автоматической настройки: уже заданные параметры не перезаписываются, а добавляются в конец файла /etc/rc.conf, где их можно затем отредактировать под собственные нужды или вообще удалить, чтобы вернуться к настройкам по умолчанию.

Многие, казалось бы, сложные вещи, которые могут поставить новичка в тупик, в FreeBSD делаются путем добавления пары строк в этот файл. Чтобы не быть голословным, приведу пример настройки шлюза в Интернет для локальной сети с частными адресами (192.168.0.0/24) на внутреннем интерфейсе и NAT на внешнем, кэширующим DNS-сервером и SSH для удаленного управления всем этим хозяйством. Хотя это не самый простой пример, конфигурация умещается всего на 11 строчках:

sshd_enable="YES"

ifconfig_rl0="inet 123.123.123.2 netmask 0xfffffff0"

ifconfig_rl1="inet 192.168.0.1 netmask 0xffffff00"

hostname="example.com"

defaultrouter="123.123.123.1"

firewall_type="OPEN"

firewall_enable="YES"

gateway_enable="YES"

natd_enable="YES"

natd_interface="rl0"

named_enable="YES

Такая лаконичность достигается благодаря тому, что параметры по умолчанию хранятся в /etc/defaults/rc.conf, а строки из /etc/rc.conf лишь изменяют и дополняют эти параметры. Редактировать файл с параметрами по умолчанию не нужно (это только усложнит последующие обновления), но вот просмотреть его хотя бы раз будет полезно.

Строки rc.conf означают не что иное, как установку переменных Bourne shell (/bin/sh). Когда в процессе загрузки системы init запускает скрипт /etc/rc, одним из первых его действий становится установка параметров настройки:

if [ -r /etc/defaults/rc.conf ]; then

    . /etc/defaults/rc.conf

    source_rc_confs

elif [ -r /etc/rc.conf ]; then

    . /etc/rc.conf

fi

В данном случае перезаписыванием параметров по умолчанию занимается функция source_rc_confs (расположенная в /etc/defaults/rc.conf), которая и включает /etc/rc.conf, /etc/rc.conf.local или любые другие файлы из списка, определенного в переменной rc_conf_files. Конструкция эта могла бы быть несколько проще, но используемая функция уже содержит «защиту от дурака», поскольку некоторые пользователи считают удобным копировать /etc/defaults/rc.conf в /etc/rc.conf, что без такой защиты привело бы к зацикливанию.

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

Начиная с FreeBSD 5.x, содержимое это поменялось почти полностью: из NetBSD были заимствованы скрипты «нового поколения» /etc/rc.d. После некоторой паузы, потребовавшейся на тестирование новых скриптов, старые были убраны. Наиболее важные из оставшихся в /etc скриптов и файлы конфигурации:

  • rc – запускается init при загрузке системы.
  • rc.shutdown – запускается init при останове системы.
  • rc.subr – часть системы, импортированной из NetBSD.
  • rc.firewall – предназначен для настройки ipfw и natd.
  • rc.conf – содержит настройки системы, переписывающие параметры по умолчанию.
  • rc.conf.local – специфичные для хоста настройки. Если используется этот файл, rc.conf может быть общим для группы хостов.
  • rc.local – все еще поддерживается для запуска локальных сервисов. Вместо него рекомендуется использовать скрипты /usr/local/etc/rc.d.

Для редактирования предназначены только скрипт rc.firewall и файлы конфигурации. Ситуация, в которой потребовалось бы приспосабливать к своей системе остальные скрипты, возникнуть не должна (по крайней мере, теоретически). Если она все же возникла – сообщите об этом разработчикам.

Принципиальное отличие скриптов нового поколения – поддержка параметров запуска. По сравнению со скриптами из /usr/local/etc/rc.d список этих параметров существенно расширен. К минимальному набору (start|stop) добавились:

  • restart – последовательно stop и start.
  • reload – перегружает процесс, посылая ему сигнал.
  • status – показывает статус процесса.
  • poll – ждет завершения процесса.
  • rcvar – показывает соответствующие переменные rc.conf.

Параметры status, reload и poll реализуются только в том случае, если скрипт запускает какой-либо процесс.

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

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

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

К тому же запуск вручную не всегда тривиален: к примеру, для запуска NFS сервера в FreeBSD 4.x так, как это происходит при установке параметра nfs_server_enable=«YES» в rc.conf, потребуются следующие команды:

# portmap

# mountd -r

# nfsd

# rpc.statd

В FreeBSD 5.x достаточно добавить эту переменную и выполнить команду:

# /etc/rc.d/nfsd start

Очевидно, это гораздо проще и к тому же проверена на правильность соответствующая переменная. В примере с NFS в обеих случаях сначала необходимо подготовить файл /etc/exports (man exports(5)).

Другие параметры также достаточно интересны: например, status поможет узнать, какие процессы запущены в данный момент, а rcvar – познакомиться со скриптами поближе:

# for i in /etc/rc.d/*; do $i status 2>/dev/null; done

# for i in /etc/rc.d/*; do echo $i; $i rcvar 2>/dev/null; echo; done

Для стартовых скриптов системы, в отличие от локальных скриптов в /usr/local/etc/rc.d, очень важен порядок запуска. Локальные скрипты не имеют механизма реализации зависимостей и определения порядка запуска. Они стартуют в алфавитном порядке и если необходимо, чтобы какой-то скрипт стартовал раньше, нужно «повысить» его место по алфавиту. Обычно перед именем скрипта добавляют пару-тройку нулей.

Зависимости и определение порядка запуска в системных стартовых скриптах FreeBSD 5.x реализуются с помощью rcorder(8).

Эта программа использует специальные ключевые слова, содержащиеся в каждом скрипте: REQUIRE, PROVIDE, BEFORE, KEYWORD. Для оболочки строки, содержащие эти слова, являются комментариями. Вот пример блока ключевых слов /etc/rc.d/nfsd (все пробелы обязательны):

# PROVIDE: nfsd

# REQUIRE: mountd

# KEYWORD: FreeBSD NetBSD

Этот скрипт предоставляет сервис nfsd, требует предварительного запуска mountd и работает в FreeBSD и NetBSD.

Должен быть хотя бы один скрипт без ключевого слова REQUIRE, чтобы rcorder мог определить первый стартовый скрипт. Например, /etc/rc.d/devd содержит следующий блок:

# PROVIDE: devd

# BEFORE: disks

# KEYWORD: FreeBSD

Ключевое слово BEFORE помогает определить последующие скрипты (в которых анализируется строка «# PROVIDE: disks»).

В FreeBSD правильную последовательность скриптов выдает следующая команда:

# rcorder -k FreeBSD -s nostart /etc/rc.d/* 2>/dev/null

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

Таких скриптов всего четыре: NETWORKING, SERVERS, DAEMON, LOGIN (man rc(8)). Они используются только rcorder, для sh это всего лишь набор комментариев. Остальные скрипты делятся по признаку наличия или отсутствия расширения «.sh». Если расширение присутствует, скрипт запускается в текущей оболочке.

В локальных скриптах поддержка параметров реализуется с помощью конструкции case. Параметр start предполагает запуск программы, stop – отправку ему сигнала TERM. Любой другой параметр – вывод краткой справки по параметрам. Шаблон локального скрипта выглядит так (man rc(8)):

#!/bin/sh -

case "$1" in

start)

    /usr/local/sbin/prog -d && echo -n " prog"

    ;;

stop)

    kill `cat /var/run/prog.pid` && echo -n " prog"

    ;;

*)

    echo "unknown option: $1 - should be "start" or "stop"" >&2

        ;;

esac

Реализация таким методом большего числа параметров потребует соответствующего числа ключевых слов в case и множества довольно тривиального и одинакового для всех скриптов кода (более сложного, чем в приведенном примере). Видимо, разработчикам NetBSD такое решение изящным не показалось и вся функциональность стартовых скриптов нового поколения была реализована в отдельном скрипте (/etc/rc.subr). Вот шаблон простейшего скрипта «нового поколения».

#!/bin/sh

#

# PROVIDE: prog

# REQUIRE: before_prog

# BEFORE:  after_prog

# KEYWORD: FreeBSD

. /etc/rc.subr 

name="prog"

rcvar=`set_rcvar`

command="/usr/local/bin/prog"

load_rc_config $name

run_rc_command "$1"

Функционально этот скрипт превосходит предыдущий за счет добавления новых параметров (и к тому же, благодаря параметрам rcorder, он «знает свое место»). Визуально он делится на четыре части: ключевые слова, включение /etc/rc.subr, переменные и запуск функций из включенного rc.subr. Между переменными и запуском функций rc.subr могут быть включены собственные функции скрипта. В скрипт могут быть помещены переменные argument_cmd. Слово argument означает параметр запуска. Если запустить любой из стартовых скриптов без параметров, он выдаст информацию примерно в таком виде:

Usage: /etc/rc.d/prog [fast|force](start|stop|restart|rcvar|reload|status|poll)

Параметрами скрипта могут быть start, faststart, forcestart, stop, faststop... и соответственно переменная argument_cmd на самом деле означает набор start_cmd, stop_cmd...

Получить примерное представление о том, какие на самом деле используются переменные, поможет следующая команда:

$ cat /etc/rc.d/[a-z]* | egrep "^[a-z]+_?[a-z]+=.*$" | awk -F= "{print $1}" | sort -u | less

Не менее интересен может быть просмотр переменных вместе с их значениями:

$ cat /etc/rc.d/[a-z]* | egrep "^[a-z]+_?[a-z]+=.*$" | sort -u | less

В man rc.subr(8) дано описание всех используемых функций и переменных.

Задаваемые в стартовых скриптах переменные используются функцией run_rc_command. Вот список этих переменных в сокращенном виде:

  • name – имя скрипта. Указывается в обязательном порядке.
  • rcvar – значение переменной, имя которой помещено в rcvar, берется из rc.conf и проверяется с помощью checkyesno. Истинными считаются значения «YES», «TRUE», «ON» или «1». Ложными «NO», «FALSE», «OFF» или «0».
  • command – полный путь к команде. Переменная не нужна, если для каждого поддерживаемого параметра указана переменная argument_cmd.
  • command_args – опциональные аргументы и/или директивы оболочки.
  • command_interpreter – командный интерпретатор, с помощью которого запускается command.
  • extra_commands – дополнительные параметры запуска.
  • pidfile – полный путь к файлу PID. Если эта переменная установлена, для проверки процесса используется check_pidfile $pidfile $procname. Иначе, если установлена переменная command, используется check_process $procname.
  • procname – имя процесса для проверки. По умолчанию – procname.
  • required_dirs – проверка на наличие директории перед стартом программы.
  • required_files – проверка на читаемость файлов.
  • required_vars – проверка переменной с помощью checkyesno.
  • ${name}_chdir – каталог, в который нужно войти перед запуском command, если нет – ${name}_chroot.
  • ${name}_chroot – каталог для запуска chroot(8) перед запуском command.
  • ${name}_flags – эта переменная используется для перезаписи соответствующей переменной из rc.conf.
  • ${name}_nice – устанавливает уровень nice(1) перед запуском command.
  • ${name}_user – пользователь, под которым запускается command. Если установлена переменная ${name}_chroot, используется chroot(8), иначе – su(1).
  • ${name}_group – группа для запуска command в chroot.
  • ${name}_groups – разделенный запятыми список групп для запуска в chroot.
  • argument_cmd – перезаписывает действие по умолчанию.
  • argument_precmd – выполняется перед argument_cmd или действием по умолчанию, которое выполняется только в случае успешного завершения argument_precmd.
  • argument_postcmd – выполняется, если argument_cmd или действие по умолчанию успешно выполнены.
  • sig_stop – сигнал, который посылается процессу для его завершения вместо SIGTERM.
  • sig_reload – сигнал, который посылается процессу для перезагрузки вместо SIGHUP.

Префикс fast означает отсутствие проверки запущенных процессов перед запуском нового и установку переменной rc_fast=YES, а префикс force – установку переменной rc_force=YES и игнорирование статуса завершения argument_precmd.

В отличие от локальных скриптов, для работы скрипта «нового поколения» в rc.conf должна быть помещена переменная, имя которой определяется значением rcvar. Кроме того, туда же можно поместить и дополнительные переменные, например ${name}_flags.

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


Комментарии отсутствуют

Добавить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

               Copyright © Системный администратор

Яндекс.Метрика
Tel.: (499) 277-12-41
Fax: (499) 277-12-45
E-mail: sa@samag.ru