From 0b430dc71f441ca0b024fdccc1f84cd3278fc273 Mon Sep 17 00:00:00 2001 From: Julio Montes Date: Mon, 8 Apr 2019 13:58:35 -0500 Subject: [PATCH] virtcontainers: Use only supported namespaces Depending of the linux versions some namespaces are supported or not. To avoid failures running containers and unit tests in old linux kernels, only the supported namespaces should be used. Depends-on: github.com/kata-containers/tests#1414 fixes #228 Signed-off-by: Julio Montes --- virtcontainers/pkg/nsenter/nsenter.go | 24 ++++++++++---- virtcontainers/pkg/nsenter/nsenter_test.go | 37 +++++++++++----------- 2 files changed, 36 insertions(+), 25 deletions(-) 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