From ec9640993b8c47a577eeb9d1b544d6a5a35d3864 Mon Sep 17 00:00:00 2001 From: Yves Chan Date: Mon, 28 Sep 2020 22:22:34 +0800 Subject: [PATCH] shimv2: handle ctx passed by containerd Sometimes shim process cannot be shutdown because of container list is not empty. This container list is written in shim service, while creating container. We find that if containerd cancel its Create Container Request due to timeout, but runtime didn't handle it properly and continue creating action, then this container cannot be deleted at all. So we should make sure the ctx passed to Create Service rpc call is effective. Fixes: #2992 Signed-off-by: Yves Chan --- containerd-shim-v2/service.go | 64 +++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/containerd-shim-v2/service.go b/containerd-shim-v2/service.go index 14291a8add..6912851361 100644 --- a/containerd-shim-v2/service.go +++ b/containerd-shim-v2/service.go @@ -337,34 +337,46 @@ func (s *service) Create(ctx context.Context, r *taskAPI.CreateTaskRequest) (_ * s.mu.Lock() defer s.mu.Unlock() - var c *container - - c, err = create(ctx, s, r) - if err != nil { - return nil, err - } - - c.status = task.StatusCreated - - s.containers[r.ID] = c + type Result struct { + container *container + err error + } + ch := make(chan Result, 1) + go func() { + container, err := create(ctx, s, r) + ch <- Result{container, err} + }() - s.send(&eventstypes.TaskCreate{ - ContainerID: r.ID, - Bundle: r.Bundle, - Rootfs: r.Rootfs, - IO: &eventstypes.TaskIO{ - Stdin: r.Stdin, - Stdout: r.Stdout, - Stderr: r.Stderr, - Terminal: r.Terminal, - }, - Checkpoint: r.Checkpoint, - Pid: s.pid, - }) + select { + case <-ctx.Done(): + return nil, errors.Errorf("create container timeout: %v", r.ID) + case res := <-ch: + if res.err != nil { + return nil, res.err + } + container := res.container + container.status = task.StatusCreated + + s.containers[r.ID] = container + + s.send(&eventstypes.TaskCreate{ + ContainerID: r.ID, + Bundle: r.Bundle, + Rootfs: r.Rootfs, + IO: &eventstypes.TaskIO{ + Stdin: r.Stdin, + Stdout: r.Stdout, + Stderr: r.Stderr, + Terminal: r.Terminal, + }, + Checkpoint: r.Checkpoint, + Pid: s.pid, + }) - return &taskAPI.CreateTaskResponse{ - Pid: s.pid, - }, nil + return &taskAPI.CreateTaskResponse{ + Pid: s.pid, + }, nil + } } // Start a process