diff --git a/daemon/daemon_unix.go b/daemon/daemon_unix.go index 587db7f6e7..12e0019a9b 100644 --- a/daemon/daemon_unix.go +++ b/daemon/daemon_unix.go @@ -194,17 +194,6 @@ func getBlkioThrottleDevices(devs []*blkiodev.ThrottleDevice) ([]specs.ThrottleD 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 { // Check for unsupported kernel versions // 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 // 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). - if !checkKernelVersion(3, 10, 0) { + if !kernel.CheckKernelVersion(3, 10, 0) { v, _ := kernel.GetKernelVersion() 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()) @@ -317,7 +306,7 @@ func verifyContainerResources(resources *containertypes.Resources, sysInfo *sysi if resources.KernelMemory > 0 && resources.KernelMemory < linuxMinMemory { 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.") 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.") } diff --git a/integration-cli/docker_cli_update_unix_test.go b/integration-cli/docker_cli_update_unix_test.go index 0c8bc1e6ca..ee1b2a3137 100644 --- a/integration-cli/docker_cli_update_unix_test.go +++ b/integration-cli/docker_cli_update_unix_test.go @@ -8,6 +8,7 @@ import ( "strings" "github.com/docker/docker/pkg/integration/checker" + "github.com/docker/docker/pkg/parsers/kernel" "github.com/docker/engine-api/types" "github.com/go-check/check" ) @@ -132,26 +133,36 @@ func (s *DockerSuite) TestUpdateKernelMemory(c *check.C) { func (s *DockerSuite) TestUpdateKernelMemoryUninitialized(c *check.C) { testRequires(c, DaemonIsLinux, kernelMemorySupport) + isNewKernel := kernel.CheckKernelVersion(4, 6, 0) name := "test-update-container" dockerCmd(c, "run", "-d", "--name", name, "busybox", "top") _, _, err := dockerCmdWithError("update", "--kernel-memory", "100M", name) - // Update kernel memory to a running container without kernel memory initialized is not allowed. - c.Assert(err, check.NotNil) + // Update kernel memory to a running container without kernel memory initialized + // 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) - _, _, err = dockerCmdWithError("update", "--kernel-memory", "100M", name) - c.Assert(err, check.NotNil) + _, _, err = dockerCmdWithError("update", "--kernel-memory", "200M", name) + if !isNewKernel { + c.Assert(err, check.NotNil) + } else { + c.Assert(err, check.IsNil) + } dockerCmd(c, "unpause", name) dockerCmd(c, "stop", name) - dockerCmd(c, "update", "--kernel-memory", "100M", name) + dockerCmd(c, "update", "--kernel-memory", "300M", 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" 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) { diff --git a/pkg/parsers/kernel/kernel_unix.go b/pkg/parsers/kernel/kernel_unix.go index 54a89d28c6..744d5e1f83 100644 --- a/pkg/parsers/kernel/kernel_unix.go +++ b/pkg/parsers/kernel/kernel_unix.go @@ -6,6 +6,8 @@ package kernel import ( "bytes" + + "github.com/Sirupsen/logrus" ) // GetKernelVersion gets the current kernel version. @@ -28,3 +30,16 @@ func GetKernelVersion() (*VersionInfo, error) { 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 +}