2009-08-31 6 views
49

최근에 나는 파일 시스템을 열었고 일부를 올바르게 닫지 않은 파일 시스템 설명자가 "유출 된"Linux 프로세스가있었습니다.리눅스에서 주어진 프로세스에 대한 열린 FD 한계를 확인하십시오.

내가 이것을 모니터링했다면, 나는 그 프로세스가 한계에 도달했다는 것을 미리 말할 수 있었다.

Ubuntu Linux 시스템에서 주어진 프로세스의 FD 사용 비율을 확인하는 멋진 Bash \ Python 방법이 있습니까?

편집 :

내가 지금 파일 기술자가 얼마나 많은 확인하는 방법을 알고 나는 단지 프로세스에 허용되는 파일 디스크립터의 수만 알아야합니다.. 일부 시스템 (예 : Amazon EC2)에는 /proc/pid/limits 파일이 없습니다.

감사합니다,

우디

+0

/proc/pid/limits가없는 Amazon EC2 Linux OS는 무엇입니까? RHEL 5에서 사용할 수 있습니다. 다른 OS에 대한 솔루션을 원한다면 어떤 것을 말해주십시오. – mark4o

+0

나는 우분투 EC2 서버를 가지고 있지만, 나는 다양한 리눅스 배포판에 적용 할 수있는 좀 더 일반적인 솔루션에 관심이있다. –

답변

94

/proc/<pid>/fd/의 항목 수를 계산하십시오. 공정에 적용되는 경도 및 연질 한계치는 /proc/<pid>/limits입니다.

+0

필자는이 방법이 폴링보다 더 우아 할 수 있다고 생각합니다. –

+0

예, 웹 서버와 같은 일부 프로세스는 ulimit을 사용하여 더 큰 할당량을 요구하고 있으며 FD 사용을 모니터링하려고합니다. –

+3

'ulimit -Hn'으로 볼 수있는 hardlimit 위의 할당량을 늘리는 프로세스는 허용되지 않습니다. proc의 – caf

2

주기적으로 주어진 PID에 lsof -p {PID} 전화 스크립트를 작성하려고 할 수 있습니다.

+0

lsof는 관련없는 항목 (예 : 메모리의 공유 라이브러리)을 많이 제공합니다. –

+1

fds가 공유 메모리 라이브러리 또는 '일반적인'응용 프로그램 특정 파일에 연결되어 있는지 여부는 중요하지 않습니다. 이러한 fds는 여전히 공유를 사용합니다. –

+0

아니요, 파일 설명자가 열려 있지 않으며 파일 설명자 한도에 포함되지 않습니다. – mark4o

2

bash/python 메소드를 요청했습니다. ulimit은 가장 좋은 bash 접근 방식 (손으로 /proc/$pid/fd 등을 통해 munging의 부족)이 될 것입니다. 파이썬의 경우 리소스 모듈을 사용할 수 있습니다.

$ python test.py 

(1024, 65536) 

resource.getrlimit

import resource 

print(resource.getrlimit(resource.RLIMIT_NOFILE)) 

는 C 프로그램의 getrlimit 호에 대응한다. 결과는 요청 된 자원의 현재 값과 최대 값을 나타냅니다. 위의 예에서 현재 (소프트) 한계는 1024입니다.이 값은 요즘 Linux 시스템의 일반적인 기본값입니다.

+0

resource.RLIMIT_NOFILE : 현재 프로세스의 열린 파일 디스크립터의 최대 수로서, 나 자신이 아닌 다른 프로세스의 결과를 얻고 싶습니다. –

31

리소스 제한을 얻기 위해 Linux 커널에서 제공하는 유일한 인터페이스는 getrlimit()/proc/pid/limits입니다. getrlimit()은 호출 프로세스의 리소스 제한 만 가져올 수 있습니다. /proc/pid/limits을 사용하면 동일한 사용자 ID로 모든 프로세스의 리소스 제한을 가져올 수 있으며 RHEL 5.2, RHEL 4.7, Ubuntu 9.04 및 2.6.24 이상의 커널이있는 모든 배포에서 사용할 수 있습니다.

이전 Linux 시스템을 지원해야하는 경우에는 getrlimit()으로 전화를 걸어야합니다. 물론 그렇게하는 가장 쉬운 방법은 프로그램이나 프로그램이 사용하는 라이브러리를 수정하는 것입니다. 프로그램을 실행중인 경우 LD_PRELOAD을 사용하여 코드를 프로그램에로드 할 수 있습니다. 가능하지 않은 경우 gdb를 사용하여 프로세스에 연결하고 프로세스 내에서 호출을 실행할 수 있습니다. ptrace()을 사용하여 동일한 작업을 직접 수행하여 메모리에 호출을 삽입 할 수도 있습니다.하지만이 작업은 매우 복잡하고 권장되지 않습니다.

적절한 권한을 가지고 다른 방법으로 커널 메모리를 살펴보고 커널 모듈을로드하거나 커널을 수정해야합니다. 그러나 이러한 질문은 잘못된 것이라고 가정합니다.

1

상위 20 개의 파일 핸들을 사용하여 프로세스를 참조한다 :

for x in `ps -eF| awk '{ print $2 }'`;do echo `ls /proc/$x/fd 2> /dev/null | wc -l` $x `cat /proc/$x/cmdline 2> /dev/null`;done | sort -n -r | head -n 20 

출력 형식 파일 핸들 수이고, PID, 프로세스 cmndline

출력 예

701 1216 /sbin/rsyslogd-n-c5 
169 11835 postgres: spaceuser spaceschema [local] idle 
164 13621 postgres: spaceuser spaceschema [local] idle 
161 13622 postgres: spaceuser spaceschema [local] idle 
161 13618 postgres: spaceuser spaceschema [local] idle 
0

에서 CentOS 6 이하 (GCC 3을 사용하는 모든 것)에서는 커널 한계를 조정해도 문제가 해결되지 않을 수 있습니다. 이는 GCC에서 사용하는 컴파일 타임에 FD_SETSIZE 값이 설정 되었기 때문입니다. 이를 위해서는 값을 높이고 프로세스를 다시 컴파일해야합니다.

또한 해당 라이브러리를 사용하는 경우 known issues in libpthread으로 인해 파일 설명자를 누설하고 있음을 알 수 있습니다. 이 호출은 GCC 4/CentOS7/RHEL 7에서 GCC로 통합되었으며 이것은 스레딩 문제를 수정 한 것으로 보입니다.

관련 문제