OS,  Study

[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다.

생성 방법

  1. Background로 수행되도록 호출
    1. fork()를 호출한 뒤에 parent process 종료
  2. 새로운 session을 생성
    1. setsid()를 통해
  3. 열려진 모든 file descriptor를 닫기
    1. 부모로 부터 상속받은 file descriptor를 닫아야 함
  4. 어떠한 파일 시스템으로부터 영향을 받지 않으려면 working directory를 root로 변경
    1. chdir(“/”)
  5. Parent process로 부터 상속받은 파일 생성 마스크를 제거
    1. umask(0)
  6. SIGCHLD signal을 처리
    1. Daemon process의 child process가 만드는 SIGCHLD에 대응하지 않음
    2. 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에 저장된다.

Leave a Reply

Your email address will not be published. Required fields are marked *