mirror of
https://github.com/aljazceru/kata-containers.git
synced 2025-12-28 11:34:40 +01:00
When SandboxCgroupsOnly is set, we are expected to just inherit our parent's cgroup settings and to move all Kata threads within that sandbox cgroup. The initial implementation still adjusted the size of this cgroup. This commit fixes this. This commit makes a couple of functional changes, small refactors, and adds clarifying comments for some functions. Fixes: #2090 Signed-off-by: Eric Ernst <eric.ernst@intel.com>
200 lines
4.1 KiB
Go
200 lines
4.1 KiB
Go
// Copyright (c) 2018 Huawei Corporation
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
package virtcontainers
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/containerd/cgroups"
|
|
"github.com/kata-containers/runtime/virtcontainers/types"
|
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
type mockCgroup struct {
|
|
}
|
|
|
|
func (m *mockCgroup) New(string, *specs.LinuxResources) (cgroups.Cgroup, error) {
|
|
return &mockCgroup{}, nil
|
|
}
|
|
func (m *mockCgroup) Add(cgroups.Process) error {
|
|
return nil
|
|
}
|
|
|
|
func (m *mockCgroup) AddTask(cgroups.Process) error {
|
|
return nil
|
|
}
|
|
|
|
func (m *mockCgroup) Delete() error {
|
|
return nil
|
|
}
|
|
|
|
func (m *mockCgroup) MoveTo(cgroups.Cgroup) error {
|
|
return nil
|
|
}
|
|
|
|
func (m *mockCgroup) Stat(...cgroups.ErrorHandler) (*cgroups.Metrics, error) {
|
|
return &cgroups.Metrics{}, nil
|
|
}
|
|
|
|
func (m *mockCgroup) Update(resources *specs.LinuxResources) error {
|
|
return nil
|
|
}
|
|
|
|
func (m *mockCgroup) Processes(cgroups.Name, bool) ([]cgroups.Process, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
func (m *mockCgroup) Freeze() error {
|
|
return nil
|
|
}
|
|
|
|
func (m *mockCgroup) Thaw() error {
|
|
return nil
|
|
}
|
|
|
|
func (m *mockCgroup) OOMEventFD() (uintptr, error) {
|
|
return 0, nil
|
|
}
|
|
|
|
func (m *mockCgroup) State() cgroups.State {
|
|
return ""
|
|
}
|
|
|
|
func (m *mockCgroup) Subsystems() []cgroups.Subsystem {
|
|
return nil
|
|
}
|
|
|
|
func (m *mockCgroup) Tasks(cgroups.Name, bool) ([]cgroups.Task, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
func mockCgroupNew(hierarchy cgroups.Hierarchy, path cgroups.Path, resources *specs.LinuxResources, opts ...cgroups.InitOpts) (cgroups.Cgroup, error) {
|
|
return &mockCgroup{}, nil
|
|
}
|
|
|
|
func mockCgroupLoad(hierarchy cgroups.Hierarchy, path cgroups.Path, opts ...cgroups.InitOpts) (cgroups.Cgroup, error) {
|
|
return &mockCgroup{}, nil
|
|
}
|
|
|
|
func init() {
|
|
cgroupsNewFunc = mockCgroupNew
|
|
cgroupsLoadFunc = mockCgroupLoad
|
|
}
|
|
|
|
func TestV1Constraints(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
systems, err := V1Constraints()
|
|
assert.NoError(err)
|
|
assert.NotEmpty(systems)
|
|
}
|
|
|
|
func TestV1NoConstraints(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
systems, err := V1NoConstraints()
|
|
assert.NoError(err)
|
|
assert.NotEmpty(systems)
|
|
}
|
|
|
|
func TestCgroupNoConstraintsPath(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
cgrouPath := "abc"
|
|
expectedPath := filepath.Join(cgroupKataPath, cgrouPath)
|
|
path := cgroupNoConstraintsPath(cgrouPath)
|
|
assert.Equal(expectedPath, path)
|
|
}
|
|
|
|
func TestUpdateCgroups(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
oldCgroupsNew := cgroupsNewFunc
|
|
oldCgroupsLoad := cgroupsLoadFunc
|
|
cgroupsNewFunc = cgroups.New
|
|
cgroupsLoadFunc = cgroups.Load
|
|
defer func() {
|
|
cgroupsNewFunc = oldCgroupsNew
|
|
cgroupsLoadFunc = oldCgroupsLoad
|
|
}()
|
|
|
|
s := &Sandbox{
|
|
state: types.SandboxState{
|
|
CgroupPath: "",
|
|
},
|
|
config: &SandboxConfig{SandboxCgroupOnly: false},
|
|
}
|
|
|
|
// empty path
|
|
err := s.cgroupsUpdate()
|
|
assert.NoError(err)
|
|
|
|
// path doesn't exist
|
|
s.state.CgroupPath = "/abc/123/rgb"
|
|
err = s.cgroupsUpdate()
|
|
assert.Error(err)
|
|
|
|
if os.Getuid() != 0 {
|
|
return
|
|
}
|
|
|
|
s.state.CgroupPath = fmt.Sprintf("/kata-tests-%d", os.Getpid())
|
|
testCgroup, err := cgroups.New(cgroups.V1, cgroups.StaticPath(s.state.CgroupPath), &specs.LinuxResources{})
|
|
assert.NoError(err)
|
|
defer testCgroup.Delete()
|
|
s.hypervisor = &mockHypervisor{mockPid: 0}
|
|
|
|
// bad pid
|
|
err = s.cgroupsUpdate()
|
|
assert.Error(err)
|
|
|
|
// fake workload
|
|
cmd := exec.Command("tail", "-f", "/dev/null")
|
|
assert.NoError(cmd.Start())
|
|
s.hypervisor = &mockHypervisor{mockPid: cmd.Process.Pid}
|
|
|
|
// no containers
|
|
err = s.cgroupsUpdate()
|
|
assert.NoError(err)
|
|
|
|
s.config = &SandboxConfig{}
|
|
s.config.HypervisorConfig.NumVCPUs = 1
|
|
|
|
s.containers = map[string]*Container{
|
|
"abc": {
|
|
process: Process{
|
|
Pid: cmd.Process.Pid,
|
|
},
|
|
config: &ContainerConfig{
|
|
Annotations: containerAnnotations,
|
|
Spec: newEmptySpec(),
|
|
},
|
|
},
|
|
"xyz": {
|
|
process: Process{
|
|
Pid: cmd.Process.Pid,
|
|
},
|
|
config: &ContainerConfig{
|
|
Annotations: containerAnnotations,
|
|
Spec: newEmptySpec(),
|
|
},
|
|
},
|
|
}
|
|
|
|
err = s.cgroupsUpdate()
|
|
assert.NoError(err)
|
|
|
|
// cleanup
|
|
assert.NoError(cmd.Process.Kill())
|
|
err = s.cgroupsDelete()
|
|
assert.NoError(err)
|
|
}
|