[OS] Daemon Process
어떤 event가 발생할 때까지 기다리거나, 주기적으로 주어진 일을 수행하기 위해 background에 있는 process를 말한다. 특징은 다음과 같다.
- 제어 터미널을 가지지 않으며 background에서 수행
- 보통 system 부팅이 될 때 시작되며 shutdown 될 때 종료
- UNIX system의 일상적인 작업 (scheduling, network monitoring 등) 수행
- 다른 process가 발생한 signal에 간섭되지 않음
이런 daemon process는 특정 session에 간섭받지 않는다.
$ ps -xj
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
17161 508 508 9560 pts/218 508 S+ 82116 0:00 -sh
6600 543 543 6274 pts/212 1975 S 82116 0:00 -sh
543 1975 1975 6274 pts/212 1975 S+ 82116 0:00 -sh
1 2108 22451 22451 ? -1 S 82116 0:10 /usr/libexec/notification-daemon
1 22395 3782 3782 ? -1 Sl 82116 2:53 /usr/bin/gnome-keyring-daemon --daemonize --login
21306 22421 22421 22421 ? -1 Ss 82116 0:00 -/bin/csh -c gnome-session
1 22449 22421 22421 ? -1 S 82116 0:00 dbus-launch --sh-syntax --exit-with-session
1 22451 22451 22451 ? -1 Ss 82116 2:56 /bin/dbus-daemon --fork --print-pid 5 --print-address 7 --session
1 22596 22596 22596 ? -1 Ss 82116 0:00 /usr/bin/seahorse-agent --variables
ps를 통해 확인해보면 TTY가 ?로 나와있는 것들이 daemon process다.
생성 방법
- Background로 수행되도록 호출
- fork()를 호출한 뒤에 parent process 종료
- 새로운 session을 생성
- setsid()를 통해
- 열려진 모든 file descriptor를 닫기
- 부모로 부터 상속받은 file descriptor를 닫아야 함
- 어떠한 파일 시스템으로부터 영향을 받지 않으려면 working directory를 root로 변경
- chdir(“/”)
- Parent process로 부터 상속받은 파일 생성 마스크를 제거
- umask(0)
- SIGCHLD signal을 처리
- Daemon process의 child process가 만드는 SIGCHLD에 대응하지 않음
- signal(SIGCHLD, SIG_IGN)
Example
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <syslog.h>
int daemon_init(void) {
pid_t pid;
int i;
if(fork() > 0)
exit(0);
setsid(); /* become session leader */
chdir("/"); /* change working directory */
umask(0); /* clear our file mode creation mask */
for(i=0;i<64;i++)
close(i);
signal(SIGCLD,SIG_IGN);
return(0);
}
int main(void) {
daemon_init();
//printf("daemon\n"); // Not working
syslog(1, "%s\n", "daemon");
while(1);
return 0;
}
Daemon process의 log를 남기기 위해 syslog()를 사용한다. syslog()의 결과는 /var/log/syslog에 저장된다.