검색어 '실전사용'에 대한 1 개의 검색 결과

  1. 2010/02/18 lsof 의 실전 사용 [펌] by 마음튼튼


이 글은 lsof 의 사용방법에 대해 설명합니다. lsof 는 프로세스의 파일핸들을 조사해 볼 수 있는 유용한 툴입니다.

lsof ("LiSt Open Files") 는 서버에 열린 파일 핸들의 리스트를 보여주는 툴입니다. 여러가지 옵션들과 스위치들을 통해서 이러한 핸들들을 필터링할 수 있게 해줌으로써 솔라리스 관리자가 문제에 대한 분석을 가능하도록 도와 줍니다.

이 가이드는 lsof 의 몇가지 커맨드라인 옵션에 대해 설명합니다. 그리고 실전에서 어떻게 lsof 를 사용할 수 있는지에 대한 몇가지 예제를 보여 드립니다. (참고: 이 글의 모든 예제는 솔라리스 8 버전 이상에서 모두 적용 가능합니다; 이전 버전에서도 사용이 가능할 것으로 생각되지만 직접 확인해 보진 않았습니다.)

"lsof" 얻기

lsof 는 기본 솔라리스 설치의 표준으로 따라서 설치되지 않습니다. 그러나 SPARC 및 x86 버전의 솔라리스 패키지로 컴파일 가능하고 http://sunfreeware.com 에서 다운로드 받으실 수 있습니다.

열린 네트워크 포트 확인하기

구문:

 
lsof -i [<protocol>][@<interface name>][:<port>]

위의 3가지 파라미터를 일부분만 혹은 전부 지정하실 수 있습니다. 생략된 부분은 와일드카드로 간주 합니다. <port> 는 단일 포트 혹은 범위로 지정될 수 있습니다. lsof 를 이러한 방식으로 사용하는 것은 netstat -a 와 비슷한 결과를 돌려주지만 거기에 덧붙여서 프로세스와 소유자의 정보 또한 제공 합니다.

주어진 프로세스가 연 파일 핸들들의 리스트

구문:

 
lsof -p <process id>[,<process id>[,<process id>[...]]]

lsof 에 하나 혹은 복수개의 프로세스 ID 를 (콤마로 구분됨) 입력함으로써 모든 연관된 파일 핸들들의 리스트를 출력할 수 있습니다. 이것은 특정 실행 프로세스가 어떠한 라이브러리를 사용하는지 확인할때 아주 유용합니다. 이 커맨드를 통해서 프로세스가 어떻게 로그 파일, 설정 파일들과 상호동작하는지 확인하실 수 있습니다.

특정 유저가 연 파일 핸들들의 리스트

구문:

 
lsof -u <username>[,<username>[,<username>[...]]]

이 커맨드는 주어진 유저에게 속한 모든 열린 핸들들을 보여 줍니다.

주어진 파일 시스템에서 열린 모든 파일 핸들들 보기

구문:

 
lsof <file system or device>

이 옵션은 umount 커맨드가 수행되는 것을 막는 프로세스들을 찾을때 유용합니다. 혹은 적절한 디렉토리 항목에 없는 열린 파일을 추적할때에 유용합니다.

다른 유용한 플래그들
  • -b – 커널을 블록할 수 있는 시스템 호출의 사용 회피하기
  • -w – 주의 메세지 생략하기
  • -P – 포트 번호를 /etc/services 에 있는 서비스 이름들과 매핑하지 말기
  • -a – 이 플래그를 다른 두 플래그 사이에 삽입함으로써 두가지 플래그 모두에 매치되는 결과만 보기. 기본적으로 lsof 는 지정된 플래그들 중에 하나라도 만족하는 모든 핸들들을 보여줌.
예제

inetd 가 리스닝하고 있는 모든 포트들 보기:
현재 inetd 가 어떠한 포트들을 열고 있는지 확인해 봅시다.

 
gouda# ps -ef | grep inetd
 
root  2849     1  0   May 25 ?        6:43 /usr/sbin/inetd -s
gouda# lsof -i -a -p 2849
COMMAND  PID USER   FD   TYPE        DEVICE SIZE/OFF NODE NAME
inetd   2849 root   11u  IPv6 0x30006ec96d0      0t0  TCP *:ftp(LISTEN)
inetd   2849 root   13u  IPv4 0x30006ec9550      0t0  UDP *:name(Idle)
inetd   2849 root   16u  IPv4 0x30008f26ad8      0t0  TCP *:52783(LISTEN)
inetd   2849 root   17u  IPv4 0x30006ec9b50      0t0  UDP *:57504(Idle)
inetd   2849 root   23u  IPv6 0x30008f264d8      0t0  UDP *:servicetag(Idle)
inetd   2849 root   24u  IPv4 0x30008f26358      0t0  TCP *:servicetag(LISTEN) 

일단 inetd 의 프로세스 ID 를 확인하고, 그 다음 lsof 가 모든 IP 핸들들과 (-i) 또한 (-a) 와 같이 포트에 의해 열린 것들을 (-p <process id>) 확인합니다.

특정 유저의 현재 열린 모든 네트워크 접속의 리스트:
가능한 보안 구멍을 추적하거나 어플리케이션이 올바른 데이타베이스에 접속하고 있는지 확인하기 위해서, lsof 는 주어진 유저의 현재 네트워크 접속들을 보여 줍니다.

 
gouda# lsof -i -a -u fred
COMMAND PID USER FD  TYPE DEVICE SIZE NODE NAME
sshd   9696 fred  5u IPv4 0x3001 0t527 TCP gouda:22->edam:46528(ESTABLISHED)
sshd   9696 fred 10u IPv4 0x300e   0t0 TCP localhost:6011(LISTEN)
sshd  14710 fred  5u IPv4 0x3008 0t404 TCP gouda:22->edam:46590(ESTABLISHED)
sshd  14710 fred 10u IPv4 0x307d   0t0 TCP localhost:6012(LISTEN)
sshd  17013 fred  5u IPv4 0x300f 0t146 TCP gouda:22->edam:50019(ESTABLISHED)
sshd  17013 fred 10u IPv4 0x30e0   0t0 TCP localhost:6010(LISTEN)
ssh   25259 fred  4u IPv4 0x3000 0t157 TCP gouda:54435->colby:22(ESTABLISHED)
sshd  25383 fred  5u IPv4 0x3000 0t126 TCP gouda:22->brie:34480(ESTABLISHED)
ssh   25438 fred  4u IPv4 0x3000  0t91 TCP gouda:54448->smokey:22(ESTABLISHED)

이 것은 fred 란 유저가 3개의 수신(incoming) ssh 접속을 가지고 있고 두개의 송신 ssh 접속을 가지고 있음을 알려 줍니다. lsof 를 다른 서버중에 하나에서 실행하고, 본래 포트를 찾아 봄으로써 (예를 들어 edam 의 포트 46528) 거기서 계속적으로 추적을 수행할 수 있습니다.

어떤 프로세스가 특정 파일 시스템의 언마운트를 막는지 찾아보기:
특정 프로세스가 umount 커맨드의 수행을 방해할 수 있습니다. -f 플래그를 통해서 잠재적으로 오류를 유발하는 대신에 lsof 는 어떠한 프로세스들이 먼저 정지 되어야 하는지를 보여 줍니다.

 
gouda# lsof /mnt/scratchdisk
COMMAND   PID USER    FD  TYPE DEVICE SIZE/OFF NODE NAME
bash     7268 fred    cwd VDIR 85,204      512    2 /mnt/scratchdisk/edam
dcm     15375 george  txt VREG 85,204   292352  202 /mnt/scratchdisk/bin/dcm
dcm     15375 george  cwd VDIR 85,204      512    5 /mnt/scratchdisk/bin/dcm

결과는 fred 가 배시 쉘을 가지고 있고 우리의 마운트 포인트 위에서 작업하고 있음을 보여 줍니다. 그리고 george 가 동일한 파일 시스템상의 다른 디렉토리에서 dcm 의 복사를 시작하였습니다.

특정 포트에 어떠한 프로세스가 리스닝하고 있고 누가 이 포트를 사용하고 있는지 보기:
포트가 이미 사용되고 있습니다(port already in use) 오류 때문에 데몬이 시작되지 않을때 관리자는 종종 좌절하게 됩니다. lsof 는 어떤 프로세스가 우리가 사용하고자 하는 포트를 사용하고 있는지 추적하기 위해 사용될 수 있습니다.

 
gouda# lsof -i :7507
COMMAND  PID   USER FD  TYPE  DEVICE  SIZE NODE NAME
inetd    668   root 34u IPv4 0x303f0   0t0  TCP *: 7507 (LISTEN)
answer 19757 nobody  0u IPv4 0x58028 0t132  TCP gouda:7507->edam:46111 (ESTABLISHED)
answer 19757 nobody  1u IPv4 0x58028 0t132  TCP gouda:7507->edam:46111 (ESTABLISHED)
answer 19757 nobody  2u IPv4 0x58028 0t132  TCP gouda:7507->edam:46111 (ESTABLISHED)

위의 결과로 볼때 inetd 가 answer 라는 서비스를 그 포트에서 실행하고 있고 edam 에서 실행되는 어떤 것이 접근하고 있음을 알 수 있습니다.edam 에서 lsof -i :46111 를 수행하여 어떠한 프로세스 인지를 확인해 봅니다.

해당되는 디렉토리 항목이 없는 열린 파일을 참조하는 프로세스 찾아내기:
만약 어떤 유저가 실행중인 프로세스가 참조하는 파일을 지웠다면, 파일 시스템은 실제로 마지막 링크가 닫힐때 까지 이 파일을 삭제하지 않습니다. 이러한 경우 실행중인 프로세스만이 남게 됩니다. 만약 이 프로세스를 찾을 수 있다면 우리는 해당 프로세스를 닫거나(파일이 삭제되길 원할때) 혹은 파일을 다시 살려야 할때 /proc 파일 시스템(솔라리스 8 이상) 을 통해서 파일의 내용을 저장할 수 있습니다.

 
gouda # df -k /opt/myapp/data
Filesystem            kbytes    used   avail capacity  Mounted on
/dev/md/dsk/d100     4129290 1458133 2629865    36%    /opt/myapp
 
gouda # lsof /opt/myapp | grep '/dev/md/dsk/d100'
less      15043 fred    4r  VREG  102,0       144 2050050 /opt/myapp (/dev/md/dsk/d100)

위의 결과는 파일이 less (프로세스 ID 15043) 에 의해 열려져 있음을 알려 줍니다. 만약 파일을 삭제하는 것이 목표라면 less 프로세스를 종료 시킴으로써 원하는 작업을 수행할 수 있습니다. 만약 파일의 내용을 다시 살리는게 목표라면, 복사를 통해서 가능합니다. 4번째 컬럼은 파일 디스크립터 4번에 읽기 전용 핸들을 보여 줍니다. 이것은 /proc/15043/fd/4 를 읽음으로써 파일의 내용을 다시 살릴 수 있음을 의미 합니다.


이 글의 영문 원본은
wikis.sun.com Using "lsof" in the Real World
에서 보실 수 있습니다.

2010/02/18 13:21 2010/02/18 13:21








마음튼튼 이 작성.

당신의 의견을 작성해 주세요.

[로그인][오픈아이디란?]
오픈아이디로만 댓글을 남길 수 있습니다