Calling setns from Go Returns EINVAL for mnt Namespace
Problem:
The Go code fails to enter the mnt namespace with the setns call, resulting in an EINVAL error. Despite identical calls in C code, the Go implementation produces the consistent error.
Investigation:
Solution:
In Go, setns must be executed in a single-threaded context before the Go runtime threads start. This is because setns acts on the calling thread, joining it to the namespace.
Alternative Solution Using CGO Constructor Trick:
Add the __attribute__((constructor)) macro to a C function to have it execute before Go initialization. This allows for entering a namespace before Go threads start, resolving the issue.
Update:
A Linux kernel mailing list conversation confirms the restriction that multi-threaded processes cannot be reassociated with a new mount namespace. This requires CAP_SYS_CHROOT and CAP_SYS_ADMIN capabilities in the caller's namespace and CAP_SYS_ADMIN in the target namespace.
The above is the detailed content of Why Does Calling setns from Go Return EINVAL for mnt Namespaces?. For more information, please follow other related articles on the PHP Chinese website!