From 52d42e0b850cde3600028b00e19f5325a61ddad3 Mon Sep 17 00:00:00 2001 From: xiadanni Date: Mon, 1 Feb 2021 19:36:53 +0800 Subject: [PATCH] containerd: kill container init process if runc start returns error Signed-off-by: xiadanni --- runtime/v1/linux/proc/init.go | 4 +++ utils/utils.go | 61 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 utils/utils.go diff --git a/runtime/v1/linux/proc/init.go b/runtime/v1/linux/proc/init.go index de76682..669c108 100644 --- a/runtime/v1/linux/proc/init.go +++ b/runtime/v1/linux/proc/init.go @@ -35,6 +35,7 @@ import ( "github.com/containerd/containerd/log" "github.com/containerd/containerd/mount" "github.com/containerd/containerd/runtime/proc" + "github.com/containerd/containerd/utils" "github.com/containerd/fifo" runc "github.com/containerd/go-runc" google_protobuf "github.com/gogo/protobuf/types" @@ -277,6 +278,9 @@ func (p *Init) Status(ctx context.Context) (string, error) { func (p *Init) start(context context.Context) error { err := p.runtime.Start(context, p.id) + if err != nil { + utils.KillInitProcess(p.id, p.pid) + } return p.runtimeError(err, "OCI runtime start failed") } diff --git a/utils/utils.go b/utils/utils.go new file mode 100644 index 0000000..c57c6ca --- /dev/null +++ b/utils/utils.go @@ -0,0 +1,61 @@ +/* +Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. +Use of this source code is governed by Apache-2.0 +license that can be found in the LICENSE file. +Description: common functions +Author: Danni Xia +Create: 2021-01-30 +*/ + +package utils + +import ( + "encoding/json" + "io/ioutil" + "path/filepath" + "strconv" + "strings" + "syscall" + + "github.com/sirupsen/logrus" +) + +type baseState struct { + InitProcessStartTime string `json:"init_process_start"` +} + +func KillInitProcess(cid string, pid int) { + if IsInitProcess(cid, pid) { + syscall.Kill(pid, syscall.SIGKILL) + } +} + +func IsInitProcess(cid string, pid int) bool { + stateBytes, err1 := ioutil.ReadFile(filepath.Join("/var/run/docker/runtime-runc/moby", cid, "state.json")) + statBytes, err2 := ioutil.ReadFile(filepath.Join("/proc", strconv.Itoa(pid), "stat")) + if err1 != nil || err2 != nil { + return true + } + + s := strings.Split(string(statBytes), ")") + if len(s) < 1 { + return true + } + + statFields := strings.Split(strings.TrimSpace(s[len(s)-1]), " ") + if len(statFields) < 20 { + return true + } + + var baseState baseState + if err := json.Unmarshal(stateBytes, &baseState); err != nil { + return true + } + + if baseState.InitProcessStartTime == statFields[19] { + return true + } + + logrus.Warnf("process(pid:%d, start time:%s) is not container %s init process", pid, statFields[19], cid) + return false +} -- 1.8.3.1