Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

systemd cgroup driver: Split support for unified cgroup2 hierarchy into its own Manager #2114

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 28 additions & 15 deletions libcontainer/cgroups/systemd/apply_systemd.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
"github.com/sirupsen/logrus"
)

type Manager struct {
type LegacyManager struct {
mu sync.Mutex
Cgroups *configs.Cgroup
Paths map[string]string
Expand Down Expand Up @@ -167,15 +167,28 @@ func NewSystemdCgroupsManager() (func(config *configs.Cgroup, paths map[string]s
if !systemdUtil.IsRunningSystemd() {
return nil, fmt.Errorf("systemd not running on this host, can't use systemd as a cgroups.Manager")
}
return func(config *configs.Cgroup, paths map[string]string) cgroups.Manager {
return &Manager{
Cgroups: config,
Paths: paths,
}
}, nil
unified, err := IsCgroup2UnifiedMode()
if err != nil {
return nil, err
}
if unified {
return func(config *configs.Cgroup, paths map[string]string) cgroups.Manager {
return &UnifiedManager{
Cgroups: config,
Paths: paths,
}
}, nil
} else {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: you don't need else here. Some lint tool may print a warning.

return func(config *configs.Cgroup, paths map[string]string) cgroups.Manager {
return &LegacyManager{
Cgroups: config,
Paths: paths,
}
}, nil
}
}

func (m *Manager) Apply(pid int) error {
func (m *LegacyManager) Apply(pid int) error {
var (
c = m.Cgroups
unitName = getUnitName(c)
Expand Down Expand Up @@ -325,7 +338,7 @@ func (m *Manager) Apply(pid int) error {
return nil
}

func (m *Manager) Destroy() error {
func (m *LegacyManager) Destroy() error {
if m.Cgroups.Paths != nil {
return nil
}
Expand All @@ -339,7 +352,7 @@ func (m *Manager) Destroy() error {
return nil
}

func (m *Manager) GetPaths() map[string]string {
func (m *LegacyManager) GetPaths() map[string]string {
m.mu.Lock()
paths := m.Paths
m.mu.Unlock()
Expand Down Expand Up @@ -456,7 +469,7 @@ func getSubsystemPath(c *configs.Cgroup, subsystem string) (string, error) {
return filepath.Join(mountpoint, initPath, slice, getUnitName(c)), nil
}

func (m *Manager) Freeze(state configs.FreezerState) error {
func (m *LegacyManager) Freeze(state configs.FreezerState) error {
path, err := getSubsystemPath(m.Cgroups, "freezer")
if err != nil {
return err
Expand All @@ -475,23 +488,23 @@ func (m *Manager) Freeze(state configs.FreezerState) error {
return nil
}

func (m *Manager) GetPids() ([]int, error) {
func (m *LegacyManager) GetPids() ([]int, error) {
path, err := getSubsystemPath(m.Cgroups, "devices")
if err != nil {
return nil, err
}
return cgroups.GetPids(path)
}

func (m *Manager) GetAllPids() ([]int, error) {
func (m *LegacyManager) GetAllPids() ([]int, error) {
path, err := getSubsystemPath(m.Cgroups, "devices")
if err != nil {
return nil, err
}
return cgroups.GetAllPids(path)
}

func (m *Manager) GetStats() (*cgroups.Stats, error) {
func (m *LegacyManager) GetStats() (*cgroups.Stats, error) {
m.mu.Lock()
defer m.mu.Unlock()
stats := cgroups.NewStats()
Expand All @@ -508,7 +521,7 @@ func (m *Manager) GetStats() (*cgroups.Stats, error) {
return stats, nil
}

func (m *Manager) Set(container *configs.Config) error {
func (m *LegacyManager) Set(container *configs.Config) error {
// If Paths are set, then we are just joining cgroups paths
// and there is no need to set any values.
if m.Cgroups.Paths != nil {
Expand Down
62 changes: 62 additions & 0 deletions libcontainer/cgroups/systemd/unified_hierarchy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// +build linux,!static_build

package systemd

import (
"fmt"
"syscall"

"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs"
"golang.org/x/sys/unix"
)

// IsCgroup2UnifiedMode returns whether we are running in cgroup v2 unified mode.
func IsCgroup2UnifiedMode() (bool, error) {
var st syscall.Statfs_t
if err := syscall.Statfs("/sys/fs/cgroup", &st); err != nil {
return false, fmt.Errorf("cannot statfs cgroup root: %v", err)
}
return st.Type == unix.CGROUP2_SUPER_MAGIC, nil
}

type UnifiedManager struct {
Cgroups *configs.Cgroup
Paths map[string]string
}

func NewUnifiedSystemdCgroupsManager() (func(config *configs.Cgroup, paths map[string]string) cgroups.Manager, error) {
return nil, fmt.Errorf("unified hierarchy not supported")
}

func (m *UnifiedManager) Apply(pid int) error {
return fmt.Errorf("unified hierarchy not supported")
}

func (m *UnifiedManager) GetPids() ([]int, error) {
return nil, fmt.Errorf("unified hierarchy not supported")
}

func (m *UnifiedManager) GetAllPids() ([]int, error) {
return nil, fmt.Errorf("unified hierarchy not supported")
}

func (m *UnifiedManager) Destroy() error {
return fmt.Errorf("unified hierarchy not supported")
}

func (m *UnifiedManager) GetPaths() map[string]string {
return nil
}

func (m *UnifiedManager) GetStats() (*cgroups.Stats, error) {
return nil, fmt.Errorf("unified hierarchy not supported")
}

func (m *UnifiedManager) Set(container *configs.Config) error {
return fmt.Errorf("unified hierarchy not supported")
}

func (m *UnifiedManager) Freeze(state configs.FreezerState) error {
return fmt.Errorf("unified hierarchy not supported")
}