1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Separating cgroup Memory and MemoryReservation.

This will allow for these to be set independently. Keep the current Docker behavior where Memory and MemoryReservation are set to the value of Memory.

Docker-DCO-1.1-Signed-off-by: Victor Marmol <vmarmol@google.com> (github: vmarmol)
This commit is contained in:
Victor Marmol 2014-04-24 05:11:43 +00:00
parent 4ed165210f
commit f188b9f623
6 changed files with 54 additions and 15 deletions

View file

@ -21,10 +21,11 @@ var actions = map[string]Action{
"net.join": joinNetNamespace, // join another containers net namespace "net.join": joinNetNamespace, // join another containers net namespace
"cgroups.cpu_shares": cpuShares, // set the cpu shares "cgroups.cpu_shares": cpuShares, // set the cpu shares
"cgroups.memory": memory, // set the memory limit "cgroups.memory": memory, // set the memory limit
"cgroups.memory_swap": memorySwap, // set the memory swap limit "cgroups.memory_reservation": memoryReservation, // set the memory reservation
"cgroups.cpuset.cpus": cpusetCpus, // set the cpus used "cgroups.memory_swap": memorySwap, // set the memory swap limit
"cgroups.cpuset.cpus": cpusetCpus, // set the cpus used
"apparmor_profile": apparmorProfile, // set the apparmor profile to apply "apparmor_profile": apparmorProfile, // set the apparmor profile to apply
@ -70,6 +71,19 @@ func memory(container *libcontainer.Container, context interface{}, value string
return nil return nil
} }
func memoryReservation(container *libcontainer.Container, context interface{}, value string) error {
if container.Cgroups == nil {
return fmt.Errorf("cannot set cgroups when they are disabled")
}
v, err := utils.RAMInBytes(value)
if err != nil {
return err
}
container.Cgroups.MemoryReservation = v
return nil
}
func memorySwap(container *libcontainer.Container, context interface{}, value string) error { func memorySwap(container *libcontainer.Container, context interface{}, value string) error {
if container.Cgroups == nil { if container.Cgroups == nil {
return fmt.Errorf("cannot set cgroups when they are disabled") return fmt.Errorf("cannot set cgroups when they are disabled")

View file

@ -93,7 +93,7 @@ func TestCpuShares(t *testing.T) {
} }
} }
func TestCgroupMemory(t *testing.T) { func TestMemory(t *testing.T) {
var ( var (
container = template.New() container = template.New()
opts = []string{ opts = []string{
@ -109,6 +109,22 @@ func TestCgroupMemory(t *testing.T) {
} }
} }
func TestMemoryReservation(t *testing.T) {
var (
container = template.New()
opts = []string{
"cgroups.memory_reservation=500m",
}
)
if err := ParseConfiguration(container, nil, opts); err != nil {
t.Fatal(err)
}
if expected := int64(500 * 1024 * 1024); container.Cgroups.MemoryReservation != expected {
t.Fatalf("expected memory reservation %d got %d", expected, container.Cgroups.MemoryReservation)
}
}
func TestAddCap(t *testing.T) { func TestAddCap(t *testing.T) {
var ( var (
container = template.New() container = template.New()

View file

@ -91,6 +91,7 @@ func (d *driver) setupCgroups(container *libcontainer.Container, c *execdriver.C
if c.Resources != nil { if c.Resources != nil {
container.Cgroups.CpuShares = c.Resources.CpuShares container.Cgroups.CpuShares = c.Resources.CpuShares
container.Cgroups.Memory = c.Resources.Memory container.Cgroups.Memory = c.Resources.Memory
container.Cgroups.MemoryReservation = c.Resources.Memory
container.Cgroups.MemorySwap = c.Resources.MemorySwap container.Cgroups.MemorySwap = c.Resources.MemorySwap
} }
return nil return nil

View file

@ -12,13 +12,14 @@ type Cgroup struct {
Name string `json:"name,omitempty"` Name string `json:"name,omitempty"`
Parent string `json:"parent,omitempty"` Parent string `json:"parent,omitempty"`
DeviceAccess bool `json:"device_access,omitempty"` // name of parent cgroup or slice DeviceAccess bool `json:"device_access,omitempty"` // name of parent cgroup or slice
Memory int64 `json:"memory,omitempty"` // Memory limit (in bytes) Memory int64 `json:"memory,omitempty"` // Memory limit (in bytes)
MemorySwap int64 `json:"memory_swap,omitempty"` // Total memory usage (memory + swap); set `-1' to disable swap MemoryReservation int64 `json:"memory_reservation,omitempty"` // Memory reservation or soft_limit (in bytes)
CpuShares int64 `json:"cpu_shares,omitempty"` // CPU shares (relative weight vs. other containers) MemorySwap int64 `json:"memory_swap,omitempty"` // Total memory usage (memory + swap); set `-1' to disable swap
CpuQuota int64 `json:"cpu_quota,omitempty"` // CPU hardcap limit (in usecs). Allowed cpu time in a given period. CpuShares int64 `json:"cpu_shares,omitempty"` // CPU shares (relative weight vs. other containers)
CpuPeriod int64 `json:"cpu_period,omitempty"` // CPU period to be used for hardcapping (in usecs). 0 to use system default. CpuQuota int64 `json:"cpu_quota,omitempty"` // CPU hardcap limit (in usecs). Allowed cpu time in a given period.
CpusetCpus string `json:"cpuset_cpus,omitempty"` // CPU to use CpuPeriod int64 `json:"cpu_period,omitempty"` // CPU period to be used for hardcapping (in usecs). 0 to use system default.
CpusetCpus string `json:"cpuset_cpus,omitempty"` // CPU to use
UnitProperties [][2]string `json:"unit_properties,omitempty"` // systemd unit properties UnitProperties [][2]string `json:"unit_properties,omitempty"` // systemd unit properties
} }

View file

@ -13,7 +13,7 @@ type memoryGroup struct {
func (s *memoryGroup) Set(d *data) error { func (s *memoryGroup) Set(d *data) error {
dir, err := d.join("memory") dir, err := d.join("memory")
// only return an error for memory if it was not specified // only return an error for memory if it was not specified
if err != nil && (d.c.Memory != 0 || d.c.MemorySwap != 0) { if err != nil && (d.c.Memory != 0 || d.c.MemoryReservation != 0 || d.c.MemorySwap != 0) {
return err return err
} }
defer func() { defer func() {
@ -22,12 +22,15 @@ func (s *memoryGroup) Set(d *data) error {
} }
}() }()
if d.c.Memory != 0 || d.c.MemorySwap != 0 { // 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 d.c.Memory != 0 {
if err := writeFile(dir, "memory.limit_in_bytes", strconv.FormatInt(d.c.Memory, 10)); err != nil { if err := writeFile(dir, "memory.limit_in_bytes", strconv.FormatInt(d.c.Memory, 10)); err != nil {
return err return err
} }
if err := writeFile(dir, "memory.soft_limit_in_bytes", strconv.FormatInt(d.c.Memory, 10)); err != nil { }
if d.c.MemoryReservation != 0 {
if err := writeFile(dir, "memory.soft_limit_in_bytes", strconv.FormatInt(d.c.MemoryReservation, 10)); err != nil {
return err return err
} }
} }

View file

@ -121,6 +121,10 @@ func Apply(c *cgroups.Cgroup, pid int) (cgroups.ActiveCgroup, error) {
properties = append(properties, properties = append(properties,
systemd1.Property{"MemoryLimit", dbus.MakeVariant(uint64(c.Memory))}) systemd1.Property{"MemoryLimit", dbus.MakeVariant(uint64(c.Memory))})
} }
if c.MemoryReservation != 0 {
properties = append(properties,
systemd1.Property{"MemorySoftLimit", dbus.MakeVariant(uint64(c.MemoryReservation))})
}
// TODO: MemorySwap not available in systemd // TODO: MemorySwap not available in systemd
if c.CpuShares != 0 { if c.CpuShares != 0 {