diff --git a/cgroups/fs/blkio.go b/cgroups/fs/blkio.go index 275b78ed..8e132643 100644 --- a/cgroups/fs/blkio.go +++ b/cgroups/fs/blkio.go @@ -21,10 +21,8 @@ func (s *BlkioGroup) Apply(d *data) error { return err } - if d.c.BlkioWeight != 0 { - if err := writeFile(dir, "blkio.weight", strconv.FormatInt(d.c.BlkioWeight, 10)); err != nil { - return err - } + if err := s.Set(dir, d.c); err != nil { + return err } return nil diff --git a/cgroups/fs/cpu.go b/cgroups/fs/cpu.go index 0a5040af..1fbf7b15 100644 --- a/cgroups/fs/cpu.go +++ b/cgroups/fs/cpu.go @@ -20,21 +20,11 @@ func (s *CpuGroup) Apply(d *data) error { if err != nil { return err } - if d.c.CpuShares != 0 { - if err := writeFile(dir, "cpu.shares", strconv.FormatInt(d.c.CpuShares, 10)); err != nil { - return err - } - } - if d.c.CpuPeriod != 0 { - if err := writeFile(dir, "cpu.cfs_period_us", strconv.FormatInt(d.c.CpuPeriod, 10)); err != nil { - return err - } - } - if d.c.CpuQuota != 0 { - if err := writeFile(dir, "cpu.cfs_quota_us", strconv.FormatInt(d.c.CpuQuota, 10)); err != nil { - return err - } + + if err := s.Set(dir, d.c); err != nil { + return err } + return nil } diff --git a/cgroups/fs/cpuset.go b/cgroups/fs/cpuset.go index 54d1aee4..3ed2f67d 100644 --- a/cgroups/fs/cpuset.go +++ b/cgroups/fs/cpuset.go @@ -19,7 +19,7 @@ func (s *CpusetGroup) Apply(d *data) error { if err != nil { return err } - return s.ApplyDir(dir, d.c.CpusetCpus, d.c.CpusetMems, d.pid) + return s.ApplyDir(dir, d.c, d.pid) } func (s *CpusetGroup) Set(path string, cgroup *configs.Cgroup) error { @@ -46,7 +46,7 @@ func (s *CpusetGroup) GetStats(path string, stats *cgroups.Stats) error { return nil } -func (s *CpusetGroup) ApplyDir(dir, cpus string, mems string, pid int) error { +func (s *CpusetGroup) ApplyDir(dir string, cgroup *configs.Cgroup, pid int) error { if err := s.ensureParent(dir); err != nil { return err } @@ -57,17 +57,10 @@ func (s *CpusetGroup) ApplyDir(dir, cpus string, mems string, pid int) error { return err } - // If we don't use --cpuset-xxx, the default value inherit from parent cgroup - // is set in s.ensureParent, otherwise, use the value we set - if cpus != "" { - if err := writeFile(dir, "cpuset.cpus", cpus); err != nil { - return err - } - } - if mems != "" { - if err := writeFile(dir, "cpuset.mems", mems); err != nil { - return err - } + // the default values inherit from parent cgroup are already set in + // s.ensureParent, cover these if we have our own + if err := s.Set(dir, cgroup); err != nil { + return err } return nil diff --git a/cgroups/fs/devices.go b/cgroups/fs/devices.go index 835cfeef..16e00b1c 100644 --- a/cgroups/fs/devices.go +++ b/cgroups/fs/devices.go @@ -14,17 +14,10 @@ func (s *DevicesGroup) Apply(d *data) error { return err } - if !d.c.AllowAllDevices { - if err := writeFile(dir, "devices.deny", "a"); err != nil { - return err - } - - for _, dev := range d.c.AllowedDevices { - if err := writeFile(dir, "devices.allow", dev.CgroupString()); err != nil { - return err - } - } + if err := s.Set(dir, d.c); err != nil { + return err } + return nil } diff --git a/cgroups/fs/freezer.go b/cgroups/fs/freezer.go index 738d9c0d..d7c0da54 100644 --- a/cgroups/fs/freezer.go +++ b/cgroups/fs/freezer.go @@ -19,20 +19,9 @@ func (s *FreezerGroup) Apply(d *data) error { return err } - if err := writeFile(dir, "freezer.state", string(d.c.Freezer)); err != nil { + if err := s.Set(dir, d.c); err != nil { return err } - - for { - state, err := readFile(dir, "freezer.state") - if err != nil { - return err - } - if strings.TrimSpace(state) == string(d.c.Freezer) { - break - } - time.Sleep(1 * time.Millisecond) - } default: if _, err := d.join("freezer"); err != nil && !cgroups.IsNotFound(err) { return err diff --git a/cgroups/fs/memory.go b/cgroups/fs/memory.go index 828d4b20..a2e4f33d 100644 --- a/cgroups/fs/memory.go +++ b/cgroups/fs/memory.go @@ -26,31 +26,10 @@ func (s *MemoryGroup) Apply(d *data) error { } }() - // Only set values if some config was specified. - if d.c.Memory != 0 || d.c.MemoryReservation != 0 || d.c.MemorySwap != 0 { - if d.c.Memory != 0 { - if err := writeFile(dir, "memory.limit_in_bytes", strconv.FormatInt(d.c.Memory, 10)); err != nil { - return err - } - } - if d.c.MemoryReservation != 0 { - if err := writeFile(dir, "memory.soft_limit_in_bytes", strconv.FormatInt(d.c.MemoryReservation, 10)); err != nil { - return err - } - } - // By default, MemorySwap is set to twice the size of RAM. - // If you want to omit MemorySwap, set it to '-1'. - if d.c.MemorySwap == 0 { - if err := writeFile(dir, "memory.memsw.limit_in_bytes", strconv.FormatInt(d.c.Memory*2, 10)); err != nil { - return err - } - } - if d.c.MemorySwap > 0 { - if err := writeFile(dir, "memory.memsw.limit_in_bytes", strconv.FormatInt(d.c.MemorySwap, 10)); err != nil { - return err - } - } + if err := s.Set(dir, d.c); err != nil { + return err } + return nil } diff --git a/cgroups/systemd/apply_systemd.go b/cgroups/systemd/apply_systemd.go index 7e8fe0a0..f4358e1a 100644 --- a/cgroups/systemd/apply_systemd.go +++ b/cgroups/systemd/apply_systemd.go @@ -405,5 +405,5 @@ func joinCpuset(c *configs.Cgroup, pid int) error { s := &fs.CpusetGroup{} - return s.ApplyDir(path, c.CpusetCpus, c.CpusetMems, pid) + return s.ApplyDir(path, c, pid) } diff --git a/container.go b/container.go index 59a544b6..cebe8273 100644 --- a/container.go +++ b/container.go @@ -90,6 +90,14 @@ type Container interface { // Systemerror - System error. Stats() (*Stats, error) + // Set cgroup resources of container as configured + // + // We can use this to change resources when containers are running. + // + // errors: + // Systemerror - System error. + Set() error + // Start a process inside the container. Returns error if process fails to // start. You can track process lifecycle with passed Process structure. // diff --git a/container_linux.go b/container_linux.go index 3ea08db2..c238e62c 100644 --- a/container_linux.go +++ b/container_linux.go @@ -78,6 +78,12 @@ func (c *linuxContainer) Stats() (*Stats, error) { return stats, nil } +func (c *linuxContainer) Set() error { + c.m.Lock() + defer c.m.Unlock() + return c.cgroupManager.Set(c.config) +} + func (c *linuxContainer) Start(process *Process) error { c.m.Lock() defer c.m.Unlock()