diff --git a/virtcontainers/api_test.go b/virtcontainers/api_test.go index 742a1b39b..8e27d727c 100644 --- a/virtcontainers/api_test.go +++ b/virtcontainers/api_test.go @@ -23,6 +23,7 @@ import ( vcTypes "github.com/kata-containers/runtime/virtcontainers/pkg/types" "github.com/kata-containers/runtime/virtcontainers/store" "github.com/kata-containers/runtime/virtcontainers/types" + "github.com/kata-containers/runtime/virtcontainers/utils" specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/stretchr/testify/assert" ) @@ -887,7 +888,8 @@ func TestStatusSandboxSuccessfulStateReady(t *testing.T) { { ID: containerID, State: types.State{ - State: types.StateReady, + State: types.StateReady, + CgroupPath: utils.DefaultCgroupPath, }, PID: 0, RootFs: filepath.Join(testDir, testBundle), @@ -945,7 +947,8 @@ func TestStatusSandboxSuccessfulStateRunning(t *testing.T) { { ID: containerID, State: types.State{ - State: types.StateRunning, + State: types.StateRunning, + CgroupPath: utils.DefaultCgroupPath, }, PID: 0, RootFs: filepath.Join(testDir, testBundle), @@ -1768,7 +1771,8 @@ func TestStatusContainerStateReady(t *testing.T) { expectedStatus := ContainerStatus{ ID: contID, State: types.State{ - State: types.StateReady, + State: types.StateReady, + CgroupPath: utils.DefaultCgroupPath, }, PID: 0, RootFs: filepath.Join(testDir, testBundle), @@ -1843,7 +1847,8 @@ func TestStatusContainerStateRunning(t *testing.T) { expectedStatus := ContainerStatus{ ID: contID, State: types.State{ - State: types.StateRunning, + State: types.StateRunning, + CgroupPath: utils.DefaultCgroupPath, }, PID: 0, RootFs: filepath.Join(testDir, testBundle), diff --git a/virtcontainers/container.go b/virtcontainers/container.go index 991ebe5d1..337d07dec 100644 --- a/virtcontainers/container.go +++ b/virtcontainers/container.go @@ -1288,14 +1288,14 @@ func (c *Container) newCgroups() error { resources.CPU = validCPUResources(spec.Linux.Resources.CPU) } + c.state.CgroupPath = utils.ValidCgroupPath(spec.Linux.CgroupsPath) cgroup, err := cgroupsNewFunc(cgroups.V1, - cgroups.StaticPath(spec.Linux.CgroupsPath), &resources) + cgroups.StaticPath(c.state.CgroupPath), &resources) if err != nil { - return fmt.Errorf("Could not create cgroup for %v: %v", spec.Linux.CgroupsPath, err) + return fmt.Errorf("Could not create cgroup for %v: %v", c.state.CgroupPath, err) } c.state.Resources = resources - c.state.CgroupPath = spec.Linux.CgroupsPath // Add shim into cgroup if c.process.Pid > 0 { diff --git a/virtcontainers/utils/utils.go b/virtcontainers/utils/utils.go index 2358f2b93..b257e49b6 100644 --- a/virtcontainers/utils/utils.go +++ b/virtcontainers/utils/utils.go @@ -14,6 +14,9 @@ import ( "path/filepath" ) +// DefaultCgroupPath runtime-determined location in the cgroups hierarchy. +const DefaultCgroupPath = "/vc" + const cpBinaryName = "cp" const fileMode0755 = os.FileMode(0755) @@ -241,3 +244,18 @@ func SupportsVsocks() bool { return true } + +// ValidCgroupPath returns a valid cgroup path. +// see https://github.com/opencontainers/runtime-spec/blob/master/config-linux.md#cgroups-path +func ValidCgroupPath(path string) string { + // In the case of an absolute path (starting with /), the runtime MUST + // take the path to be relative to the cgroups mount point. + if filepath.IsAbs(path) { + return filepath.Clean(path) + } + + // In the case of a relative path (not starting with /), the runtime MAY + // interpret the path relative to a runtime-determined location in the cgroups hierarchy. + // clean up path and return a new path relative to defaultCgroupPath + return filepath.Join(DefaultCgroupPath, filepath.Clean("/"+path)) +} diff --git a/virtcontainers/utils/utils_test.go b/virtcontainers/utils/utils_test.go index 51375ebc6..5403e9c94 100644 --- a/virtcontainers/utils/utils_test.go +++ b/virtcontainers/utils/utils_test.go @@ -325,3 +325,18 @@ func TestSupportsVsocks(t *testing.T) { assert.True(SupportsVsocks()) } + +func TestValidCgroupPath(t *testing.T) { + assert := assert.New(t) + + assert.Equal(DefaultCgroupPath, ValidCgroupPath("../../../")) + assert.Equal(filepath.Join(DefaultCgroupPath, "foo"), ValidCgroupPath("../../../foo")) + assert.Equal("/hi", ValidCgroupPath("/../hi")) + assert.Equal("/hi/foo", ValidCgroupPath("/../hi/foo")) + assert.Equal(DefaultCgroupPath, ValidCgroupPath("")) + assert.Equal(DefaultCgroupPath, ValidCgroupPath("")) + assert.Equal(DefaultCgroupPath, ValidCgroupPath("../")) + assert.Equal(DefaultCgroupPath, ValidCgroupPath(".")) + assert.Equal(DefaultCgroupPath, ValidCgroupPath("./../")) + assert.Equal(filepath.Join(DefaultCgroupPath, "o / g"), ValidCgroupPath("o / m /../ g")) +}