From 54535356f1d989a6072b0898d9ddc4dd7009dcd3 Mon Sep 17 00:00:00 2001 From: Benoit Sigoure Date: Mon, 29 Feb 2016 00:37:13 -0800 Subject: [PATCH] x/sys/unix: Add support for the setns system call. This system call is used to reassociate the current thread with a Linux namespace (e.g. a network namespace or a mount namespace). This system call is key to interacting with the primitives enabling Linux containers. The users of this system call will most likely want to wrap their calls with a pair of LockOSThread / UnlockOSThread calls. Here is an example that is a reasonably close approximation of the `ns_exec' program given as an example in `man 2 setns': package main import ( "log" "os" "os/exec" "runtime" "golang.org/x/sys/unix" ) func main() { if len(os.Args) < 3 { log.Fatalf("%s /proc/PID/ns/FILE cmd args...", os.Args[0]) } fd, err := unix.Open(os.Args[1], unix.O_RDONLY, 0) if err != nil { log.Fatalf("open: %s", err) } runtime.LockOSThread() defer runtime.UnlockOSThread() if err = unix.Setns(fd, 0); err != nil { log.Fatalf("setns: %s", err) } cmd := exec.Command(os.Args[2], os.Args[3:]...) cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr err = cmd.Run() if err != nil { log.Fatalf("exec: %s", err) } } Fixes golang/go#5968. Change-Id: I78dc54667cfaef4f9e99a08d48f6e423686f1b22 Reviewed-on: https://go-review.googlesource.com/20054 Reviewed-by: Brad Fitzpatrick --- unix/syscall_linux.go | 1 + unix/zsyscall_linux_386.go | 10 ++++++++++ unix/zsyscall_linux_amd64.go | 10 ++++++++++ unix/zsyscall_linux_arm.go | 10 ++++++++++ unix/zsyscall_linux_arm64.go | 10 ++++++++++ unix/zsyscall_linux_mips64.go | 10 ++++++++++ unix/zsyscall_linux_mips64le.go | 10 ++++++++++ unix/zsyscall_linux_ppc64.go | 10 ++++++++++ unix/zsyscall_linux_ppc64le.go | 10 ++++++++++ 9 files changed, 81 insertions(+) diff --git a/unix/syscall_linux.go b/unix/syscall_linux.go index 9f6727c5..3df5f9cb 100644 --- a/unix/syscall_linux.go +++ b/unix/syscall_linux.go @@ -895,6 +895,7 @@ func Getpgrp() (pid int) { //sysnb Setpgid(pid int, pgid int) (err error) //sysnb Setsid() (pid int, err error) //sysnb Settimeofday(tv *Timeval) (err error) +//sys Setns(fd int, nstype int) (err error) // issue 1435. // On linux Setuid and Setgid only affects the current thread, not the process. diff --git a/unix/zsyscall_linux_386.go b/unix/zsyscall_linux_386.go index af464ca7..106cd592 100644 --- a/unix/zsyscall_linux_386.go +++ b/unix/zsyscall_linux_386.go @@ -922,6 +922,16 @@ func Settimeofday(tv *Timeval) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Setns(fd int, nstype int) (err error) { + _, _, e1 := Syscall(SYS_SETNS, uintptr(fd), uintptr(nstype), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Setpriority(which int, who int, prio int) (err error) { _, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio)) if e1 != 0 { diff --git a/unix/zsyscall_linux_amd64.go b/unix/zsyscall_linux_amd64.go index 350aaaa1..c1bae650 100644 --- a/unix/zsyscall_linux_amd64.go +++ b/unix/zsyscall_linux_amd64.go @@ -922,6 +922,16 @@ func Settimeofday(tv *Timeval) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Setns(fd int, nstype int) (err error) { + _, _, e1 := Syscall(SYS_SETNS, uintptr(fd), uintptr(nstype), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Setpriority(which int, who int, prio int) (err error) { _, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio)) if e1 != 0 { diff --git a/unix/zsyscall_linux_arm.go b/unix/zsyscall_linux_arm.go index 5782e496..3383f970 100644 --- a/unix/zsyscall_linux_arm.go +++ b/unix/zsyscall_linux_arm.go @@ -922,6 +922,16 @@ func Settimeofday(tv *Timeval) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Setns(fd int, nstype int) (err error) { + _, _, e1 := Syscall(SYS_SETNS, uintptr(fd), uintptr(nstype), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Setpriority(which int, who int, prio int) (err error) { _, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio)) if e1 != 0 { diff --git a/unix/zsyscall_linux_arm64.go b/unix/zsyscall_linux_arm64.go index 1ee44a2f..8c5cd137 100644 --- a/unix/zsyscall_linux_arm64.go +++ b/unix/zsyscall_linux_arm64.go @@ -922,6 +922,16 @@ func Settimeofday(tv *Timeval) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Setns(fd int, nstype int) (err error) { + _, _, e1 := Syscall(SYS_SETNS, uintptr(fd), uintptr(nstype), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Setpriority(which int, who int, prio int) (err error) { _, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio)) if e1 != 0 { diff --git a/unix/zsyscall_linux_mips64.go b/unix/zsyscall_linux_mips64.go index 8488755e..7eac55b5 100644 --- a/unix/zsyscall_linux_mips64.go +++ b/unix/zsyscall_linux_mips64.go @@ -922,6 +922,16 @@ func Settimeofday(tv *Timeval) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Setns(fd int, nstype int) (err error) { + _, _, e1 := Syscall(SYS_SETNS, uintptr(fd), uintptr(nstype), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Setpriority(which int, who int, prio int) (err error) { _, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio)) if e1 != 0 { diff --git a/unix/zsyscall_linux_mips64le.go b/unix/zsyscall_linux_mips64le.go index d6535ac6..e8b61a6e 100644 --- a/unix/zsyscall_linux_mips64le.go +++ b/unix/zsyscall_linux_mips64le.go @@ -922,6 +922,16 @@ func Settimeofday(tv *Timeval) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Setns(fd int, nstype int) (err error) { + _, _, e1 := Syscall(SYS_SETNS, uintptr(fd), uintptr(nstype), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Setpriority(which int, who int, prio int) (err error) { _, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio)) if e1 != 0 { diff --git a/unix/zsyscall_linux_ppc64.go b/unix/zsyscall_linux_ppc64.go index 57580683..f8eaae9a 100644 --- a/unix/zsyscall_linux_ppc64.go +++ b/unix/zsyscall_linux_ppc64.go @@ -922,6 +922,16 @@ func Settimeofday(tv *Timeval) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Setns(fd int, nstype int) (err error) { + _, _, e1 := Syscall(SYS_SETNS, uintptr(fd), uintptr(nstype), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Setpriority(which int, who int, prio int) (err error) { _, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio)) if e1 != 0 { diff --git a/unix/zsyscall_linux_ppc64le.go b/unix/zsyscall_linux_ppc64le.go index fbe422b9..22d444fe 100644 --- a/unix/zsyscall_linux_ppc64le.go +++ b/unix/zsyscall_linux_ppc64le.go @@ -922,6 +922,16 @@ func Settimeofday(tv *Timeval) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Setns(fd int, nstype int) (err error) { + _, _, e1 := Syscall(SYS_SETNS, uintptr(fd), uintptr(nstype), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Setpriority(which int, who int, prio int) (err error) { _, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio)) if e1 != 0 {