-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
libcontainer: ability to compile without kmem
Commit fe898e7 (PR #1350) enables kernel memory accounting for all cgroups created by libcontainer -- even if kmem limit is not configured. Kernel memory accounting is known to be broken in some kernels, specifically the ones from RHEL7 (including RHEL 7.5). Those kernels do not support kernel memory reclaim, and are prone to oopses. Unconditionally enabling kmem acct on such kernels lead to bugs, such as * #1725 * kubernetes/kubernetes#61937 * moby/moby#29638 This commit gives a way to compile runc without kernel memory setting support. To do so, use something like make BUILDTAGS="seccomp nokmem" Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
- Loading branch information
Showing
4 changed files
with
69 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
// +build linux,!nokmem | ||
|
||
package fs | ||
|
||
import ( | ||
"fmt" | ||
"io/ioutil" | ||
"os" | ||
"path/filepath" | ||
"strconv" | ||
"syscall" // for Errno type only | ||
|
||
"github.com/opencontainers/runc/libcontainer/cgroups" | ||
"golang.org/x/sys/unix" | ||
) | ||
|
||
const cgroupKernelMemoryLimit = "memory.kmem.limit_in_bytes" | ||
|
||
func EnableKernelMemoryAccounting(path string) error { | ||
// Check if kernel memory is enabled | ||
// 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. | ||
for _, i := range []int64{1, -1} { | ||
if err := setKernelMemory(path, i); err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func setKernelMemory(path string, kernelMemoryLimit int64) error { | ||
if path == "" { | ||
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 | ||
} | ||
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" | ||
// The EBUSY signal is returned on attempts to write to the | ||
// memory.kmem.limit_in_bytes file if the cgroup has children or | ||
// once tasks have been attached to the cgroup | ||
if pathErr, ok := err.(*os.PathError); ok { | ||
if errNo, ok := pathErr.Err.(syscall.Errno); ok { | ||
if errNo == unix.EBUSY { | ||
return fmt.Errorf("failed to set %s, because either tasks have already joined this cgroup or it has children", cgroupKernelMemoryLimit) | ||
} | ||
} | ||
} | ||
return fmt.Errorf("failed to write %v to %v: %v", kernelMemoryLimit, cgroupKernelMemoryLimit, err) | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
// +build linux,nokmem | ||
|
||
package fs | ||
|
||
func EnableKernelMemoryAccounting(path string) error { | ||
return nil | ||
} | ||
|
||
func setKernelMemory(path string, kernelMemoryLimit int64) error { | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters