Как написать демон Linux

Обновлено: 21.11.2024

В среде Linux демоны запускаются во время загрузки. Поскольку система Linux является идеальным клоном Unix, процесс инициализации считается родительским процессом для демона.

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

Соглашение об именах, определяющее большинство процессов-демонов, — это однобуквенный суффикс d. Это соглашение об именах позволяет различать обычные системные процессы и процессы, управляемые демоном. Например, sshd — это процесс-демон, отвечающий за управление входящими соединениями SSH. Другой пример процесса демона — syslogd. Он отвечает за ведение журнала системы Linux.

В среде Linux демоны запускаются во время загрузки. Поскольку система Linux является идеальным клоном Unix, процесс инициализации считается родительским процессом для демона. Чтобы запускать и останавливать демоны в вашей операционной системе Linux, вам сначала нужно получить доступ к каталогу скриптов /etc/init.d в вашей ОС.

Общие функции демонов

  • Это позволяет вашей системе правильно отвечать на сетевые запросы, связывая каждый запрос с совместимым сетевым портом. Типичным сетевым портом, который обрабатывает демон, является порт 80.
  • Демоны позволяют запускать или выполнять запланированные системные задачи. Демон, ответственный за эту конкретную задачу, называется cron. Это создаст задание cron, которое будет обрабатывать периодическое выполнение ваших запланированных задач.
  • Демоны также вносят бесценный вклад в мониторинг производительности вашей системы. Например, они могут проверить состояние RAID-массива или жесткого диска.

Полезные сервисные демоны Linux

Независимо от того, являетесь ли вы новичком, продвинутым пользователем или опытным пользователем в мире операционной системы Linux, вы обязательно ознакомитесь с одним из перечисленных выше демонов, по мере того, как будете развивать свои навыки и опыт в среде этой ОС.

Запуск/остановка/перезапуск демонов: подход на основе терминала

Теперь, когда у вас есть список полезных демонов Linux для запоминания и изучения, первое, что вам нужно знать, это то, как запускать, останавливать или перезапускать эти демоны. Запустив терминал Linux, примите во внимание следующие правила синтаксиса для запуска, остановки и перезапуска демона в операционной системе Linux.

Замените синтаксический аргумент preferred-daemon-name именем системного демона Linux по вашему выбору. Вы можете выбрать один из демонов из выделенного выше списка, если он активен или уже определен в вашей системе Linux. Например, мы можем реализовать практическое использование приведенного выше синтаксиса, пытаясь запустить, остановить и перезапустить демон. Перейдите в каталог /etc/init.d на вашем терминале, чтобы просмотреть список доступных демонов в вашей системе Linux.

список активных демонов в вашей системе Linux.jpg как запустить, остановить и перезапустить службу демона в вашей системе Linux.jpg

Список демонов ваших систем Linux

Более эффективный способ узнать о доступных демонах в вашей системе Linux вместо перехода к каталогу /etc/init.d — составить список всех определенных активных и неактивных демонов из этого каталога с помощью одной команды. Следующая команда эффективна для достижения этой цели.

список всех демонов в вашей операционной системе Linux.jpg

Заключенные в фигурные скобки положительные знаки [+] и отрицательные [-] перед перечисленными именами демонов подразумевают, что они либо активны, либо неактивны соответственно.

Работа с пользовательскими демонами

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

Достойная реализация демона с использованием Python тщательно продемонстрирована и задокументирована Сандером Маречалом. Стремитесь следовать порядку выполнения при создании этого демона. Во-первых, ваша система Linux нуждается в установке пакетов Python для успешной разработки демонов.Чтобы установить Python, вы можете использовать следующую команду.

Ссылка на код демона Python, созданный Сандером Маречалом, также предлагает улучшенную версию кода Python 3. Было бы полезно, если бы вы решили реализовать его, чтобы лучше понять, как работают демоны.

Если вы не уверены, установлен ли у вас Python, выполните следующую команду на своем терминале Linux.

Назначение любого демона

Поскольку один демон предназначен для обработки конкретной задачи, он должен выполнять ее в совершенстве. Рассматриваемая задача может быть простой, как создание отчета и отправка его администратору через sendmail, или сложной, как управление несколькими доменами, связанными с несколькими почтовыми ящиками. В какой-то момент демон, который вы собираетесь создать, должен будет взаимодействовать с другими существующими демонами.

взаимодействие пользователя с демоном

Не рекомендуется, чтобы системный пользователь и созданный демон взаимодействовали напрямую. Если это необходимо для демона, вы создаете для связи с системным пользователем. Это общение может быть облегчено с помощью чего-то вроде интерфейса GUI. Эта коммуникационная платформа может иметь либо сложный графический интерфейс GTK+, либо простой набор сигналов.

Создание демона

Многочисленные подходы поддерживают создание демонов. Например, вы можете использовать свой интерфейс командной строки для демонизации скрипта Python следующим образом:

Вы можете сохранить код демона Python3, созданный Сандером Маречалом, в файле Python и демонизировать его с помощью приведенной выше команды. Хотя приведенная выше команда терминала легко создаст для вас демона, вам придется столкнуться с такими проблемами, как непредсказуемые выходные данные терминала. Эти проблемы зависят от того, насколько хорошо вы провели рефакторинг кода демона Python. Кроме того, описанный выше подход не поддерживает назначение файлов блокировки PID конкретным демонам. Это делает невозможным управление любым демоном, так как большинство из них будут выполняться мгновенно. С другой стороны, если вам нужен только простой демон, вышеупомянутый подход даст вам желаемые результаты демона.

Базовая структура демона

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

В Linux я хочу добавить демон, который нельзя остановить и который отслеживает изменения в файловой системе. Если обнаружены какие-либо изменения, он должен записать путь к консоли, где он был запущен, плюс новую строку.

У меня уже почти готов код изменения файловой системы, но я не могу понять, как создать демон.

Что делать после форка?

Если вам не нужно соответствие POSIX, вас может заинтересовать API-интерфейс inotify. См.: inotify_init, inotify_add_watch, inotify_rm_watch.

9 ответов 9

В Linux я хочу добавить демона, который нельзя остановить и который отслеживает изменения файловой системы. Если будут обнаружены какие-либо изменения, он должен указать путь к консоли, с которой он был запущен, + новую строку.

Демоны работают в фоновом режиме и (обычно. ) не относятся к TTY, поэтому вы не можете использовать stdout/stderr так, как вам, вероятно, нужно. Обычно демон системного журнала (syslogd) используется для регистрации сообщений в файлах (отладка, ошибка. ).

Помимо этого, есть несколько необходимых шагов для демонизации процесса.

  • разветвить родительский процесс и позволить ему завершиться, если разветвление прошло успешно. -> Поскольку родительский процесс завершен, дочерний процесс теперь работает в фоновом режиме.
  • setsid — создать новый сеанс. Вызывающий процесс становится лидером нового сеанса и лидером группы процессов новой группы процессов. Теперь процесс отсоединен от управляющего терминала (CTTY).
  • Перехватывать сигналы — игнорировать и/или обрабатывать сигналы.
  • разветвить еще раз и позволить родительскому процессу завершиться, чтобы убедиться, что вы избавились от процесса, ведущего сеанс. (Только лидеры сеансов могут снова получить телетайп.)
  • chdir — изменить рабочий каталог демона.
  • umask — изменить маску режима файла в соответствии с потребностями демона.
  • close — закрыть все дескрипторы открытых файлов, которые могут быть унаследованы от родительского процесса.

Чтобы дать вам отправную точку: посмотрите на этот скелет кода, который показывает основные шаги. Этот код теперь также можно разветвить на GitHub: базовый скелет демона linux

  • Скомпилируйте код: gcc -o firstdaemon daemonize.c
  • Запустите демон: ./firstdaemon

Проверьте, все ли работает правильно: ps -xj | первый демон grep

Вывод должен быть похож на этот:

Здесь вы должны увидеть следующее:

  • У демона нет управляющего терминала (TTY = ?)
  • Идентификатор родительского процесса (PPID) равен 1 (процесс инициализации).
  • PID != SID, что означает, что наш процесс НЕ является лидером сеанса
    (из-за второго форка())
  • Поскольку PID != SID, наш процесс не может снова взять под контроль TTY

Чтение системного журнала:

Выполните: grep firstdaemon /var/log/syslog

Вывод должен быть похож на этот:


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

Дополнительная литература:

В принципе, да. Но этот код — всего лишь пример. Это полностью зависит от того, чего вы хотите достичь с помощью процесса демона. Обязательно прочитайте и этот ответ: @Edwin

Обратите внимание, что функция sigaction() обеспечивает более полный и надежный механизм управления сигналами; новые приложения должны использовать sigaction(), а не signal().

man 7 daemon очень подробно описывает, как создать демон. Мой ответ — это просто выдержка из этого руководства.

Существует как минимум два типа демонов:

Демоны SysV

Если вас интересует традиционный демон SysV, вам следует выполнить следующие шаги:

  1. Закрыть все открытые файловые дескрипторы, кроме стандартных вводных, выходных и ошибочных (т. е. первых трех файловых дескрипторов 0, 1, 2). . Это гарантирует, что ни один случайно переданный файловый дескриптор не останется в процессе демона. В Linux это лучше всего реализовать путем итерации через /proc/self/fd с откатом от итерации от дескриптора файла 3 до значения, возвращаемого getrlimit() для RLIMIT_NOFILE . все обработчики сигналов по умолчанию. Это лучше всего сделать, перебирая доступные сигналы до предела _NSIG и сбрасывая их на SIG_DFL .
  2. Сбросить маску сигнала с помощью sigprocmask().
  3. Очистите блок среды, удалив или сбросив переменные среды, которые могут негативно повлиять на время выполнения демона.
  4. Вызовите fork() , чтобы создать фоновый процесс.
  5. В дочернем элементе вызовите setsid(), чтобы отсоединиться от любого терминала и создать независимый сеанс.
  6. В дочернем элементе снова вызовите fork(), чтобы гарантировать, что демон больше никогда не сможет повторно захватить терминал.
  7. Вызовите exit() у первого дочернего процесса, чтобы остался только второй дочерний процесс (фактический процесс-демон). Это гарантирует, что процесс демона перенастроен на init/PID 1, как и должно быть у всех демонов.
  8. В процессе демона подключите /dev/null к стандартному вводу, выводу и ошибке.
  9. В процессе демона сбросьте umask на 0, чтобы режимы файлов, передаваемые в open() , mkdir() и т.п., напрямую управляли режимом доступа к создаваемым файлам и каталогам.
  10. В процессе демона измените текущий каталог на корневой каталог ( / ), чтобы демон непреднамеренно блокировал размонтирование точек монтирования.
  11. В процессе демона запишите PID демона (возвращенный функцией getpid() ) в файл PID, например, /run/foobar.pid (для гипотетического демона "foobar"), чтобы убедиться, что демон не может быть запущен. больше чем единожды. Это должно быть реализовано без состязаний, чтобы файл PID обновлялся только тогда, когда он проверяется в то же время, когда PID, ранее сохраненный в файле PID, больше не существует или принадлежит чужому процессу.
  12. В процессе демона отмените привилегии, если это возможно и применимо.
  13. Из процесса демона уведомить исходный запущенный процесс о завершении инициализации. Это можно реализовать с помощью безымянного канала или аналогичного канала связи, который создается до первого fork() и, следовательно, доступен как в исходном процессе, так и в процессе демона.
  14. Вызовите exit() в исходном процессе. Процесс, вызвавший демона, должен иметь возможность полагаться на то, что этот выход() произойдет после завершения инициализации и установления и доступности всех внешних каналов связи.

Обратите внимание на это предупреждение:

Функция BSD daemon() не должна использоваться, так как она реализует только подмножество этих шагов.

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

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

Что вам нужно знать.

Основное понимание C++ и некоторые базовые знания об использовании Linux, и под Linux мы подразумеваем знание того, как запустить процесс и завершить процесс. Использование eclipse в Linux с C++.

Что я использую

В настоящее время я использую Fedora 13 с установленным eclipse. Однако вы можете запрограммировать приведенное ниже в Ubuntu и протестировать своего демона на обеих платформах.

Теперь, когда мы обсудили требования, давайте немного познакомимся с местными особенностями

Понимание того, как Linux обрабатывает службы

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

Начнем: два зайца, один выстрел

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

Демон и программы довольно похожи друг на друга, однако демоны не выводят свой внешний код на консоль. Так что это хорошая идея, чтобы разобраться с ведением журнала ваших выходных данных, а не с использованием cout или printf . Ниже мы собираемся добавить запись системного журнала в нашу функцию процесса.

Что мы сделали выше. Проще говоря, мы открыли соединение с системным журналом (openlog()), затем мы написали в системный журнал с помощью (syslog()) и, наконец, закрываем соединение (closelog()). Вы можете указать, что такое setlogmask и все входные параметры, такие как LOG_INFO, LOG_NOTICE. Что ж, давайте пройдемся по основам. setlogmask() позволяет нам выбирать, что регистрировать, а что нет, даже если вызывается функция syslog(). Это удобно, так как мы оставляем много сообщений при отладке, но мы хотим отключить сообщения, когда запускаем наш демон. Поэтому вместо того, чтобы просматривать ваш код и комментировать все записи уведомлений, мы просто меняем маску журнала.

Если вы никогда не работали с системным журналом на C++, неплохо с ним ознакомиться. Если вам интересно, вы можете найти больше о командах системного журнала здесь.

Хорошо, теперь вы зарегистрировали свои сообщения, где их можно найти. В Ubuntu или Fedora журналы находятся в папке /var/logs/messages, поэтому после того, как вы скомпилировали свою программу и запустили ее, попробуйте эту команду (последние 100 строк файла message).

Демон

Мы установили наш процесс и управляли ведением журнала, теперь мы хотим добавить код демона. Лучше всего начать с просмотра кода нашего демона ниже.

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

Разветвление — это метод создания дочернего процесса. Когда мы запускаем команду fork(), мы фактически создаем дочерний клон нашей программы. Из нашего приведенного выше кода мы пытаемся разветвить наш родительский процесс. Если возвращаемое значение меньше 0, значит, что-то пошло не так. Поэтому мы выходим из нашей программы, в противном случае мы выходим из нашего родителя и продолжаем работу с нашим дочерним процессом. Это может привести к путанице. Для получения дополнительной информации обратитесь к ссылке в нижней части руководства.

маскировать

Когда вы создаете новый файл в Linux, вам нужны разрешения на его чтение или запись. Команда umask указывает разрешения для этого процесса. Это сложно, чтобы копаться. Вы можете прочитать больше на справочной странице.

установить

setsid — это сокращение от Set Session Id. Поскольку мы разветвили наш процесс, нам нужно присвоить нашему новому процессу собственный уникальный идентификатор процесса, поэтому мы запускаем эту функцию, чтобы определить новый идентификатор процесса.

кдир

Эта команда изменяет текущий рабочий каталог. В Linux эквивалентом этой функции будет cd / . Это будет рабочий каталог процесса. Причина, по которой мы выбираем / или root в качестве рабочего каталога, заключается в том, что это единственный каталог, который глобально существует во всех типах Linux. Однако вы можете изменить каталог по своему усмотрению.

закрыть

Поскольку демон является фоновым процессом, мы хотим закрыть все входные и выходные данные. Итак, если вы посмотрите на функцию закрытия, мы закрыли все стандартные файловые дескрипторы.

спать

Команда sleep переводит процесс в спящий режим на определенное количество секунд. Думайте об этом числе всякий раз, когда вы проектируете своего демона. Небольшое количество потребует большей вычислительной мощности, так как ваш ЦП обрабатывает больше процессов за короткий промежуток времени.

Я уверен, прежде чем вы перейдете к этой части. вы уже протестировали своего демона, поэтому я оставлю вас с несколькими последними советами.

Подробнее, используйте Руководство Devon Watson по написанию демона, чтобы заполнить некоторые черные дыры, которые я, возможно, упустил.Также неплохо попробовать пример Питера Ламбардо, чтобы понять, как обрабатывать сигналы и убедиться, что ваш демон всегда корректно завершает работу.

Всякий раз, когда вы создаете свою функцию процесса: занимайте оборонительную позицию, защищайтесь и еще раз защищайтесь; и когда вы закрепите его, попытайтесь вернуться и занять очень-очень оборонительную позицию. И наслаждайтесь

Надеюсь, вышеизложенное поможет вам понять, что такое демоны в операционной системе на базе Linux. Однако это не заканчивается здесь. Во второй части объясняется, как создать сценарий init.d для управления запуском и остановкой этого демона.

Ресурсы

Шахмир Джавид

Удалить запрос с ограничением в Mysql

Когда-нибудь задумывались, как выполнить запрос на удаление с ограничением в MySQL, у меня наконец-то появилось время, чтобы решить эту проблему, и я опубликовал ее для всеобщего обозрения. Настоятельно рекомендуется внести улучшения и предложения.

Предыдущий

Код подсветки синтаксиса

Библиотека подсветки синтаксиса на основе JavaScript, разработанная Алексеем Горбачевым.

Данило Карвалью

6 февраля 2012 г.

Привет, Шахмир, очень хороший гид. Есть шанс, что часть 2, объясняющая сценарии init.d, скоро выйдет? Нормального руководства по нему найти не удалось. В любом случае, спасибо за это.

Шахмир Джавид

14 февраля 2012 г.

Я могу это сделать, дайте мне выходные. Я соберу простой скрипт init.d, который вы можете легко передать своему демону.

Процесс-демон — это процесс, работающий в фоновом режиме и не имеющий управляющего терминала.

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

Например, процесс, который работает в фоновом режиме и наблюдает за сетевой активностью и регистрирует любые подозрительные сообщения, может быть разработан как процесс-демон.

Дизайн процесса демона

Процесс-демон может быть разработан так же, как и любой другой процесс, но есть одна вещь, которая отличает его от любого другого обычного процесса, а именно отсутствие управляющего терминала. Это основной аспект дизайна при создании процесса демона. Этого можно достичь следующим образом:

  • Создать обычный процесс (родительский процесс)
  • Создать дочерний процесс из указанного выше родительского процесса
  • Иерархия процессов на этом этапе выглядит следующим образом: ТЕРМИНАЛ -> РОДИТЕЛЬСКИЙ ПРОЦЕСС -> ДОЧЕРНИЙ ПРОЦЕСС
  • Завершить родительский процесс.
  • Теперь дочерний процесс становится потерянным и передается процессу инициализации.
  • Вызовите функцию setsid(), чтобы запустить процесс в новом сеансе и создать новую группу.
  • После вышеуказанного шага мы можем сказать, что теперь этот процесс становится демоном без управляющего терминала.
  • Измените рабочий каталог процесса демона на root и закройте файловые дескрипторы stdin, stdout и stderr.
  • Запустить основную логику процесса демона.

Итак, мы видим, что приведенные выше шаги отмечают основные этапы проектирования для создания демона.

Функция fork() в Си

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

Система fork() создает дочерний процесс, который является точной копией родительского процесса. Этот новый процесс называется «дочерним».

Этот системный вызов вызывается один раз (в родительском процессе), но возвращается дважды (один раз в родительском и второй раз в дочернем). Обратите внимание, что после системного вызова fork(), будет ли родитель запускаться первым или дочерний, не является детерминированным. Это зависит исключительно от механизма переключения контекста. Этот вызов возвращает ноль в дочернем процессе, в то время как возвращает PID дочернего процесса в родительском процессе.

Ниже приведены некоторые важные аспекты этого звонка:

  • У дочернего процесса есть собственный уникальный идентификатор процесса, и этот PID не совпадает с идентификатором какой-либо существующей группы процессов.
  • Идентификатор родительского процесса совпадает с идентификатором родительского процесса.
  • Потомок не наследует блокировки памяти своего родителя.
  • Счетчики использования ресурсов процесса и процессорного времени обнуляются в дочернем элементе.
  • Дочерний набор ожидающих сигналов изначально пуст.
  • Потомок не наследует настройки семафора от родителя.
  • Дочерний элемент не наследует блокировки записей от своего родителя.
  • Дочерний элемент не наследует таймеры своего родителя.
  • Дочерний элемент не наследует невыполненные операции асинхронного ввода-вывода от своего родителя, а также не наследует какие-либо контексты асинхронного ввода-вывода от своего родителя.

Для получения дополнительной информации прочитайте справочную страницу этого системного вызова.

Реализация

На основе дизайна, упомянутого в первом разделе. Вот полная реализация:

Вот как был скомпилирован и выполнен код:

Обратите внимание, что управление немедленно вернулось на терминал, т. е. демон теперь не связан ни с одним терминалом.

Читайте также: