Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>
Docbook 원문

Proc filesystem - 시스템 정보 수집

1절. 소개

이미 몇번에 걸쳐서 간단하게 proc 파일시스템에 대해서 알아보긴 했으나, 지금까지의 문서는 거의 입문수준의 이벤트성 문서였었다.

그래서 이번에는 좀더 자세히 다루고자 마음먹고 문서를 작성한다. 이문서는 리눅스 커널 2.4.x 를 기준으로 작성될것이나, 대부분의 경우 2.2.x 에도 동일하게 적용될 것이다. 가끔은 솔라리스와 비교 설명을 하게 될것이다.

proc 파일시스템에 관련된 문서는 크게 3장으로 다룰것이다. 첫번째 문서는 시스템정보 수집에 대한 내용을 다루며, 두번째 문서는 시스템정보 변경에 대한 내용을 다룰것이다. 마지막 문서는 시스템정보 수집기능을 이용한 간단한 어플리케이션 제작과 함께 자신만의 proc 시스템을 만드는 법에 대해서 알아볼 것이다. 이번 문서는 그중 첫번째 장으로 시스템정보 수집에 대한 내용을 다루게 된다.


2절. 시스템 정보수집

이번장에서는 pseudo 파일 시스템인 /proc 에 대한 개략적인 설명과 함께, LInux 시스템상의 어떠한 정보를 제공하고 있는지 알아볼것이다. 이해를 돕기 위해서 실례를 들어가면서 설명을 하게 될것이다.

기본적으로 proc 파일 시스템은 커널이 가지고 있는 여러가지 데이타 구조체를 시스템 사용자(프로그래머 혹은 시스템 관리자)에게 쉽게 전달하기 위해서 사용하는 목적으로 만들어져 있다. 이 /proc 파일시스템 을 이용하게 됨으로써 좀더 쉽게 각종 시스템 정보를 얻어올수 있으며, 여러가지 커널옵션을 특별한 프로그래밍 과정없이 단지 파일의 정보변경 만을 통해서 쉽게 변경할수 있도록 도와준다.

실제 proc 파일시스템을 이용하지 않고 커널 데이타 구조체에서 직접 원하는 시스템 정보를 가져올수 있기는 하지만, 별도의 프로그래밍 과정을 거쳐야 할뿐더라 꽤 귀찮은 여러가지 요건을 만족시켜주어야 한다. 특별히 성능을 중요시 여기지 않는 대부분의 경우 proc 파일시스템을 이용해서 정보를 가져오는 것으로도 충분히 기본적인 목적을 달성할수 있을것이다.

수집된 정보는 특히 시스템관리를 위한 시스템 모니터링 시스템(SMS) 과 시스템 최적화를 위한 시스템성능분석등에 유용하게 사용될수 있다.

특히 리눅스의 경우 다른 운영체제 보다 더욱 많은 상세한 정보들을 (사실상 거의 대부분의 중요 정보들을) proc 파일시스템을 통해서 제공함으로, 여기에 대한 정보를 제대로 알게 될경우 시스템 프로그래밍을 좀더 원할하게 할수 있다. 사실 리눅스 상에서 제대로된 시스템 프로그래밍을 원한다면 proc 파일시스템을 활용할줄 알아야 할것이다.

아래의 내용들은 linux 를 사용하고 있다면 cat 혹은 vi 와 같은 에디터를 통해서 바로 테스트 가능함으로, 가급적이면 내용을 반드시 확인해 보도록 하자.


2.1절. 프로세스 정보 디렉토리

/proc 디렉토리에는 프로세스 정보를 가지는 디렉토리가 존재한다. 이들 프로세스정보 디렉토리는 각 프로세스의 PID를 이름으로 가지며 이 디렉토리 안에는 다음과 같은 다양한 정보들을 제공한다.

표 1. /proc/PID 에서 제공하는 프로세스 정보들

파일명제공 정보
cmdline명령행 옵션
cpuSMP 시스템일경우 어떤 cpu 에서 실행되었는지
cwd작업디렉토리 링크
exe프로세스를 실행시킨 명령어의 링크
fd디렉토리로 모든 파일지정자를 가진다.
maps실행어와 라이브러리파일의 메모리 맵
mem이 프로세스에 의해서 사용되는 메모리
root이 프로세스의 루트 디렉토리
stat프로세스 상태
statm프로세스 메모리 상태
status프로세스 상태(인간이 알아보기 쉬운 포맷)
예를 들어서 PID가 1264 인 프로세스의 정보를 알아보고 싶다면 /proc/1264/status 정보를 확인하면 된다.
 		 
[root@localhost 1264]# cat /proc/1264/status 
Name:   bx
State:  S (sleeping)
Tgid:   1264
Pid:    1264
PPid:   1225
TracerPid:      0
Uid:    500     500     500     500
Gid:    500     500     500     500
FDSize: 256
Groups: 500 
VmSize:     3620 kB
VmLck:         0 kB
VmRSS:      1900 kB
VmData:      636 kB
VmStk:       140 kB
VmExe:       896 kB
VmLib:      1756 kB
SigPnd: 0000000000000000
SigBlk: 0000000080000000
SigIgn: 8000000000001004
SigCgt: 0000000000036203
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
			
내용을 보면 ps 명령어가 보여주는 대부분의 정보를 보여주고 있음을 알수 있으며, 실질적으로도 ps 프로그램은 proc 파일시스템의 정보를 이용해서 시스템 정보를 출력시켜준다. 실제 프로세스 정보 분석프로그램을 만들일이 있다면 status 보다는 stat 파일을 사용하는게 편할것이다. status 는 인간이 보기에는 편하지만 프로그래밍 작업을 통해서 원하는 데이타를 가져오기에는 적당하지 않은 포맷으로 되어 있다.

또한 ststm 파일을 확인하면 프로세스 메모리 사용에 대한 더욱 상세한 내용을 확인해 볼수 있다. 여기에는 다음과 같은 상세 메모리 정보가 포함되어 있다.

표 2. statm 파일이 가지는 정보들

필드
size프로그램의 총 크기
resident할당된 메모리의 크기
shared공유영역으로 할당된 페이지의 수
trscode 를 위해 할당된 페이지의 수
drsdata및 stack 로 할당된 페이지의 수
lrs라이브러리 로 할당된 페이지의 수
dtdirty 페이지의 수


2.2절. 커널 정보들

리눅스의 proc 파일시스템은 프로세스의 정보뿐만 아니라 커널이 실행되면서 작성된 각종 정보들을 역시 파일로 관리하고 있다. (솔라리스의 경우에는 단지 프로세스 정보만을 제공한다.) 제공하는 정보는 다음의 테이블에서 확인하기 바란다.

표 3. /proc 의 파일정보들

파일내용
apmAdvanced power management 정보
busbus 관련정보
cmdline커널 실행옵션
cpuinfo사용cpu 정보
device사용가능한 디바이스(블럭/문자 장치)
dma사용하고 있는 DMS 채널
filesystems지원되는 파일시스템
driver/rtc드라이버 정보
execdomainsexecdomains, 보안과 관련
fb프레임버퍼 디바이스
ideIDE 장치에 대한 정보 디렉토리
interrupts인터럽트 사용율
iomem메모리지도
ioports사용중인 입출력포트
isapnppnp 정보
kcore커널 core 이미지
kmsg커널메시지
ksyms커널 심볼 테이블
loadavg최근 1,5,15 분의 평균 load
lockskernel locks 정보
meminfo메모리 정보
misc기타등등
modules실행중인(load) 모듈 목록, lsmod로 나오는 정보다
mounts마운트된 파일시스템 정보
net네트워킹 정보
partitions파티션 정보
pciPCI 버스 정보
scsiSCSI 정보
slabinfoSlab pool 정보
swapsswap 파일시스템 사용정보
sysvipcSysVIPC 자원정보(메시지큐, 세마포어, 공유메모리등)
ttytty 드라이버 정보
uptime시스템 가도시간
version커널버젼

예를들어서 시스템 인터럽트를 확인해 보고 싶다면 interrupts 화일을 확인하면 된다.

[root@localhost /proc]# cat /proc/interrupts
           CPU0       
  0:   55607808          XT-PIC  timer
  1:     479783          XT-PIC  keyboard
  2:          0          XT-PIC  cascade
  8:          1          XT-PIC  rtc
  9:    2217067          XT-PIC  eth0
 10:      88957          XT-PIC  usb-uhci, usb-uhci, Crystal CS4281
 12:    2121308          XT-PIC  PS/2 Mouse
 14:     487260          XT-PIC  ide0
 15:      80045          XT-PIC  ide1
NMI:          0 
ERR:          0
			
CPU0 이란 헤더명에서 볼수 있듯이 복수의 CPU 인터럽트정보를 표시해 줄수 있다. interrupts 는 각각의 장치가 어느정도의 사용율을 보이고 있는지 확인하기 위해서 유용하게 사용할수 있다. 이것은 일정한 시간간격을 가지고 위의 파일의 내용을 검사하여서 현재의 값에서 이전의 값을 뺀 값으로 조사할수 있다. 실제 지금 find ./ -name 과 같은 하드디스크 인터럽트를 많이 사용하는 작업을 시킨후 ide0 의 변화율을 보기 바란다. 아마도 평소에 비해서 변화율이 극적으로 증가하는걸 볼수 있을 것이다. 다음은 필자가 테스트를 위해서 작성한 간단한 스크립트이다.
[root@localhost proc]# while [ 1 ] 
> do
> cat interrupts | grep "ide0"
> sleep 1
> done
 14:      48529          XT-PIC  ide0  
 14:      48529          XT-PIC  ide0
 14:      48529          XT-PIC  ide0  
 14:      48538          XT-PIC  ide0   -- find 를 실행시켰다. 
 14:      48624          XT-PIC  ide0   ---+
 14:      48723          XT-PIC  ide0      |
 14:      48836          XT-PIC  ide0      | 인터럽트가 증가함을 알수 있다. 
 14:      48930          XT-PIC  ide0      |
 14:      49031          XT-PIC  ide0   ---+
			

커널 2.4 부터는 irq 라는 흥미로운 정보를 담고 있는 새로운 시스템정보를 알려주기 위한 디렉토리가 만들어져 있다. 여기에 있는 정보들을 변경하면 IRQ와 CPU의 관계를 조정할수 있다. 이 이야기는 여러분이 단지 하나의 CPU 에서 IRQ 를 "hook" 할수 있도록 할수 있음을 의미한다. - 물론 테스트를 위해서는 2개 이상의 CPU 를 사용하는 시스템이 필요로 하지만 - irq 디렉토리를 보면 각각의 IRQ 번호를 이름으로 갖는 서브 디렉토리를 가지며 이 디렉토리에는 prof_cpu_mask 라는 파일을 가진다. (이 파일은 CPU 가 2개 이상일때만 존재한다)

[root@localhost /proc]# ls irq/
0  1  10  11  12  13  14  15  2  3  4  5  6  7  8  9  prof_cpu_mask
[root@localhost /proc]# ls irq/0/
smp_affinity
			
smp_affinity 를 보면 다음과 같은 값이 세팅되어 있을것이다.
[root@localhost /proc]# cat irq/0/smp_affinity 
ffffffff
			
이 값은 bitmask 로써, 당신이 이 IRQ(0번)를 제어하기 위해서 어떤 CPU를 할당할것인지를 지정할수 있다. 예를들어서 단지 첫번째 CPU 만이 IRQ 를 제어하도록 하려면 아래와 같이하면된다.
  
[root@localhost /proc]# echo 1 > irq/0/smp_affinity 
			


2.3절. IDE 장치 정보 /proc/ide

/proc/ide 디렉토리는 커널에서 등록중인 모든 IDE 장치에 대한 정보를 가지고 있다. 이 디렉토리에는 각각의 IDE 컨트롤러 정보를 가지는 써브디렉토리를 가진다. 그리고 각각의 IDE 컨트롤러를 가리키는 심볼릭 링크 파일과 각 장치 버젼을 담고 있는 drivers 파일을 제공한다. 다음은 IDE 장치의 버젼정보를 담고 있는 drivers 파일의 출력 내용 이다.

[root@coco ide]# cat drivers 
ide-cdrom version 4.59
ide-floppy version 0.97
ide-disk version 1.10
			
위의 drivers 에는 가장 일반적인 정보인 어떤 ide 장치인지( 하드디스크, cdrom, 플로프)와 그 버젼만을 가지고 있는데, 좀더 자세한 내용을 알기를 원한다면 ide0, ide1 과 같은 디렉토리의 내용을 확인해야 한다. 다음 테이블을 참고하기 바란다.

표 4. IDE 컨트롤러 정보 /proc/ide/ide?

파일명제공 정보
channelIDE 체널 (0 또는 1)
configPCI/IDE bridge 를 위한 설정
mateMate name
modelIDE 컨트롤러의 칩셋/타입

IDE 컨트롤러 정보 /proc/ide? 디렉토리 아래에는 IDE 장치 정보를 가지는 파일들이 제공된다. 다음 테이블을 참고하라.

표 5. IDE 컨트롤러 정보 /proc/ide/ide?/

파일명제공 정보
cachecache 정보
capacity저장공간블럭(1블럭 == 512byte)
driver드라이버 버젼
geometry물리적/논리적 geometry
identifydevide identify block
media매체의 종류
settings디바이스 셋업 정보
smart_thresholdsIDE disk management thresholds
smart_valueIDE disk management values

필자의 PC 에는 하나의 HDD 와 하나의 CDROM (둘다 IDE) 가 달려있자. CDROM 은 hdc 와 연결되어 있는데, /proc/ide/hdc/media 의 내용을 출력하자 cdrom 이라고 나왔다. 미더어 타입을 쉽게 알수 있다. 또한 capacity 사이즈가 1108760 블럭 으로 나왔는데, 1block 은 512byte 임으로 계산하면 567685120 으로 cdrom 미디어의 용량을 계산할수 있다. HDD 역시 마찬가지의 방법을 이용해서 미디어와 용량을 계산할수 있을것이다.

그러나 가장 중요한 정보를 주는 것은 settings 파일일것이다.

[root@localhost hda]# cat settings 
name                    value           min             max             mode
----                    -----           ---             ---             ----
bios_cyl                1861            0               65535           rw
bios_head               255             0               255             rw
bios_sect               63              0               63              rw
breada_readahead        4               0               127             rw
bswap                   0               0               1               r
current_speed           66              0               69              rw
file_readahead          0               0               2097151         rw
ide_scsi                0               0               1               rw
init_speed              12              0               69              rw
io_32bit                1               0               3               rw
keepsettings            0               0               1               rw
lun                     0               0               7               rw
max_kb_per_request      64              1               127             rw
multcount               8               0               8               rw
nice1                   1               0               1               rw
nowerr                  0               0               1               rw
number                  0               0               3               rw
pio_mode                write-only      0               255             w
slow                    0               0               1               rw
unmaskirq               1               0               1               rw
using_dma               1               0               1               rw
			
언뜻봐도 실린더, 헤더, 섹터 등에 대한 정보가 눈에 들어올 것이다.


2.4절. 네트워킹 정보 /proc/net

/proc/net 디렉토리에는 네트웍과 관련된 다양한 정보를 가지고 있는 파일들이 있다. 당신의 시스템이 ipv6 를 지금지원하고 있다면 ipv6 와 정보와 관련된 다음의 추가 파일들이 가지고 있을 것이다. 당신이 kernel 2.4.x 를 사용하고 ipv6 모듈을 가지고 있다면 지금 modprobe 를 이용해서 ipv6 모듈을 적재하기 바란다. 그럼 아래와 같은 IPv6 정보관련 파일들이 생성될 것이다.

	
[root@localhost /]# modprobe ipv6
[root@localhost root]# lsmod
ipv6                  140416  -1 
sb                      7968   0  (autoclean)
sb_lib                 34624   0  (autoclean) [sb]
uart401                 6560   0  (autoclean) [sb_lib]
sound                  59052   0  (autoclean) [sb_lib uart401]
soundcore               4324   5  (autoclean) [sb_lib sound]
mga                   100656  14 
...
			

표 6. /proc/net 에서 제공하는 IPv6 정보

파일명제공 정보
udp6열린 UDP 소켓리스트
tcp6열린 TCP 소켓리스트
raw6RAW 디바이스 상태
igmp6IP 멀티캐스트 주소
if_inet6IPv6 인터페이스 주소목록
ipv6_routeIPv6 를 위한 커널 라우팅 테이블
ipv6_statsGlobal IPv6 라우팅 테이블
sockstat6IPv6 소켓 상태
snmp6IPv6 snmp 데이타

다음은 일반적인 데이타이다. IPv4 관련 네트웍 정보파일과 다른 것들을 포함하고 있다.

표 7. /proc/net 에서 제공하는 네트웍 정보

파일명제공 정보
arp커널 ARP 테이블
dev네트웍 디바이스 상태
ip_fwchains방화벽
ip_fwchains방화벽 chain 룰
ip_fwnames방화벽 chain 이름
netstat네트웍통계
rawraw 디바이스 통계
route커널 라우팅 테이블
rpcrpc 정보 디렉토리
rt_cache라우팅 캐쉬
snmpSNMP 데이타
sockstat소켓 통계
tcptcp 소켓
tr_rifToken ring RIF 라우팅 테이블
udpUDP 소켓
unixUnix 도메인 소켓
wirelessWireless 인터페이스 데이타
igmpIP 멀티캐스트 주소
pschedGlobal packet scheduler parameters
netlinkPF_NETLINK 소켓 리스트
ip_mr_vifsList of multicast virtual interface
ip_mr_cacheList of multicast routing cache

예를 들어서 dev 파일을 일정 시간간격으로 분석하면, 각각의 네트웍 장치에 어느정도의 트레픽이 있는지 알아낼수 있다.

[root@localhost net]# cat dev
Inter-|   Receive                                                |  Transmit ...
    lo:       0       0    0    0    0     0          0         0        0  ...
  eth0: 3471409    8518    0    0    0     0          0         0   522127  ...
			

또한 tcp 파일을 보면 현재 커널에서 관리중인 소켓의 정보를 알수 있다. 현재 필자는 bx 를 이용해서 irc 채팅중인데, 이 bx 가 사용하는 소켓 정보를 알아본 결과 다음과 같았다.

     
[root@localhost /]# ps -aux | grep bx | grep -v grep
yundream  9420  0.0  0.8  3600 2096 pts/2    S    Nov12   0:01 bx irc.nuri.net
[root@localhost /]# cd /proc/9420/fd  
[root@localhost fd]# ls -al
합계 0
dr-x------    2 yundream yundream        0 11월 13 00:14 .
dr-xr-xr-x    3 yundream yundream        0 11월 13 00:14 ..
lrwx------    1 yundream yundream       64 11월 13 00:14 0 -> /dev/pts/2
lrwx------    1 yundream yundream       64 11월 13 00:14 1 -> /dev/pts/2
lrwx------    1 yundream yundream       64 11월 13 00:14 2 -> /dev/pts/2
lrwx------    1 yundream yundream       64 11월 13 00:14 3 -> socket:[10592]
lrwx------    1 yundream yundream       64 11월 13 00:14 4 -> socket:[10594]
			
그럼 tcp 파일을 열어서 실제 위의 소켓정보가 tcp 파일에 유지 되고 있는지 확인 해보자.
[root@localhost net]# cat tcp
  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt ... 
   0: 00000000:1770 00000000:0000 0A 00000000:00000000 00:00000000 00000000 ...
   1: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 ...
   2: C3D2CDD2:807B CC2F3ED3:0050 01 00000000:00000000 00:00000000 00000000 ...
   3: C3D2CDD2:807D CC2F3ED3:0050 01 00000000:00000000 00:00000000 00000000 ...
   4: C3D2CDD2:804D 5070FFCB:1A0B 01 00000000:00000000 02:0004982C 00000000   500        0 10594 2 c1ab9080 30 4 30 2 2                              
...
			
필요없는 부분은 생략했다. 10594 부분을 눈여겨 보기 바란다. 이부분이 커널에서 소켓을 가리키기 위해서 사용하는 번호이다. /proc/pid/fd 의 소켓 번호와 일치되고 있음을 알수 있다. C3D2CDD2 는 지금 시스템의 IP 번호이다. 804D 는 사용하고 있는 포트번호이며 5070FFCB:1A0B 는 연결된 irc 서버 의 주소:포트 정보임을 알수 있다. 1A08 은 6667 로 표준 irc 서버 포트이다. 이들 정보는 16진수 정보로 표현되지 진수변환이 가능한 계산기를 써서 확인해 보길 바란다.

arp 파일의 내용은 arp 테이블의 내용을 보여준다. TCP/IP 개요(2) 를 눈여겨 보았다면 어디에 쓰는테이블인지 이해가 될것이다.


2.5절. SCSI 정보

만약 현재 시스템이 SCSI 어뎁터를 가지고 있다면 /proc/scsi 에 각 어뎁터 정보를 가지는 디렉토리가 생성될 것이다. /proc/scsi 디렉토리에는 scsi 란 파일이 있는데, 이 파일은 모든 scsi 장비의 대략적인 정보를 보여준다.

[root@localhost scsi]# cat scsi
Attached devices:
Host: scsi0 Channel: 00 Id: 00 Lun: 00
  Vendor: IBM      Model: DGHS09U          Rev: 03E0
  Type:   Direct-Access                    ANSI SCSI revision: 03
Host: scsi0 Channel: 00 Id: 06 Lun: 00
  Vendor: PIONEER  Model: CD-ROM DR-U06S   Rev: 1.04
  Type:   CD-ROM                           ANSI SCSI revision: 02
			
그리고 각 scsi 어뎁터 이름으로 디렉토리가 생성되어 있음을 볼수 있을것이다. 이 파일들은 어뎁터가 사용하는 컨트롤러의 IRQ, IO 주소 범위 등의 정보를 포함하고 있다. 예를 들어서 만약 Adaptec AHA-2940 SCSI 어뎁터를 사용한다고 하면 아마도 aic7xxx 디렉토리가 생성되어 있을것이다. 그러면
[root@localhost scsi]# cat aic7xxx/0 
  Adaptec AIC7xxx driver version: 5.1.19/3.2.4
  Compile Options:
    TCQ Enabled By Default : Disabled
    AIC7XXX_PROC_STATS     : Disabled
    AIC7XXX_RESET_DELAY    : 5
  Adapter Configuration:
             SCSI Adapter: Adaptec AHA-294X Ultra SCSI host adapter
                             Ultra Wide Controller
      PCI MMAPed I/O Base: 0xeb001000
   Adapter SEEPROM Config: SEEPROM found and used.
        Adaptec SCSI BIOS: Enabled
                      IRQ: 10
                     SCBs: Active 0, Max Active 2,
                           Allocated 15, HW 16, Page 255
               Interrupts: 160328
....
			
과 같은 정보를 볼수 있을것이다. 정보의 양이 꽤 많음으로 생략했다.


2.6절. TTY 정보 /proc/tty

여기에는 활성화되어있거나 사용할수 있는 tty 의 정보들을 가져올수 있다. 이 디렉토리는 몇개의 파일과 서브디렉토리를 포함하고 있다. 다음은 이들 파일과 파일을 통해서 얻을수 있는 정보를 정리한 테이블이다.

표 8. /proc/PID 에서 제공하는 프로세스 정보들

파일명제공정보
drivers드라이버와 사용하고 있는 리스트
ldiscsregistered line disciplines
driver/serial사용통계와 tty lines 의 정보


3절. 결론

이상 proc 파일시스템을 이용한 시스템 정보 가져오기에 대해서 알아보았다.

여기에 있는 내용들은 완전한 내용을 담고 있지 않다. 필자가 모르는 몇몇 생소한 용어들이 꽤있었고, 몇몇은 하드웨어에 관한 꽤 상세한 지식을 가지고 있어야 제대로 설명이 가능한것들이 였는데, 그러한 것들에 대한 설명은 부족할 것이다. 그리고 위의 ipv6 관련 정보에서 보다시피, 커널의 종류와 시스템의 종류 Load 되어 있는 모듈에 따라서 proc 파일시스템에서 제공하는 파일 자체가 달라질수 있다. 그럼으로 몇가지 정보가 빠졌을수도 있다. 이러한 정보는 직접 알아봐야 할것이다.

하지만 자주 사용되는 중요한 내용들에 대해서는 대부분 다룬것으로 생각된다. 시스템을 분석하는데 많은 도움이 되었으면 한다.