diff --git a/virtcontainers/pkg/nsenter/nsenter.go b/virtcontainers/pkg/nsenter/nsenter.go index 20824c13ef..8ae666408b 100644 --- a/virtcontainers/pkg/nsenter/nsenter.go +++ b/virtcontainers/pkg/nsenter/nsenter.go @@ -49,13 +49,7 @@ const ( // CloneFlagsTable is exported so that consumers of this package don't need // to define this same table again. -var CloneFlagsTable = map[NSType]int{ - NSTypeCGroup: unix.CLONE_NEWCGROUP, - NSTypeIPC: unix.CLONE_NEWIPC, - NSTypeNet: unix.CLONE_NEWNET, - NSTypePID: unix.CLONE_NEWPID, - NSTypeUTS: unix.CLONE_NEWUTS, -} +var CloneFlagsTable = make(map[NSType]int) // Namespace describes a namespace that will be entered. type Namespace struct { @@ -69,6 +63,22 @@ type nsPair struct { threadNS *os.File } +func init() { + var ns = map[NSType]int{ + NSTypeCGroup: unix.CLONE_NEWCGROUP, + NSTypeIPC: unix.CLONE_NEWIPC, + NSTypeNet: unix.CLONE_NEWNET, + NSTypePID: unix.CLONE_NEWPID, + NSTypeUTS: unix.CLONE_NEWUTS, + } + + for k, v := range ns { + if _, err := os.Stat(fmt.Sprint("/proc/self/ns/", string(k))); err == nil { + CloneFlagsTable[k] = v + } + } +} + func getNSPathFromPID(pid int, nsType NSType) string { return filepath.Join(procRootPath, strconv.Itoa(pid), nsDirPath, string(nsType)) } diff --git a/virtcontainers/pkg/nsenter/nsenter_test.go b/virtcontainers/pkg/nsenter/nsenter_test.go index 8d277520c6..b2d7f4520d 100644 --- a/virtcontainers/pkg/nsenter/nsenter_test.go +++ b/virtcontainers/pkg/nsenter/nsenter_test.go @@ -138,22 +138,23 @@ func TestSetNSWrongFileFailure(t *testing.T) { assert.NotNil(t, err, "Should fail because file is not a namespace") } -var testNamespaceList = []Namespace{ - { - Type: NSTypeCGroup, - }, - { - Type: NSTypeIPC, - }, - { - Type: NSTypeNet, - }, - { - Type: NSTypePID, - }, - { - Type: NSTypeUTS, - }, +func supportedNamespaces() []Namespace { + var list []Namespace + var ns = []Namespace{ + {Type: NSTypeCGroup}, + {Type: NSTypeIPC}, + {Type: NSTypeNet}, + {Type: NSTypePID}, + {Type: NSTypeUTS}, + } + + for _, n := range ns { + if _, err := os.Stat(fmt.Sprint("/proc/self/ns/", string(n.Type))); err == nil { + list = append(list, n) + } + } + + return list } func testToRunNil() error { @@ -161,7 +162,7 @@ func testToRunNil() error { } func TestNsEnterEmptyPathAndPIDFromNSListFailure(t *testing.T) { - err := NsEnter(testNamespaceList, testToRunNil) + err := NsEnter(supportedNamespaces(), testToRunNil) assert.NotNil(t, err, "Should fail because neither a path nor a PID"+ " has been provided by every namespace of the list") } @@ -172,7 +173,7 @@ func TestNsEnterEmptyNamespaceListSuccess(t *testing.T) { } func TestNsEnterSuccessful(t *testing.T) { - nsList := testNamespaceList + nsList := supportedNamespaces() sleepDuration := 60 cloneFlags := 0