add Set interface

Signed-off-by: Qiang Huang <h.huangqiang@huawei.com>
This commit is contained in:
Qiang Huang 2015-02-25 17:20:01 +08:00
parent 12a63757db
commit cc524f1b72
13 changed files with 163 additions and 2 deletions

View File

@ -31,6 +31,9 @@ type Manager interface {
// Returns cgroup paths to save in a state file and to be able to // Returns cgroup paths to save in a state file and to be able to
// restore the object later. // restore the object later.
GetPaths() map[string]string GetPaths() map[string]string
// Set the cgroup as configured.
Set(container *configs.Config) error
} }
type NotFoundError struct { type NotFoundError struct {

View File

@ -32,6 +32,8 @@ type subsystem interface {
Remove(*data) error Remove(*data) error
// Creates and joins the cgroup represented by data. // Creates and joins the cgroup represented by data.
Apply(*data) error Apply(*data) error
// Set the cgroup represented by cgroup.
Set(path string, cgroup *configs.Cgroup) error
} }
type Manager struct { type Manager struct {
@ -147,6 +149,20 @@ func (m *Manager) GetStats() (*cgroups.Stats, error) {
return stats, nil 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) {
continue
}
if err := sys.Set(path, container.Cgroups); err != nil {
return err
}
}
return nil
}
// Freeze toggles the container's freezer cgroup depending on the state // Freeze toggles the container's freezer cgroup depending on the state
// provided // provided
func (m *Manager) Freeze(state configs.FreezerState) error { func (m *Manager) Freeze(state configs.FreezerState) error {

View File

@ -9,6 +9,7 @@ import (
"strings" "strings"
"github.com/docker/libcontainer/cgroups" "github.com/docker/libcontainer/cgroups"
"github.com/docker/libcontainer/configs"
) )
type BlkioGroup struct { type BlkioGroup struct {
@ -29,6 +30,16 @@ func (s *BlkioGroup) Apply(d *data) error {
return nil return nil
} }
func (s *BlkioGroup) Set(path string, cgroup *configs.Cgroup) error {
if cgroup.BlkioWeight != 0 {
if err := writeFile(path, "blkio.weight", strconv.FormatInt(cgroup.BlkioWeight, 10)); err != nil {
return err
}
}
return nil
}
func (s *BlkioGroup) Remove(d *data) error { func (s *BlkioGroup) Remove(d *data) error {
return removePath(d.path("blkio")) return removePath(d.path("blkio"))
} }

View File

@ -7,6 +7,7 @@ import (
"strconv" "strconv"
"github.com/docker/libcontainer/cgroups" "github.com/docker/libcontainer/cgroups"
"github.com/docker/libcontainer/configs"
) )
type CpuGroup struct { type CpuGroup struct {
@ -37,6 +38,26 @@ func (s *CpuGroup) Apply(d *data) error {
return nil return nil
} }
func (s *CpuGroup) Set(path string, cgroup *configs.Cgroup) error {
if cgroup.CpuShares != 0 {
if err := writeFile(path, "cpu.shares", strconv.FormatInt(cgroup.CpuShares, 10)); err != nil {
return err
}
}
if cgroup.CpuPeriod != 0 {
if err := writeFile(path, "cpu.cfs_period_us", strconv.FormatInt(cgroup.CpuPeriod, 10)); err != nil {
return err
}
}
if cgroup.CpuQuota != 0 {
if err := writeFile(path, "cpu.cfs_quota_us", strconv.FormatInt(cgroup.CpuQuota, 10)); err != nil {
return err
}
}
return nil
}
func (s *CpuGroup) Remove(d *data) error { func (s *CpuGroup) Remove(d *data) error {
return removePath(d.path("cpu")) return removePath(d.path("cpu"))
} }

View File

@ -8,6 +8,7 @@ import (
"strings" "strings"
"github.com/docker/libcontainer/cgroups" "github.com/docker/libcontainer/cgroups"
"github.com/docker/libcontainer/configs"
"github.com/docker/libcontainer/system" "github.com/docker/libcontainer/system"
) )
@ -30,6 +31,10 @@ func (s *CpuacctGroup) Apply(d *data) error {
return nil return nil
} }
func (s *CpuacctGroup) Set(path string, cgroup *configs.Cgroup) error {
return nil
}
func (s *CpuacctGroup) Remove(d *data) error { func (s *CpuacctGroup) Remove(d *data) error {
return removePath(d.path("cpuacct")) return removePath(d.path("cpuacct"))
} }

View File

@ -8,6 +8,7 @@ import (
"strconv" "strconv"
"github.com/docker/libcontainer/cgroups" "github.com/docker/libcontainer/cgroups"
"github.com/docker/libcontainer/configs"
) )
type CpusetGroup struct { type CpusetGroup struct {
@ -21,6 +22,22 @@ func (s *CpusetGroup) Apply(d *data) error {
return s.ApplyDir(dir, d.c.CpusetCpus, d.c.CpusetMems, d.pid) return s.ApplyDir(dir, d.c.CpusetCpus, d.c.CpusetMems, d.pid)
} }
func (s *CpusetGroup) Set(path string, cgroup *configs.Cgroup) error {
if cgroup.CpusetCpus != "" {
if err := writeFile(path, "cpuset.cpus", cgroup.CpusetCpus); err != nil {
return err
}
}
if cgroup.CpusetMems != "" {
if err := writeFile(path, "cpuset.mems", cgroup.CpusetMems); err != nil {
return err
}
}
return nil
}
func (s *CpusetGroup) Remove(d *data) error { func (s *CpusetGroup) Remove(d *data) error {
return removePath(d.path("cpuset")) return removePath(d.path("cpuset"))
} }

View File

@ -1,6 +1,9 @@
package fs package fs
import "github.com/docker/libcontainer/cgroups" import (
"github.com/docker/libcontainer/cgroups"
"github.com/docker/libcontainer/configs"
)
type DevicesGroup struct { type DevicesGroup struct {
} }
@ -25,6 +28,22 @@ func (s *DevicesGroup) Apply(d *data) error {
return nil return nil
} }
func (s *DevicesGroup) Set(path string, cgroup *configs.Cgroup) error {
if !cgroup.AllowAllDevices {
if err := writeFile(path, "devices.deny", "a"); err != nil {
return err
}
for _, dev := range cgroup.AllowedDevices {
if err := writeFile(path, "devices.allow", dev.CgroupString()); err != nil {
return err
}
}
}
return nil
}
func (s *DevicesGroup) Remove(d *data) error { func (s *DevicesGroup) Remove(d *data) error {
return removePath(d.path("devices")) return removePath(d.path("devices"))
} }

View File

@ -42,6 +42,28 @@ func (s *FreezerGroup) Apply(d *data) error {
return nil return nil
} }
func (s *FreezerGroup) Set(path string, cgroup *configs.Cgroup) error {
switch cgroup.Freezer {
case configs.Frozen, configs.Thawed:
if err := writeFile(path, "freezer.state", string(cgroup.Freezer)); err != nil {
return err
}
for {
state, err := readFile(path, "freezer.state")
if err != nil {
return err
}
if strings.TrimSpace(state) == string(cgroup.Freezer) {
break
}
time.Sleep(1 * time.Millisecond)
}
}
return nil
}
func (s *FreezerGroup) Remove(d *data) error { func (s *FreezerGroup) Remove(d *data) error {
return removePath(d.path("freezer")) return removePath(d.path("freezer"))
} }

View File

@ -8,6 +8,7 @@ import (
"strconv" "strconv"
"github.com/docker/libcontainer/cgroups" "github.com/docker/libcontainer/cgroups"
"github.com/docker/libcontainer/configs"
) )
type MemoryGroup struct { type MemoryGroup struct {
@ -53,6 +54,32 @@ func (s *MemoryGroup) Apply(d *data) error {
return nil return nil
} }
func (s *MemoryGroup) Set(path string, cgroup *configs.Cgroup) error {
if cgroup.Memory != 0 {
if err := writeFile(path, "memory.limit_in_bytes", strconv.FormatInt(cgroup.Memory, 10)); err != nil {
return err
}
}
if cgroup.MemoryReservation != 0 {
if err := writeFile(path, "memory.soft_limit_in_bytes", strconv.FormatInt(cgroup.MemoryReservation, 10)); err != nil {
return err
}
}
// By default, MemorySwap is set to twice the size of Memory.
if cgroup.MemorySwap == 0 && cgroup.Memory != 0 {
if err := writeFile(path, "memory.memsw.limit_in_bytes", strconv.FormatInt(cgroup.Memory*2, 10)); err != nil {
return err
}
}
if cgroup.MemorySwap > 0 {
if err := writeFile(path, "memory.memsw.limit_in_bytes", strconv.FormatInt(cgroup.MemorySwap, 10)); err != nil {
return err
}
}
return nil
}
func (s *MemoryGroup) Remove(d *data) error { func (s *MemoryGroup) Remove(d *data) error {
return removePath(d.path("memory")) return removePath(d.path("memory"))
} }

View File

@ -2,6 +2,7 @@ package fs
import ( import (
"github.com/docker/libcontainer/cgroups" "github.com/docker/libcontainer/cgroups"
"github.com/docker/libcontainer/configs"
) )
type PerfEventGroup struct { type PerfEventGroup struct {
@ -15,6 +16,10 @@ func (s *PerfEventGroup) Apply(d *data) error {
return nil return nil
} }
func (s *PerfEventGroup) Set(path string, cgroup *configs.Cgroup) error {
return nil
}
func (s *PerfEventGroup) Remove(d *data) error { func (s *PerfEventGroup) Remove(d *data) error {
return removePath(d.path("perf_event")) return removePath(d.path("perf_event"))
} }

View File

@ -38,6 +38,10 @@ func (m *Manager) GetStats() (*cgroups.Stats, error) {
return nil, fmt.Errorf("Systemd not supported") return nil, fmt.Errorf("Systemd not supported")
} }
func (m *Manager) Set(container *configs.Config) error {
return nil, fmt.Errorf("Systemd not supported")
}
func (m *Manager) Freeze(state configs.FreezerState) error { func (m *Manager) Freeze(state configs.FreezerState) error {
return fmt.Errorf("Systemd not supported") return fmt.Errorf("Systemd not supported")
} }

View File

@ -26,7 +26,10 @@ type Manager struct {
} }
type subsystem interface { type subsystem interface {
GetStats(string, *cgroups.Stats) error // Returns the stats, as 'stats', corresponding to the cgroup under 'path'.
GetStats(path string, stats *cgroups.Stats) error
// Set the cgroup represented by cgroup.
Set(path string, cgroup *configs.Cgroup) error
} }
var subsystems = map[string]subsystem{ var subsystems = map[string]subsystem{
@ -323,6 +326,10 @@ func (m *Manager) GetStats() (*cgroups.Stats, error) {
return stats, nil return stats, nil
} }
func (m *Manager) Set(container *configs.Config) error {
panic("not implemented")
}
func getUnitName(c *configs.Cgroup) string { func getUnitName(c *configs.Cgroup) string {
return fmt.Sprintf("%s-%s.scope", c.Parent, c.Name) return fmt.Sprintf("%s-%s.scope", c.Parent, c.Name)
} }

View File

@ -29,6 +29,10 @@ func (m *mockCgroupManager) Apply(pid int) error {
return nil return nil
} }
func (m *mockCgroupManager) Set(container *configs.Config) error {
return nil
}
func (m *mockCgroupManager) Destroy() error { func (m *mockCgroupManager) Destroy() error {
return nil return nil
} }