-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
Move the cgroups v2 hybrid check from init() #3432
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,33 +13,8 @@ import ( | |
"github.com/opencontainers/runc/libcontainer/configs" | ||
) | ||
|
||
var subsystems = []subsystem{ | ||
&CpusetGroup{}, | ||
&DevicesGroup{}, | ||
&MemoryGroup{}, | ||
&CpuGroup{}, | ||
&CpuacctGroup{}, | ||
&PidsGroup{}, | ||
&BlkioGroup{}, | ||
&HugetlbGroup{}, | ||
&NetClsGroup{}, | ||
&NetPrioGroup{}, | ||
&PerfEventGroup{}, | ||
&FreezerGroup{}, | ||
&RdmaGroup{}, | ||
&NameGroup{GroupName: "name=systemd", Join: true}, | ||
} | ||
|
||
var errSubsystemDoesNotExist = errors.New("cgroup: subsystem does not exist") | ||
|
||
func init() { | ||
// If using cgroups-hybrid mode then add a "" controller indicating | ||
// it should join the cgroups v2. | ||
if cgroups.IsCgroup2HybridMode() { | ||
subsystems = append(subsystems, &NameGroup{GroupName: "", Join: true}) | ||
} | ||
} | ||
|
||
type subsystem interface { | ||
// Name returns the name of the subsystem. | ||
Name() string | ||
|
@@ -54,9 +29,10 @@ type subsystem interface { | |
} | ||
|
||
type manager struct { | ||
mu sync.Mutex | ||
cgroups *configs.Cgroup | ||
paths map[string]string | ||
mu sync.Mutex | ||
cgroups *configs.Cgroup | ||
paths map[string]string | ||
subsystems []subsystem | ||
} | ||
|
||
func NewManager(cg *configs.Cgroup, paths map[string]string) (cgroups.Manager, error) { | ||
|
@@ -69,17 +45,41 @@ func NewManager(cg *configs.Cgroup, paths map[string]string) (cgroups.Manager, e | |
return nil, cgroups.ErrV1NoUnified | ||
} | ||
|
||
subsystems := []subsystem{ | ||
&CpusetGroup{}, | ||
&DevicesGroup{}, | ||
&MemoryGroup{}, | ||
&CpuGroup{}, | ||
&CpuacctGroup{}, | ||
&PidsGroup{}, | ||
&BlkioGroup{}, | ||
&HugetlbGroup{}, | ||
&NetClsGroup{}, | ||
&NetPrioGroup{}, | ||
&PerfEventGroup{}, | ||
&FreezerGroup{}, | ||
&RdmaGroup{}, | ||
&NameGroup{GroupName: "name=systemd", Join: true}, | ||
} | ||
|
||
// If using cgroups-hybrid mode then add a "" controller indicating | ||
// it should join the cgroups v2. | ||
if cgroups.IsCgroup2HybridMode() { | ||
subsystems = append(subsystems, &NameGroup{GroupName: "", Join: true}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is mutating a package var in a constructor. Can that race with other readers of subsystems? If the constructor is called multiple times, this will append multiple times, right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ugh, yeah, from a quick look, we could move the subsystems under the manager instance. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pushed a commit to test that out (will check later). |
||
} | ||
|
||
if paths == nil { | ||
var err error | ||
paths, err = initPaths(cg) | ||
paths, err = initPaths(cg, subsystems) | ||
if err != nil { | ||
return nil, err | ||
} | ||
} | ||
|
||
return &manager{ | ||
cgroups: cg, | ||
paths: paths, | ||
cgroups: cg, | ||
paths: paths, | ||
subsystems: subsystems, | ||
}, nil | ||
} | ||
|
||
|
@@ -110,7 +110,7 @@ func (m *manager) Apply(pid int) (err error) { | |
|
||
c := m.cgroups | ||
|
||
for _, sys := range subsystems { | ||
for _, sys := range m.subsystems { | ||
name := sys.Name() | ||
p, ok := m.paths[name] | ||
if !ok { | ||
|
@@ -154,7 +154,7 @@ func (m *manager) GetStats() (*cgroups.Stats, error) { | |
m.mu.Lock() | ||
defer m.mu.Unlock() | ||
stats := cgroups.NewStats() | ||
for _, sys := range subsystems { | ||
for _, sys := range m.subsystems { | ||
path := m.paths[sys.Name()] | ||
if path == "" { | ||
continue | ||
|
@@ -177,7 +177,7 @@ func (m *manager) Set(r *configs.Resources) error { | |
|
||
m.mu.Lock() | ||
defer m.mu.Unlock() | ||
for _, sys := range subsystems { | ||
for _, sys := range m.subsystems { | ||
path := m.paths[sys.Name()] | ||
if err := sys.Set(path, r); err != nil { | ||
// When rootless is true, errors from the device subsystem | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does not make sense to have a per-manager subsystem list.
Instead, I think, we should keep subsystems global, and wrap their initialization into
once.Do
.