반응형

출처 : http://blog.tanelpoder.com/2009/01/22/identifying-shared-memory-segment-users-using-lsof/

lsof를 사용하여 공유메모리 사용자를 식별하기

lsof(열린 파일의 목록을 보여주는 프로그램)은 지워진 파일의 해제 또는 공유메모리의 삭제를 방해하는 열려있는 파일 디스크립터의 문제를 해결하는데 매우 유용한 도구입니다.

이 예시는 리눅스에서 Oracle 사용자의 공유메모리가 해제되지 않고 아직 사용중이라고 표시되고 있는 상황입니다.

$ ipcs -ma

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0x00000000 393216     oracle    640        289406976  1          dest
0xbfb94e30 425985     oracle    640        289406976  18
0x3cf13430 557058     oracle    660        423624704  22

------ Semaphore Arrays --------
key        semid      owner      perms      nsems
0xe2260ff0 1409024    oracle    640        154
0x9df96b74 1671169    oracle    660        154

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages

진하게 표시된 줄은 인스턴스가 닫힌 후에 사라져야 하지만 그렇지 못했습니다. "nattch"(공유메모리에 접근한 프로세스들의 수)로부터 저는 공유메모리를 사용하는 몇개의 프로세스가 아직 있다는 것을 알았습니다. 그래서 이 조각은 해제되지 않았고 ipcrm 명령어조차 그것(누군가 파일들을 열었다면 정상 파일인것처럼)을 삭제할 수 없었습니다.

그래서 이 공유메모리를 사용하는 프로세스를 식별할 필요가 있었습니다. 만약 보통 존재하는 파일이었다면 어떤 프로세스가 그 파일을 열었는지 /sbin/fuser 명령을 사용했겠지만 이 명령은 디렉터리에서 현재 존재하는 파일에 대해서만 작동합니다.

하지만 지워진 파일, 소켓이나 공유 메모리를 위해서는 lsof 명령을 사용할 수 있습니다. (보통 리눅스에 기본으로 설치되어 있지만 Unix에서는 별도로 다운로드 받아 설치해야 합니다.)

ipcs -ma가 보여주듯이 사용중인 SHM ID는 393216이며 저는 SHM ID를 grep하여 모든 열여 있는 파일 디스크립터를 보여주도록 lsof를 다음처럼 실행하였습니다.

$ lsof | egrep "393216|COMMAND"
COMMAND     PID      USER   FD      TYPE     DEVICE       SIZE       NODE NAME
python    18811    oracle  DEL       REG        0,8                393216 /SYSVbfb94e30

NODE 열에 대응되는 ipcs의 출력된 SHM ID와 대응되는지 알 수 있습니다.
그래서 저는 아직 SHM 에 접근 중인 PID 18811을 kill 하였습니다.

$ kill 18811

$ ipcs -ma

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0xbfb94e30 425985     oracle    640        289406976  18
0x3cf13430 557058     oracle    660        423624704  25

------ Semaphore Arrays --------
key        semid      owner      perms      nsems
0xe2260ff0 1409024    oracle    640        154
0x9df96b74 1671169    oracle    660        154

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages

해당 공유메모리가 사라지고 해제되었습니다.

명령은 다른 작업을 하는데도 매우 유용합니다. 예를 들어, 네트워크 프로토콜, IP, port 등 열여 있는 소켓을 보여주기도 합니다. 예를 들어 OS level에서 어떤 클라이언트가 서버 프로세스와 통신하는 지 확인 할 수 있습니다.

$ lsof -i:1521
COMMAND   PID   USER   FD   TYPE DEVICE SIZE NODE NAME
tnslsnr  6212 oracle   11u  IPv4  49486       TCP *:1521 (LISTEN)
tnslsnr  6212 oracle   13u  IPv4 276708       TCP linux03:1521->linux03:37277 (ESTABLISHED)
tnslsnr  6212 oracle   14u  IPv4 264894       TCP linux03:1521->linux03:41122 (ESTABLISHED)
oracle  22687 oracle   20u  IPv4 264893       TCP linux03:41122->linux03:1521 (ESTABLISHED)
oracle  25250 oracle   15u  IPv4 276707       TCP linux03:37277->linux03:1521 (ESTABLISHED)
oracle  25530 oracle   15u  IPv4 279910       TCP linux03:1521->192.168.247.1:nimsh (ESTABLISHED)

불행히도 lsof는 클래식 유닉스에서 기본적으로 설치되지 않지만 일부에서는 시스템 관리자가 설치하기로 선택했습니다. 그러나 lsof는 /dev/kmem 또는 이와 유사한 것을 통해 커널 메모리 구조에 액세스해야 하므로 일반 사용자에게는 작동하지 않을 수 있습니다. lsof에 액세스할 수 없다면 lsof가 할 수 있는 몇 가지 트릭을 수행할 수 있는 다른 도구가 있을 수 있습니다. 예를 들어 Solaris에는 프로세스의 열린 파일을 표시할 수 있는 유용한 명령 pfiles가 있으며 (내 생각에는) Solaris 9 부터 네트워크 소켓의 TCP 연결 endpoint도 보고할 수 있습니다…

반응형
반응형

출처 : http://stackoverflow.com/questions/5658568/how-to-list-processes-attached-to-a-shared-memory-segment-in-linux

리눅스에 공유메모리에 접근한 프로세스의 목록을 아는 방법?

공유 메모리에 접근한 프로세스가 무엇인지 어떻게 알 수 있습니까?

awagner@tree:/home/awagner$ ipcs -m

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      
0x00000000 0          root       777        102400     1                       
0x00000000 32769      root       774        96         1          dest         
0x00000000 98306      awagner    600        393216     2          dest         
0x00000000 131075     awagner    600        393216     2          dest    

예시. 98305 공유메모리에 접근한 2개의 프로세스를 어떻게 알 수 있습니까?


5개의 답변 중 1개의 답변

표준 툴로는 이것을 알 수 없다고 생각합니다. 당신은 마지막으로 접근하거나 공유메모리와 분리된 프로세스의 ID를 ipcs -mp 를 사용하여 알 수 있지만 ipcs로 접근한 모든 프로세스를 아는 방법을 저는 모릅니다.

공유메모리에 접근한 두개의 프로세스가 현재도 공유메모리에 붙어있다고 가정하면 공유메모리를 생성한 PID cpid와 마지막에 접근한 PID lpid를 통하여 두개의 프로세스를 알 수는 있지만 그 이상으로 확장하여 알 수는 없기 때문에 유용함이 제한됩니다.

cat /proc/sysvipc/shm 방법은 비슷하게 제한적이지만 /proc 파일 시스템의 다른 부분으로 프로세스의 목록을 아는 방법이 있다고 믿습니다. 아래를 보시면,

모든 프로세스에 대응하는 procfs(파일시스템)에서 grep을 할 때, cpidlpid의 프로세스들을 포함하는 목록을 얻었습니다.

예를 들어, 다음 공유메모리를 ipcs -m 명령으로 얻었습니다.

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      
0x00000000 123456     pax        600        1024       2          dest

그리고 주어진 공유메모리 id (123456)을 통해 ipcs -mpcpid는 3956 이고 lpid는 9999 라는 것을 알아내었습니다.

그리고 명령어 grep 123456 /proc/*/maps 을 통해 다음을 알 수 있습니다.

/proc/3956/maps: blah blah blah 123456 /SYSV000000 (deleted)
/proc/9999/maps: blah blah blah 123456 /SYSV000000 (deleted)

그래서 이것이 공유메모리에 접근한 프로세스 목록을 얻는 방법입니다. dest 상태와 (deleted) 표시가 마지막 분리가 발생했을 때 삭제를 위한 표시를 생성자가 했기 때문에 이미 그 공유메모리가 파괴된 것이 아님을 저는 매우 확신합니다.

/proc/*/maps 파일들을 검사함으로서, 당신은 주어진 공유메모리에 현재 접근하고 있는 PID들을 발견할 수 있습니다.


출처 : http://www.linuxforums.org/forum/red-hat-fedora-linux/168472-unable-remove-shared-memory.html

안 지워지는 공유메모리 삭제하는 방법

저 같은 경우에는 위의 방법으로 접근한 프로세스의 목록을 얻은 다음 해당 프로세스를 kill하여 문제를 해결하였습니다.

다음 내용은 위의 출처에서 답변만 번역 하였습니다.

man 페이지는 ipcrm -m 는 삭제를 위해 표시만을 한다고 쓰여 있습니다. ipcs -p는 공유메모리에 접근한 프로세스 id를 제공합니다. 해제하고자 하는 공유메모리에 접근하고 있는 프로세스를 kill하면 그 공유메모리가 사라진 것을 확인하실 수 있습니다.

반응형

+ Recent posts