diff --git a/cmd/containerd/config.go b/cmd/containerd/config.go index f219eb8f2..d47951f8d 100644 --- a/cmd/containerd/config.go +++ b/cmd/containerd/config.go @@ -53,6 +53,8 @@ type config struct { Plugins map[string]toml.Primitive `toml:"plugins"` // Enable containerd as a subreaper Subreaper bool `toml:"subreaper"` + // OOMScore adjust the containerd's oom score + OOMScore int `toml:"oom_score"` md toml.MetaData } diff --git a/cmd/containerd/main_unix.go b/cmd/containerd/main_unix.go index f45dca938..6aa5626d2 100644 --- a/cmd/containerd/main_unix.go +++ b/cmd/containerd/main_unix.go @@ -29,6 +29,12 @@ func platformInit(context *cli.Context) error { return err } } + if conf.OOMScore != 0 { + log.G(global).Infof("changing OOM score to %d", conf.OOMScore) + if err := sys.SetOOMScore(os.Getpid(), conf.OOMScore); err != nil { + return err + } + } return nil } diff --git a/linux/shim.go b/linux/shim.go index eb06d65c6..0c2809826 100644 --- a/linux/shim.go +++ b/linux/shim.go @@ -51,6 +51,9 @@ func newShim(path string, remote bool) (shim.ShimClient, error) { if err := reaper.Default.Start(cmd); err != nil { return nil, errors.Wrapf(err, "failed to start shim") } + if err := sys.SetOOMScore(cmd.Process.Pid, sys.OOMScoreMaxKillable); err != nil { + return nil, err + } return connectShim(socket) } diff --git a/sys/oom_unix.go b/sys/oom_unix.go new file mode 100644 index 000000000..23fcc9437 --- /dev/null +++ b/sys/oom_unix.go @@ -0,0 +1,31 @@ +// +build !windows + +package sys + +import ( + "fmt" + "os" + "strconv" + + "github.com/opencontainers/runc/libcontainer/system" +) + +// OOMScoreMaxKillable is the maximum score keeping the process killable by the oom killer +const OOMScoreMaxKillable = -999 + +// SetOOMScore sets the oom score for the provided pid +func SetOOMScore(pid, score int) error { + path := fmt.Sprintf("/proc/%d/oom_score_adj", pid) + f, err := os.OpenFile(path, os.O_WRONLY, 0) + if err != nil { + return err + } + defer f.Close() + if _, err = f.WriteString(strconv.Itoa(score)); err != nil { + if os.IsPermission(err) && system.RunningInUserNS() { + return nil + } + return err + } + return nil +} diff --git a/sys/oom_windows.go b/sys/oom_windows.go new file mode 100644 index 000000000..a72568b27 --- /dev/null +++ b/sys/oom_windows.go @@ -0,0 +1,5 @@ +package sys + +func SetOOMScore(pid, score int) error { + return nil +}