Исследование организации и функционирования приложений типа демон в Unix-системах

Иванов Ю.А.
Донецкий национальный технический университет


Источник: Інформатика та комп'ютерні технології - 2007 / Матеріали III науково-технічної конференції молодих учених та студентів. - Донецьк, ДонНТУ - 2007.


Демон (от англ. daemon) – фоновый процесс, который находится постоянно в памяти после запуска и выполняет обработку каких-либо внешних или внутренних сигналов. Если провести аналогию с операционными системами фирмы Microsoft, то демонов можно сопоставить с резидентными программами (DOS) на примитивном уровне и более соответствующими им службами в Windows. Рабочий файл демона представляет собой обычный исполнимый файл для Unix. Поэтому запуск демона может производиться любым способом пригодным для запуска исполнимых файлов, например, с помощью терминала. Демон можно запускать в любой момент функционирования операционной системы тогда, когда в этом возникла необходимость, но так как демоны обычно выполняют функции необходимые на всем протяжении работы ОС, они обычно запускаются непосредственно при запуске ОС, описанные в конфигурационном фале процесса init /etc/inittab. Для запуска демона используются родительская программа, которая необходима только для порождения дочернего процесса, который впоследствии станет демоном. Выполнив создание дочернего процесса, родительская программа сразу же завершается, поскольку её потомок (демон) продолжает выполнение, ОС автоматически делает родителем данного процесса процесс init. Процесс порождения демона, как дочернего процесса, с точки зрения ОС, не отличается от создания обычного процесса, и выполняются одни и те же функции, а именно:

  1. Создается новая структура task_struct в таблице процессов ядра и содержание такой же структуры старого (или текущего) процесса копируется в новую структуру.
  2. Назначается идентификатор (PID) нового процесса. PID – это уникальное положительное число, которое присваивается каждому процессу при его рождении. Именно по этим идентификаторам система различает процессы.
  3. Увеличиваются счетчики открытия файлов (порожденный процесс наследует все открытые файлы родительского процесса).
  4. После того, как процесс создан, запускается выполняемая им программа с помощью одного из вариантов системного вызова exec. Параметрами функции exec является имя выполняемого файла и, если нужно, параметры, которые будут переданы этой программе.
  5. Программа из указанного файла загружается в адресное пространство процесса, порожденного с помощью fork(), счетчик команд устанавливается в начальное значение и вновь созданный процесс переходит в режим ожидания того момента, когда планировщик выделит ему время центрального процессора.
  6. В том процессе, откуда вызывались функции fork() и exec, управление передается в точку возврата из системного вызова и выполнение этого процесса продолжается. Родительский процесс может дожидаться окончания выполнения всех своих процессов-потомков с помощью системного вызова wait.

После запуска демона в памяти будет храниться непосредственно основная программа демона. ОС сохранит в своем адресном пространстве данные необходимые для корректного функционирования процесса-демона (структура task_struct и контекст процесса), что необходимо для организации переключения между процессами. Основная программа демона хранится в памяти полностью, как любой обычный процесс, дополнительной дозагрузки кода не производится. Модель функционирования демона эквивалентна модели функционирования обычных процессов. Основные этапы “жизни” демона по временным интервалам отличаются от обычного процесса. С момента создания и до завершения процесса преобладает этап ожидания и, обычно, время ожидания на порядок превышает длительность готовности и выполнения. Для управления демоном (посылки ему каких-то данных) можно использовать стандартные методы межпроцессного взаимодействия, в случае если это предусмотрено разработчиком. Обычно же демон представляет собой “закрытую” программу, не требующую непосредственного управления: т.е. демоны используются для сервисных функций, обслуживание запросов от других процессов, драйверов. Пользователь непосредственно демонами не управляет, он влияет на их работу, посылая им какие-либо задания. Важной особенностью демонов является то, что они работают в неинтерактивном режиме. Если с обычным процессом всегда ассоциирован какой-то терминал или псевдотерминал, через который осуществляется взаимодействие процесса с пользователем, то демон такого терминала не имеет. Исходя из того, что демон не имеет привязки к определенному терминалу, но во время работы демона дескрипторы стандартных потоков ввода, вывода и ошибок могут быть открыты, поскольку они необходимы многим функциям стандартной библиотеки, необходимо сделать так, чтобы дескрипторы не указывали на какие-либо реальные потоки ввода/вывода. Кроме того, необходимо изменить текущую директорию на корневую, так как демон может работать вплоть до перезагрузки системы и текущая директория демона должна принадлежать файловой системе, которая не может быть размонтирована, чтобы не вызвать конфликта работы с ФС. Каждый демон после запуска должен создавать pid-файл. Этот файл обычно содержится в директории /var/run и имеет имя .pid, где соответствует имени демона. Этот файл (файл блокировки) содержит значение PID процесса демона. Этот файл важен по двум причинам. Во-первых, его наличие позволяет установить, что в системе уже запущен один экземпляр демона. Большинство демонов, включая данный, должны выполняться не более чем в одном экземпляре, чтобы не вызвать конфликтов при работе с не разделяемыми ресурсами. Завершаясь, демон удаляет pid-файл, указывая тем самым, что можно запустить другой экземпляр процесса. Однако, работа демона не всегда завершается нормально, и тогда на диске остается pid-файл несуществующего процесса. Это, казалось бы, может стать непреодолимым препятствием для повторного запуска демона, но на самом деле, демоны успешно справляются с такими ситуациями. В процессе запуска демон проверяет наличие на диске pid-файла с соответствующим именем. Если такой файл существует, демон считывает из него значение PID и с помощью функции kill(2) проверяет, существует ли в системе процесс с указанным PID. Если процесс существует, значит, пользователь пытается запустить демон повторно. В этом случае программа выводит соответствующее сообщение и завершается. Если процесса с указанным PID в системе нет, значит, pid-файл принадлежал аварийно завершенному демону. В этой ситуации программа обычно советует пользователю удалить pid-файл и попытаться запустить ее еще раз. Может, конечно, случиться и так, что после аварийного завершения демона на диске останется его pid-файл, а затем какой-то другой процесс получит тот же самый PID, что был у демона. В этой ситуации для вновь запускаемого демона все будет выглядеть так, как будто его копия уже работает в системе, и запустить демон повторно пользователь не сможет. Но описанная ситуация крайне маловероятна. Вторая причина, по которой pid-файл считается полезным, заключается в том, что с помощью этого файла мы можем быстро выяснить PID демона, не прибегая к команде ps. Область применения демонов – создание таких приложений, которые могут, выполняться без участия пользователя, следовательно, типичные задачи – серверы сетевых протоколов, управление оборудованием, поддержание очередей печати, управление выполнением по расписанию и подобные задачи. Проведенные исследования представляют собой первый этап будущей разработки программного обеспечения мониторинга доступа к внешней памяти.

Литература

  1. D. P. Bovet, M. Cesati, Understanding the Linux Kernel, 3rd Edition, O'Reilly, 2005.
  2. W. R. Stevens, S. A. Rago, Advanced Programming in the UNIX® Environment: Second Edition, Addison Wesley Professional, 2005.