В наше время выходит множество интересных сетевых проектов. Чаще всего это демоны, которые вертятся в бэграунде на каком-либо сервере. Примеров масса: ircd, icqserver, mysqld, smtpd... Цепочку продолжают пользовательские скрипты, которые должны всегда висеть в таблице процессов. Но людям свойственно ошибаться, поэтому софт часто падает по 11 сигналу (попросту, в кору). Этого избежать помогают лишь свежевыпущенные патчи, либо новая версия проекта. Но все равно, контроль за процессами необходим всегда.
Рассмотрим живой пример: сервер выходит в Инет через vpn-шлюз. Однажды такой шлюз перезагрузили. Естественно, что соединение падает. Восстановить его можно лишь автоматизированным скриптом. Иначе - админу придется бежать и поднимать интерфейс непосредственно с консоли ;).
Как пишутся подобные скрипты? Очень просто. Существуют даже несколько вариантов их реализации. Рассмотрим два из них.
1. По pid-файлу.
"Умные" демоны всегда оставляют за собой файл, который хранит идентификатор процесса. Естественно, что файл существует лишь тогда, когда приложение запущено. Это нам и надо. Скрипт сводится к пару строчкам, которые проверяют - существует ли pid-файл в системе? Напишем скрипт для вышеизложенного случая. Как ты уже догадался, проверять мы будем активность pppd, который активизирует интерфейс ppp0.
#!/usr/bin/perl
unless(-e "/var/run/ppp0.pid") {
system("/sbin/service pptptunnel start");
}
Всего одно условие. Если файл не существует - запускаем pptptunnel. После написания этого скрипта, поместим его в кронтаб суперпользователю. Это достигается командой crontab -e. В среде vi жмем "i" и набираем следующее:
*/5 * * * * /usr/bin/chkpppd > /dev/null 2>&1.
Таким образом, активация скрипта /usr/bin/chkpppd будет производиться каждые пять минут.
2. По таблице процессов.
Если приложение не оставляет никаких файлов, то остается только один выход - узнать, существует ли в данный момент идентификатор процесса. Получить его можно с помощью стандартных утилит ps, grep и awk. Само выделение идентификатора очень полезно - с ним можно сделать много вещей - например, послать сигнал SIGINT (rehash). Таким образом, промодифицируем скрипт.
#!/usr/bin/perl
chomp($cmd=`ps ax|grep pppd|grep -v grep|awk \'\{print \$1\}\'`);
unless($cmd) {
system("/sbin/service pptptunnel start");
}
Экранирование символов очень важно, поскольку Perl примет конструкцию языка awk за свой синтаксис ;). Промежуточная команда grep -v grep обезопасит тебя от ложных выводов идентификатора grep.
Но это все стандартно. Что если тебе захочется проконтролировать пять, а то и двадцать процессов, которые крутятся у тебя на машине? Не писать же двадцать разных скриптов для этой нужды. Достаточно написать один. Сценарий будет просматривать специальный файл, в котором записана маска процесса, а также команда запуска демона в случае падения сервиса. Общий синтаксис документа такой:
pptp;/usr/sbin/pptp vpn.server.ru
ircd;/usr/ircd/ircd
squid;/usr/squid/sbin/squid -D
Теперь пропарсим его скриптом.
#!/usr/bin/perl
$pfile = 'ps.lst'; ## Файл с данными
open(PFILE,$pfile);
@ps=<PFILE>;
close(PFILE); ## Получим данные в отдельный массив.
foreach (@ps) {
($proc,$start)=split(";",$_); ## Сплитуем их на две составляющие
chomp;
$match = `ps ax | grep $proc | grep -v grep | awk \{\'printf(\$1)\'\}`; ## Выделяем PID
system("$start")
unless ($match); ## Если PID не найден - запускаем процесс
undef $match; ## И делаем переменную неявной.
}
Теперь прописываем скрипт в кронтаб и радуемся жизни - твои сервисы никогда не упадут на длительное время ;). Можно промодифицировать скрипт, чтобы он писал в лог о падении того или иного сервиса. Было бы желание...