From 634f0c0c8371023f7c6e90bf8ca35448c1cce679 Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Wed, 12 Apr 2017 11:34:32 -0700 Subject: [PATCH] Set oom score for containerd and shims This adds a config option to set the oom score for the containerd daemon as well as automatically setting the oom score for the shim's lauched so that they are not killed until the very end of an out of memory condition. Signed-off-by: Michael Crosby --- cmd/containerd/config.go | 2 ++ cmd/containerd/main_unix.go | 6 ++++++ linux/shim.go | 3 +++ sys/oom_unix.go | 31 +++++++++++++++++++++++++++++++ sys/oom_windows.go | 5 +++++ 5 files changed, 47 insertions(+) create mode 100644 sys/oom_unix.go create mode 100644 sys/oom_windows.go 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 +}