이것은 SuperUser/ServerFault와는 반대로 StackOverflow와 syscd 및 sshd에 의해 수행되는 OS 상호 작용과 관련이 있기 때문에, 나는 을 사용하여 SSH를 사용하고있는 문제가 아닙니다.).왜 서버의 'sshd'에서 양쪽 끝이 열린 파이프의 출력을 기다리는 SSH 명령을 걸고 있습니까?
는 문맥 :
나는 SSH, 예를 통해 스크립트의 복잡한 일련의 호출 ssh [email protected] -- /my/command
. 원격 명령은 많은 복잡한 분기 및 실행을 수행하며 결과적으로 원격 호스트에서 백그라운드에서 실행되는 데몬 프로세스를 실행합니다. 가끔 (안정적인 재생 조건을 찾기 위해 서서히 노력하고 있습니다) ssh
명령은 절대로 클라이언트 셸에 제어권을 반환하지 않습니다. 이러한 상황에서 대상 호스트로 이동하여 자식이 무한정 걸어 다니지 않고 sshd: [email protected]
프로세스를 볼 수 있습니다.
이 문제의 해결은이 질문의 내용과 관련이 없습니다. 이 질문은 그 sshd
프로세스가 일 때 일을합니다.
SSH 구현은 OpenSSH이며 버전 버전은 5.3p1-112.el6_7입니다.
문제 :
내가 갇혀 그 중 하나 찾을 경우 sshd
들과 strace
가, 내가,이 두 개의 손잡이에 선택을하고있어 예를 볼 수 있습니다 select(12, [3 6], [], NULL, NULL
또는 이와 유사한 것. lsof
은 그 핸들 중 하나가 SSH 클라이언트에 다시 연결되는 TCP 소켓임을 알려줍니다. 다른 하나는 파이프이며, 다른 쪽 파이프는 동일한 sshd
프로세스에만 열려 있습니다. this SuperUser question에 대한 응답을 사용하여 해당 파이프를 ID로 검색하면 해당 파이프에 대한 참조를 포함하는 유일한 프로세스가 동일한 프로세스입니다. lsof
은 이것을 확인합니다. 파이프의 읽기 및 쓰기 끝이 모두 동일한 프로세스에서 열려 있습니다. (파이프 788,422,703 및 sshd
PID 22744에 대한) :
sshd 22744 user 6r FIFO 0,8 0t0 788422703 pipe
sshd 22744 user 7w FIFO 0,8 0t0 788422703 pipe
질문 : SSH 기다리고 무엇
? 파이프가 아무 것도 연결되어 있지 않고 하위 프로세스가없는 경우 예상 할 수있는 이벤트가 무엇인지 상상할 수 없습니다.
"루프 된"파이프 란 무엇입니까/무엇을 나타 냅니까? 내 유일한 이론은 STDIN이 SSH 클라이언트에 제공되지 않는다면 대상 호스트 sshd
은 더미 STDIN 파이프를 열어 일부 내부 자식 관리 코드가 더 균일 할 수 있다는 것입니다. 그러나 그것은 꽤 약해 보인다.
어떻게 이런 상황에 처하게 되나요? 나는 무엇을 시도했다
/추가 정보 :
- 처음에 나는이 데몬에 핸들 누수 생각했다. 자신을 배경으로하는 명령을 실행하여 대기 중이며 어린이가없는
sshd
프로세스를 만들 수 있습니다 (예 :ssh [email protected] -- 'sleep 60 &'
;sshd
은 스트림이 데몬 프로세스에 닫힐 때까지 대기합니다. 직계 아동의 퇴거 만이 아닙니다.문제가되는 스크립트는 결국 데몬이 시작될 때 (프로세스 트리 아래로) 결과로 시작하기 때문에 처음에는 데몬이 핸들을 잡고있을 가능성이있는 것처럼 보였습니다. 그러나, 예를 들어sleep 60 &
명령을 사용하면,sshd
프로세스가 데몬과 통신하고 개의 열린 파이프가 두 개가 아닌 개의 파이프로 구성되며 두 개 이상이sshd
에서 연결됩니다. 루프되지 않은 데몬 프로세스. 추적 할 수있는 방법이 없다면 (그리고 내가 모르는 경우) (예를 들어,dup
파일 핸들이close()
세마포어 대기 또는 파이핑으로 어떻게 작동하는지 알지 못한다. pipe-to-self 상황은 데몬 대기 상태를 나타냅니다. sshd
은 주기적으로 (strace
에서 SIGCHLD를 차단하는 것으로 표시되는)select
s에서 깨어나서 TCP 소켓/ssh 연결 자체에서 통신을 수신 한 다음 같은 FD들.- this race condition (커널이 파이프에서 데이터를 사용할 수있게 만들기 전에 SIGCHLD가 전달됨)의 영향을받을 수 있습니다. 그러나이 상태가 나타나는 속도와 대상 호스트에서 실행되는 프로세스가 Perl 스크립트 및 Perl runtime closes and flushes open file descriptors on shutdown이라는 사실을 감안할 때 거의 불가능합니다.
디버깅을 켜고 로그를보고 sshd를 다시 시작해 보셨습니까? – xxfelixxx
질문에 키워드는 * Open * SSH입니다. 블랙 박스가 내부적으로 수행하는 작업을 추측하는 대신 [코드 자체를 읽으십시오] (https://github.com/openssh/openssh-portable/blob/master/sshd.c#L1242). 그것은 꽤 잘 쓰여졌습니다. – msw
깊이있는 설명 주셔서 감사합니다 - 간결하게 내가 가진 문제를 요약합니다. 제 경우에는 ssh 명령이 [packer] (https://packer.io)를 사용하여 VirtualBox VM을 시작했습니다. Packer는 빌드가 실패한 경우 VM을 실행중인 상태로 두도록 구성되었습니다. 게시 한 경쟁 조건 링크를 읽은 후에 나는 주위가 멍청했고 VirtualBox가 패커의 STDOUT/STDERR 파이프 중 하나를 상속 받고 패커가 종료 된 후에도 계속 열어 둡니다. 이렇게하면 sshd가 파이프가 닫힐 때까지 기다리게됩니다. 버추얼 박스를 죽이면 ssh 연결이 제대로 종료됩니다. – Matt