From b90babb93ac223e9833bb073569ce913ba5136e3 Mon Sep 17 00:00:00 2001 From: bin liu Date: Wed, 16 Sep 2020 14:19:51 +0800 Subject: [PATCH] runtime: write oom file to notify CRI-O OOM occurred Fixes: #2955 Signed-off-by: bin liu --- containerd-shim-v2/wait.go | 22 +++++++++++++++++++ virtcontainers/pkg/oci/utils.go | 10 +++++++++ virtcontainers/pkg/oci/utils_test.go | 32 ++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+) diff --git a/containerd-shim-v2/wait.go b/containerd-shim-v2/wait.go index 815178bade..3d38d5976c 100644 --- a/containerd-shim-v2/wait.go +++ b/containerd-shim-v2/wait.go @@ -7,12 +7,14 @@ package containerdshim import ( "context" + "os" "path" "time" "github.com/containerd/containerd/api/events" "github.com/containerd/containerd/api/types/task" "github.com/containerd/containerd/mount" + "github.com/kata-containers/runtime/virtcontainers/pkg/oci" "github.com/sirupsen/logrus" "google.golang.org/grpc/codes" ) @@ -151,6 +153,26 @@ func watchOOMEvents(ctx context.Context, s *service) { continue } + // write oom file for CRI-O + if c, ok := s.containers[containerID]; ok && oci.IsCRIOContainerManager(c.spec) { + oomPath := path.Join(c.bundle, "oom") + logrus.WithFields(logrus.Fields{ + "sandbox": s.sandbox.ID(), + "container": containerID, + }).Infof("write oom file to notify CRI-O: %s", oomPath) + + f, err := os.OpenFile(oomPath, os.O_CREATE, 0666) + if err != nil { + logrus.WithFields(logrus.Fields{ + "sandbox": s.sandbox.ID(), + "container": containerID, + }).Warnf("failed to write oom file %s", oomPath) + } else { + f.Close() + } + } + + // publish event for containerd s.send(&events.TaskOOM{ ContainerID: containerID, }) diff --git a/virtcontainers/pkg/oci/utils.go b/virtcontainers/pkg/oci/utils.go index 51077e935e..26ed68cf78 100644 --- a/virtcontainers/pkg/oci/utils.go +++ b/virtcontainers/pkg/oci/utils.go @@ -1040,3 +1040,13 @@ func GetOCIConfig(status vc.ContainerStatus) (specs.Spec, error) { return *status.Spec, nil } + +// IsCRIOContainerManager check if a Pod is created from CRI-O +func IsCRIOContainerManager(spec *specs.Spec) bool { + if val, ok := spec.Annotations[crioAnnotations.ContainerType]; ok { + if val == crioAnnotations.ContainerTypeSandbox || val == crioAnnotations.ContainerTypeContainer { + return true + } + } + return false +} diff --git a/virtcontainers/pkg/oci/utils_test.go b/virtcontainers/pkg/oci/utils_test.go index dbc844b031..ae15811027 100644 --- a/virtcontainers/pkg/oci/utils_test.go +++ b/virtcontainers/pkg/oci/utils_test.go @@ -17,6 +17,7 @@ import ( "testing" "github.com/cri-o/cri-o/pkg/annotations" + crioAnnotations "github.com/cri-o/cri-o/pkg/annotations" specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/stretchr/testify/assert" "golang.org/x/sys/unix" @@ -869,3 +870,34 @@ func TestAddRuntimeAnnotations(t *testing.T) { assert.Equal(config.NetworkConfig.DisableNewNetNs, true) assert.Equal(config.NetworkConfig.InterworkingModel, vc.NetXConnectMacVtapModel) } + +func TestIsCRIOContainerManager(t *testing.T) { + assert := assert.New(t) + + testCases := []struct { + annotations map[string]string + result bool + }{ + { + annotations: map[string]string{crioAnnotations.ContainerType: "abc"}, + result: false, + }, + { + annotations: map[string]string{crioAnnotations.ContainerType: crioAnnotations.ContainerTypeSandbox}, + result: true, + }, + { + annotations: map[string]string{crioAnnotations.ContainerType: crioAnnotations.ContainerTypeContainer}, + result: true, + }, + } + + for i := range testCases { + tc := testCases[i] + ocispec := specs.Spec{ + Annotations: tc.annotations, + } + result := IsCRIOContainerManager(&ocispec) + assert.Equal(tc.result, result, "test case %d", (i + 1)) + } +}