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

Merge pull request #25105 from hqhq/fix_kmem_test

Fix TestUpdateKernelMemoryUninitialized on new kernel version
This commit is contained in:
Sebastiaan van Stijn 2016-08-02 17:15:53 +02:00 committed by GitHub
commit b47df1ddbe
5 changed files with 58 additions and 35 deletions

View file

@ -194,17 +194,6 @@ func getBlkioThrottleDevices(devs []*blkiodev.ThrottleDevice) ([]specs.ThrottleD
return throttleDevices, nil return throttleDevices, nil
} }
func checkKernelVersion(k, major, minor int) bool {
if v, err := kernel.GetKernelVersion(); err != nil {
logrus.Warnf("error getting kernel version: %s", err)
} else {
if kernel.CompareKernelVersion(*v, kernel.VersionInfo{Kernel: k, Major: major, Minor: minor}) < 0 {
return false
}
}
return true
}
func checkKernel() error { func checkKernel() error {
// Check for unsupported kernel versions // Check for unsupported kernel versions
// FIXME: it would be cleaner to not test for specific versions, but rather // FIXME: it would be cleaner to not test for specific versions, but rather
@ -215,7 +204,7 @@ func checkKernel() error {
// For details see https://github.com/docker/docker/issues/407 // For details see https://github.com/docker/docker/issues/407
// Docker 1.11 and above doesn't actually run on kernels older than 3.4, // Docker 1.11 and above doesn't actually run on kernels older than 3.4,
// due to containerd-shim usage of PR_SET_CHILD_SUBREAPER (introduced in 3.4). // due to containerd-shim usage of PR_SET_CHILD_SUBREAPER (introduced in 3.4).
if !checkKernelVersion(3, 10, 0) { if !kernel.CheckKernelVersion(3, 10, 0) {
v, _ := kernel.GetKernelVersion() v, _ := kernel.GetKernelVersion()
if os.Getenv("DOCKER_NOWARN_KERNEL_VERSION") == "" { if os.Getenv("DOCKER_NOWARN_KERNEL_VERSION") == "" {
logrus.Fatalf("Your Linux kernel version %s is not supported for running docker. Please upgrade your kernel to 3.10.0 or newer.", v.String()) logrus.Fatalf("Your Linux kernel version %s is not supported for running docker. Please upgrade your kernel to 3.10.0 or newer.", v.String())
@ -317,7 +306,7 @@ func verifyContainerResources(resources *containertypes.Resources, sysInfo *sysi
if resources.KernelMemory > 0 && resources.KernelMemory < linuxMinMemory { if resources.KernelMemory > 0 && resources.KernelMemory < linuxMinMemory {
return warnings, fmt.Errorf("Minimum kernel memory limit allowed is 4MB") return warnings, fmt.Errorf("Minimum kernel memory limit allowed is 4MB")
} }
if resources.KernelMemory > 0 && !checkKernelVersion(4, 0, 0) { if resources.KernelMemory > 0 && !kernel.CheckKernelVersion(4, 0, 0) {
warnings = append(warnings, "You specified a kernel memory limit on a kernel older than 4.0. Kernel memory limits are experimental on older kernels, it won't work as expected and can cause your system to be unstable.") warnings = append(warnings, "You specified a kernel memory limit on a kernel older than 4.0. Kernel memory limits are experimental on older kernels, it won't work as expected and can cause your system to be unstable.")
logrus.Warn("You specified a kernel memory limit on a kernel older than 4.0. Kernel memory limits are experimental on older kernels, it won't work as expected and can cause your system to be unstable.") logrus.Warn("You specified a kernel memory limit on a kernel older than 4.0. Kernel memory limits are experimental on older kernels, it won't work as expected and can cause your system to be unstable.")
} }

View file

@ -37,9 +37,9 @@ limits on a single container or on many. To specify more than one container,
provide space-separated list of container names or IDs. provide space-separated list of container names or IDs.
With the exception of the `--kernel-memory` option, you can specify these With the exception of the `--kernel-memory` option, you can specify these
options on a running or a stopped container. You can only update options on a running or a stopped container. On kernel version older than
`--kernel-memory` on a stopped container or on a running container with 4.6, you can only update `--kernel-memory` on a stopped container or on
kernel memory initialized. a running container with kernel memory initialized.
## EXAMPLES ## EXAMPLES
@ -66,9 +66,10 @@ $ docker update --cpu-shares 512 -m 300M abebf7571666 hopeful_morse
### Update a container's kernel memory constraints ### Update a container's kernel memory constraints
You can update a container's kernel memory limit using the `--kernel-memory` You can update a container's kernel memory limit using the `--kernel-memory`
option. This option can be updated on a running container only if the container option. On kernel version older than 4.6, this option can be updated on a
was started with `--kernel-memory`. If the container was started *without* running container only if the container was started with `--kernel-memory`.
`--kernel-memory` you need to stop the container before updating kernel memory. If the container was started *without* `--kernel-memory` you need to stop
the container before updating kernel memory.
For example, if you started a container with this command: For example, if you started a container with this command:
@ -92,6 +93,8 @@ Update kernel memory of running container `test2` will fail. You need to stop
the container before updating the `--kernel-memory` setting. The next time you the container before updating the `--kernel-memory` setting. The next time you
start it, the container uses the new value. start it, the container uses the new value.
Kernel version newer than (include) 4.6 does not have this limitation, you
can use `--kernel-memory` the same way as other options.
### Update a container's restart policy ### Update a container's restart policy

View file

@ -8,6 +8,7 @@ import (
"strings" "strings"
"github.com/docker/docker/pkg/integration/checker" "github.com/docker/docker/pkg/integration/checker"
"github.com/docker/docker/pkg/parsers/kernel"
"github.com/docker/engine-api/types" "github.com/docker/engine-api/types"
"github.com/go-check/check" "github.com/go-check/check"
) )
@ -132,26 +133,36 @@ func (s *DockerSuite) TestUpdateKernelMemory(c *check.C) {
func (s *DockerSuite) TestUpdateKernelMemoryUninitialized(c *check.C) { func (s *DockerSuite) TestUpdateKernelMemoryUninitialized(c *check.C) {
testRequires(c, DaemonIsLinux, kernelMemorySupport) testRequires(c, DaemonIsLinux, kernelMemorySupport)
isNewKernel := kernel.CheckKernelVersion(4, 6, 0)
name := "test-update-container" name := "test-update-container"
dockerCmd(c, "run", "-d", "--name", name, "busybox", "top") dockerCmd(c, "run", "-d", "--name", name, "busybox", "top")
_, _, err := dockerCmdWithError("update", "--kernel-memory", "100M", name) _, _, err := dockerCmdWithError("update", "--kernel-memory", "100M", name)
// Update kernel memory to a running container without kernel memory initialized is not allowed. // Update kernel memory to a running container without kernel memory initialized
c.Assert(err, check.NotNil) // is not allowed before kernel version 4.6.
if !isNewKernel {
c.Assert(err, check.NotNil)
} else {
c.Assert(err, check.IsNil)
}
dockerCmd(c, "pause", name) dockerCmd(c, "pause", name)
_, _, err = dockerCmdWithError("update", "--kernel-memory", "100M", name) _, _, err = dockerCmdWithError("update", "--kernel-memory", "200M", name)
c.Assert(err, check.NotNil) if !isNewKernel {
c.Assert(err, check.NotNil)
} else {
c.Assert(err, check.IsNil)
}
dockerCmd(c, "unpause", name) dockerCmd(c, "unpause", name)
dockerCmd(c, "stop", name) dockerCmd(c, "stop", name)
dockerCmd(c, "update", "--kernel-memory", "100M", name) dockerCmd(c, "update", "--kernel-memory", "300M", name)
dockerCmd(c, "start", name) dockerCmd(c, "start", name)
c.Assert(inspectField(c, name, "HostConfig.KernelMemory"), checker.Equals, "104857600") c.Assert(inspectField(c, name, "HostConfig.KernelMemory"), checker.Equals, "314572800")
file := "/sys/fs/cgroup/memory/memory.kmem.limit_in_bytes" file := "/sys/fs/cgroup/memory/memory.kmem.limit_in_bytes"
out, _ := dockerCmd(c, "exec", name, "cat", file) out, _ := dockerCmd(c, "exec", name, "cat", file)
c.Assert(strings.TrimSpace(out), checker.Equals, "104857600") c.Assert(strings.TrimSpace(out), checker.Equals, "314572800")
} }
func (s *DockerSuite) TestUpdateSwapMemoryOnly(c *check.C) { func (s *DockerSuite) TestUpdateSwapMemoryOnly(c *check.C) {

View file

@ -29,9 +29,9 @@ limits on a single container or on many. To specify more than one container,
provide space-separated list of container names or IDs. provide space-separated list of container names or IDs.
With the exception of the **--kernel-memory** option, you can specify these With the exception of the **--kernel-memory** option, you can specify these
options on a running or a stopped container. You can only update options on a running or a stopped container. On kernel version older than
**--kernel-memory** on a stopped container or on a running container with 4.6, You can only update **--kernel-memory** on a stopped container or on
kernel memory initialized. a running container with kernel memory initialized.
# OPTIONS # OPTIONS
@ -59,9 +59,10 @@ kernel memory initialized.
**--kernel-memory**="" **--kernel-memory**=""
Kernel memory limit (format: `<number>[<unit>]`, where unit = b, k, m or g) Kernel memory limit (format: `<number>[<unit>]`, where unit = b, k, m or g)
Note that you can not update kernel memory on a running container if the container Note that on kernel version older than 4.6, you can not update kernel memory on
is started without kernel memory initialized, in this case, it can only be updated a running container if the container is started without kernel memory initialized,
after it's stopped. The new setting takes effect when the container is started. in this case, it can only be updated after it's stopped. The new setting takes
effect when the container is started.
**-m**, **--memory**="" **-m**, **--memory**=""
Memory limit (format: <number><optional unit>, where unit = b, k, m or g) Memory limit (format: <number><optional unit>, where unit = b, k, m or g)
@ -100,9 +101,10 @@ $ docker update --cpu-shares 512 -m 300M abebf7571666 hopeful_morse
### Update a container's kernel memory constraints ### Update a container's kernel memory constraints
You can update a container's kernel memory limit using the **--kernel-memory** You can update a container's kernel memory limit using the **--kernel-memory**
option. This option can be updated on a running container only if the container option. On kernel version older than 4.6, this option can be updated on a
was started with **--kernel-memory**. If the container was started *without* running container only if the container was started with **--kernel-memory**.
**--kernel-memory** you need to stop the container before updating kernel memory. If the container was started *without* **--kernel-memory** you need to stop
the container before updating kernel memory.
For example, if you started a container with this command: For example, if you started a container with this command:
@ -126,6 +128,9 @@ Update kernel memory of running container `test2` will fail. You need to stop
the container before updating the **--kernel-memory** setting. The next time you the container before updating the **--kernel-memory** setting. The next time you
start it, the container uses the new value. start it, the container uses the new value.
Kernel version newer than (include) 4.6 does not have this limitation, you
can use `--kernel-memory` the same way as other options.
### Update a container's restart policy ### Update a container's restart policy
You can change a container's restart policy on a running container. The new You can change a container's restart policy on a running container. The new

View file

@ -6,6 +6,8 @@ package kernel
import ( import (
"bytes" "bytes"
"github.com/Sirupsen/logrus"
) )
// GetKernelVersion gets the current kernel version. // GetKernelVersion gets the current kernel version.
@ -28,3 +30,16 @@ func GetKernelVersion() (*VersionInfo, error) {
return ParseRelease(string(release)) return ParseRelease(string(release))
} }
// CheckKernelVersion checks if current kernel is newer than (or equal to)
// the given version.
func CheckKernelVersion(k, major, minor int) bool {
if v, err := GetKernelVersion(); err != nil {
logrus.Warnf("error getting kernel version: %s", err)
} else {
if CompareKernelVersion(*v, VersionInfo{Kernel: k, Major: major, Minor: minor}) < 0 {
return false
}
}
return true
}