Лабораторная 1. Демоны - chrislvt/OS GitHub Wiki
Daemon
Daemon
- долгоживущий процесс. В основном, запускают во время старта системы и терминейтят, когда выключают систему. Стоит отметить, что поскольку демоны не имеют управляющего терминала, говорят, что они работают в backgroound
. Если в вкратце, то:
Daemon - это долгоживущий процесс, который работает в background
.
Где их найти?
Раз такой смелый, то можно к примеру здесь ps -axj
если вертишься под BSD.
- a - процессы других пользователей;
- x - процессы, которые не имеют управляющего терминала (те самые демоны);
- j - дополнительная информация.
States
S
- interruptible process;s
- session leader;l
- multithreaded process;TTY = ??
=> нет управляющего терминала;
Классификация демонов
Kernel Daemons
ppid = 0
+ некоторая специфика реализации системы;- Daemons
init
(Linux),launchd
(OS X) не являются Kernel Daemons хотяppid = 0
. Являются user-level command запускаемые ядром; - superuser privileges;
- нет управляющего терминала;
Linux
:- Kernell Daemon который является для всех остальных Kernell Daemon родителем - [kthreadd] -
pid = 2
.
- Kernell Daemon который является для всех остальных Kernell Daemon родителем - [kthreadd] -
В Linux
, ps
выводит имена kernel daemons заключенные в квадратные кавычки.
User-level Daemons
ppid = 1
;- process group leader;
- session leaders;
- как правило единственные в process group and session.
Как правило процесс у которого pid = 1
является daemom init
(Linux) или launchd
(OS X). Это системный демон, который отвечает за запуск системных служб для различного уровня выполнения. Эти службы реализуются с помощью их собственных демонов.
Coding Rules by Rago
- Вызвать
umask()
, что бы установить необходимую маску создания новых файлов (обычно просто сбрасывают в 0). - Вызвать
fork()
, a для процесса предка выполнитьexit()
. На это есть следующие причины:- Если daemon был запущен через shell, завершаем бесполезный процесс parent.
- Гарантируем что Child не будет process group leader.
- Примечание: При защите данной лабораторной, лулзы отхватываются здесь на изи, поэтому лучше 1 подпункт вообще не говорить. Во 2 подпункте сказать, что будет лидером группы, хотя если бы так было, мы бы словили лулзы от
setsid()
(man setsid()
). Реальная цель подпунктов: избавиться от управляющего терминала и сделать бла бла с помощью корректного вызоваsetsid()
, но кого это волнует...
- Вызвать
setsid()
, чтобы создать новую session. Таким образом процесс:- Становится лидером новой session.
- Становится лидером новой process group.
- Лишается управляющего терминала.
- Изменить текущую рабочею директорию (к примеру на
/
). Причина в том, что от parent наследуется текущая рабочая директория, которая может оказаться mounted. Пока daemon работает на mounted FS,unmount
сделать не получится. - Закрыть неиспользуемые файловые дескрипторы. Иначе daemon будет препятствовать их закрытию.
- Некоторые daemons открывают файловые дескрипторы 0 (
stdin
), 1 (stdout
), 2 (stderr
) в/dev/null
таким образом, не будет возникать ошибок при работе библиотечных функций, которые взаимодействуют сstdin
,stdout
,stderr
.
Quest
- Собрать демона;
- Запустить демона (
sudo
в помощь); - Вывести то, что делает демон. К примеру:
tail -f "Log.txt"
; ps -axj
;- Рассказать о state;
- Ответить почему
TTY = ??
; - Открыть
daemonize.cpp
и рассказать по коду, как работаетdaemonize()
. Либо вы шустро говорите, что бы не успели переварить ваши слова, либо говорите мало, но стараетесь выудить наводящие вопросы. Желательно отвечать без использования оборотов, как робот. Можно всё объяснять в виде0
и1
, либо на ментальном уровне; - Повторять пункт 7, 7 и ещё раз 7 до тех пор пока не постигните дзен;
- Верить в силу 777 и получить заветное зачтено.
Top Questions
- Зачем отнимать управляющий терминал (
TTY
). Пример- Чтобы user не смог взаимодействовать с daemon. К примеру не смог послать сигнал
SIG_INT
с помощьюCtrl + C
тем самым остановив работу daemon.
- Чтобы user не смог взаимодействовать с daemon. К примеру не смог послать сигнал
- Зачем закрывать файловые дескрипторы?
- Можно попробовать так. Так как они
daemon
'у не нужны, то мы их закрываем. Если глубже то, так какdaemon
был запущен черезshell
мы унаследовали stdin, stdout, stderr, а посколькуdaemon
'у они не нужны, то мы их закрываем (всё равно у daemon'a нет терминала и что бы не было потенциальной угрозы). В общем, чтобы не было контакта с юзером. Без понятия, что от вас захотят услышать, но всё будет сводиться к этому.
- Можно попробовать так. Так как они
- Зачем мы подключили файловые дескрипторы 0, 1, 2?
- Чтобы не было ошибок, если демон будет использовать функции работающие с
stdin
,stdout
,stderr
- Чтобы не было ошибок, если демон будет использовать функции работающие с
- Покажите PID процесса в lock-файле
- shell:
$ cd /var/run $ cat daemon.pid ```
- Покажите место в коде, где процесс становится демоном
in main.c function daemonize()