Демон
Демон
Демоны играют важную роль в работе операционной системы. Достаточно будет сказать, что возможность терминального входа пользователей в систему, доступ по сети, использование системы печати и электронной почты, — все это обеспечивается соответствующими демонами — неинтерактивными программами, составляющими собственные сеансы (и группы) и не принадлежащими ни одному из пользовательских сеансов (групп).
Некоторые демоны работают постоянно, наиболее яркий пример такого демона — процесс init(1M), являющийся прародителем всех прикладных процессов в системе. Другими примерами являются cron(1M), позволяющий запускать программы в определенные моменты времени, inetd(1M) обеспечивающий доступ к сервисам системы из сети, и sendmail(1M), обеспечивающий получение и отправку электронной почты.
При описании взаимодействия процессов с терминалом и пользователем в разделе "Группы и сеансы", отмечалось особое место демонов, которые не имеют управляющего терминала. Теперь в отношении демонов можно сформулировать ряд правил, определяющих их нормальное функционирование, которые необходимо учитывать при разработке таких программ:
1. Демон не должен реагировать на сигналы управления заданиями, посылаемые ему при попытке операций ввода/вывода с управляющим терминалом. Начиная с некоторого времени, демон снимает ассоциацию с управляющим терминалом, но на начальном этапе запуска ему может потребоваться вывести то или иное сообщение на экран.
2. Необходимо закрыть все открытые файлы (файловые дескрипторы), особенно стандартные потоки ввода/вывода. Многие из этих файлов представляют собой терминальные устройства, которые должны быть закрыты, например, при выходе пользователя из системы. Предполагается, что демон остается работать и после того, как пользователь "покинул" UNIX.
3. Необходимо снять его ассоциацию с группой процессов и управляющим терминалом. Это позволит демону избавиться от сигналов, генерируемых терминалом (SIGINT или SIGHUP), например, при нажатии определенных клавиш или выходе пользователя из системы.
4. Сообщения о работе демона следует направлять в специальный журнал с помощью функции syslog(3), — это наиболее корректный способ передачи сообщений от демона.
5. Необходимо изменить текущий каталог на корневой. Если этого не сделать, а текущий каталог, допустим, находится на примонтированной файловой системе, последнюю нельзя будет размонтировать. Самым надежным выбором является корневой каталог, всегда принадлежащий корневой файловой системе.
Приведем скелет программы-демона:
#include <stdio.h>
#include <syslog.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/resource.h>
main(int argc, char **argv) {
int fd;
struct rlimit flim;
/* Если родительский процесс — init, можно не беспокоиться
за терминальные сигналы. Если нет — необходимо игнорировать
сигналы, связанные с вводом/выводом на терминал
фонового процесса: SIGTTOU, SIGTTIN, SIGTSTP */
if (getppid() != 1) {
signal(SIGTTOU, SIG_IGN);
signal(SIGTTIN, SIG_IGN);
signal(SIGTSTP, SIG_IGN);
/* Теперь необходимо организовать собственную группу и сеанс,
не имеющие управляющего терминала. Однако лидером группы и
сеанса может стать процесс, если он еще не является лидером.
Поскольку предыстория запуска данной программы неизвестна,
необходима гарантия, что наш процесс не является лидером.
Для этого порождаем дочерний процесс. Т.к. его PID уникален,
то ни группы, ни сеанса с таким идентификатором не существует,
а значит нет и лидера. При этом родительский процесс
немедленно завершает выполнение, поскольку он уже не нужен.
Существует еще одна причина необходимости порождения
дочернего процесса. Если демон был запущен из командной строки
командного интерпретатора shell не в фоновом режиме,
последний будет ожидать завершения выполнения демона,
и таким образом, терминал будет заблокирован.
Порождая процесс и завершая выполнение родителя,
имитируем для командного интерпретатора завершение
работы демона, после чего shell выведет свое приглашение */
if (fork () !=0)
exit(0); /* Родитель заканчивает работу */
/* Дочерний процесс с помощью системного вызова
становится лидером новой группы, сеанса и не имеет
ассоциированного терминала */[28]
}
/* Теперь необходимо закрыть открытые файлы. Закроем
все возможные файловые дескрипторы. Максимальное число
открытых файлов получим с помощью функции getrlimit */
getrlimit(RLIMIT_NOFILE, &flim);
for (fd = 0; fd < flim.rlim_max; fd++)
close(fd);
/* Сменим текущий каталог на корневой */
chdir("/");
/* Заявим о себе в системном журнале. Для этого сначала
установим опции ведения журнала: каждая запись будет
предваряться идентификатором PID демона, при невозможности
записи в журнал сообщения будут выводиться на консоль,
источник сообщений определим как "системный демон"
(см. комментарии к функциям ведения журнала ниже). */
openlog("Скелет демона" , LOG_PID | LOG_CONS, LOG_DAEMON);
/* Отметимся */
syslog(LOG_INFO, "Демон начал плодотворную работу...");
closelog();
/* Далее следует текст программы, реализующий полезные функции
демона. Эта часть предоставляется читателю для собственной
разработки. */
...
}
В программе использовалось еще не обсуждавшаяся возможность системного журнала сообщений выполняющихся программ. Функцией генерации сообщений является syslog(3), отправляющая сообщение демону системного журнала syslogd(1M), который в свою очередь либо дописывает сообщения в системный журнал, либо выводит на их консоль, либо перенаправляет в соответствии со списком пользователей данной или удаленной системы. Конкретный пункт назначения определяется конфигурационным файлом (/etc/syslog.conf). Функция имеет определение:
#include <syslog.h>
void syslog(int priority, char *logstring, /* параметры*/...);
Каждому сообщению logstring назначается приоритет, указанный параметром priority. Возможные значения этого параметра включают:
LOG_EMERG Идентифицирует состояние "паники" в системе. Обычно рассылается всем пользователям. LOG_ALERT Идентифицирует ненормальное состояние, которое должно быть исправлено немедленно, например, нарушение целостности системной базы данных. LOG_CRIT Идентифицирует критическое событие, например, ошибку дискового устройства. LOG_ERR Идентифицирует различные ошибки. LOG_WARNING Идентифицирует предупреждения. LOG_NOTICE Идентифицирует события, которые не являются ошибками, но требуют внимания. LOG_INFO Идентифицирует информационные сообщения, как, например, использованное в приведенной программе. LOG_DEBUG Идентифицирует сообщение, обычно используемое только при отладке программы.Последний тип сообщений подсказывает еще одну возможность использования системного журнала — для отладки программ, особенно неинтерактивных.
Строка logstring может включать элементы форматирования, такие же, как и в функции printf(3), с одним дополнительным выражением %m, которое заменяется сообщением, соответствующим ошибке errno. При этом может осуществляться вывод значений дополнительных параметров.
Функция openlog(3) позволяет определить ряд опций ведения журнала. Она имеет следующее определение:
void openlog(char *ident, int logopt, int facility);
Строка ident будет предшествовать каждому сообщению программы. Аргумент logopt задает дополнительные опции, в том числе:
LOG_PID Позволяет указывать идентификатор процесса в каждом сообщении. Эта опция полезна при журналировании нескольких демонов с одним и тем же значением ident, например, когда демоны порождаются вызовом fork(2). LOG_CONS Позволяет выводить сообщения на консоль при невозможности записи в журнал.Наконец, аргумент facility позволяет определить источник сообщений:
LOG_KERN Указывает, что сообщения отправляются ядром. LOG_USER Указывает, что сообщения отправлены прикладным процессом (используется по умолчанию). LOG_MAIL Указывает, что инициатором сообщений является система электронной почты. LOG_DAEMON Указывает, что инициатором сообщений является системный демон. LOG_NEWS Указывает, что инициатором сообщений является система телеконференций USENET. LOG_CRON Указывает, что инициатором сообщений является система cron(1).Закончив работу с журналом, следует аккуратно закрыть его с помощью функции closelog(3):
void closelog(void);
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКДанный текст является ознакомительным фрагментом.
Читайте также
Демон ksoftirqd
Демон ksoftirqd Обработка отложенных прерываний (softirq) и, соответственно, тасклетов может осуществляться с помощью набора потоков пространства ядра (по одному потоку на каждый процессор). Потоки пространства ядра помогают обрабатывать отложенные прерывания, когда система
Демон pdflush
Демон pdflush Измененные (dirty, "грязные") страницы памяти когда-нибудь должны быть записаны на диск. Обратная запись страниц памяти выполняется в следующих двух случаях.• Когда объем свободной памяти становится меньше определенного порога, ядро должно записать измененные
13.2. Демон syslogd
13.2. Демон syslogd Системы Unix обычно запускают демон syslogd в одном из сценариев инициализации системы, и он функционирует, пока система работает. Реализации syslogd, происходящие от Беркли, выполняют при запуске следующие действия:1. Считывается файл конфигурации, обычно /etc/syslog.conf,
13.5. Демон inetd
13.5. Демон inetd В типичной системе Unix может существовать много серверов, ожидающих запроса клиента. Примерами являются FTP, Telnet, Rlogin, TFTP и т.д. В системах, предшествующих 4.3BSD, каждая из этих служб имела связанный с ней процесс. Этот процесс запускался во время загрузки из файла
28.7. Демон сообщений ICMP
28.7. Демон сообщений ICMP Получение асинхронных ошибок ICMP на сокет UDP всегда было и продолжает оставаться проблемой. Ядро получает сообщения об ошибках ICMP, но они редко доставляются приложениям, которым необходимо о них знать. Мы видели, что для получения этих ошибок в API
Демон icmpd
Демон icmpd Начинаем описание нашего демона icmpd с заголовочного файла icmpd.h, приведенного в листинге 28.23.Листинг 28.23. Заголовочный файл icmpd.h для демона icmpd//icmpd/icmpd.h 1 #include "unpicmpd.h" 2 struct client { 3 int connfd; /* потоковый доменный сокет Unix к клиенту */ 4 int family; /* AF_INET или AF_INET6 */ 5 int lport; /*
5.4. Демон inetd/xinetd
5.4. Демон inetd/xinetd Для того чтобы сервер смог обрабатывать запросы клиентов, программа должна быть постоянно загружена и связана с определенным портом. В этом нет ничего сложного, но зачем постоянно держать программу в памяти, особенно если она слишком большая, а работает
5.8.5. Демон klogd
5.8.5. Демон klogd Демон klogd предназначен для перехвата и протоколирования сообщений ядра Linux (klogd расшифровывается как kernel-logging daemon). В своей работе вы можете использовать параметры демона, указанные в табл. 5.9.Параметры демона klogd Таблица 5.9 Параметр Описание -c n
9.4.2. Диспетчер расписаний — демон cron
9.4.2. Диспетчер расписаний — демон cron Этот демон запускается во время инициализации системы (сценарий /etc/init.d/crond), читает свои конфигурационные файлы и переходит в режим ожидания. Раз в минуту демон просыпается, проверяет дату последнего изменения конфигурационных файлов,
19.2.1. Демон routed
19.2.1. Демон routed Стандартной программой маршрутизации в Linux является демон routed. Этот демон, как правило, настраивается сам (динамически) и не требует конфигурирования. Обнаруженные маршруты он заносит в маршрутную таблицу ядра.В своей работе демон routed использует протокол
19.2.2. Демон gated — правильный выбор
19.2.2. Демон gated — правильный выбор В последнее время демон gated используется чаще, чем стандартный routed. Объясняется это тем, что gated более гибок в конфигурировании и обладает большими возможностями, в частности, им поддерживаются протоколы RIP-2 и OSFP.Программа gated была
11.6.8.2. Пара спулер/демон
11.6.8.2. Пара спулер/демон Облегченный вариант пары конфигуратор/актор может оказаться полезным в ситуациях, когда требуется сериализованный доступ к общему ресурсу в пакетном режиме, т.е. когда четко определенный поток заданий или последовательность запросов требует
11.6.8.2. Пара спулер/демон
11.6.8.2. Пара спулер/демон Облегченный вариант пары конфигуратор/актор может оказаться полезным в ситуациях, когда требуется сериализованный доступ к общему ресурсу в пакетном режиме, т.е. когда четко определенный поток заданий или последовательность запросов требует
Пердем – персональный демон
Пердем – персональный демон LinuxFormat #112 (декабрь 2008)Все знают, что пермаш – это персональная машина, пердач – персональная дача, перпен – это... нет, не то, что вы подумали, а персональная пенсия, и так далее. А вот что такое пердем? Это – персональный демон, система PC-BSD,