From 8a4629f7b57333365fa8b0e56357680adf7c80c8 Mon Sep 17 00:00:00 2001 From: Aleksa Sarai Date: Thu, 22 Nov 2018 10:22:36 +1100 Subject: [PATCH] cgroups: nokmem: error out on explicitly-set kmemcg limits When built with nokmem we explicitly are disabling support for kmemcg, but it is a strict specification requirement that if we cannot fulfil an aspect of the container configuration that we error out. Completely ignoring explicitly-requested kmemcg limits with nokmem would undoubtably lead to problems. Fixes: 6a2c15596845 ("libcontainer: ability to compile without kmem") Signed-off-by: Aleksa Sarai --- libcontainer/cgroups/fs/kmem.go | 13 ++++++++++--- libcontainer/cgroups/fs/kmem_disabled.go | 6 +++++- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/libcontainer/cgroups/fs/kmem.go b/libcontainer/cgroups/fs/kmem.go index 8df73777..69b5a194 100644 --- a/libcontainer/cgroups/fs/kmem.go +++ b/libcontainer/cgroups/fs/kmem.go @@ -3,6 +3,7 @@ package fs import ( + "errors" "fmt" "io/ioutil" "os" @@ -17,7 +18,12 @@ import ( const cgroupKernelMemoryLimit = "memory.kmem.limit_in_bytes" func EnableKernelMemoryAccounting(path string) error { - // Check if kernel memory is enabled + // Ensure that kernel memory is available in this kernel build. If it + // isn't, we just ignore it because EnableKernelMemoryAccounting is + // automatically called for all memory limits. + if !cgroups.PathExists(filepath.Join(path, cgroupKernelMemoryLimit)) { + return nil + } // We have to limit the kernel memory here as it won't be accounted at all // until a limit is set on the cgroup and limit cannot be set once the // cgroup has children, or if there are already tasks in the cgroup. @@ -34,8 +40,9 @@ func setKernelMemory(path string, kernelMemoryLimit int64) error { return fmt.Errorf("no such directory for %s", cgroupKernelMemoryLimit) } if !cgroups.PathExists(filepath.Join(path, cgroupKernelMemoryLimit)) { - // kernel memory is not enabled on the system so we should do nothing - return nil + // We have specifically been asked to set a kmem limit. If the kernel + // doesn't support it we *must* error out. + return errors.New("kernel memory accounting not supported by this kernel") } if err := ioutil.WriteFile(filepath.Join(path, cgroupKernelMemoryLimit), []byte(strconv.FormatInt(kernelMemoryLimit, 10)), 0700); err != nil { // Check if the error number returned by the syscall is "EBUSY" diff --git a/libcontainer/cgroups/fs/kmem_disabled.go b/libcontainer/cgroups/fs/kmem_disabled.go index 12253b6b..ac290fd7 100644 --- a/libcontainer/cgroups/fs/kmem_disabled.go +++ b/libcontainer/cgroups/fs/kmem_disabled.go @@ -2,10 +2,14 @@ package fs +import ( + "errors" +) + func EnableKernelMemoryAccounting(path string) error { return nil } func setKernelMemory(path string, kernelMemoryLimit int64) error { - return nil + return errors.New("kernel memory accounting disabled in this runc build") }