3장. init : 그 이후

앞 절에서 설명한 바와 같이 init 프로세스가 자신에게 할당된 초기화 과정을 모두 끝마치고 나면, inittab 파일의 맨 끝부분에 명시된 것처럼 mingetty 혹은 getty 프로세스를 실행시킵니다. 실행시키는 방법은 최초에 pid 0 의 프로세스 [1] 에 의해 실행된 init 가 fork() 시스템 콜을 한번 수행하고, 그에 의해 생성된 자식 init 가 exec() 시스템 콜을 이용해서 getty 혹은 mingetty 등의 프로세스를 수행하게 됩니다.

getty 가 하는 일은 화면에

	login :
프롬프트를 띄우고서 사용자의 userid 가 입력되기를 기다리는 일입니다. 사용자가 자신의 userid 를 입력하고서 엔터키를 치게 되면, getty 는 /bin/login 을 실행시키게 됩니다.

/bin/login 프로그램은

	Password:
라는 프롬프트를 띄우고, 사용자가 password 를 입력하기를 기다립니다. 사용자가 암호를 입력하면, /etc/passwd 혹은 /etc/shadow 파일로부터 패스워드를 읽어서 암호화 한 패스워드와 일치하는지를 검사합니다. 만약 패스워드가 일치하지 않으면, login 프로그램은 에러를 내고 종료합니다. 그러면, init 프로세스는 다시 자신을 fork() 하고, /sbin/getty 프로그램을 exec() 해서 화면에 로그인 프롬프트를 출력하도록 하고 사용자의 입력을 기다리게 됩니다. 만약 패스워드가 일치하면, login 프로그램은 홈디렉토리를 바꾸는 등 여러가지 작업을 하고, 최종적으로 exec()를 하여, 로그인 쉘 [2] 을 띄우게 됩니다.

그러면, 사용자는 자신의 쉘 (주로 bash) 로 작업을 하고, 쉘에서 입력하는 명령어들은 먼저 쉘이 fork() 를 한 후 쉘의 자식프로세스가 exec() 를 하여 실행되고, 종료하는 것입니다. 이 과정을 간단하게 그림으로 그리면 다음과 같습니다.

        +-------------+
        |    init     |
        |   (pid 1)   |                                
        +------+------+
               | <-------------------------------------+
               | fork()                                | respawn
              \|/                                      |
        +------+------+                                |
        | "자식" init |                                |
        |  (pid 266)  |                                |
        +------+------+                                |
               |                                       |
               | exec()                                |
              \|/                                      |
        +------+------+                                |
        |  mingetty   |                                |
        |  (pid 266)  |                                |
        +------+------+                                |
               |                                       |
               | exec()                                |
              \|/                                      |
        +------+------+                                |
        |    login    |                                |
        |  (pid 266)  |                                |
        +------+------+                                |
               |                                       |
               | exec()                                |
              \|/                                      |
        +------+------+                                |
        |    bash     +---------------------------- 쉘 종료
        |  (pid 266)  |          로그아웃          
        +------+------+
               | 명령어 수행
               | fork()
              \|/
        +------+------+
        |    bash     |
        |  (pid5909)  |
        +------+------+
               |
               | exec()
              \|/
        +------+------+
        |다른 프로세스|
        |  (pid5909)  |
        +------+------+

주석

[1]

최초의 init 는 커널의 init 쓰레드에 의해 실행됩니다.

[2]

ps 를 수행했을 때 bash 등의 앞에 '-' 기호가 붙어서 -bash 등과 같이 표시된 것이 로그인 쉘입니다. 자세한 것은 다른 문서를 찾아보세요.