mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-06-26 15:32:30 +00:00
Merge pull request #1514 from fgiudici/port_cgroup_fix
[forwardport] Fixup systemd cgroup handling
This commit is contained in:
commit
3369fc8b4b
@ -54,9 +54,6 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
// If set to true, expects cgroupsPath to be of form "slice:prefix:name", otherwise cgroups creation will fail
|
||||
systemdCgroup *bool
|
||||
|
||||
cgroupsLogger = logrus.WithField("source", "virtcontainers/pkg/cgroups")
|
||||
)
|
||||
|
||||
@ -67,18 +64,6 @@ func SetLogger(logger *logrus.Entry) {
|
||||
cgroupsLogger = logger.WithFields(fields)
|
||||
}
|
||||
|
||||
func EnableSystemdCgroup() {
|
||||
systemd := true
|
||||
systemdCgroup = &systemd
|
||||
}
|
||||
|
||||
func UseSystemdCgroup() bool {
|
||||
if systemdCgroup != nil {
|
||||
return *systemdCgroup
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// returns the list of devices that a hypervisor may need
|
||||
func hypervisorDevices() []specs.LinuxDeviceCgroup {
|
||||
devices := []specs.LinuxDeviceCgroup{}
|
||||
@ -108,7 +93,6 @@ func hypervisorDevices() []specs.LinuxDeviceCgroup {
|
||||
// New creates a new CgroupManager
|
||||
func New(config *Config) (*Manager, error) {
|
||||
var err error
|
||||
useSystemdCgroup := UseSystemdCgroup()
|
||||
|
||||
devices := config.Resources.Devices
|
||||
devices = append(devices, hypervisorDevices()...)
|
||||
@ -126,6 +110,9 @@ func New(config *Config) (*Manager, error) {
|
||||
cgroups := config.Cgroups
|
||||
cgroupPaths := config.CgroupPaths
|
||||
|
||||
// determine if we are utilizing systemd managed cgroups based on the path provided
|
||||
useSystemdCgroup := IsSystemdCgroup(config.CgroupPath)
|
||||
|
||||
// Create a new cgroup if the current one is nil
|
||||
// this cgroups must be saved later
|
||||
if cgroups == nil {
|
||||
@ -221,7 +208,14 @@ func (m *Manager) moveToParent() error {
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
for _, cgroupPath := range m.mgr.GetPaths() {
|
||||
|
||||
pids, err := readPids(cgroupPath)
|
||||
// possible that the cgroupPath doesn't exist. If so, skip:
|
||||
if os.IsNotExist(err) {
|
||||
// The cgroup is not present on the filesystem: no pids to move. The systemd cgroup
|
||||
// manager lists all of the subsystems, including those that are not actually being managed.
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -287,7 +281,10 @@ func (m *Manager) GetPaths() map[string]string {
|
||||
func (m *Manager) Destroy() error {
|
||||
// cgroup can't be destroyed if it contains running processes
|
||||
if err := m.moveToParent(); err != nil {
|
||||
return fmt.Errorf("Could not move processes into parent cgroup: %v", err)
|
||||
// If the process migration to the parent cgroup fails, then
|
||||
// we expect the Destroy to fail as well. Let's log an error here
|
||||
// and attempt to execute the Destroy still to help cleanup the hosts' FS.
|
||||
m.logger().WithError(err).Error("Could not move processes into parent cgroup")
|
||||
}
|
||||
|
||||
m.Lock()
|
||||
|
@ -11,34 +11,11 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestEnableSystemdCgroup(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
orgSystemdCgroup := systemdCgroup
|
||||
defer func() {
|
||||
systemdCgroup = orgSystemdCgroup
|
||||
}()
|
||||
|
||||
useSystemdCgroup := UseSystemdCgroup()
|
||||
if systemdCgroup != nil {
|
||||
assert.Equal(*systemdCgroup, useSystemdCgroup)
|
||||
} else {
|
||||
assert.False(useSystemdCgroup)
|
||||
}
|
||||
|
||||
EnableSystemdCgroup()
|
||||
assert.True(UseSystemdCgroup())
|
||||
}
|
||||
|
||||
//very very basic test; should be expanded
|
||||
func TestNew(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
useSystemdCgroup := false
|
||||
orgSystemdCgroup := systemdCgroup
|
||||
defer func() {
|
||||
systemdCgroup = orgSystemdCgroup
|
||||
}()
|
||||
systemdCgroup = &useSystemdCgroup
|
||||
|
||||
// create a cgroupfs cgroup manager
|
||||
c := &Config{
|
||||
Cgroups: nil,
|
||||
CgroupPath: "",
|
||||
@ -48,8 +25,14 @@ func TestNew(t *testing.T) {
|
||||
assert.NoError(err)
|
||||
assert.NotNil(mgr.mgr)
|
||||
|
||||
useSystemdCgroup = true
|
||||
mgr, err = New(c)
|
||||
assert.Error(err)
|
||||
assert.Nil(mgr)
|
||||
// create a systemd cgroup manager
|
||||
s := &Config{
|
||||
Cgroups: nil,
|
||||
CgroupPath: "system.slice:kubepod:container",
|
||||
}
|
||||
|
||||
mgr, err = New(s)
|
||||
assert.NoError(err)
|
||||
assert.NotNil(mgr.mgr)
|
||||
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
@ -60,13 +60,20 @@ func ValidCgroupPath(path string, systemdCgroup bool) (string, error) {
|
||||
}
|
||||
|
||||
func IsSystemdCgroup(cgroupPath string) bool {
|
||||
// systemd cgroup path: slice:prefix:name
|
||||
re := regexp.MustCompile(`([[:alnum:]]|\.)+:([[:alnum:]]|\.)+:([[:alnum:]]|\.)+`)
|
||||
found := re.FindStringIndex(cgroupPath)
|
||||
|
||||
// if found string is equal to cgroupPath then
|
||||
// it's a correct systemd cgroup path.
|
||||
return found != nil && cgroupPath[found[0]:found[1]] == cgroupPath
|
||||
// If we are utilizing systemd to manage cgroups, we expect to receive a path
|
||||
// in the format slice:scopeprefix:name. A typical example would be:
|
||||
//
|
||||
// system.slice:docker:6b4c4a4d0cc2a12c529dcb13a2b8e438dfb3b2a6af34d548d7d
|
||||
//
|
||||
// Based on this, let's split by the ':' delimiter and verify that the first
|
||||
// section has .slice as a suffix.
|
||||
parts := strings.Split(cgroupPath, ":")
|
||||
if len(parts) == 3 && strings.HasSuffix(parts[0], ".slice") {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func DeviceToCgroupDevice(device string) (*configs.Device, error) {
|
||||
|
@ -22,8 +22,8 @@ func TestIsSystemdCgroup(t *testing.T) {
|
||||
path string
|
||||
expected bool
|
||||
}{
|
||||
{"slice:kata:afhts2e5d4g5s", true},
|
||||
{"slice.system:kata:afhts2e5d4g5s", true},
|
||||
{"foo.slice:kata:afhts2e5d4g5s", true},
|
||||
{"system.slice:kata:afhts2e5d4g5s", true},
|
||||
{"/kata/afhts2e5d4g5s", false},
|
||||
{"a:b:c:d", false},
|
||||
{":::", false},
|
||||
@ -78,9 +78,9 @@ func TestValidCgroupPath(t *testing.T) {
|
||||
{":a:b", true, true},
|
||||
{"@:@:@", true, true},
|
||||
|
||||
// valid system paths
|
||||
{"slice:kata:55555", true, false},
|
||||
{"slice.system:kata:afhts2e5d4g5s", true, false},
|
||||
// valid systemd paths
|
||||
{"x.slice:kata:55555", true, false},
|
||||
{"system.slice:kata:afhts2e5d4g5s", true, false},
|
||||
} {
|
||||
path, err := ValidCgroupPath(t.path, t.systemdCgroup)
|
||||
if t.error {
|
||||
|
Loading…
Reference in New Issue
Block a user