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 <bradfitz@golang.org>
diff --git a/unix/syscall_linux.go b/unix/syscall_linux.go
index 9f6727c..3df5f9c 100644
--- a/unix/syscall_linux.go
+++ b/unix/syscall_linux.go
@@ -895,6 +895,7 @@
 //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 af464ca..106cd59 100644
--- a/unix/zsyscall_linux_386.go
+++ b/unix/zsyscall_linux_386.go
@@ -922,6 +922,16 @@
 
 // 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 350aaaa..c1bae65 100644
--- a/unix/zsyscall_linux_amd64.go
+++ b/unix/zsyscall_linux_amd64.go
@@ -922,6 +922,16 @@
 
 // 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 5782e49..3383f97 100644
--- a/unix/zsyscall_linux_arm.go
+++ b/unix/zsyscall_linux_arm.go
@@ -922,6 +922,16 @@
 
 // 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 1ee44a2..8c5cd13 100644
--- a/unix/zsyscall_linux_arm64.go
+++ b/unix/zsyscall_linux_arm64.go
@@ -922,6 +922,16 @@
 
 // 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 8488755..7eac55b 100644
--- a/unix/zsyscall_linux_mips64.go
+++ b/unix/zsyscall_linux_mips64.go
@@ -922,6 +922,16 @@
 
 // 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 d6535ac..e8b61a6 100644
--- a/unix/zsyscall_linux_mips64le.go
+++ b/unix/zsyscall_linux_mips64le.go
@@ -922,6 +922,16 @@
 
 // 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 5758068..f8eaae9 100644
--- a/unix/zsyscall_linux_ppc64.go
+++ b/unix/zsyscall_linux_ppc64.go
@@ -922,6 +922,16 @@
 
 // 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 fbe422b..22d444f 100644
--- a/unix/zsyscall_linux_ppc64le.go
+++ b/unix/zsyscall_linux_ppc64le.go
@@ -922,6 +922,16 @@
 
 // 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 {