Use array instead of map for cgroup subsystems

Also add cpuset as the first in the list to address issues setting the
pid in any cgroup before the cpuset is populated.

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
Michael Crosby 2015-10-15 15:24:53 -07:00
parent 02fdc70837
commit 2554f49d5e
1 changed files with 31 additions and 22 deletions

View File

@ -16,23 +16,34 @@ import (
)
var (
subsystems = map[string]subsystem{
"devices": &DevicesGroup{},
"memory": &MemoryGroup{},
"cpu": &CpuGroup{},
"cpuset": &CpusetGroup{},
"cpuacct": &CpuacctGroup{},
"blkio": &BlkioGroup{},
"hugetlb": &HugetlbGroup{},
"net_cls": &NetClsGroup{},
"net_prio": &NetPrioGroup{},
"perf_event": &PerfEventGroup{},
"freezer": &FreezerGroup{},
subsystems = subsystemSet{
&CpusetGroup{},
&DevicesGroup{},
&MemoryGroup{},
&CpuGroup{},
&CpuacctGroup{},
&BlkioGroup{},
&HugetlbGroup{},
&NetClsGroup{},
&NetPrioGroup{},
&PerfEventGroup{},
&FreezerGroup{},
}
CgroupProcesses = "cgroup.procs"
HugePageSizes, _ = cgroups.GetHugePageSize()
)
type subsystemSet []subsystem
func (s subsystemSet) Get(name string) subsystem {
for _, ss := range s {
if ss.Name() == name {
return ss
}
}
return nil
}
type subsystem interface {
// Name returns the name of the subsystem.
Name() string
@ -103,21 +114,21 @@ func (m *Manager) Apply(pid int) (err error) {
cgroups.RemovePaths(paths)
}
}()
for name, sys := range subsystems {
for _, sys := range subsystems {
if err := sys.Apply(d); err != nil {
return err
}
// TODO: Apply should, ideally, be reentrant or be broken up into a separate
// create and join phase so that the cgroup hierarchy for a container can be
// created then join consists of writing the process pids to cgroup.procs
p, err := d.path(name)
p, err := d.path(sys.Name())
if err != nil {
if cgroups.IsNotFound(err) {
continue
}
return err
}
paths[name] = p
paths[sys.Name()] = p
}
m.Paths = paths
@ -152,22 +163,21 @@ func (m *Manager) GetStats() (*cgroups.Stats, error) {
defer m.mu.Unlock()
stats := cgroups.NewStats()
for name, path := range m.Paths {
sys, ok := subsystems[name]
if !ok || !cgroups.PathExists(path) {
sys := subsystems.Get(name)
if sys == nil || !cgroups.PathExists(path) {
continue
}
if err := sys.GetStats(path, stats); err != nil {
return nil, err
}
}
return stats, nil
}
func (m *Manager) Set(container *configs.Config) error {
for name, path := range m.Paths {
sys, ok := subsystems[name]
if !ok || !cgroups.PathExists(path) {
sys := subsystems.Get(name)
if sys == nil || !cgroups.PathExists(path) {
continue
}
if err := sys.Set(path, container.Cgroups); err != nil {
@ -194,13 +204,12 @@ func (m *Manager) Freeze(state configs.FreezerState) error {
prevState := m.Cgroups.Freezer
m.Cgroups.Freezer = state
freezer := subsystems["freezer"]
freezer := subsystems.Get("freezer")
err = freezer.Set(dir, m.Cgroups)
if err != nil {
m.Cgroups.Freezer = prevState
return err
}
return nil
}