Files
kata-containers/containerd-shim-v2/wait.go
Ace-Tang 854cc86e8d shimv2: fix set status when container exit
in wait function, should send msg to exit channel after task status has
updated, since shim.Wait() is running in another goroutine, when it
receive msg from exit channel, it will stop waiting and return, then
someone who hold this Wait() get return, it can delete task, if exit msg
is send first, the container status may still be running.

Fixes: #1600

Signed-off-by: Ace-Tang <aceapril@126.com>
2019-04-29 13:22:26 +08:00

67 lines
1.3 KiB
Go

// Copyright (c) 2018 HyperHQ Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
package containerdshim
import (
"time"
"github.com/containerd/containerd/api/types/task"
"github.com/sirupsen/logrus"
)
func wait(s *service, c *container, execID string) (int32, error) {
var execs *exec
var err error
processID := c.id
if execID == "" {
//wait until the io closed, then wait the container
<-c.exitIOch
} else {
execs, err = c.getExec(execID)
if err != nil {
return exitCode255, err
}
<-execs.exitIOch
//This wait could be triggered before exec start which
//will get the exec's id, thus this assignment must after
//the exec exit, to make sure it get the exec's id.
processID = execs.id
}
ret, err := s.sandbox.WaitProcess(c.id, processID)
if err != nil {
logrus.WithError(err).WithFields(logrus.Fields{
"container": c.id,
"pid": processID,
}).Error("Wait for process failed")
}
timeStamp := time.Now()
c.mu.Lock()
if execID == "" {
c.status = task.StatusStopped
c.exit = uint32(ret)
c.exitTime = timeStamp
} else {
execs.status = task.StatusStopped
execs.exitCode = ret
execs.exitTime = timeStamp
}
c.mu.Unlock()
if execID == "" {
c.exitCh <- uint32(ret)
} else {
execs.exitCh <- uint32(ret)
}
go cReap(s, int(ret), c.id, execID, timeStamp)
return ret, nil
}