문제:
Go에서 setns 호출은 EINVAL(잘못된 인수)을 반환합니다. 컨테이너에 대한 마운트 네임스페이스를 입력하려고 할 때.
설명:
setns를 사용하여 네임스페이스를 입력하려면 먼저 단일 스레드 컨텍스트에서 호출을 수행해야 합니다. Go 런타임 스레드가 시작됩니다.
해결책:
이 문제에 대한 두 가지 접근 방식이 있습니다.
1. 생성자 트릭 사용:
<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"</code>
2. syscall.RawSyscall 사용:
<code class="go">package main import ( "fmt" "os" "path/filepath" "syscall" "runtime" ) func main() { if syscall.Geteuid() != 0 { fmt.Println("abort: you want to run this as root") os.Exit(1) } if len(os.Args) != 2 { fmt.Println("abort: you must provide a PID as the sole argument") os.Exit(2) } // Lock the main thread to the OS thread runtime.LockOSThread() namespaces := []string{"ipc", "uts", "net", "pid", "mnt"} for i := range namespaces { fd, _ := syscall.Open(filepath.Join("/proc", os.Args[1], "ns", namespaces[i]), syscall.O_RDONLY, 0644) err, _, msg := syscall.RawSyscall(308, uintptr(fd), 0, 0) // 308 == setns if err != 0 { fmt.Println("setns on", namespaces[i], "namespace failed:", msg) } else { fmt.Println("setns on", namespaces[i], "namespace succeeded") } } }</code>
참고:
위 내용은 Go에서 마운트 네임스페이스를 입력할 때 발생하는 \'EINVAL\' 오류를 어떻게 해결하나요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!