diff --git a/daemon/mgr/container_utils.go b/daemon/mgr/container_utils.go index b8629a0b1..2370eebc8 100644 --- a/daemon/mgr/container_utils.go +++ b/daemon/mgr/container_utils.go @@ -228,6 +228,8 @@ func parsePSOutput(output []byte, pids []int) (*types.ContainerProcessList, erro // validateConfig validates container config func validateConfig(config *types.ContainerCreateConfig) ([]string, error) { + amendResource(&config.HostConfig.Resources) + // validates container hostconfig warnings := make([]string, 0) warns, err := validateResource(&config.HostConfig.Resources) @@ -262,6 +264,9 @@ func validateResource(r *types.Resources) ([]string, error) { warnings = append(warnings, warn) r.MemorySwap = 0 } + if r.Memory > 0 && r.MemorySwap > 0 && r.MemorySwap < 2*r.Memory { + warnings = append(warnings, "You should typically size your swap space to approximately 2x main memory for systems with less than 2GB of RAM") + } if r.MemorySwappiness != nil && !cgroupInfo.Memory.MemorySwappiness { warn := "Current Kernel does not support memory swappiness , discard --memory-swappiness" logrus.Warn(warn) @@ -362,3 +367,10 @@ func validateResource(r *types.Resources) ([]string, error) { return warnings, nil } + +// amendResource modify resource to correct setting. +func amendResource(r *types.Resources) { + if r.Memory > 0 && r.MemorySwap == 0 { + r.MemorySwap = 2 * r.Memory + } +} diff --git a/daemon/mgr/spec_linux.go b/daemon/mgr/spec_linux.go index 999c786b0..b0cdae16c 100644 --- a/daemon/mgr/spec_linux.go +++ b/daemon/mgr/spec_linux.go @@ -251,7 +251,7 @@ func setupCPU(ctx context.Context, r types.Resources, s *specs.Spec) { // setupResource creates linux memory resource spec. func setupMemory(ctx context.Context, r types.Resources, s *specs.Spec) { memory := &specs.LinuxMemory{} - if r.Memory != 0 { + if r.Memory > 0 { v := r.Memory memory.Limit = &v } diff --git a/test/cli_run_memory_test.go b/test/cli_run_memory_test.go index f42f2d0ad..03dea4cbb 100644 --- a/test/cli_run_memory_test.go +++ b/test/cli_run_memory_test.go @@ -58,6 +58,30 @@ func (suite *PouchRunMemorySuite) TestRunWithMemoryswap(c *check.C) { "/sys/fs/cgroup/memory/default/%s/memory.memsw.limit_in_bytes", containerID) checkFileContains(c, path, "209715200") + + // test memory swap should be 2x memory if not specify it. + cname = "TestRunWithMemoryswap2x" + res = command.PouchRun("run", "-d", "-m", "10m", + "--name", cname, busyboxImage, "sleep", "10000") + defer DelContainerForceMultyTime(c, cname) + res.Assert(c, icmd.Success) + + // test if the value is in inspect result + res = command.PouchRun("inspect", cname) + res.Assert(c, icmd.Success) + + result = []types.ContainerJSON{} + if err := json.Unmarshal([]byte(res.Stdout()), &result); err != nil { + c.Errorf("failed to decode inspect output: %v", err) + } + c.Assert(result[0].HostConfig.MemorySwap, check.Equals, int64(20971520)) + + // test if cgroup has record the real value + containerID = result[0].ID + path = fmt.Sprintf( + "/sys/fs/cgroup/memory/default/%s/memory.memsw.limit_in_bytes", + containerID) + checkFileContains(c, path, "20971520") } // TestRunWithMemoryswappiness is to verify the valid running container