# 발료자 : 김현덕(현덕0)/ 제 5회 데비안 유저스 세미나 강의 자료
시스템 관리에서 가장 중요한 부분은 시스템의 정상적으로 작동을 관리하는 것이다.
시스템이 정상적으로 작동을 하지 않거나 어떠한 문제로 인하여 서비스가 작동하지
않는다면 사용자는 관리자를 찾을 것이다.
또한 관리자는 최소한 시스템의 잘못된 상황을 파악하여 문제를 해결해야 한다.
본 파트는 위와 같은 시스템 관리를 위해 서비스와 디스크 관리에 해당하는 부분을
설명할 것이다.
############ 목차 ############
서비스 관리 부분(pcharly님, soju님)
1. 시스템 V 스타일 초기화
2. init 설정파일
3. init.d 와 rc?.d 디렉토리의 구조
4. rc 스크립트 파일
5. 부팅시 서비스 등록
6. update-rc.d
##############################
######################################################################
시스템 관리 부분
######################################################################
*1 시스템 V 스타일 초기화
-커널의 하드웨어 인식과 초기화를 마친 후 커널은 모든 프로세스의 어머니
역활을 하는 PID 1 번의 init를 실행시킨다.
init는 새로운 프로세스를 생성하고 프로세스가 종료되면 이를 다시 시작시키는
기능과 시스템이 부팅할 때 스크립트를 실행할 책임을 진다.
-데비안에서 구동되는 모든 프로그램과 데몬들은 커널에 의해 처음으로 실행되는
init에 의해 실행이된다. 당연한 말이겠지만 이 init가 종료된다는 것은
시스템 종료와 같다.
-유닉스 계열의 운영체제에서 init가 실행되는 방식에는 크게 'System V'와 'BSD'
방식이 있다. 리눅스는 다른 면에서는 'BSD' 방식을 많이 사용하나 init가
실행되는 기동 방식만큼은 'System V' 방식을 따른다.
-데비안에서 init 명령은 sysvinit 패키지에 들어 있다.
이 패키지에는 init 외에도 shutdown, runlevel 같은 시스템 운영에 필요한
중요한 명령이 들어있다.
-리눅스 시스템 관리자라면 리눅스 시스템의 초기화 관정을 이해하는 것이
상당히 중요하다. 이 'System V' 방식의 기동 과정을 제대로 이해해야지만
시스템을 자기 입맛에 맞게 고치고 유지 할 수가 있다.
리눅스의 시동 경로 --------------------------------------------------
+------+
|전원on| (부팅) POST(Power of self test)
+--+---+
|
+--+---------+
| /sbin/init |
+--------+---+
|
| /etc/inittab
| +--------------+
| | |
| | rcS-----+---- rcS.d 디렉토리
| | | [시스템의 기본적인 초기화]
+--+ | (rc.boot)
| |
| rcN-----+---- rcN.d디렉토리
| | +-------------+
| | | S 파일 실행 |
| | | K 파일 실행 |
| | +-------------+
+-------+------+
|
+--+---+
|로그인|
+------+
주) 여기서 N 은 런레벨을 의미한다.
---------------------------------------------------------------------
*2 init 설정 파일(/etc/inittab)
-init도 일종의 프로그램이다 그렇기때문에 이 프로그램의 실행 방법을 명시하는
설정 파일이 있다. init 설정 파일은 /etc/inittab(inittab=INITial TABle) 이다
-inittab 파일을 간략하게 살펴보며 데비안 시스템이 구동되는 방법을 알아 보자.
inittab 파일의 각 행은 다음과 같은 형태로 되어 있다.
----------------------------------------------------------------------
id:runlevels:action:command
----------------------------------------------------------------------
-id
유일하게 한 글자나 두 글자가 나열된 것으로 항목을 구별하기 위해 사용된다.
몇몇 항목은 정확한 작업때문에 특별한 코드를 가져야 하나 보통 파일 내에서
다른 것과 충돌하지만 않으면 어떤것이 와도 상관없다.
-runlevels
이 항목이 실행될 실행 레벨이 무엇인지를 나타낸다.
실행 레벨은 현재 시스템의 상태를 단순하게 숫자나 글자로 정의한 것이다.
가령 시스템 실행 레벨이 3으로 바뀐다면 init 프로그램은 inittab파일 runlevel
필드에 3을 포함하는 모든 항목이 실행한다.
-action
init가 이 항목을 어떻게 처리할 것인지를 지시 한다.
한 번만 실행하고 말 것인지, 아니면 명령이 종료할때마다 다시 시작할 것인지를
결정할 수 있다.
-command
init가 이 항목에 대해 실행할 명령이다.
-'System V' 방식의 초기화를 이해할려면 먼저 실행레벨(Run Level)개념을
이해하고 넘어가야만 한다.
실행 레벨은 선택된 그룹의 프로세스만 시스템에서 실행되도록 허락하기 위해
만든 설정이다.
-데비안 7가지 실행계층
0 : 시스템 정지(halt)
1 : 단일 사용자 모드
2 - 5 : 여러가지 다중 사용자 모드
6 : 시스템 재기동(reboot)
참고
----------------------------------------------------------------------
레드햇 계열의 런레벨은 데비안의 그것과는 조금 다르다.
0 - 시스템 중지(halt)
1 - 단일 사용자 모드
2 - NFS를 제외한 다중 사용자 모드(만 네트워크와 연결되어 있지 않으면 런레벨
3과 같다)
3 - 모든 기능이 작동하는 다중 사용자 모드(default)
4 - 사용하지 않음
5 - X 윈도우 부팅(xdm, gdm)
6 - 리부팅(reboot)
----------------------------------------------------------------------
-/etc/inittab 파일의 내용을 분석해보면서 실행레벨을 이해하자.
----------------------------------------------------------------------
# /etc/inittab: init(8) configuration.
# $Id: seminar.txt,v 1.8 2002/04/29 21:15:11 pcharley Exp $
# The default runlevel.
id:2:initdefault:
# Boot-time system configuration/initialization script.
# This is run first except when booting in emergency (-b) mode.
si::sysinit:/etc/init.d/rcS
# What to do in single-user mode.
~~:S:wait:/sbin/sulogin
# /etc/init.d executes the S and K scripts upon change
# of runlevel.
#
# Runlevel 0 is halt.
# Runlevel 1 is single-user.
# Runlevels 2-5 are multi-user.
# Runlevel 6 is reboot.
l0:0:wait:/etc/init.d/rc 0
l1:1:wait:/etc/init.d/rc 1
l2:2:wait:/etc/init.d/rc 2
l3:3:wait:/etc/init.d/rc 3
l4:4:wait:/etc/init.d/rc 4
l5:5:wait:/etc/init.d/rc 5
l6:6:wait:/etc/init.d/rc 6
# Normally not reached, but fallthrough in case of emergency.
z6:6:respawn:/sbin/sulogin
# What to do when CTRL-ALT-DEL is pressed.
ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
# Action on special keypress (ALT-UpArrow).
kb::kbrequest:/bin/echo "Keyboard Request--edit /etc/inittab to let this work."
# What to do when the power fails/returns.
pf::powerwait:/etc/init.d/powerfail start
pn::powerfailnow:/etc/init.d/powerfail now
po::powerokwait:/etc/init.d/powerfail stop
# /sbin/getty invocations for the runlevels.
#
# The "id" field MUST be the same as the last
# characters of the device (after "tty").
#
# Format:
# <id>:<runlevels>:<action>:<process>
1:2345:respawn:/sbin/getty 38400 tty1
2:23:respawn:/sbin/getty 38400 tty2
3:23:respawn:/sbin/getty 38400 tty3
4:23:respawn:/sbin/getty 38400 tty4
5:23:respawn:/sbin/getty 38400 tty5
6:23:respawn:/sbin/getty 38400 tty6
# Example how to put a getty on a serial line (for a terminal)
#
#T0:23:respawn:/sbin/getty -L ttyS0 9600 vt100
#T1:23:respawn:/sbin/getty -L ttyS1 9600 vt100
# Example how to put a getty on a modem line.
#
#T3:23:respawn:/sbin/mgetty -x0 -s 57600 ttyS3
----------------------------------------------------------------------
-id:2:initdefault:
데비안 시스템은 다중 사용자 상태로 들어가는 실행계층 '2'를 기본으로 해서
시작하고 /etc/rc2.d/에 있는 스크립트를 실행한다. 위의 행에서 지정한 숫자
2가 데비안 시스템의 기본 부팅 레벨이 2임을 가리킨다. 기본 실행 레벨을
바꾸기 위해서는 여기서 숫자를 바꾸면 된다.당연히 0 이나 6을 지정하면
않된다. 시스템이 부팅하자 마자 중지되거나 리부팅될 것이다.
-si::sysinit:/etc/init.d/rcS
/etc/init.d/rcS 스크립트는 부팅 과정에 단 1 회 실행되는 스크립트로
시스템에 기본적인 초기화를 수행하도록 한다.
----------------------------------------------------------------------
for i in /etc/rcS.d/S??*
do
# Ignore dangling symlinks for now.
[ ! -f "$i" ] && continue
case "$i" in
*.sh)
# Source shell script for speed.
(
trap - INT QUIT TSTP
set start
. $i
)
;;
*)
# No sh extension, so fork subprocess.
$i start
;;
esac
done
----------------------------------------------------------------------
위 내용은 /etc/init.d/rcS 스크립트에 들어 있는 내용으로, /etc/init.d/rcS
스크립트의 가장 중요한 내용이라 할 수있으며 /etc/rcS.d 디렉토리에 있는 모든
명령들을 불어 오도록 한다.
rcS 스크립트에서 수행하는 초기화는 대략 다음과 같다.
1) 파일 시스템 검사 및 연결
2) 모듈 적재(modconf에서 지정한 모듈)
3) 네트워크 서비스 시작
4) 시스템 시간을 CMOS 시간에 맞춘다.
5) /etc/rc.boot 에 있는 모든 스크립트 실행 (파일 이름 처음이 '.'으로 시작하는
파일은 제외)
6) 기본 키보드 지정
7) 읽어버린 편집 파일 복구
8) 직렬 포트 설정
5)번 초기화를 제외한 모든 초기화가 /etc/rcS.d 디렉토리에 있는 명령에서
실행된다. /etc/init.d/rcS 에서 실행되는 초기화는 싱글 모드에서도 실행이 된다.
-~~:S:wait:/sbin/sulogin
싱글모드로 들어갈때 관리자 패스워드를 물어보게 한다. 레드햇 계열에서는
싱글 모드로 들어갈때 로그인 과정을 생략한다. 하지만 데비안의 경우에는
기본적으로 관리자 패스워드를 입력해야지만 싱글모드로 들어갈 수가 있다.
하지만 이 설정도 콘솔 앞에 앉은 공격자를 막을수는 없다.
부팅시 lilo에서 아래 옵션을 주면 관리자 패스워드 없이 싱글모드로 부팅할
수가 있다.
init=/bin/bash
-l0:0:wait:/etc/init.d/rc 0
l1:1:wait:/etc/init.d/rc 1
l2:2:wait:/etc/init.d/rc 2
l3:3:wait:/etc/init.d/rc 3
l4:4:wait:/etc/init.d/rc 4
l5:5:wait:/etc/init.d/rc 5
l6:6:wait:/etc/init.d/rc 6
각 실행 레벨에 대하여 어떤 명령을 수행할 것인지를 정한다.
보이는 것처럼 /etc/init.d/rc 스크립트에 실행 레벨 번호를 매개 변수로 전달하여
실행시키고 있다.
action 필드의 wait는 모든 command를 실행하고 종료될 때까지 기다린 후 다음
작업으로 넘어가라는 지시다.
/etc/init.d/rc 스크립트는 실행 레벨이 바뀔 때마다 실행 레벨 번호를 인수로
실행되는 다목적 시동 스크립트로 각 실행 레벨에서 알맞은 다른 스크립트를
실행시켜 줌으로 각 실행 레벨에서 실행하거나 중지시켜야할 스크립트들을
start나 stop 매개 변수로 차례로 실행시키거나 중지시킨다.
-z6:6:respawn:/sbin/sulogin
싱글 모드로 들어갈때 관리자 패스워드를 물어보는것처럼 실행 레벨을 6으로
바꿀때-실행 레벨을 6으로 바꾼다는 것은 시스템 리부팅을 뜻한다-도 관리자
패스워드를 물어보게 한다.
-ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
<Ctrl>+<Alt>+<Del> 키를 누르면 재부팅이 되도록 한다.
만약 리부팅이 아니라 종료를 시키고 싶다면 -r 을 -h 로 바꾸어주면 된다.
-pf::powerwait:/etc/init.d/powerfail start
pn::powerfailnow:/etc/init.d/powerfail now
po::powerokwait:/etc/init.d/powerfail stop
UPS 상태를 모니터링할 수 있는 bpowerd 패키지를 인스톨 했을 경우 사용되어 진다.
-1:2345:respawn:/sbin/getty 38400 tty1
2:23:respawn:/sbin/getty 38400 tty2
3:23:respawn:/sbin/getty 38400 tty3
4:23:respawn:/sbin/getty 38400 tty4
5:23:respawn:/sbin/getty 38400 tty5
6:23:respawn:/sbin/getty 38400 tty6
1번부터 6번까지의 가상 콘솔에 대하여 login: 프롬프트를 보여주는 getty
프로그램을 실행시킨다. runlevel 필드를 보면 모든 행들에 대해 1번 실행
레벨이 빠져 있음을 알것이다. 1번 실행 레벨은 싱글 모드로 이미 위의
'~~:S:wait:/sbin/sulogin' 행에서 설정을 했기 때문에 이곳에는 빠져있다.
그러나 레드햇 계열은 싱글 모드를 위한 특별한 설정이 없기 때문에 1번
콘솔에서만 1번 실행 레벨로 로그인을 가능하게 하고 나머지 콘솔에서는 싱글
모드로 로그인을 불가 한다.
action 필드에 있는 respawn는 프로그램이 죽으면 다시 계속 실행하라는
의미이다. 로그아웃을 하여도 계속해서 로그인 화면이 뜨는 이유가 init
프로그램이 inittab에서 respawn 옵션을 보고 계속적으로 getty를 실행 시키기
때문이다.
영문 주석에서 설명한 것 처럼 code 필드는 반드시 디바이스의 마지막 글자하고
같아야 한다. 대부분 경우 코드는 파일 내에서 다른 것과 충돌 하지만 않으면
돼지만 이번 경우에는 정확한 작업을 위해서 정확한 코드를 기입해야한다.
-#T0:23:respawn:/sbin/getty -L ttyS0 9600 vt100
#T1:23:respawn:/sbin/getty -L ttyS1 9600 vt100
#T3:23:respawn:/sbin/mgetty -x0 -s 57600 ttyS3
init는 콘솔을 통한 사용자들의 로그인을 처리한다. 하지만 리눅스 시스템은
콘솔뿐만이 아니라 터미널을 위한 serial 포트나 모뎀으로의 로그인도 처리할
수 있다. 여기서 자세히 설명을 하지는 않겠다.
만약 필요 하다면 위의 주석 처리 되어 있는 부분과 getty, mgetty 맨 페이지를
보고 시도해 보기 바란다. mgetty의 경우 mgetty 패키지를 인스톨 해야 한다.
-inittab 파일을 변경할 경우 init에게 inittab 파일의 변경을 밑에 명령으로
알려 주어야 한다.
init q
*3 init.d 와 rc?.d 디렉토리의 구조
-먼저 데비안의 초기화 시스템의 파일과 디렉토리 구성을 알아 보자.
데비안도 리눅스 배포판에 하나지만 같은 리눅스 배포판인 레드햇과도 약간의
차이를 갖는다.
----------------------------------------------------------------------
- 실행 파일
/sbin/init
/etc/inittab : init가 실행해야할 모든 일이 명시된 파일
/etc/init.d/rc : 각 실행 레벨 실행 스크립트
/etc/init.d/rcS : init에서 처음으로 실행하는 스크립트
- 디렉토리
/etc/init.d : 각 실행 레벨에서 실행되는 실제 스크립트가 저장
/etc/rcS.d : rcS 스크립트에 의해 실행되어질 명령 목록
/etc/rc0.d : 0번 실행 레벨에서 실행되어질 명령 목록
/etc/rc1.d .
/etc/rc2.d .
/etc/rc3.d .
/etc/rc4.d
/etc/rc5.d
/etc/rc6.d
----------------------------------------------------------------------
-데비안에서 데몬으로 돌아가는 패키지를 설치하면 시스템 부팅시 자동으로
실행하기 위하여 실행 스크립트를 /etc/init.d/ 디렉토리에 설치한다.
그리고 각 실행 레벨별 디렉토리에 /etc/init.d 디렉토리에 설치된 실제
스크립트를 향하는 심볼릭 링크를 만든다.
-실제로 각 실행 레벨 디렉토리 /etc/rc?.d (?은 0~6의 실행 레벨을 나타냄)에서
ls -l 명령을 내려 보면 'SnnXXXX' 'KnnXXXX' 형태의 많은 심볼릭 링크 파일만을
볼 수가 있을것이다. 'S' 나 'K' 는 각 실행 레벨 디렉토리에 있는 심볼릭 링크
파일이 /etc/init.d 디렉토리에서 실제 실행되어지는 스크립트의 실행 방향을
지시한다. 'S'로 시작하는 파일은 start 매개 변수로 /etc/init.d 디렉토리에
스크립트를 시작하고 'K'로 시작하는 파일은 stop 매개 변수로 /etc/init.d
디렉토리에 스크립트를 중지한다.
nn은 00-99 사이의 숫자 중 하나이며 이 숫자는 스크립트의 실행 순서를
맞추려는 것으로 실행 순서를 의미한다. 스크립트는 항상 작은 숫자를 먼저
실행한다. XXXX는 시스템 서비스 명으로 /etc/init.d 에 존재하는 실질적인
스크립트 이름을 나타낸다.
S/K 파일명 형식 -----------------------------------------------------
+--- 시동(start)이나 정지(stop)를 결정한다.
|
| +--- 실행 순서를 정한다.
| |
| | +- 서비스 기능 표시
| | |
+---+----+ +------+------+ +-----+----+
| S or K | + | 두자리 숫자 | + | 서비스명 | ex)s91apache
+--------+ +-------------+ +----------+
---------------------------------------------------------------------
실제적으로 'K'로 시작하는 파일은 /etc/rc0.d, /etc/rc1.d, /etc/rc6.d 에만
존재하고 나머지 실행 레벨(2-5) 디렉토리에는 'S'로 시작되는 파일만이
존재한다.
apache를 예로 설명하면 apache를 패키지로 시스템에 인스톨을 할 경우 실제
실행 스크립트는 /etc/init.d/apache 로 존재하고 실행 레벨 디렉토리 2에서
5까지에는 'S91apache'로 실제 스크립트를 실행하는 심볼릭 링크가 만들어진다.
실행 레벨 디렉토리 0,1,6 에는 'K20apache'로 실제 스크립트를 중지하는 심볼릭
링크가 만들어진다.
*4. rc 스크립트
-자신이 제공하고자 하는 서비스를 원하는 특정 런레벨에 진입할 때 자동으로 실행
시키거나 중지시키기 위해서는 부팅시 실행되는 스크립트가 무엇이며, 또한 그 구조에
대한 지식이 필요하다.
-System V 스타일의 init 를 사용하는 데비안의 특성상 특정 런레벨에서 실행되어야
하는 daemon 들을 시작 / 중지 시키는 스크립트들이 /etc/init.d 와 /etc/rcN.d
(N 은 런레벨임) 디렉토리에 존재하게 된다.
-init.d는 부팅시에 쓰이는 모든 스크립트들이 집합해 있는 디렉토리 이고,
rcN.d는 init.d의 디렉토리 안에 있는 스크립트들 중에 각 런레벨에 해당하는,
그러니까 자신들이 필요로 하는 스크립트들만을 링크시킨 파일이다.
-그리고 실제로 이것들을 실행시켜주는 파일은 /etc/init.d/rc 이다.
rc 가 어떻게 해서 실행되는지는 부팅과정을 설명할 때 자세히 다루겠다.
rc 스크립트의 일부이다.
---------------------------------------------------------------------
for i in /etc/rc$runlevel.d/S*
do
[ ! -f $i ] && continue
if [ $previous != N ] && [ $previous != S ]
then
#
# Find start script in previous runlevel and
# stop script in this runlevel.
#
suffix=${i#/etc/rc$runlevel.d/S[0-9][0-9]}
stop=/etc/rc$runlevel.d/K[0-9][0-9]$suffix
previous_start=/etc/rc$previous.d/S[0-9][0-9]$suffix
#
# If there is a start script in the previous level
# and _no_ stop script in this level, we don't
# have to re-start the service.
#
[ -f $previous_start ] && [ ! -f $stop ] && continue
fi
case "$runlevel" in
0|6)
startup $i stop
;;
*)
startup $i start
;;
esac
done
---------------------------------------------------------------------
주석 해석>
# Find start script in previous runlevel and
# stop script in this runlevel.
이 전의 런레벨에 있던 start 스크립트와
현재의 런레벨에 있는 stop 스크립트를 찾는다.
# If there is a start script in the previous level
# and _no_ stop script in this level, we don't
# have to re-start the service.
만약에 이전 런레벨에 start 스크립트가 있는데,
지금 현재의 런레벨에는 stop 스크립트가 없을경우,
해당하는 스크립트의 서비스를 제시작 할 수 없다.
---------------------------------------------------------------------
-rc 스크립트의 이 부분은, /etc/rcN.d 디렉토리 아래에 있는 S로 시작하는
모든 파일에 대해서 다음과 같은 일을 수행한다.
- 현재의 런레벨이 0이나 6일때는 startup 함수를 stop인수로 호출하고,
- 그 나머지 런레벨인 1.2.3.4.5일때는 start를 인수로 하여 startup을 호출한다.
startup() 함수는 다음과 같이 정의되어 있다 :
---------------------------------------------------------------------
startup() {
case "$1" in
*.sh)
$debug sh "$@"
;;
*)
$debug "$@"
;;
esac
}
---------------------------------------------------------------------
startup 함수는 인수로 넘겨받은 "$1" 파일을 실행한다.
여기서 startup함수가 넘겨받는 인수는 파일 이름 뿐 만이 아니고,
뒤에 따라붙는 stop 혹은 start 의 지시자까지도 넘겨받게 된다.
즉, startup foo start 라고 호출하였을 경우 함수는 foo start ($@ 변수)를 실행하게
되는 것이다.
-여기서 우선, /etc/init.d 에 들어갈, daemon 을 실행 / 중지 시키는 스크립트의
작성요령 보자.
친절하게도 데비안에서는 /etc/init.d/skeleton 파일에 /etc/init.d 디렉토리에 들어갈
스크립트들의 기본 골격을 만들어 두었다.
/etc/init.d/skeleton 의 코드는 약간 복잡한데, 더 단순화 하면 다음과 같다.
---------------------------------------------------------------------
case "$1" in
start)
#이부분에 시작되는 코드를 넣는다.
;;
stop)
#이부분에 종료하는 코드를 넣는다.
;;
*)
#만약 start 혹은 stop이 명시되지 않으면 다음줄을 실행한다.
echo "Usage: skeleton {start|stop}"
esac
---------------------------------------------------------------------
스크립트에 이 부분만 포함되어 있으면, 시스템이 시작할 때,
원하는 daemon 을 실행시키고, 종료될 때 안전하게 끝날 수 있도록 할 수 있다.
그 이유는, 앞서 설명한 rc 스크립트에서도 보았듯이 rc 가 /etc/init.d 의 스크립트를
실행하면서 넘겨주는 인수인 start 혹은 stop 으로 daemon 을 시작할 것인지,
아니면 종료할 것인지를 결정하기 때문이고, 따라서, 위의 형태와 같이 스크립트를
작성해야만 rc 파일과 함께 무리없이 잘 동작하는 스크립트를 만들 수 있을 것이다.
*6. 부팅시 서비스 등록
-부팅시에 실행하고자 하는 daemon 이나 그 daemon을 실행하는 스크립트를 원하는
런레벨에서 실행하도록 할려면 /etc/rcN(런레벨).d 에 링크를 걸어주면 된다.
-먼저 링크를 거는 방법에 대해 얘기해 보겠다.
다음과 같은 예를 보자.
---------------------------------------------------------------------
# cat > /etc/init.d/runa
#!/bin/sh
case $i in
start)
echo Runa hello
;;
stop)
echo Runa Bye
;;
*)
echo "Usage: runa [start|stop]"
easc
^D
---------------------------------------------------------------------
# chmod a+x /etc/init.d/runa
# cd /etc/rc0.d
# ln -s /etc/init.d/runa K80runa
# cd /etc/rc1.d
# ln -s /etc/init.d/runa K80runa
# cd /etc/rc2.d
# ln -s /etc/init.d/runa S80runa
# cd /etc/rc3.d
# ln -s /etc/init.d/runa S80runa
# cd /etc/rc4.d
# ln -s /etc/init.d/runa S80runa
# cd /etc/rc5.d
# ln -s /etc/init.d/runa S80runa
# cd /etc/rc6.d
# ln -s /etc/init.d/runa K80runa
---------------------------------------------------------------------
*7. update-rc.d
위 방법을 보다 간편하게 링크를 걸기 위해 사용되는 도구가 update-rc.d이다.
스크립트를 위와 같이 작성했다고 가정하고, 다음과 같이 써주면 된다.
---------------------------------------------------------------------
# update-rc.d runa defaults
Adding system startup for /etc/init.d/runa ...
/etc/rc0.d/K20runa -> ../init.d/runa
/etc/rc1.d/K20runa -> ../init.d/runa
/etc/rc6.d/K20runa -> ../init.d/runa
/etc/rc2.d/S20runa -> ../init.d/runa
/etc/rc3.d/S20runa -> ../init.d/runa
/etc/rc4.d/S20runa -> ../init.d/runa
/etc/rc5.d/S20runa -> ../init.d/runa
#
---------------------------------------------------------------------
-보는 바와 같이 자동으로 링크가 걸렸다.
defaults 를 써 주었을때에는 런레벨 2,3,4,5 에는 start 를,
016 에는 stop을 해서 링크가 걸리게 된다.
보다 자세한 update-rc.d 의 사용법을 알기 위해서 man page에 나오는 설명과
예제를 요약해 보면
# man update-rc.d
SYNOPSIS
update-rc.d [-n] [-f] name remove
update-rc.d [-n] name defaults [NN | NN-start NN-stop]
update-rc.d [-n] name start|stop NN runlevel runlevel ...
. start|stop NN runlevel runlevel ... . ..
설명>
update-rc.d는 system V 스타일의 /etc/rcRUNLEVEL.d/NNname 을 /etc/init.d/name
으로의 init 스크립트의 링크를 자동으로 갱신해 준다.
이 스크립트들은 runlevel 을 바꿀 때 init 프로그램에 의해서
시스템의 daemon 과 같은 서비스를 시작하거나 중지할 때 사용된다. (중략)
INSTALLING INIT SCRIPT LINKS
defaults 값을 주고서 실행했을 경우에 update-rc.d 는 런레벨 2345 에
서비스를 시작하는 링크를 만들고, 런레벨 016에 서비스를 중지하는 링크를 만들어 준다.
그리고, 기본적으로 모든 링크는 숫자 20 을 사용하여 링크된다.
즉, name 에 foobar 가 주어졌다면, S20foobar K20foobar 와 같은 식의 이름의 링크가
생성된다.
예제>
defaults 값 대신 여러 가지 값들이 주어질 수가 있다.
defaults 값 대신에 줄 수 있는 여러 가지 값들은 예제를 통해서 알아보면,
---------------------------------------------------------------------
# update-rc.d -n test defaults 80
---------------------------------------------------------------------
과 같이 하면, S80test K80 test 와 같은 식으로 링크가 생성된다.
시작링크와 종료링크, 즉, S 로 시작되는 링크와 K 로 시작되는 링크가 생성되는
런레벨은 앞서 얘기한 defaults 값으로 되며, 그것은 2345 에는 서비스를
시작할 수 있도록 링크를 걸어주며,
016에는 서비스를 종료하도록 링크를 생성해 주는 것이다.
-n 옵션이 주어졌을 때에는 update-rc.d 는 실제로 아무것도 하지 않고,
단지 실제로 실행되었을 때 어떠어떠하게 될 것이다라는 메세지만을 화면에 출력하고
종료한다.
---------------------------------------------------------------------
# update-rc.d -f test remove
---------------------------------------------------------------------
를 하면, test 를 가리키는 링크들을 /etc/rcN.d 디렉토리들에서 찾아서 모두 지워준다.
여기서 잠시 -f 옵션에 대해서 알아보도록 하겠다.
먼저, -f 옵션을 주지 않고 update-rc.d 를 이용해서 링크를 생성하거나
링크를 삭제할 경우에는 어떻게 되는지를 이야기해 보겠다.
첫번째로, -f 옵션 없이 링크를 생성하는 update-rc.d 명령을 실행하게 되면,
update-rc.d 는 /etc/init.d 에 있는 스크립트 파일로의 링크가 /etc/rc?.d 에
존재할 경우에는 링크를 생성시켜주지 않고 에러를 출력하고 종료한다.
두번째로, -f 옵션 없이 링크를 삭제하는 update-rc.d 명령을 실행하게 되면,
update-rc.d 는 /etc/init.d 에 있는 스크립트가 존재하는지를 체크하게 된다.
그렇게 하여서 만약 /etc/init.d 에 스크립트가 (삭제하고자 하는 링크가 가리키는 파일)
존재하고 있다면, 삭제를 수행하지 않고, 에러를 출력하고 종료하게 된다.
그러나 -f 옵션이 주어질 경우, 파일의 존재여부를 무시하고 링크를 삭제
내지는 생성하게 된다.
---------------------------------------------------------------------
# update-rc.d test start 80 2 5 . stop 20 0 1 .
---------------------------------------------------------------------
과 같이 '.' 으로 start 와 stop 을 구분해서 적어주면,
/etc/rc2.d/S80test
/etc/rc5.d/S80test
/etc/rc0.d/K20test
/etc/rc1.d/K20test
의 링크가 생성되는데 이 예제는,
앞서 언급한 update-rc.d 명령의 형식에 보면, 다음과 같은 라인이 나온다 :
update-rc.d [-n] name start|stop NN runlevel runlevel ...
. start|stop NN runlevel runlevel ... . ..
이것을 번역하면 다음과 같다.
update-rc.d (이름) (start 혹은 stop) (S 혹은 K 뒤에 들어갈 두자리 숫자)
(start 혹은 stop 의 링크가 생성될 런레벨의 목록) .
(start 혹은 stop) (S 혹은 K 뒤에 들어갈 두자리 숫자)
(start 혹은 stop 의 링크가 생성될 런레벨의 목록) .
-이처럼 rc 파일의 구조와 동작 원리를 알고, 또한 그에 따르는 디렉토리의 내용과
디렉토리 내부의 파일들의 역할을 잘 이해한다면, 시스템 부팅시에 제공할 서비스들을
자유롭게 선택할 수 있을 것이다.
-또한, 편리한 관리 도구인 update-rc.d 도 이용한다면
보다 쉽게 시스템의 서비스나 프로세스들에 대한 컨트롤을 가질 수 있을 것이다.
참고
----------------------------------------------------------------------
레드헷의 경우 ntsysv라는 일반 콘솔에서 조작하는 런레벨 메니저가 있다.
또한 X윈도우용인 tksysv가 있다.
----------------------------------------------------------------------

Comments List
釉
안녕하세요 init.d 와 rcN에서 궁금했었는데, 덕분에 많은걸 배우고 갑니다.
감사합니다.^*^