github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/runc/libcontainer/configs/namespaces_unix.go (about) 1 // +build linux freebsd 2 3 package configs 4 5 import ( 6 "fmt" 7 "os" 8 "sync" 9 ) 10 11 const ( 12 NEWNET NamespaceType = "NEWNET" 13 NEWPID NamespaceType = "NEWPID" 14 NEWNS NamespaceType = "NEWNS" 15 NEWUTS NamespaceType = "NEWUTS" 16 NEWIPC NamespaceType = "NEWIPC" 17 NEWUSER NamespaceType = "NEWUSER" 18 ) 19 20 var ( 21 nsLock sync.Mutex 22 supportedNamespaces = make(map[NamespaceType]bool) 23 ) 24 25 // NsName converts the namespace type to its filename 26 func NsName(ns NamespaceType) string { 27 switch ns { 28 case NEWNET: 29 return "net" 30 case NEWNS: 31 return "mnt" 32 case NEWPID: 33 return "pid" 34 case NEWIPC: 35 return "ipc" 36 case NEWUSER: 37 return "user" 38 case NEWUTS: 39 return "uts" 40 } 41 return "" 42 } 43 44 // IsNamespaceSupported returns whether a namespace is available or 45 // not 46 func IsNamespaceSupported(ns NamespaceType) bool { 47 nsLock.Lock() 48 defer nsLock.Unlock() 49 supported, ok := supportedNamespaces[ns] 50 if ok { 51 return supported 52 } 53 nsFile := NsName(ns) 54 // if the namespace type is unknown, just return false 55 if nsFile == "" { 56 return false 57 } 58 _, err := os.Stat(fmt.Sprintf("/proc/self/ns/%s", nsFile)) 59 // a namespace is supported if it exists and we have permissions to read it 60 supported = err == nil 61 supportedNamespaces[ns] = supported 62 return supported 63 } 64 65 func NamespaceTypes() []NamespaceType { 66 return []NamespaceType{ 67 NEWNET, 68 NEWPID, 69 NEWNS, 70 NEWUTS, 71 NEWIPC, 72 NEWUSER, 73 } 74 } 75 76 // Namespace defines configuration for each namespace. It specifies an 77 // alternate path that is able to be joined via setns. 78 type Namespace struct { 79 Type NamespaceType `json:"type"` 80 Path string `json:"path"` 81 } 82 83 func (n *Namespace) GetPath(pid int) string { 84 if n.Path != "" { 85 return n.Path 86 } 87 return fmt.Sprintf("/proc/%d/ns/%s", pid, NsName(n.Type)) 88 } 89 90 func (n *Namespaces) Remove(t NamespaceType) bool { 91 i := n.index(t) 92 if i == -1 { 93 return false 94 } 95 *n = append((*n)[:i], (*n)[i+1:]...) 96 return true 97 } 98 99 func (n *Namespaces) Add(t NamespaceType, path string) { 100 i := n.index(t) 101 if i == -1 { 102 *n = append(*n, Namespace{Type: t, Path: path}) 103 return 104 } 105 (*n)[i].Path = path 106 } 107 108 func (n *Namespaces) index(t NamespaceType) int { 109 for i, ns := range *n { 110 if ns.Type == t { 111 return i 112 } 113 } 114 return -1 115 } 116 117 func (n *Namespaces) Contains(t NamespaceType) bool { 118 return n.index(t) != -1 119 } 120 121 func (n *Namespaces) PathOf(t NamespaceType) string { 122 i := n.index(t) 123 if i == -1 { 124 return "" 125 } 126 return (*n)[i].Path 127 }