2011-12-07 4 views
0

다음 작품을 발표 할 때 시작하는 데 실패FreeBSD의 감옥은 파이썬 스레드에서

root 15231 0.0 0.0 8296 2056 1 I+ 4:52PM 0:00.01 /bin/sh /usr/local/etc/rc.d/ezjail.sh start content 
root 15240 0.0 0.0 8296 2120 1 I+ 4:52PM 0:00.06 sh /etc/rc.d/jail onestart content 
root 15407 0.0 0.0 8296 2016 1 I+J 4:52PM 0:00.01 /bin/sh /etc/rc 
root 15467 0.0 0.0 8296 2060 1 I+J 4:52PM 0:00.00 /bin/sh /etc/rc 
root 15474 0.0 0.0 6920 1224 1 I+J 4:52PM 0:00.00 /usr/sbin/syslogd -ss 

감옥이 시작되지만 무료로 /etc/rc 보인다 잘하지만 제대로 시작되지 않습니다 syslogd를 시작한 후 ze하십시오.

어떻게 든 스레드에서 실행하면 jail rc가 실패합니다. jexec이 제대로 작동하려면 일부 환경 설정이 누락 된 것 같습니다 (어쩌면 pty?).

jexec 또는 ezjail-admin console과 함께 콘솔을 연결하려고해도 실패합니다 (실제 감옥 사본이 별도로 실행됩니다). 감옥의 /var/log에는 내용이 없으며 (syslogd를 시작할 때 빈 로그 파일이 생성되는 것을 제외하고) 호스트 로그 파일도 마찬가지입니다.

아무도 왜 스레드가 아닌 응용 프로그램에서 작업 명령을 실행하는지 알 수 있습니까?하지만 스레드에서 실행되자 마자 뭔가 잘못되었습니다.

TLDR : 파이썬 스레드에서 감옥을 시작하려고하면 syslogd가 시작된 후 rc가 중단됩니다. 동일한 명령이 스레드되지 않은 응용 프로그램에서 감옥을 성공적으로 시작합니다.

편집 : 포크가 작동합니다 ... 스레드와 관련이 있습니다.

ezjail-admin start의 경우 다음은 작동하지 않습니다. ezjail-admin create은 완벽하게 작동합니다.

class TestThread(threading.Thread): 
    def run(self): 
    command = 'ezjail-admin create -f content content 10.0.254.33' 
    os.system(command) 
    command = 'ezjail-admin start content' 
    os.system(command)  

tt = TestThread() 
tt.start() 

실제 코드는 초기 포크를 사용 https://github.com/masom/Puck/tree/master/client 현재 구현에서 볼 수 있지만, 스레드가 훨씬 깨끗하다.

+0

초기 포크는 내가 끝내 었습니다. 추악한 해킹하지만 작동합니다. 이것은 여전히 ​​나를 괴롭힌다. –

답변

-1

정말 popen을 사용하고 싶습니까? stdout 또는 stderr을 읽거나 stdin에 쓰기를 원하십니까? .wait()에서 보면 그 모양이 아닙니다. 그렇다면 왜 popen을 사용합니까?

저는 파이썬에 대해 구체적으로 알지 못합니다. 따라서 popprocess (3)와 관련하여 subprocess.Popen이 구현됩니다.

내부적으로 popen은/exec를 fork해야하므로 스레딩 문제가있을 수 있습니다. popen을 사용하고 있기 때문에 부모 프로세스에 파이프 중 하나를 사용하려고 시도하는 것이 차단되는 경우가 많습니다. 스레딩을 추가하면 Python에서 I/O를 처리하는 방법이 변경되어 문제가 발생할 수 있습니다.

이렇게 테스트하려면 동일한 명령을 시도 할 수 있지만 stdin, stdout 및 stderr은/dev/null로 리디렉션됩니다. 이 명령을 사용

sh -c 'ezjail-admin start test </dev/null> /dev/null 2> /dev/null' 

ezjail 문서가 표준 I/O 핸들 아무것도하지 여부에 대해 말할 수 있습니다. 그렇지 않다면, 기본 jail (2) 호출은 상속 된 핸들을 사용할 것이고, 코드를 제공하면 닫고 싶거나 유용한 곳으로 리디렉션하고 싶을 것입니다.

업데이트 : 명령은/dev/null로 방향이 재설정 된 표준 핸들 일 경우, 다음 문제는 표준 I/O 핸들이 아닌 스레드를 처리하는 방법과 관련이있다

. 당신은 그 손잡이가 어디로 가고 싶은지를 결정해야하고, 감옥을 시작할 때 올바르게 처리해야합니다. 감옥 어린이와 연결된 파이프를 읽고 쓰려고한다면 교착 상태를 피하기 위해 주석에서 언급 한 문서 페이지에 큰 빨간색 경고가 있음을 알아야합니다. 그것이 거의 확실하게 당신이보고있는 문제입니다.

ssh 및 서버 프로세스에 대해 이야기합니다. 당신이 정말로 무엇을 얻고 있는지 불분명합니다. 감옥을 만들고 감옥에서/etc/rc를 실행하고 있습니다. 이 프로세스는 부모로부터 표준 I/O 핸들을 상속 받아 시스템 환경을 설정합니다. 시스템 환경을 구성하는 프로세스도 핸들을 상속 받아 사용합니다. 시스템은 그들이 가리키는 위치에 따라 다르게 작동합니다. 감옥에서/etc/rc를 호출하는 다른 방법은 핸들을 다양하게합니다. "스레드"와 함께 작동하게하려면 핸들을 올바르게 설정하십시오. 명령이 완료 될 때까지

+0

내일 sh 시험을 해보겠습니다. os.system()도 쓰레드에서 같은 경우에 실패합니다. CherryPy 스레드를 시작하기 전에 popen/system 호출이 수행되면 모든 것이 완벽하게 작동합니다. 참고로 subprocess.Popen()은 응용 프로그램을 시작하기 위해 제안되는 방법입니다. http://docs.python.org/library/subprocess.html –

+0

OK, Popen이 popen (3) 이상인 것으로 확인되었습니다. Popen 인터페이스를 사용하면 쉘을 사용하는 대신 stdin, stdout 및 stderr을/dev/null로 설정할 수 있습니다. 나는 당신의 코드와 os.system 사이에 어떤 실질적인 차이점도 보이지 않는다. 그래서 나는 아무런 차이가 없다는 것에 놀라지 않는다. – janm

+0

'sh -c' 접근법이 작동합니다. 서버에 ssh하고 명령을 실행하는 경우와 동일합니다. 이제는 프로세스를 포크하고 유닉스 소켓을 사용하여 작업자와 스레드 된 파이썬 응용 프로그램간에 통신 할 생각입니다. –

-1

os.system을 기다리지 않습니다. 따라서 생성 및 시작은 병렬로 실행되기 때문에 경쟁 조건으로 인해 시작이 실패합니다. wait()를 호출하거나 잠그기 위해 호출 한 후 잠깐 기다리십시오. wait()를 사용하여 호출하기

ezjail-admin은 결과를 기다리지 않는 쉘 스크립트이기 때문에 대기가 작동하지 않습니다. .

내가 옳고 그름은 그 사이 일초 수면과 같은 명령을 실행 해주십시오 해요 여부를 증거를 얻으려면.

감옥 제작에는 pty가 필요하지 않습니다. (이 쿵푸 요즘 네트워크에서 찾기 어렵하지만) 사실 당신은

수면 투박하지만 통해 감옥을 실행 확인 ... 전혀 파일 시스템과 메모리를 정적으로 링크 된 과정에서 가상 감옥을 실행할 수 있습니다 jls는 방법입니다 (ezjail은 통일되어있을뿐만 아니라 거기에 등록합니다).

+0

질문의 시작 부분에'subrocess.Popen' +'wait()'로 실패한 예제가 있는데, 역시 작동하지 않았습니다. –

+0

ezjail-admin은 SH 스크립트이며 실제로 기다리지 않고 감옥에 전화를 걸고 실제로 작업을하기 전에 성공으로보고합니다. 내가 제안하는 것은 감옥을 운영하는 데 필요한 파일을 감시하는 것이다. 생성 된 경우 계속할 수 있습니다. 그렇지 않으면 그냥 ezjail을 사용하여 jail.h를 직접 사용하거나 jls, jail 및 다른 명령을 사용하여 jail을 설정하고 수동으로 처리하십시오 (요즘에는 어렵지 않습니다). – Andrew

관련 문제