2007/12/12

솔라리스 프로세스의 오픈 화일 보는 법

리눅스 사용자들을 보면, 왕왕 lsof 라는 툴을 사용하는 것을 보게된다. lsof라는 툴은 기본적으로 실행중인 프로세스가 어떤 화일을 열고 있는 지를 보여주는 툴인데, 오픈한 화일 뿐 만 아니라, 네트웍(소켓)을 오픈한 것도 보여주기 때문에, 어떤 포트를 사용하는 지 확인할 때 아주 유용한 툴로 널리 사용되어 왔다.

솔라리스에서는 이와 유사한 툴로 pfiles 라는 유틸리티가 제공이 되고 있으며, 솔라리스 8 에서는 /usr/proc/ bin 디렉토리에 있던 유틸리티였으나, 솔라리스 9때부터 /usr/bin으로 옮겨졌다.

lsof가 오랜동안 사용되어 오면서 보다 verbose한 내용을 제공하는 것은 사실이나, pfiles도 거의 동등한 수준에 내용을 제공하므로 상당히 유용할뿐 아니라, 솔라리스에서는 pfiles 면 충분하다는 생각이 든다.
pfiles의 사용법은 다음과 같다.

$pfiles

그런데, lsof나 pfiles는 프로세스의 특정 순간 (캡쳐를 시도하는 타임의 스냅샷)에 오픈된 화일만 보여준다. 만약, 해당 프로세스가 주기적으로 짧게 화일을 열고 닫는 것을 반복적으로 한다면, 이 유틸리티로는 매우 그 과정을 매우 찾기 힘들다. 리눅스에서는 그것을 해결하기가 현재는 매우 힘든 반면, 솔라리스 10에서는 dtrace라는 환상적인 툴을 제공함에 따라, 상상 이상의 데이타를 제공해준다.

다음의 dtrace 툴은 해당 프로세스가 언제 어떤 화일을 여는 지를 보여준다. dtrace에서 화일을 여는 것을 트레이스 하는 방법은 syscall의 open을 추적하는 방법이 있을 수도 있고, dtrace가 제공하는 io Provider를 이용하는 방법도 있다. 단순 화일명이외에 화일이 위치하는 디스크의 이름등과 같이 구체적인 정보를 보고자하는 경우에는 io Provider를 화일 이름정도만을 트레이스 하고 싶으면 open을 트레이스 하는 것이 편리하다.

/* open.d */
#!/usr/sbin/dtrace

syscall::open:entry
/execname == firefox-bin/
{
trace(copyinstr(arg0));
}



#dtrace -s open.d
와 같이 실행하고 있으면, dtrace는 firefox-bin 이라는 실행프로그램이 나타날때까지 가만히 있는다. 나타나게 되면, 그때 부터 트레이스를 시작한다. 실행 화일 이름은 실제로 실행된 프로그램의 이름과 간혹 다른 경우가 있다. 대게 환경 설정과 같은 것을 수반하기 위해서 쉘스크립트를 실행하는 경우가 있는데, 이런 경우에는 시작하는 쉘이 invoke하는 실제의 애플리케이션의 이진화일의 이름을 주는 것이 좋다.

위의 예처럼 firefox는 대게 firefox라는 쉘스크립트로 실행되지만, 실제 실행해보면, 실행 화일은 firefox-bin이라는 화일이 수행되고 있다.

위의 예에서 lsof와 같이 프로세스의 pid로 추적을 하고 싶으면서 dtrace의 아규먼트로 pid를 주고 싶다면 다음과 같이 변경해서 실행시키면 된다.

/* open2.d */
#!/usr/sbin/dtrace

syscall::open:entry
/pid == $1/
{
trace(copyinstr(arg0));
}

실행 예
#dtrace -s open2.d `pgrep firefox-bin`

2007/12/11

솔라리스 화일 시스템 성능 테스트 스크립트

솔라리스와 같은 유닉스 혹은 유닉스 유사 계열은 주로 서버사이드에서 많이 사용되는 관계로 화일 시스템의 혹독한 테스트를 필요로 하는 경우가 왕왕 있다. 이런 경우를 위해서 다양한 화일 시스템 테스트 툴이 있는데, iGen이라던가, bonnie라던가 하는 것들이 웹에서 쉽게 찾아서 사용할 수 있는데,단순한 화일 쓰기 테스트만을 테스트하기 위해서 복잡한 툴을 사용하는 것은 다소 번거로운 것 같아서 하나 작성해보았다.

/dev/urandom에서 생성되는 랜덤 데이타 화일을 기반으로 테스트 화일을 1M 기준으로 동시에 작성하도록 되어 있다. 총 종료 시간을 측정하기 위해서는 실행화일 끝에 wait를 두도록 한다.

#!/usr/bin/bash
ARG1=$1; NUM_OF_FILES=${ARG1:=10}

set i=0
i=$((i+1))

maketmpfile() {
# 1MB file generation
tmpfilename=test$RANDOM

#echo $tmpfilename#

dd if=/dev/urandom of=$tmpfilename bs=1024 count=1024 > /dev/null 2>&1 &

# for debugging
#echo " dd if=/dev/urandom of=$tmpfilename bs=1024 count=1024"
#

}

while true
do
# for debugging
#echo -n "$i:"
#

maketmpfile
i=$((i+1))
if [ $i -gt $NUM_OF_FILES ] ; then
exit 1
fi
done
wait

테스트 방법은

$timex filebench_v2.bash 1000
과 같이 실행함으로써 테스트할 수 있다.