}

블로그 소개


*여러분들의 따듯한 댓글은 5%, 팔로우는 10% 블로그 포스팅 속도와 퀄리티를 높여줍니다.*

프로필

팔로우 해주시면 포스트할 때 큰 힘이 됩니다!!! 사실 저도 이 팔로우가 무슨 기능이 있는지는 모르겠습니다만, 팔로우 수가 늘면 '날 응원해주는 사람들이 있구나' 생각이 들어서 큰 힘이 됩니다.

팔로어

다른 페이지로 이동


리눅스 독학 페이지 운영체제 독학 페이지 네트워크 독학 페이지 시스템 해킹 하드웨어 독학 페이지 프로그래밍 독학 페이지 보안 페이지

오스 페이지 다이어트 정보 페이지 게임 정보 페이지 인생 꿀팁


****사진을 클릭하시면 페이지로 이동할 수 있습니다!****

<===***===↓↓↓You can use translate using chrome ↓↓↓===***===>

2021년 7월 30일 금요일

리눅스 /etc/rc.d/ 매우 자세히!

안녕하세요~ 마무입니다. 오늘은 'init 런레벨 파일', '리눅스 init 부팅 과정', 'init 런레벨 디렉토리', '리눅스 /etc/rc.d/' 등등에 대해서 매우 자세히 포스트해보겠습니다.

오늘 이 포스트를 다 읽으시면, 레드햇 6.9이하의 'sysV init을 사용하는 시스템'에 대한 자연스러운 이해를 하게 되실 것이며, 모든 의문이 풀리실 겁니다!


/***알고 있어야 하는 사전 지식***/

최초의 프로세스란, 부모, 자식 프로세스란, sysVinit(init)과 systemd 차이와 상세한 비교

런레벨이란?(0, 1, 2, 3, 4, 5, 6)

/***********************************/


-----목차-----

1. Centos init시스템 부팅과정

2. /etc/rc.d/rc.sysinit

3. /etc/inittab

4. /etc/rc.d/init.d/functions

5. /etc/rc.d/init.d와 /etc/rc.d/rc0~6

6. /etc/rc.d/rc.local

7. /etc/rc.d/rc란

8. 총 정리
---------------

여기서 못 찾은 정보는 

리눅스 독학 포스트 : https://mamu2830.blogspot.com/p/blog-page_13.html

운영체제 독학 포스트 : https://mamu2830.blogspot.com/p/blog-page_14.html

에 있을 수 있습니다!




1. Centos init시스템 부팅과정


'init 프로세스'를 사용하는 6.9이하의 레드햇(CentOS)에서의 'init 프로세스의 총 과정'을 쭈욱 먼저 나열해 전체적인 흐름을 보인 다음에, 이후 하나하나 자세하게 설명을 해드리는 방식을 취하겠습니다!

그러니 여기서 모르는 단어가 나와도, 그런가보다 하고 일단 살짝 읽고 넘어가주세요~

1. 'init'이 "/etc/rc.d/rc.sysinit(run commands.system initialization)"파일을 실행하여 파일 이름대로(system initialization) 시스템 초기화를 합니다.

2. 이후 'init'이 "/etc/inittab" 파일에 써져있는 '런레벨(runlevel)'을 읽어들입니다.

3. 'init'이 다른 데몬들이 공통적으로 사용하는 라이브러리 소스코드인 '/etc/rc.d/init.d/functions'라는 파일을 설정합니다. 이 과정을 통해 '/etc/rc.d/init.d/내부의 데몬'들이 이 'functions'파일을 불러들여, PID를 어떻게 결정하고, 시작하고, 종료할지를 설정합니다.

4. 아까 '/etc/inittab'에서 읽어온 '런레벨'에 따라 "/etc/rc.d/rc[runlevel].d" 디렉토리에 있는 S가 붙은 링크 파일들을 실행하고 K가 붙은 링크 파일들은 종료합니다. 

5. 만약 런레벨을 바꿀시 'init'은 "/etc/rc.d/rc"파일을 실행합니다.

6. 모든 'init'과정이 끝나고 'init'은 "/etc/rc.d/rc.local"파일을 실행해 추가적으로 실행하고 싶은 코드를 마지막에 수행합니다.

7. 런레벨 과정이 끝나고, 런레벨이 2~5중 하나면, '/sbin/mingetty'프로세스를 만들어 가상콘솔을 6개 엽니다.(터미널 포스트에서 다루겠습니다)

8. 런레벨이 5(GUI)라면 '/etc/X11/prefdm' 스크립트를 실행하고, 'prefdm'스크립트는 그래픽 화면인 즉 X 디스플레이어 매니저를 실행합니다.(X 윈도 포스트에서 다루겠습니다)




2. /etc/rc.d/rc.sysinit 


제일 먼저 'init'이 실행하는 이 "/etc/rc.d/rc.sysinit"이란 "run commands system initialization"의 줄임말로, system initialization(시스템 초기화)에 사용하는 run commands(실행 명령어들)이 들어있는 파일입니다.




이렇게 /etc/rc.d/로 이동하신 다음  "ll(ls -l)"로 보시면, 이 'rc.sysinit'파일'x'권한이 있는 쉘 스크립트 파일인 걸 알 수 있는데요, vi(vim)을 이용해 열어보시면



이렇게 '/bin/bash'를 이용한 쉘 스크립트가 써져 있는 것을 볼 수 있습니다. 

내용은, /bin/hostname에서 호스트 이름을 가져오고, 호스트이름에 값이 없을 경우 'localhost'를 넣고, /etc/sysconfig/network 파일을 실행하고, /proc/mounts가 없을 경우 proc와 sysfs를 마운트 하는 등, 말 그대로 시스템 초기화 코드가 적혀있는 것을 볼 수 있습니다.

사실 이 부분은 쉘 스크립트를 배우신 분들이라면 읽는게 그리 어렵진 않겠지만, 모를 경우 이해가 안되는건 당연합니다. 그러니 나중에 이 부분은 쉘 스크립트를 가르치는 포스트에서 다시 다루도록 하겠습니다.

그 외에도 내리다 보시면



SELinux 상태 체크,



하드웨어 초기화 등등 말 그대로 설정 파일들 체크 및 시스템 초기화를 위한 스크립트들이 적혀있는 것을 볼 수 있습니다.

응용프로그램(애플리케이션)을 실행하기에 앞서 당연히 시스템(환경)부터 초기화 하는 건 당연한 것이기 때문에, 이처럼 'init'은 데몬들을 실행하기전에, "/etc/rc.d/rc.sysinit"제일 먼저 실행하는 것입니다.

'init'이 "/etc/rc.d/rc.sysinit"을 실행해 시스템을 초기화(안정화)시켰다면, 본격적으로 프로세스들을 실행하면 됩니다만, 그 전에 "/etc/inittab"이란 파일을 통해 '런레벨(run level)'을 확인합니다.




3.  /etc/inittab 


'inittab(initialization table)'이란, 말 그대로 초기화를 할 때(initialization) 참고하는 테이블(table)입니다.

바로 이 파일에 위에서 배웠던, 원하는 런레벨을 쓰면, 시스템이 켜질 때 설정해놓은 런레벨대로 자동으로 부팅이 됩니다.

사실 이 '/etc/inittab'파일은 유닉스나 다른 리눅스 종류에선  부팅 때 실행하는 초기화 테이블이라는 이름대로, 원래 런레벨 외에도 특정 터미널에 실행되길 원하는 프로세스와 행위를 적는 파일이기도 했습니다만!

지금 제가 사용중인 레드햇 리눅스 6버전에선 맨 위 주석에 써져있는 것처럼, 디폴트 런레벨 설정으로만 쓰입니다. (디폴트 런레벨 설정외 다른 용도로 사용하는 버전도 있을 수 있습니다.)

백문이 불여일견, 한번 직접 파일을 보면서 말해보겠습니다.



맨 위에서부터 친절하게 주석을 통해 이 파일이 무엇인지, 무엇을 해도 되지만, 무엇을 하면 안되는지 적혀있습니다. 한번쯤은 읽어보고 넘어가도록 할게요!

# inittab은 오직 시스템 시작 때 디폴트 런레벨을 위해서만 사용이 됩니다.

# 이 파일에 다른 시스템 설정을 추가해도, 당신의 시스템에는 영향이 가지 않습니다.

# 시스템 초기화는 /etc/init/rcS.conf에 의해서 시작이 되며

# 개인 런레벨들은 /etc/init/rc.conf에 의해 시작이 됩니다.

# Ctrl-Alt-Delete 는 /etc/init/control-alt-delete.conf 에 의해서 다뤄집니다.(ctrl + alt + delete를 누르면 60초 내 자동으로 시스템을 종료하겠다는 창이 뜸)

# 터미널 gettys(터미널을 관리하는 유닉스 프로그램)들은 /etc/init/tty.conf,  /etc/init/serial.conf 그리고 /etc/sysconfig/init와 함께 다뤄집니다.

# 어떻게 시스템 시작 이벤트 핸들러들을 적는지나 어떻게 시스템 시작이 작동하는지의 정보는 man page init(5), init(8), initctl(8)을 보세요.

# 디폴트 런레벨. 이 런레벨들은 이렇게 사용됩니다:
#    0 - 정지(이걸 디폴트 런레벨로 사용하지 마시오)
#    1 - 싱글 유저 모드
#    2 - NFS 없이 사용하는 멀티유저(만약 당신이 네트워크를 사용하지 않으면 3과 똑같다)
#    3 - 풀 멀티유저 모드
#    4 - 사용하지 않음
#    5 - X11(유닉스의 GUI 환경)
#    6 - 재부팅(이걸 디폴트 런레벨로 사용하지 마시오)
 
이렇게 적혀있습니다~ 영어를 못하셔도 한번쯤은 읽어야 뭔가 안심이 되니까! 한번은 꼭 읽고 넘어갑시다~

자 그리고 이 설명들 밑에 



이렇게 적혀있는데요. 

그냥 런레벨만 적는게 아니라, 'id''initdefault'니 등 콜론(:)으로 구분이 돼 있는걸 볼 수 있는데요. 

이건 과거 여러 갈래 유닉스에서(솔라리니, BSD 등등)나 다른 리눅스 버전에서 사용되오던 기능과 그 때 사용하는 필드로, 이제는 굳이 알 필요가 없을 것 같습니다.(현재 저처럼 6.9이하 에선 디폴트 런레벨용으로만 사용하며, systemd에선 사용을 안하기에)

그래도 저와 같이 궁금한거 못참는 분들이 있을까봐! 살짝 언급을 하자면

/***굳이 알 필요 없는 TMI ***/

'첫 번째' 필드인 'id' 위치엔 원래 터미널번호를 쓰며 ex) tty1인 경우 '1' 
이렇게 씁니다.

그 다음 '두 번째' 필드는 저희가 알 듯이 런레벨 숫자를 적으며

다음 '세 번째' 필드는 미리 정의된 행동을 적는 곳으로, 위에선 'initdefault'는 이름 그대로 '디폴트 런레벨'을 말하며, 그 외에도 뭐 'respawn, wait, once, boot...'등등 많습니다.

마지막 '네 번째' 필드는 세 번째 필드에서 정의한 행위를 적용할 파일(프로세스)를 적는 곳입니다. 

그래서 이러한 설정을 통해 가상터미널(ctrl + alt 2~6)을 만드는 버전도 있습니다.

/***굳이 알 필요 없는 TMI ***/

그냥 사실 위에 적은 정보는 무시해도 되고, 저희는 그냥 '두 번째' 필드인 런레벨만 알면 됩니다.

예를 들어, 두 번째 필드에 '5'대신 '3'을 적으면 다음부터 시스템이 켜질 때 CLI 환경으로 켜지는 겁니다.

좀 TMI를 적어서 복잡했던거지, 그리 어렵진 않죠?





4. /etc/rc.d/init.d/functions



'/etc/inittab'을 통해 '런레벨'을 인식을 한 뒤에, 이제 'init'은 런레벨에 맞는 프로세스들을 만들어내야합니다만, 당연히 프로세스를 어떻게 만들지를 정해야할지 않습니까?

바로 그 때! 즉, 'init'이 데몬을 만들 때, 어떻게 PID를 결정할지, 프로세스를 시작할지, 종료할지정할 때 사용하는 공통 스크립트가 있으니.. 그것이 바로! 

'/etc/rc.d/init.d/functions'라는 파일입니다!



바로 위 'functions'라는 일반파일을 'vim'을 통해 열어보시면


맨 위 주석으로 

# functnions  이 파일은 /etc/init.d/ 디렉토리에 들어있는 모든 혹은 대부분의 쉘 스크립트가 사용하는 함수들을 포함하고 있습니다.

라고 적혀있죠? 말 그대로 거의 모든 '/etc/init.d/내부에 들어있는 데몬이 될 스크립트'를 보
functions 내부에 적혀있는 함수들을 불러와, 기본적인 데몬 생성 및 관리에 필요한 코드를(umask, PATH, PID, 프로세스 종료 등등) 사용하는 것을 볼 수 있습니다.

아직 서버프로그램을 많이 알지 못하실 것이라, 대부분 아실 'sshd(ssh)' 스크립트를 예를 들어 보겠습니다.



이렇게 /etc/rc.d/init.d/에 들어있는 sshd 스크립트를 읽어보시면, '/etc/rc.d/init.d/functions'현재 스크립트 "sshd"로 불러오는 것을 볼 수 있습니다.

이렇듯 대부분의 데몬이 공통적인 PID관리에 필요한 코드를'functions'라는 파일을 불러와 처리한다는 것이죠.

'/etc/rc.d/init.d/functions'라는 파일에 적혀있는 쉘 스크립트를 모두 다 해석하는건... 여러분들이 쉘 스크립트도 모르고, 너무나 방대하기에... 나중에 쉘 스크립트를 가르키는 포스트나 PID관련 포스트에서 집중적으로 다루도록 하겠습니다.

그래도 궁금하실 분들이 있을까봐 '/etc/rc.d/init.d/functions'코드를 살짝 보여드리자면



이렇게 /proc/내부에 실행되고 있는 pid가 있는지 체크하는 코드나



kill_list라는 로컬변수에 담긴 체크된 PID들을 "kill -TERM"으로 종료하듯, pid를 종료하는 코드나



이렇게 데몬을 실행하기 위한 함수등등이 담겨있습니다.

이렇듯, '/etc/rc.d/init.d/functions'파일은 데몬들이 자신들의 개인 코드를 실행하기전 공통적으로 실행하는 코드이기 때문에, 데몬들이 실행되기 전 먼저 세팅이 되야 한다는겁니다.





5. /etc/rc.d/init.d와 /etc/rc.d/rc0~6 

 

'/etc/inittab'적혀있는 런레벨을 확인하고, '/etc/rc.d/init.d/functions'파일을 세팅 후

이제 본격적으로 'init'은 그 런레벨에 맞춰서, /etc/rc.d/rc[0~6]에서 런레벨에 맞는 숫자의 디렉토리 내부에 있는 데몬들을 실행합니다.

예를 들어, 저희는 현재 GUI 환경인 '런레벨 5'를 쓰고 있으니, 부팅 때 'init'프로세스는



/etc/rc.d/rc5.d 디렉토리 내부의



이렇게 'S02lvm2-monitor', 'S05rmda'와 같은 'S(Start)'로 시작하는 데몬들을 숫자 순서에 따라 실행합니다.

지난번 '최초의 프로세스 포스트' 에서 다뤘던 것처럼, 'init'시스템은 직렬적으로 프로세스들을 시작하기에 이렇게 숫자로 순서가 나타나 있는겁니다!

어? 그럼 K는 뭔가요? 

'K'는 'Kill'의 약자로, K뒤에 적힌 데몬들을 숫자 순서에 따라 종료하라는 말입니다.

??? 종료를 하지 말고 첨부터 데몬을 안 키면 되는거 아닌가요??

맞습니다. 그럼 왜 여기서 K로 시작하는 데몬들을 넣어놨느냐? 그것은 바로 다른 런레벨로 바꿀 때를 위해서 정의를 해놓은겁니다.

예를 들어, CLI환경의 런레벨 3인 경우 GUI환경에서 쓰이는 데몬들이 필요가 없습니다.
그래서 만약 (GUI 환경 런레벨 5 --> CLI 환경 런레벨 3)으로 변경할 시, 런레벨 3에서 필요 없는 데몬들을 종료하라는 의미로 이때 'K로 시작하는 데몬'들을 종료하라는겁니다.

그럼 이런 심화 의문이 생길 수 있습니다.

런레벨에 맞춰서 '/etc/rc.d/rc[0~6].d'가 실행이 된다면, '/etc/rc.d/init.d'는 왜 존재하는건가요??? 보니까 /etc/rc.d/init.d'도 여러가지로 데몬들이 있던데요?

아하~ 그건 '/etc/rc.d/init.d'가 바로 실제로 데몬 파일들을 두는 곳이기 때문입니다.

무슨소리냐! 

데몬 파일들은 '/etc/rc.d/init.d'에 넣은 다음, 이 /etc/rc.d/init.d에 있는 데몬들을 링크로 만들어서 /etc/rc.d/rc[0~6]에서 쓴다는 것입니다.

실제로 확인을 해보시면, '/etc/rc.d/init.d'는



이렇게 'x'권한이 있는 실제 데몬 파일들이 있는 것을 확인할 수 있고

다른 '/etc/rc.d/rc[0~6].d' 디렉토리들은 내부를 보시면



모두 /etc/rc.d/init.d/ 내부의 실제 데몬 파일들의 링크파일로 이루어진 것을 확인할 수 있습니다.

그래서 말 그대로 /etc/rc.d/rcX.d의 숫자 X는 런레벨에 맞춰 스크립트를 실행하기 위해서다~

또한 앞서 시스템 종료용 '런레벨 0'재부팅용 '런레벨 6'같은 경우에는 
각각 '/etc/rc.d/rc0.d''/etc/rc.d/rc6.d'를 보시면



이렇게 rc0이나



rc6나 
앞서 K01~99까지 데몬들을 종료하고, 완전한 종료를 위한 쉘 스크립트 "S00killall, S01halt"
를 실행하거나, 완전한 재부팅을 위한 "S00killall, S01reboot'를 실행하라는 것을 볼 수 있습니다.

각각의 killall, halt, reboot 코드를 보시면



이렇게 건전한 체크를 위해, 현재 여전히 실행중인 필요하지 않은 서비스를 종료하는 'killall'스크립트나



런레벨 0이나 6에 쓰이는, 모든 프로세스 종료후, 파일시스템 마운트 해제까지, 완전한 시스템 종료를 위한 'halt'스크립트인걸 볼 수 있습니다.

참고로 rc6에 들어있는 'reboot스크립트'는 구분하기 쉽게 이 'halt 스크립트'를 이름만 바꾼겁니다.

TMI로 이 스크립트는 'Miquel van Smoorenburg'라는 분이 만드셨다네요. 와우






6. /etc/rc.d/rc.local 


/etc/rc.d/ 내부를 보시면, 특이한 쉘스크립트가 하나 더 있습니다. 바로



'/etc/rc.d/rc.local'이라는 쉘 스크립트죠.

이 파일은 무엇이냐? 바로 런레벨 관련 작업중 가장 마지막에 실행되는 스크립트 입니다.

왜 마지막에 실행되는 이 rc.local이란 스크립트를 뒀느냐?  바로 런레벨과 상관없이, 자기가 부팅때 실행하고 싶은 행위를 적기 위해서죠.

무슨 말이냐... 저희는 기존에 런레벨에 맞춰서, 쉘 스크립트를 런레벨에 맞는 디렉토리에 권한을 부여해 넣어두면 부팅 때 자동으로 실행이 됩니다만! 

이건 말 그대로 '런레벨'에서만 실행되는 것으로, 만약 런레벨 3 디렉토리인 rc3.d에 넣어뒀다면, 다른 런레벨 5로 부팅했을 때에는 제가 원하는 쉘스크립트가 당연히 실행 되지 않는다는 것이죠.

물론 런레벨 5 디렉토리인 rc5.d에도 똑같은 쉘 스크립트를 넣으면 됩니다만.. 그렇게 할바엔~~ 그냥 모든 런레벨 부팅 과정이 끝나면 실행하는 "rc.local"코드를 써서 사용하라는 것이죠~

그래서 부팅 런레벨 과정중 마지막에 실행이 되는 이 'rc.local'이란 파일이 존재하는겁니다.

실제로 vim을 통해 내부를 보시면



#이 스크립트는 모든 init 스크립트가 실행된 다음 실행됩니다. 

#만약 당신이 기존 sysV스타일의 init 과정을 원하지 않으면, 당신만의 초기화 과정이나 기타등등을 이곳에 쓸 수 있습니다.

이렇게 쓰여있는 것을 볼 수 있습니다~




7. /etc/rc.d/rc란


똑같이 /etc/rc.d/내부를 보시면 'rc'라는 특이한 스크립트가 있습니다. 

이것이 무엇이냐~? 바로 저희가 런레벨을 바꿀 때 실행되는 스크립트입니다.



런레벨을 바꿀 때 실행된다는 말대로, 내부를 보시면 런레벨 체크와, 현재 런레벨을 저장하고

그 밑에를 또 보시다보면



이렇게 다음 런레벨에 맞는 디렉토리 내 스크립트를 실행하는 등 말 그대로 '런레벨 변경'때 실행되는 스크립트 파일이 바로 'etc/rc.d/rc'였습니다.




8. 총 정리




부팅 때 'sysV init'의 런레벨 과정은 위 사진처럼

1. 'init'이 "/etc/rc.d/rc.sysinit(run commands.system initialization)"파일을 실행하여 파일 이름대로(system initialization) 시스템 초기화를 합니다.

2. 이후 'init'이 "/etc/inittab" 파일에 써져있는 '런레벨(runlevel)'을 읽어들인다, 그러니 /etc/inittab에 원하는 런레벨을 적으면 매번 그 런레벨로 부팅이 된다.

3. 'init'이 다른 데몬들이 공통적으로 사용하는 라이브러리 소스코드인 '/etc/rc.d/init.d/functions'라는 파일을 설정합니다. 이 과정을 통해 '/etc/rc.d/init.d/내부의 데몬'들이 이 'functions'파일을 불러들여, PID를 어떻게 결정하고, 시작하고, 종료할지를 설정합니다. 

4. 아까 '/etc/inittab'에서 읽어온 '런레벨'에 따라 "/etc/rc.d/rc[runlevel].d" 디렉토리에 있는 S가 붙은 링크 파일들을 실행하고 K가 붙은 링크 파일들은 종료합니다. 

5. 모든 'init'과정이 끝나고 'init'은 "/etc/rc.d/rc.local"파일을 실행해 추가적으로 실행하고 싶은 코드를 마지막에 수행합니다. 그러니 런레벨과 상관 없이 항상 부팅 때 실행하고자 하는 코드가 있으면 이곳에 쓰자.

6. 만약 런레벨을 바꿀시 'init'은 "/etc/rc.d/rc"파일을 실행합니다.

7. 런레벨 과정이 끝나고, 런레벨이 2~5중 하나면, '/sbin/mingetty'프로세스를 만들어 가상콘솔을 6개 엽니다.(터미널 포스트에서 다루겠습니다)

8. 런레벨이 5(GUI)라면 '/etc/X11/prefdm' 스크립트를 실행하고, 'prefdm'스크립트는 그래픽 화면인 즉 X 디스플레이어 매니저를 실행합니다.(X 윈도 포스트에서 다루겠습니다)




하 이번 포스트도 생각보다 시간이 꽤 많이 걸렸네요... 하루 5시간씩 5일이 걸렸습니다..

저의 노력이 꼭 리눅스 공부하시는 분들에게 도움이 됐으면 좋겠으며! 도움이 되셨다면, 따뜻한 댓글 및 팔로우를 클릭해주시면 저에게 아주 큰 힘이 돼! 포스트 퀄리티 향상에 큰 도움이 됩니다!

그럼 다음에는 systmed 부팅과정, PID와 리눅스 프로세스 생성과정, 터미널이란, X 윈도란 포스트 중 하나로 찾아뵙겠습니다!


댓글 없음:

댓글 쓰기

#1 여러분들이 소중한 시간을 투자해 달아주시는 따뜻한 댓글들은 저에게 정말 큰 힘이 됩니다!

#2 저의 각 포스트들은 엄청난 노력과 시간 투자를 통해 만들어진 포스트들로, 무단 복제나 모방하는 것을 금지합니다.

#3 저의 포스트에도 틀린 정보가 있을 수도 있습니다. 그럴 경우 친절한 말투로 근거와 함께 댓글로 달아주시면 정말 감사하겠습니다!