Fix error messages for --cpus from daemon

This fix fixes error messages for `--cpus` from daemon.

When `docker run` takes `--cpus`, it will translate into NanoCPUs
and pass the value to daemon. The `NanoCPU` is not visible to the user.
The error message generated from daemon used 'NanoCPU' which may cause
some confusion to the user.

This fix fixes this issue by returning the error in CPUs instead.

This fix fixes 28456.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
This commit is contained in:
Yong Tang 2016-11-15 15:48:46 -08:00
parent b35973ffe8
commit d22ac2f3a0
3 changed files with 16 additions and 6 deletions

View file

@ -112,10 +112,11 @@ func getCPUResources(config containertypes.Resources) *specs.CPU {
}
if config.NanoCPUs > 0 {
// Use the default setting of 100ms, as is specified in:
// We set the highest value possible (1s), as is specified in:
// https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt
// cpu.cfs_period_us=100ms
period := uint64(100 * time.Millisecond / time.Microsecond)
// cpu.cfs_period_us=1s
// The purpose is to get the highest precision
period := uint64(1 * time.Second / time.Microsecond)
quota := uint64(config.NanoCPUs) * period / 1e9
cpu.Period = &period
cpu.Quota = &quota
@ -361,8 +362,15 @@ func verifyContainerResources(resources *containertypes.Resources, sysInfo *sysi
if resources.NanoCPUs > 0 && (!sysInfo.CPUCfsPeriod || !sysInfo.CPUCfsQuota) {
return warnings, fmt.Errorf("NanoCPUs can not be set, as your kernel does not support CPU cfs period/quota or the cgroup is not mounted")
}
// The highest precision we could get on Linux is 0.001, by setting
// cpu.cfs_period_us=1000ms
// cpu.cfs_quota=1ms
// See the following link for details:
// https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt
// Here we don't set the lower limit and it is up to the underlying platform (e.g., Linux) to return an error.
// The error message is 0.01 so that this is consistent with Windows
if resources.NanoCPUs < 0 || resources.NanoCPUs > int64(sysinfo.NumCPU())*1e9 {
return warnings, fmt.Errorf("Range of Nano CPUs is from 1 to %d", int64(sysinfo.NumCPU())*1e9)
return warnings, fmt.Errorf("Range of CPUs is from 0.01 to %d.00, as there are only %d CPUs available", sysinfo.NumCPU(), sysinfo.NumCPU())
}
if resources.CPUShares > 0 && !sysInfo.CPUShares {

View file

@ -129,8 +129,10 @@ func verifyContainerResources(resources *containertypes.Resources, isHyperv bool
if resources.NanoCPUs > 0 && resources.CPUShares > 0 {
return warnings, fmt.Errorf("conflicting options: Nano CPUs and CPU Shares cannot both be set")
}
// The precision we could get is 0.01, because on Windows we have to convert to CPUPercent.
// We don't set the lower limit here and it is up to the underlying platform (e.g., Windows) to return an error.
if resources.NanoCPUs < 0 || resources.NanoCPUs > int64(sysinfo.NumCPU())*1e9 {
return warnings, fmt.Errorf("range of Nano CPUs is from 1 to %d", int64(sysinfo.NumCPU())*1e9)
return warnings, fmt.Errorf("range of CPUs is from 0.01 to %d.00, as there are only %d CPUs available", sysinfo.NumCPU(), sysinfo.NumCPU())
}
if len(resources.BlkioDeviceReadBps) > 0 {

View file

@ -1577,7 +1577,7 @@ func (s *DockerSuite) TestRunWithNanoCPUs(c *check.C) {
file1 := "/sys/fs/cgroup/cpu/cpu.cfs_quota_us"
file2 := "/sys/fs/cgroup/cpu/cpu.cfs_period_us"
out, _ := dockerCmd(c, "run", "--cpus", "0.5", "--name", "test", "busybox", "sh", "-c", fmt.Sprintf("cat %s && cat %s", file1, file2))
c.Assert(strings.TrimSpace(out), checker.Equals, "50000\n100000")
c.Assert(strings.TrimSpace(out), checker.Equals, "500000\n1000000")
out = inspectField(c, "test", "HostConfig.NanoCpus")
c.Assert(out, checker.Equals, "5e+08", check.Commentf("setting the Nano CPUs failed"))