mirror of https://github.com/docker/docs.git
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:
parent
4ed165210f
commit
f188b9f623
|
@ -23,6 +23,7 @@ var actions = map[string]Action{
|
||||||
|
|
||||||
"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_reservation": memoryReservation, // set the memory reservation
|
||||||
"cgroups.memory_swap": memorySwap, // set the memory swap limit
|
"cgroups.memory_swap": memorySwap, // set the memory swap limit
|
||||||
"cgroups.cpuset.cpus": cpusetCpus, // set the cpus used
|
"cgroups.cpuset.cpus": cpusetCpus, // set the cpus used
|
||||||
|
|
||||||
|
@ -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")
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -14,6 +14,7 @@ type Cgroup struct {
|
||||||
|
|
||||||
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)
|
||||||
|
MemoryReservation int64 `json:"memory_reservation,omitempty"` // Memory reservation or soft_limit (in bytes)
|
||||||
MemorySwap int64 `json:"memory_swap,omitempty"` // Total memory usage (memory + swap); set `-1' to disable swap
|
MemorySwap int64 `json:"memory_swap,omitempty"` // Total memory usage (memory + swap); set `-1' to disable swap
|
||||||
CpuShares int64 `json:"cpu_shares,omitempty"` // CPU shares (relative weight vs. other containers)
|
CpuShares int64 `json:"cpu_shares,omitempty"` // CPU shares (relative weight vs. other containers)
|
||||||
CpuQuota int64 `json:"cpu_quota,omitempty"` // CPU hardcap limit (in usecs). Allowed cpu time in a given period.
|
CpuQuota int64 `json:"cpu_quota,omitempty"` // CPU hardcap limit (in usecs). Allowed cpu time in a given period.
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in New Issue