Skip to content
This repository has been archived by the owner on May 12, 2021. It is now read-only.

cherry pick shimv2 fixes from master branch to stable-1.6 #1729

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions containerd-shim-v2/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
package containerdshim

import (
"sync"
"time"

"github.com/containerd/containerd/api/types/task"
Expand All @@ -31,7 +30,6 @@ type container struct {
stderr string
bundle string
cType vc.ContainerType
mu sync.Mutex
exit uint32
status task.Status
terminal bool
Expand Down
22 changes: 11 additions & 11 deletions containerd-shim-v2/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,21 @@ import (
)

func deleteContainer(ctx context.Context, s *service, c *container) error {

status, err := s.sandbox.StatusContainer(c.id)
if err != nil {
return err
}
if status.State.State != types.StateStopped {
_, err = s.sandbox.StopContainer(c.id)
if !c.cType.IsSandbox() {
status, err := s.sandbox.StatusContainer(c.id)
if err != nil {
return err
}
}
if status.State.State != types.StateStopped {
_, err = s.sandbox.StopContainer(c.id)
if err != nil {
return err
}
}

_, err = s.sandbox.DeleteContainer(c.id)
if err != nil {
return err
if _, err = s.sandbox.DeleteContainer(c.id); err != nil {
return err
}
}

// Run post-stop OCI hooks.
Expand Down
41 changes: 22 additions & 19 deletions containerd-shim-v2/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,12 @@ func (s *service) Create(ctx context.Context, r *taskAPI.CreateTaskRequest) (_ *
}

rootfs := filepath.Join(r.Bundle, "rootfs")
if _, err := os.Stat(rootfs); os.IsNotExist(err) {
if err := os.Mkdir(rootfs, 0711); err != nil {
return nil, err
}
}

defer func() {
if err != nil {
if err2 := mount.UnmountAll(rootfs, 0); err2 != nil {
Expand Down Expand Up @@ -432,29 +438,12 @@ func (s *service) Delete(ctx context.Context, r *taskAPI.DeleteRequest) (_ *task
}

if r.ExecID == "" {
err = deleteContainer(ctx, s, c)
if err != nil {
if err = deleteContainer(ctx, s, c); err != nil {
return nil, err
}

// Take care of the use case where it is a sandbox.
// Right after the container representing the sandbox has
// been deleted, let's make sure we stop and delete the
// sandbox.
if c.cType.IsSandbox() {
if err = s.sandbox.Stop(); err != nil {
logrus.WithField("sandbox", s.sandbox.ID()).Error("failed to stop sandbox")
return nil, err
}

if err = s.sandbox.Delete(); err != nil {
logrus.WithField("sandbox", s.sandbox.ID()).Error("failed to delete sandbox")
return nil, err
}
}

s.send(&eventstypes.TaskDelete{
ContainerID: s.id,
ContainerID: c.id,
Pid: s.pid,
ExitStatus: c.exit,
ExitedAt: c.time,
Expand Down Expand Up @@ -678,6 +667,20 @@ func (s *service) Kill(ctx context.Context, r *taskAPI.KillRequest) (_ *ptypes.E
return nil, err
}

// According to CRI specs, kubelet will call StopPodSandbox()
// at least once before calling RemovePodSandbox, and this call
// is idempotent, and must not return an error if all relevant
// resources have already been reclaimed. And in that call it will
// send a SIGKILL signal first to try to stop the container, thus
// once the container has terminated, here should ignore this signal
// and return directly.
if signum == syscall.SIGKILL || signum == syscall.SIGTERM {
if c.status == task.StatusStopped {
logrus.WithField("sandbox", s.sandbox.ID()).WithField("Container", c.id).Debug("Container has already been stopped")
return empty, nil
}
}

processID := c.id
if r.ExecID != "" {
execs, err := c.getExec(r.ExecID)
Expand Down
34 changes: 26 additions & 8 deletions containerd-shim-v2/wait.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,24 +41,42 @@ func wait(s *service, c *container, execID string) (int32, error) {
}).Error("Wait for process failed")
}

if execID == "" {
c.exitCh <- uint32(ret)
} else {
execs.exitCh <- uint32(ret)
}

timeStamp := time.Now()
c.mu.Lock()

s.mu.Lock()
if execID == "" {
// Take care of the use case where it is a sandbox.
// Right after the container representing the sandbox has
// been deleted, let's make sure we stop and delete the
// sandbox.

if c.cType.IsSandbox() {
if err = s.sandbox.Stop(); err != nil {
logrus.WithField("sandbox", s.sandbox.ID()).Error("failed to stop sandbox")
}

if err = s.sandbox.Delete(); err != nil {
logrus.WithField("sandbox", s.sandbox.ID()).Error("failed to delete sandbox")
}
} else {
if _, err = s.sandbox.StopContainer(c.id); err != nil {
logrus.WithError(err).WithField("container", c.id).Warn("stop container failed")
}
}
c.status = task.StatusStopped
c.exit = uint32(ret)
c.time = timeStamp

c.exitCh <- uint32(ret)

} else {
execs.status = task.StatusStopped
execs.exitCode = ret
execs.exitTime = timeStamp

execs.exitCh <- uint32(ret)
}
c.mu.Unlock()
s.mu.Unlock()

go cReap(s, int(ret), c.id, execID, timeStamp)

Expand Down