問題:
在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中文網其他相關文章!