
man 7 daemon
기존 SysV 데몬이 시작되면 초기화의 일부로 다음 단계를 실행해야 합니다. 이러한 단계는 새로운 스타일의 데몬(아래 참조)에는 필요하지 않으며 SysV와의 호환성이 필수적인 경우에만 구현해야 합니다.
[...]
6. 하위에서 setid()를 호출하여 터미널에서 분리하고 독립 세션을 만듭니다.
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를 수신할 때 원치 않는/치명적인 신호를 수신하는 것으로 보입니다. TTY 파일을 열 때 O_NOCTTY를 설정하는 것을 기억하지 않는 한.
프로그램이 사용자 정의 파일에 메시지 쓰기를 지원하는 경우 SysV 호환성 없이 시스템 서비스로 실행되도록 프로그램을 작성하거나 변환할 때 이는 약간의 함정인 것 같습니다. 체계적인 스타일을 옹호하는 이 문서에서는 이를 지적하지 않는 것 같습니다. 문서에서는 SysV에서 이를 방지하려면 이중 포크가 필요하다고 주장하고 기본 시스템 서비스가 사용할 단계를 설명할 때 이를 문제로 언급하지 않음으로써 오히려 그 반대를 암시합니다.
그 맞습니까? systemd는 내가 간과한 이에 대한 보호 기능을 제공합니까, 아니면 systemd 문서의 다른 곳에서 문제가 지적되어 있습니까?
답변1
systemd는 이에 대한 보호 기능을 제공합니까 [...]?
당신은 그렇게 해야 한다고 가정하고 있습니다. 반대로 다음과 같은 설정 TTYPath
및 서비스를 고려하십시오 [email protected]
. 제어 단말기를 얻는 능력은 실제로필요한, 서비스 관리가 정확하게 수행해야 하는 TTY 로그인 서비스를 포함할 수 있도록 합니다.
실제로 이를 방지하는 방법은 제어 터미널의 자동 할당에서 벗어나 open()
이전 의미를 폐기하는 것입니다. 또는~일 것이다그것으로부터 보호하십시오. Linux에서는 그렇지 않지만 FreeBSD, NetBSD, OpenBSD 및 Hurd에서는 요즘 플래그 O_NOCTTY
가 open()
완전히 불필요합니다. 그만큼오직제어 터미널을 획득하는 방법은 ioctl(…TIOSCTTY)
. 이것은 실제로 4.4BSD 시대 이후 거의 25년 동안 지속되어 왔습니다.
그동안 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
.