package ns
import (
"errors"
"os"
"path"
"strconv"
"syscall"
)
type Namespace struct {
Path string
Type uintptr
}
const (
CLONE_NEWNS = syscall . CLONE_NEWNS
CLONE_NEWUTS = syscall . CLONE_NEWUTS
CLONE_NEWIPC = syscall . CLONE_NEWIPC
CLONE_NEWNET = syscall . CLONE_NEWNET
CLONE_NEWUSER = syscall . CLONE_NEWUSER
CLONE_NEWPID = syscall . CLONE_NEWPID
)
var (
Types [ ] Namespace
)
func init ( ) {
Types = [ ] Namespace {
Namespace { Path : "ns/user" , Type : syscall . CLONE_NEWUSER } ,
Namespace { Path : "ns/ipc" , Type : syscall . CLONE_NEWIPC } ,
Namespace { Path : "ns/uts" , Type : syscall . CLONE_NEWUTS } ,
Namespace { Path : "ns/net" , Type : syscall . CLONE_NEWNET } ,
Namespace { Path : "ns/pid" , Type : syscall . CLONE_NEWPID } ,
Namespace { Path : "ns/mnt" , Type : syscall . CLONE_NEWNS } ,
}
}
func Set ( fd , nsType uintptr ) error {
_ , _ , err := syscall . Syscall ( SYS_SETNS , uintptr ( fd ) , uintptr ( nsType ) , 0 )
if err != 0 {
return errors . New ( "Unable to set namespace" )
}
return nil
}
func GetPath ( pid int , nsType uintptr ) ( string , error ) {
var nsPath string
for _ , n := range Types {
if n . Type == nsType {
nsPath = path . Join ( "/" , "proc" , strconv . Itoa ( pid ) , n . Path )
break
}
}
if nsPath == "" {
return "" , errors . New ( "Unable to find namespace type" )
}
return nsPath , nil
}
func OpenProcess ( pid int , nsType uintptr ) ( uintptr , error ) {
nsPath , err := GetPath ( pid , nsType )
if err != nil {
return 0 , err
}
return Open ( nsPath )
}
func Open ( nsPath string ) ( uintptr , error ) {
fd , err := os . Open ( nsPath )
if err != nil {
return 0 , err
}
return fd . Fd ( ) , nil
}
func Close ( fd uintptr ) error {
return syscall . Close ( int ( fd ) )
}