[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
에 저장된다.