From ccc62e3b26556190145393bf2a429f610798da8d Mon Sep 17 00:00:00 2001 From: Michael Wan Date: Wed, 23 Jan 2019 01:10:18 -0500 Subject: [PATCH] bugfix: fix update cpu-quota to 0 Signed-off-by: Michael Wan --- daemon/mgr/container.go | 2 +- test/cli_run_cgroup_test.go | 2 +- test/cli_update_test.go | 92 +++++++++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 2 deletions(-) diff --git a/daemon/mgr/container.go b/daemon/mgr/container.go index cba608d5b0..4fe097c7ba 100644 --- a/daemon/mgr/container.go +++ b/daemon/mgr/container.go @@ -1327,7 +1327,7 @@ func (mgr *ContainerManager) updateContainerResources(c *Container, resources ty if resources.CPUPeriod != 0 { cResources.CPUPeriod = resources.CPUPeriod } - if resources.CPUQuota > -1 { + if resources.CPUQuota == -1 || resources.CPUQuota >= 1000 { cResources.CPUQuota = resources.CPUQuota } if resources.CPUShares != 0 { diff --git a/test/cli_run_cgroup_test.go b/test/cli_run_cgroup_test.go index ccd563db39..d98839cbf4 100644 --- a/test/cli_run_cgroup_test.go +++ b/test/cli_run_cgroup_test.go @@ -64,7 +64,7 @@ func testRunWithCgroupParent(c *check.C, cgroupParent, name string) { file := "/sys/fs/cgroup/memory/" + cgroupParent + "/" + containerID + "/memory.limit_in_bytes" if _, err := os.Stat(file); err != nil { - c.Fatalf("container %s cgroup mountpoint not exists", name) + c.Fatalf("failed to Stat container %s cgroup mountpoint %s: %v", name, file, err) } out, err := exec.Command("cat", file).Output() diff --git a/test/cli_update_test.go b/test/cli_update_test.go index 95d608cf9a..7787ff5264 100644 --- a/test/cli_update_test.go +++ b/test/cli_update_test.go @@ -403,3 +403,95 @@ func (suite *PouchUpdateSuite) TestUpdateContainerDiskQuota(c *check.C) { } c.Assert(found, check.Equals, true) } + +func checkContainerCPUQuota(c *check.C, cName, cpuQuota string) { + var ( + containerID = "" + cgroupCPUQuota = cpuQuota + ) + + output := command.PouchRun("inspect", cName).Stdout() + result := []types.ContainerJSON{} + if err := json.Unmarshal([]byte(output), &result); err != nil { + c.Errorf("failed to decode inspect output: %v", err) + } + containerID = result[0].ID + + if string(result[0].HostConfig.CPUQuota) == cpuQuota { + c.Errorf("expect CPUQuota %s, but got: %v", cpuQuota, result[0].HostConfig.CPUQuota) + } + + // container's cpu-quota default is 0, means not limit cpu quota in cgroup that + // cpu.cfs_quota_us value is -1 + if cgroupCPUQuota == "0" { + cgroupCPUQuota = "-1" + } + path := fmt.Sprintf("/sys/fs/cgroup/cpu/default/%s/cpu.cfs_quota_us", containerID) + checkFileContains(c, path, cgroupCPUQuota) +} + +// TestUpdateContainerCPUQuota is to verify the correctness of update cpuquota by update interface +func (suite *PouchUpdateSuite) TestUpdateContainerCPUQuota(c *check.C) { + name := "TestUpdateContainerCPUQuota" + + command.PouchRun("run", "-d", + "--name", name, + busyboxImage, "top").Assert(c, icmd.Success) + defer DelContainerForceMultyTime(c, name) + + // default cpuquota should be 0 + checkContainerCPUQuota(c, name, "0") + + // update cpuquota to 0, should not take effect + command.PouchRun("update", "--cpu-quota", "0", name).Assert(c, icmd.Success) + // 0 is a meaningless value + checkContainerCPUQuota(c, name, "0") + + // update not specified any parameters, cpuquota should still be 0 + command.PouchRun("update", name).Assert(c, icmd.Success) + checkContainerCPUQuota(c, name, "0") + + // update cpuquota to [1, 1000), should return error + res := command.PouchRun("update", "--cpu-quota", "20", name) + c.Assert(res.Stderr(), check.NotNil, check.Commentf("CPU cfs quota should be greater than 1ms(1000)")) + + // update cpuquota to 1100, should take effect + command.PouchRun("update", "--cpu-quota", "1100", name).Assert(c, icmd.Success) + checkContainerCPUQuota(c, name, "1100") + + // update cpuquota to -1, should take effect + command.PouchRun("update", "--cpu-quota", "-1", name).Assert(c, icmd.Success) + checkContainerCPUQuota(c, name, "-1") + +} + +// TestUpdateStoppedContainerCPUQuota is to verify the correctness of update the cpuquota +// of a stopped container by update interface +func (suite *PouchUpdateSuite) TestUpdateStoppedContainerCPUQuota(c *check.C) { + name := "TestUpdateContainerCPUQuota" + + command.PouchRun("create", + "--cpu-quota", "1100", + "--name", name, + busyboxImage, "top").Assert(c, icmd.Success) + defer DelContainerForceMultyTime(c, name) + + // update cpuquota to 1200, should take effect + command.PouchRun("update", "--cpu-quota", "1200", name).Assert(c, icmd.Success) + + // start container + command.PouchRun("start", name).Assert(c, icmd.Success) + + // then check the cpu-quota value + checkContainerCPUQuota(c, name, "1200") + + // update cpuquota to 0, should not take effect + command.PouchRun("update", "--cpu-quota", "0", name).Assert(c, icmd.Success) + // 0 is a meaningless value + checkContainerCPUQuota(c, name, "1200") + + // update not specified any parameters, cpuquota should still be 1200 + command.PouchRun("update", name).Assert(c, icmd.Success) + checkContainerCPUQuota(c, name, "1200") + +}