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>
This commit is contained in:
Ace-Tang 2019-04-29 12:10:37 +08:00
parent 437b3cb2f7
commit 854cc86e8d
3 changed files with 11 additions and 11 deletions

View File

@ -21,7 +21,7 @@ type container struct {
s *service
ttyio *ttyIO
spec *oci.CompatOCISpec
time time.Time
exitTime time.Time
execs map[string]*exec
exitIOch chan struct{}
exitCh chan uint32
@ -61,7 +61,6 @@ func newContainer(s *service, r *taskAPI.CreateTaskRequest, containerType vc.Con
status: task.StatusCreated,
exitIOch: make(chan struct{}),
exitCh: make(chan uint32, 1),
time: time.Now(),
}
return c, nil
}

View File

@ -444,12 +444,12 @@ func (s *service) Delete(ctx context.Context, r *taskAPI.DeleteRequest) (_ *task
ContainerID: s.id,
Pid: s.pid,
ExitStatus: c.exit,
ExitedAt: c.time,
ExitedAt: c.exitTime,
})
return &taskAPI.DeleteResponse{
ExitStatus: c.exit,
ExitedAt: c.time,
ExitedAt: c.exitTime,
Pid: s.pid,
}, nil
}
@ -860,6 +860,7 @@ func (s *service) Wait(ctx context.Context, r *taskAPI.WaitRequest) (_ *taskAPI.
return &taskAPI.WaitResponse{
ExitStatus: ret,
ExitedAt: c.exitTime,
}, nil
}

View File

@ -41,18 +41,12 @@ 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()
if execID == "" {
c.status = task.StatusStopped
c.exit = uint32(ret)
c.time = timeStamp
c.exitTime = timeStamp
} else {
execs.status = task.StatusStopped
execs.exitCode = ret
@ -60,6 +54,12 @@ func wait(s *service, c *container, execID string) (int32, error) {
}
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