MNT에 진입하기 위해 Go에서 'setns' 호출을 시도할 때 네임스페이스가 있는 경우 호출은 지속적으로 EINVAL을 반환합니다. 이 문제는 동일한 기능이 올바르게 작동하는 C 구현에도 불구하고 관찰됩니다.
이 문제는 Go가 다중 스레드 언어인 반면 'setns'는 다중 스레드 언어라는 사실에서 발생합니다. 단일 스레드 컨텍스트에서 호출됩니다. 다중 스레드 환경에서 호출할 때 'setns'는 현재 스레드를 대상 네임스페이스와 제대로 연결하지 못합니다.
이 문제에 대한 해결책은 다음을 활용하는 것입니다. "CGO 생성자 트릭." 이 기술을 사용하면 Go 런타임이 초기화되기 전에 실행될 C 함수를 지정할 수 있습니다. 이 접근 방식을 사용하면 C 함수는 Go 스레드가 생성되기 전에 'setns'를 호출할 수 있으므로 호출이 단일 스레드 컨텍스트에서 이루어지도록 할 수 있습니다.
<code class="go">/* #include <sched.h> #include <stdio.h> #include <fcntl.h> __attribute__((constructor)) void enter_namespace(void) { setns(open("/proc/<PID>/ns/mnt", O_RDONLY, 0644), 0); } */ import "C" ... rest of file is unchanged ... </code>
자리 표시자
이 접근 방식에는 몇 가지 제한 사항이 있습니다.
'setns(2)' 패치는 다중 스레드 환경에서 단일 스레드 실행에 대한 요구 사항을 확인합니다. 기능이 있는 프로세스는 자체 사용자 네임스페이스에 CAP_SYS_CHROOT 및 CAP_SYS_ADMIN을 보유하고 대상 마운트 네임스페이스에 CAP_SYS_ADMIN도 보유해야 합니다.
위 내용은 Go 다중 스레드 환경에서 EINVAL과 함께 \'setns\'가 실패하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!