'semop lock failed'에 해당되는 글 1건

  1. 2010.04.09 [ semop lock failed error ] : How to clean unused semaphore
병렬 컴퓨터에서 작업을 하다 보면, 별다른 이유없이 프로그램이 실행되지 않으며 아래와 같은 에러 메시지를 출력할 때가 있다. 

p4_error: OOPS: semop lock failed: -1

대개의 경우, 이는 더 이상의 가용 세마포어 (semaphore, 깃발 신호)가 남아 있지 않아서이다. 이에 대한 해결책을 제시하기에 앞서, 우선 세마포어가 무엇인지부터 간략하게 알아보자.  

세마포어 (semaphore) 란?

복수의 프로세스 (process) 들이 하나의 또는 제한된 공동 자원 (common resources, or shared resources)에 접속을 할 때, 동시 접속을 방지하는 것에 관여하는 메모리 변수를 지칭한다. 메모리 변수라는 점에서 일반 프로그램 변수와 비슷하나, 차이점은 프로그램 변수는 그 프로그램 안에서만 다루어지는데 비하여 semaphore 데이타는 다른 프로세스들에 의해서도 사용된다는 점이다. (출처: The Linux Tutorial

[binary semaphore 의 예]
예를 들어, 하나의 데이타 파일에 접속할 수 있는 프로세스들이 여러 개 있는 상황을 가정하자. 한 프로세스가 파일을 편집하고 있는 상황에서 다른 프로세스의 접속을 허용하면, 데이터 파일이 뒤죽박죽되기 마련이다. 이를 막기 위해서, semaphore 의 값이 on (또는 참값) 이면 접근을 허용하고 그 반대의 경우는 불허하게 정한다. 처음으로 접근하는 프로세스가 semaphore 의 값을 off (또는 거짓값) 으로 바꾸고, 파일 작업이 끝나면 semaphore 의 값을 원래대로 돌린다. 다음에 오는 프로세스들은 이 값이 거짓이면 참이 될 때가지 기다리게 된다. 비유를 하자면 공용 화장실이 하나 밖에 없는데, 사람들이 줄서서 기다리는 상황과 비슷하다. 한 명이 들어가서 문을 잠구면(locked), 나머지는 문이 열릴(unlocked) 때까지 기다리는 수 밖에 없다. (Toilet example

[counting semaphore 의 예]
다른 예로서 식당의 비유 (출처: wiki)를 드는데, 이 비유에서 식당의 자리는 공동 자원에, 찾아오는 손님은 프로세스에 해당한다. 자리의 수는 제한되어 있으므로 찾아오는 손님마다 다 앉힐 수는 없는 노릇이다. 이 경우 식당에 안내하는 사람이 있어서, 자리가 다 차면 손님을 기다리게 하고 자리가 나면 우선 순위의 손님부터 받아들이는 등의 조정을 할 것이다. 이 안내자의 역할이 semaphore 에 해당하는 것이다. 

세마포어에 대해 좀 더 자세히 알고 싶다면 Vikram Shukla 가 쓴 "Semaphores in Linux" 란 웹문서를 추천한다.

이 semaphore 를 포함한 IPC (Inter-Process Communication)들의 크기나 개수는 시스템이 정한 제한이 있다. (출처:Vinay's Tech Stuff

병렬 프로그램들이 비정상적으로 종료한 경우, semaphore가 여전히 그 프로그램에 의해서 사용되고 있는 것으로 남아서 제한된 가용 semaphore을 잠식한다. semop locked failed error 는 이러한 상황에서 연유한다. 그러므로, 사용되지 않는 semaphore array를 지우면 문제가 해결된다. 먼저, 아래의 명령어로 어떤 semaphore가 남아 있는지 알아 보자. 

[user@linuxcluster ~]$ ipcs -s

------ Semaphore Arrays --------
key        semid      owner      perms      nsems
0x00000000 10485790   user   777        1
0x00000000 10518559   user   777        1
0x00000000 10551328   user   777        1
0x00000000 10584097   user   777        1
0x00000000 10616866   user   777        1
0x00000000 10649635   user   777        1
0x00000000 10682404   user   777        1
0x00000000 10715173   user   777        1
0x00000000 10747942   user   777        1
0x00000000 10780711   user   777        1
0x00000000 10813480   user   777        1
0x00000000 10846249   user   777        1
0x00000000 10879018   user   777        1
0x00000000 10911787   user   777        1
0x00000000 10944556   user   777        1
0x00000000 10977325   user   777        1
0x00000000 11010094   user   777        1
0x00000000 11042863   user   777        1
0x00000000 11075632   user   777        1
0x00000000 11108401   user   777        1
0x00000000 11141170   user   777        1
0x00000000 11173939   user   777        1
0x00000000 11206708   user   777        1
0x00000000 11239477   user   777        1
0x00000000 11272246   user   777        1
0x00000000 11305015   user   777        1
0x00000000 11337784   user   777        1

이는 header node에 남아 있는 semaphore array만 보여준다. 모든 node 에 남아 있는 semaphore array를 볼려면 cluster-fork 라는 명령어를 이용한다. 이 때, node의 숫자에 따라 출력문이 길 수도 있으므로 파일( semaphore-list.txt) 로 받는게 더 좋다.

[user@linuxcluster ~]$ cluster-fork ipcs -s > semaphore-list.txt 

확인된 semaphore array 의 소유자 (owner)가 자신이면 ipcrm -s <SEMID> 란 명령어로 지울 수 있다. 예를 들어, 이런 식이다. 

[user@linuxcluster ~]$ ipcrm -s 11337784

위 명령어는 오직 지정된 ID의 semaphore array만 삭제한다. 모든 sem array를 지우고 싶다면, cleanipcs란 명령어를 이용한다. cleanipcs는 보통 관리자 권한에서만 실행되므로 일반 사용자는 실행할 수 없다. 관리자에게 부탁해서 자신의 로컬 디렉토리에 복사해서 사용한다. (본인은 ~/bin 디렉토리에 저장해서 사용한다.) 이 경우, 타인에게 권한이 있는 sem array는 삭제할 수 없다. 타인의 sem array는 해당 사용자에게 지워줄 것을 부탁해야 한다. 모든 node에서 자신의 sem array를 지울려면 다음과 같이 cluster-fork를 이용하여 cleanipcs를 실행한다. 

[user@linuxcluster ~]$ cluster-fork ~/bin/cleanipcs

만약에 cleanipcs를 구할 수 없으면, 차선책으로 다음의 쉘 스크립트 (shell script) 파일을 만들어서 실행한다. 

[user@linuxcluster ~]$ cat > rmsem.i686.sh 
#!/bin/sh
ipcs | cut -f 2 -d ' ' | xargs ipcrm shm
ipcs | cut -f 2 -d ' ' | xargs ipcrm sem
ipcs
ctrl + D
[user@linuxcluster ~]$ chmod 744 rmsem.i686.sh
[user@linuxcluster ~]$ cluster-fork rmsem.i686.sh

이제 좀비(zombie) semaphore array를 깨끗하게 지웠으니, 프로그램이 문제없이 실행될 것이다. 
Posted by 참향그늘
,