
man 7 daemon
Когда запускается традиционный демон SysV, он должен выполнить следующие шаги в рамках инициализации. Обратите внимание, что эти шаги не нужны для демонов нового стиля (см. ниже) и должны быть реализованы только в том случае, если совместимость с SysV имеет важное значение.
[...]
6. В дочернем процессе вызовите setsid(), чтобы отсоединиться от любого терминала и создать независимый сеанс.
7. В дочернем процессе снова вызовите fork(),чтобы гарантировать, что демон никогда больше не сможет повторно захватить терминал.
но сравните это с процессами, запущенными без малейшего признака совместимости с SysV:
$ ps -efj
UID PID PPID PGID SID C STIME TTY TIME CMD
root 1 0 1 1 0 May10 ? 00:06:44 /sbin/init
...
root 185 1 185 185 0 May10 ? 00:09:48 /lib/systemd/systemd-journald
root 16434 1 16434 16434 0 May26 ? 00:00:11 /usr/sbin/rsyslogd -n
Процессы для обоих rsyslog.service
и systemd-journal.service
являются лидерами сеансов (SID = PID).
Кажется, что если бы такие программы были настроены на запись в TTY, они бы получили TTY в качестве управляющего терминала и получили бы нежелательный / фатальный сигнал, когда TTY зависает / получает Ctrl+C, соответственно. Если только они не вспомнят установить O_NOCTTY при открытии файла TTY.
Кажется, это небольшая ловушка при написании или конвертации программы для запуска в качестве службы systemd без какой-либо совместимости с SysV, если ваша программа поддерживает запись сообщений в пользовательские файлы. Похоже, что в этом документе, который пропагандирует стиль systemd, на это не указано. Документ скорее подразумевает обратное, настаивая на том, что double-fork необходим для избежания этого в SysV, а затем не упоминая это как проблему при описании шагов, которые будет использовать собственная служба systemd.
Это правильно? Предоставляет ли systemd какую-то защиту от этого, о чем я умолчал, или проблема указана в другом месте в документации systemd?
решение1
Обеспечивает ли systemd какую-либо защиту от этого […]?
Вы предполагаете, что это должно быть так. Напротив, рассмотрите такие настройки, как TTYPath
и такие услуги, как [email protected]
. Возможность получить управляющий терминал на самом деленеобходимый, чтобы управление услугами могло охватывать услуги входа в систему TTY, которые должны делать именно это.
На самом деле от этого защищает отход от автоматического выделения управляющего терминала в open()
и отказ от старой семантики. Илибызащитить от этого. Это не относится к Linux, но в FreeBSD, NetBSD, OpenBSD и Hurd в настоящее время флаг O_NOCTTY
to open()
совершенно излишен.толькоспособ получить управляющий терминал — явно потребовать его, с помощью ioctl(…TIOSCTTY)
. Это фактически имело место в течение почти четверти века, со времен 4.4BSD.
В то же время, привычка работать с Linux — это привычка, которая существовала уже долгое время, задолго до systemd:O_NOCTTY
повсюду. ☺
(Да, библиотеки GNU и musl C не предоставляют вам этого fopen()
. Это одна из нескольких причин, по которым fdopen()
этот механизм по-прежнему полезен.)
Управление службами с помощью набора инструментов nosh service-manager
принимает несколько иной подход. Вместо того, чтобы всегда делать процессы демонов лидерами сеансов, каждая служба выделяет свой собственный объект сеанса ядра, который затем не видит использования, только определенные службы также setsid
явно объединяются в цепочку; например, службы, которые используют , службы, где, конечно, устанавливается управляющий терминал, и службы. (Как отмечено в исходном коде службы, вызывает себя.)ttylogin@*
open-controlling-tty
agetty@*
agetty
getty@*
mgetty
setsid()
дальнейшее чтение
- Джонатан де Бойн Поллард (2018).
setsid
.Руководство по еде. Программное обеспечение. - Джонатан де Бойн Поллард (2018).
open-controlling-tty
.Руководство по еде. Программное обеспечение. - Джонатан де Бойн Поллард (2015).Наследование и заблуждение демонизации
".Больше никаких проблем с
service
командой.. рекламный текст. Программное обеспечение. - Джонатан де Бойн Поллард (2001).Не делайте этого
fork()
, чтобы «отодвинуть демона на задний план».".Ошибки, которых следует избегать при разработке программ-демонов Unix. Часто задаваемые ответы. - Джонатан де Бойн Поллард.Вход в виртуальный терминал".Руководство по еде. Программное обеспечение.
- Джонатан де Бойн Поллард.Реальный вход в терминал".Руководство по еде. Программное обеспечение.
- http://git.musl-libc.org/cgit/musl/tree/src/stdio/__fmodeflags.c
- https://github.com/lattera/glibc/blob/a2f34833b1042d5d8eeb263b4cf4caaea138c4ad/libio/fileops.c#L274
решение2
systemd не защищает служебные программы от получения управляющего терминала. Они должны защищать себя при открытии указанных пользователем файлов журналов, используя флаг O_NOCTTY
.
$ rpm -q systemd
systemd-238-8.git0e0aa59.fc28.x86_64
$ systemctl cat test
# /etc/systemd/system/test.service
[Service]
Type=simple
ExecStart=/bin/sh -c "exec cat </dev/tty10 >/dev/tty10"
$ systemctl status test
● test.service
Loaded: loaded (/etc/systemd/system/test.service; static; vendor preset: disabled)
Active: active (running) since Fri 2018-06-01 11:28:41 BST; 1min 35s ago
Main PID: 12173 (cat)
Tasks: 1 (limit: 4915)
Memory: 180.0K
CGroup: /system.slice/test.service
└─12173 cat
Jun 01 11:28:41 alan-laptop systemd[1]: Started test.service.
$ ps -ejf
UID PID PPID PGID SID C STIME TTY TIME CMD
...
root 12173 1 12173 12173 0 11:28 tty10 00:00:00 cat
Я также подтвердил, что переключение на tty10 и нажатие Ctrl+C останавливает cat
процесс.