Tuesday, September 14, 2010

리눅스(우분투)의 init이 하는 일들

Ubuntu의 upstart 0.6.5 버전을 기준으로 한다.

1. 자기가 맨 처음 실행된 애가 아니면(pid != 1) telinit을 실행시킨다.
2. setsid()로 새로운 session을 시작한다.
3. system_setup_console에서는 tcsetattr()을 이용해 tty를 설정하고, file descriptor를 모두 /dev/null에 연결시킨다. 여기서 tty설정을 통해 특수키 등을 설정할 수 있다.
4. PATH를 bin과 sbin등의 디렉토리로 설정한다.
5. proc과 sys를 mount한다.

6. 여기부터 NIH 라이브러리가 사용된다. Ubuntu에서는 apt-get source libnih-dbus-dev를 통해 받을 수 있다.

참고로 NihOption은 getopt_long에서 쓰이는 struct option과 비슷한 역할을 한다. (restart는 이 구조체를 이용해 setting된다.)

7. SIGSEGV, SIGABRT (둘 다 crash), SIGCHLD, SIGALRM(둘 다 handling만, no response) 에 대한 handler를 등록한다.
8. reboot() syscall에 RB_DISABLE_CAD를 건네줌으로써 Ctrl+Alt+Del 를 누르면 init에게 SIGINT가 건네지도록 한다.
9. SIGWINCH, SIGPWR, SIGHUP, SIGUSR1에 대한 핸들러를 등록한다. (SIGHUP은 configuration reload, USR1은 d-bus reconnection에 대한 시그널)
10.  nih_child_add_watch를 통해 다른 프로세스가 exit, kill등을 하는 경우 detect한다.
11. polling하는 loop에서 불려질 event_poll을 등록한다.
12. configuration directory(/etc/init) 또는 file(/etc/init.conf)를 등록하고 configuration을 reload한다.
13. dbus를 통해 연락할 server를 열고 connect시와 disconnect시에 사용될 callback을 저장한다. 서버의 주소는 unix:abstract=/com/ubuntu/upstart 이다.
13-1. control_bus_open은 fail한다고 하니 넘어가자.
14. system log에 로그하기 위해 openlog를 부른다.
15. STARTUP_EVENT를 만들어 event queue에 등록시키고 nih_main_loop_interrupt()를 부른다
16. main loop은 event를 /etc/init에 저장된 configuration대로 event-driven loading을 해준다.

No comments:

Post a Comment