Наши партнеры

UnixForum






Книги по Linux (с отзывами читателей)

Библиотека сайта rus-linux.net

На главную -> MyLDP -> Тематический каталог -> Процесс начальной загрузки системы

Как написать скрипт загрузки


В первую очередь рассмотрим структуру скриптов загрузки, последовательность их запуска.

Все скрипты загрузки находятся в директории /etc/rc.d - который будем считать корнем. В корне находятся три основных скрипта - rc, rc.sysinit и rc.local, а также директории init.d, содержащая скрипты запуска различных сервисов и директории rcN.d (N - номера от 1 до 6), в которых находятся символьные ссылки в определенном формате на скрипты в init.d. По этим ссылкам осуществляется запуск необходимого набора сервисов для каждого уровня запуска (runlevel). В корне могут также содержаться скрипты rc.modules и rc.serial

При загрузке первым выполняется rc.sysinit. В этом скрипте происходит инициализация оборудования, подключение swap-раздела, монтирование и проверка локальных файловых систем. Если имеются скрипты rc.modules и rc.serial, то они будут вызваны из rc.sysinit. Обычно, в этих скрипты предназначены для загрузки моделуй в ядро и инициализации последовательных портов.

Затем выпоняется rc. В качестве параметра ему передается текущий уровень запуска. Этот скрипт просто вызывает скрипты старта сервисов, находящиеся в rcN.d (N - текущий уровень запуска).

Скрипт запуска сервиса рассмотрим на примере старта сервиса fetchmail. Вот полный текст скрипта:

#! /bin/sh
#
# chkconfig: 345 80 20
# description: run fetchmail service
#

if [ ! -x /usr/bin/fetchmail ]; then
    exit 1
fi

if [ -x /etc/rc.d/init.d/functions ]; then
   . /etc/rc.d/init.d/functions
fi

RETVAL=0

start () {
    echo "Starting fetchmail"
    daemon /usr/bin/fetchmail
    RETVAL=$?
    [ $RETVAL -eq 0 ] && touch /var/lock/subsys/fetchmail
    echo
    return $RETVAL
}

stop () {
    echo -n "Stopping $prog: "
    killproc /usr/bin/fetchmail
    RETVAL=$?
    [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/fetchmail
    echo
    return $RETVAL
}

case $1 in
    start)
	start
	;;
    stop)
	stop
	;;
    restart|reload)
	stop
	start
	;;
    condrestart)                                                                
	if [ -f /var/lock/subsys/fetchmail ]; then                                    
            stop
            start                                                             
        fi                                                                      
        ;;                                                                      
    status)
	status /usr/bin/fetchmail
	;;
    *)
	echo "Usage: $0 {start|stop|restart|reload|condrestart|status}"
	;;
esac

RETVAL=$?

exit $RETVAL

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

Затем следуют проверки существования программ, необходимых для сервиса. Это - /usr/bin/fetchmail и /etc/rc.d/init.d/functions. Вторая проверка должна присутствовать во всех скриптах, так как файл /etc/rc.d/init.d/functions содержит набор функций, использующихся при запуске сервисов изи скриптов загрузки. Полное описание функций дано в Приложении.

Затем идут функции запуска и останова сервиса. В них очень желательно использовать процедуры daemon или action и killproc из набора функций /etc/rc.d/init.d/functions, так как при использовании этих процедур производится запись в системные лог-файлы. Скрипт rc также проверяет наличие этих функций в скрипте запуска сервиса. Если функции отсутствуют - весь вывод скрипта перенаправляется в лог, и rc дает свое сообщение о старте сервиса.

Основная часть скрипта - выполнение определенных действий в зависимости от аргумента. Аргументы могут быть следующими:
start - запуск сервиса;
stop - остановка сервиса;
restart - полный перезапуск сервиса;
reload - перезагрузка сервиса (например когда необходимо просто перечитать конфигурационные файлы и нет необходимости полного перезапуска сервиса);
condrestart - условный перезапуск (например - перезапустить сервис, если он был запущен не из скрипта загрузки);
status - получить статус сервиса.

Обязательно должна присутствовать обработка аргументов start и stop.

Для работы со скриптами усществуют две утилиты - chkconfig и service. service просто запускает указанный в аргументах скрипт (с указанными параметрами), что избавляет от необходимости набора полного пути к скрипту.

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


Приложение. Формат заголовка.

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

Остальные поля - чисто информативные, служат для описания скрипта, использыемых файлов конфигурации и т.д. Функции, предоставляемые /etc/rc.d/init.d/functions

checkpid <pid> - проверка наличия процесса по pid;
daemon [+/-nicelevel] <program> - запуск процесса; необязательные параметр - уровень приоритетности
killproc - остановка процесса
pidfileofproc <program> - определение pid процесса по pid-файлу
pidofproc <program> - определение pid процесса
status <program> - получение статуса процесса
success - вывод [ OK ]
failure - вывод [FAILED]
passed - вывод [PASSED]
action <command string> - выполение команды
strstr <string> <substring> - проверка наличия построки в строке
confirm - запрос подтверждения запуска сервиса

Небольшое дополнение про уровни выполнения

В тех системах, в которых процесс начальной загрузки построен по принципу System V (в отличие от принципа BSD) - RedHat, Mandrake, etc, используется такое понятие как уровни выполнения - ранлевелы (runlevels). Их можно рассматривать как способ приведения системы к определенной конфигурации без ее переустановки.

В один из моментов начальной загрузки системы управление переходит к скрипту /etc/rc.d/rc. Именно этот скрипт занимается управлением уровнями выполнения в этом случае. Очень рекомендую почитать его - он достаточно просто написан и поэтому легок для понимания.

Из его текста видно, что он просматривает каталоги /etc/rc.d/rcN.d (N - некоторое число) и сначала ищет в них файлы, начинающиеся на K и запускает их по порядку возрастания номеров, идущих сразу после буквы K в их имени. Как вы наверное успели заметить, каталог /etc/rc.d/rcN.d не содержит файлов как таковых, а только символические ссылки на файлы в /etc/rc.d/init.d. Это сделано специально для того, чтобы не множить файлы по системе и, как следствие, для предотвращения рассинхронизации их версий (и для удобства управления процессами). Файл, лежащий в /etc/rc.d/init.d должен быть написан так, как выше написал Ananas, хотя это и не критично. При разгрузке система обязательно убьет все процессы, однако при использовании скриптов в init.d есть возможность завершить свой процесс корректно.

Буква K в начале имени ссылки как раз и говорит rc, что скрипт из init.d надо запустить с ключом stop.

Все это справедливо и для ссылок с именами на S, только те же файлы из init.d будут запущены теперь с ключом start.

Таким образом мы получили систему запуска одних программ и останова других грубо говоря при помощи указания одной цифры (N) в определенном месте. Состояние, в котором оказывается система после указания этой самой цифры как раз и называется уровнем выполнения или ранлевелом.

Добавлять ссылки в каталоги /etc/rc.d/rcN.d можно и вручную, но тогда придется еще несколько вещей делать также вручную, поэтому лучше для этих целей воспользоваться программой chkconfig. Однако у этой программы есть одно не очень приятное свойство - уровней выполнения может быть только 10 - от 0 до 9 (хотя man chkconfig в RH 6.0 говорит, что их всего 8 - от 0 до 7). Теоретически же (исходя из текста скрипта rc) их количество неограничено и в данном случае ручки рулят.

В разных системах ранлевелы несколько разнятся, в конкретном случае их назначение можно поискать в файле /etc/inittab. Тем не менее, чаще всего выглядит это так:

0 - останов
1 - single (однопользовательский без сети)
2 - многопользовательский без сети
3 - многопользовательский с сетью
4 - многопользовательский с иксами без сети
5 - многопользовательский с иксами и с сетью
6 - перезагрузка

Этот файл (/etc/inittab), кстати сказать, прочитывается Первым процессом - init, который устанавливает дефолтовый уровень выполнения N через строку

id:N:initdefault:

С помощью этого же процесса можно перевести систему на другой уровень при помощи команды

# init N

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

Авторы: Ananas, San АНДРЕЕВ

Опубликовал: Ananas
Дата: 23.07.2003
постоянный адрес статьи: http://linuxportal.ru/entry.php/P21_0_3_0/