Go에서 setns를 호출하면 mnt 네임스페이스에 대해 EINVAL이 반환됩니다.
문제 설명
Go 코드에서 , syscall.RawSyscall을 사용하여 mnt 네임스페이스 입력을 시도합니다. setns 시스템 호출을 호출하는 함수는 EINVAL 오류를 반환합니다. 이 문제는 올바른 설정과 네임스페이스에 성공적으로 진입한 작동하는 C 구현에도 불구하고 지속됩니다.
원인 및 해결 방법
문제의 근본 원인은 다중에 있습니다. Go의 스레드 특성. setns 시스템 호출이 성공하려면 단일 스레드 컨텍스트에서 실행되어야 합니다. Go 애플리케이션은 기본적으로 멀티 스레드이므로 Go 런타임 스레드가 시작되기 전에 setns 호출이 이루어져야 합니다.
이 문제를 해결하려면 "cgo 생성자 트릭"을 사용할 수 있습니다. 이 기술을 사용하면 Go 런타임이 시작되기 전에 C 코드를 실행할 수 있습니다. C 코드에서 __attribute__((생성자)) 매크로를 사용하면 Go 초기화 전에 단일 스레드 C 컨텍스트에서 실행되도록 함수를 장식할 수 있습니다.
수정된 Go 코드
다음 수정된 Go 코드는 생성자 트릭을 사용하여 문제를 해결합니다. 문제:
<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>
이제 Go 애플리케이션은 cgo 생성자 트릭을 활용하여 setns 시스템 호출을 사용하여 mnt 네임스페이스를 성공적으로 입력할 수 있습니다.
위 내용은 Go에서 'setns'를 호출하면 Mnt 네임스페이스에 대해 'EINVAL'이 반환되는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!