2009-08-23 2 views
3

권한 부여 서비스의 "AuthorizationExecuteWithPrivileges"호출을 통해 root/admin 권한으로 실행되는 수많은 셸 명령이 있습니다. 문제는 그 동안 (10 ~ 15 초 어쩌면 100 쉘 명령어) 프로그램이 디버거에서이 오류와 함께 응답을 중지 한 후 : 응용 프로그램이있는 동안 다음의 errno 35100 개 이상의 프로세스를 실행할 수 없습니다.

을 그리고 :

는 포크 없습니다 실행 중이므로 더 이상 응용 프로그램을 시작할 수 없습니다. 이 문제를 조사한 결과 분명히 시스템에서 사용할 수있는 스레드가 더 이상 없다는 것을 의미합니다. 그러나, 나는 활동 모니터를 사용하여 확인하고 내 애플 리케이션은 4-5 스레드를 사용하고 있습니다.

이 문제를 해결하려면 쉘 명령을 별도의 스레드 (메인 스레드가 아닌)로 분리해야한다고 생각합니다. 내가 전에 스레딩을 사용한 적이 있고, (I 찾을 수있는 포괄적 예)

감사

답변

7

Louis Gerbarg가 이미 지적했듯이 질문은 스레드와 관련이 없습니다. 제목과 태그를 적절히 편집했습니다.

권한 부여 서비스의 "AuthorizationExecuteWithPrivileges"호출을 통해 root/admin 권한으로 실행되는 많은 셸 명령이 있습니다.

하지 마십시오. 이 기능은 오직 root : admin 소유권과 setuid 모드 비트를 루트로 실행할 도구로 복원 할 수 있도록 존재합니다.

아이디어는 루트로 실행할 필요가없는 부분과 완전히 별개의 프로그램으로 루트로 실행해야하는 코드를 제외해야하므로 루트가 필요한 부분에 setuid 비트)와 뿌리가 필요없는 부분은 (setuid를 갖지 않음으로써) 그것없이 갈 수 있습니다.

코드 예는 Authorization Services Programming Guide입니다.

문제점은 잠시 (10 ~ 15 초 100 아마 쉘 명령) 후 프로그램이 디버거이 오류 응답하지 않는다이다 :

couldn't fork: errno 35 

예. 한 번에 두 개의 프로세스 만 실행할 수 있습니다. 이것은 OS 강제 제한입니다.

소프트 한도입니다. 인상 할 수는 있지만 하드 한도까지는 올릴 수 없습니다. limitlimit -h의 출력을보십시오 (zsh에서는 다른 쉘에 대해서는 알지 못합니다).

더 많은 프로세스를 실행하기 전에 프로세스가 완료 될 때까지 기다려야합니다.

그리고 나서 앱이 실행되는 동안 더 이상 애플리케이션을 실행할 수 없습니다.

당신이 이미 허용 한만큼 많은 프로세스를 실행하고 있기 때문에. 그 x-hundred 프로세스 제한은 프로세스별로가 아니라 사용자 별입니다.

이 문제를 조사한 결과 분명히 시스템에서 사용할 수있는 스레드가 더 이상 없다는 것을 의미합니다.

아니요.

errno 오류 코드는 많은 경우에 사용됩니다. EAGAIN (35, "resource temporarily unavailable")은 스레드를 시작하는 시스템 호출로 설정할 때 더 이상의 스레드를 의미 할 수는 없지만 다른 시스템 호출이나 함수에 의해 설정 될 때 스레드를 의미하지는 않습니다.

명시 적으로 인용 오류 메시지가 새로운 과정이 아닌 새로운 스레드을 시작하는 시스템 호출 인 fork가 설정 한 것을 말한다. 그 맥락에서 EAGAIN은 "이미 많은 프로세스를 실행할 수 있습니다"라는 의미입니다. the fork manpage을 참조하십시오.

그러나 Activity Monitor를 사용하여 확인한 결과 내 스레드는 4-5 스레드 만 사용합니다.

참조?

이 문제를 해결하려면 쉘 명령을 별도의 스레드 (메인 스레드가 아닌)로 분리해야한다고 생각합니다.

스레드 당 하나의 프로세스를 시작하면 훨씬 더 빨리 프로세스를 실행할 수 있습니다.

나는 ... 이전 스레딩 사용한 적이 당신이 아직하지 않은 것처럼 당신이 언급하고있는 기능은 프로세스가 아닌 스레드를 시작하기 때문에

그것은 소리.

+0

답변 주셔서 감사합니다 :) 나는 이러한 명령을 실행하는 새로운 CLI 도구 또는 스크립트를 작성한 다음 관리자 priveleges와 함께 도구를 실행하도록해야한다고 생각합니다. 그게 효과가 있니? – indragie

+0

루트로 * 모든 프로세스를 실행할 수 없도록 만드는 것이 좋은 해결책 일뿐입니다. 그것은 엄청난 보안 구멍이 될 것입니다. 하나의 작업마다 하나의 도구를 만들거나 도구가 시스템에 설치된 다른 도구를 실행하는 경우 도구는 화이트리스트에있는 선택 만 허용합니다. –

+0

또한 도구가 시스템에 설치된 도구를 실행하는 경우 PATH를 가능한 위치로만 제한하십시오. 하드 코딩 된 경로 (예 :/bin/ls)가 더 좋을 수 있습니다. 공격자가 PATH를 사용하여 가정 된 이름으로 자신이 선택한 코드를 실행하도록 허용하지 마십시오. –

3

이 스레드에 대한 아닙니다을 시작하지 않으려면 어디 확실 해요 (응용 프로그램에서 적어도 스레드). 이것은 시스템 자원에 관한 것입니다. fork 된 각 프로세스는 최소한 1 개의 커널 스레드 (어쩌면 그 이상), 일부 vnode 및 기타 많은 것을 사용합니다. 결국 시스템에서 더 많은 프로세스를 생성하도록 허용하지 않습니다.

첫 번째 제한은 관리 제한입니다. 시스템이 더 많은 것을 지원할 수는 있지만 성능이 떨어지거나 다른 문제가 발생할 수 있습니다. 일반적으로 sysctls와 같은 다양한 메카니즘을 통해 이러한 문제를 제기 할 수 있습니다. 일반적으로 그렇게하는 것은 특정 개조로 이익을 얻을 수있는 특정 (특수) 작업 부하가없는 한 나쁜 생각입니다.

가능성이 높아지면 문제가 해결되지 않을 수도 있습니다. 이러한 제한을 조정하면 실제로는 문제를 해결하기 위해 리소스를 시스템에 반환하지 않는 이유를 파악해야 할 수 있습니다. 위에서 설명한 내용을 토대로 포크 프로세스가 종료되지 않았다고 추측 할 수 있습니다.

+2

IIRC에서는 누군가가'wait (2) '를 호출하도록해야합니다. 'init' 프로세스는 결국 기다리게 될 것이지만, 각 자식 프로세스의 런타임이 매우 짧은 경우 리소스가 부족할 수 있습니다. –

+0

이것은 사실입니다. 일반적으로 프로세스가 어떻게 든 분리되지 않는 한 wait() 또는 witpid()를 호출해야합니다. –

+0

hmm이 상황에서 wait()를 사용하는 방법을 자세히 설명 할 수 있습니까? 감사합니다. – indragie