From 2554f49d5ee54e63d5a05859f437e4398c6332fa Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Thu, 15 Oct 2015 15:24:53 -0700 Subject: [PATCH] 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 --- libcontainer/cgroups/fs/apply_raw.go | 53 ++++++++++++++++------------ 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/libcontainer/cgroups/fs/apply_raw.go b/libcontainer/cgroups/fs/apply_raw.go index e597d43e..5d3e265f 100644 --- a/libcontainer/cgroups/fs/apply_raw.go +++ b/libcontainer/cgroups/fs/apply_raw.go @@ -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 }