Skip to content

Commit

Permalink
fix: lock the whole markStoppendAndRelease to be automic
Browse files Browse the repository at this point in the history
Signed-off-by: Allen Sun <allensun.shl@alibaba-inc.com>
  • Loading branch information
allencloud committed Jun 13, 2018
1 parent a0ef39d commit b7b7643
Showing 1 changed file with 20 additions and 21 deletions.
41 changes: 20 additions & 21 deletions daemon/mgr/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,7 @@ func (mgr *ContainerManager) Restart(ctx context.Context, name string, timeout i

if c.IsRunningOrPaused() {
// stop container if it is running or paused.
logrus.Infof("stop container(id: %s, name: %s) when restarting", c.ID, c.Name)
if err := mgr.stop(ctx, c, timeout); err != nil {
ex := fmt.Errorf("failed to stop container %s when restarting: %v", c.ID, err)
logrus.Errorf(ex.Error())
Expand Down Expand Up @@ -905,6 +906,7 @@ func (mgr *ContainerManager) Remove(ctx context.Context, name string, options *t
c.Unlock()

// remove meta data
logrus.Infof("start to remove meta data of container %s", c.ID)
if err := mgr.Store.Remove(c.Key()); err != nil {
logrus.Errorf("failed to remove container %s from meta store: %v", c.ID, err)
}
Expand Down Expand Up @@ -1659,17 +1661,30 @@ func attachConfigToOptions(attach *AttachConfig) []func(*containerio.Option) {

func (mgr *ContainerManager) markStoppedAndRelease(c *Container, m *ctrd.Message) error {
var (
code int64 // container exit code used for container state setting
errMsg string // container exit error message used for container state setting
exitCode int64 // container exit code used for container state setting
errMsg string // container exit error message used for container state setting
)
if m != nil {
code = int64(m.ExitCode())
exitCode = int64(m.ExitCode())
if err := m.RawError(); err != nil {
errMsg = err.Error()
}
}

c.SetStatusStopped(code, errMsg)
defer func() {
if err := c.Write(mgr.Store); err != nil {
logrus.Errorf("failed to update meta: %v", err)
}
}()

c.Lock()
defer c.Unlock()

c.State.Status = types.StatusStopped
c.State.FinishedAt = time.Now().UTC().Format(utils.TimeLayout)
c.State.Pid = -1
c.State.ExitCode = exitCode
c.State.Error = errMsg

// unset Snapshot MergedDir. Stop a container will
// delete the containerd container, the merged dir
Expand All @@ -1689,26 +1704,18 @@ func (mgr *ContainerManager) markStoppedAndRelease(c *Container, m *ctrd.Message
return nil
}

// Remove io and network config may occur error, so we should update
// container's status on disk as soon as possible.
if err := c.Write(mgr.Store); err != nil {
logrus.Errorf("failed to update meta: %v", err)
return err
}

// release resource
if io := mgr.IOs.Get(c.ID); io != nil {
io.Close()
mgr.IOs.Remove(c.ID)
}

// No network binded, just return
c.Lock()
if c.NetworkSettings == nil {
c.Unlock()
return nil
}

// when container exits, pouchd should automatically remove container network endpoints.
for name, epConfig := range c.NetworkSettings.Networks {
endpoint := mgr.buildContainerEndpoint(c)
endpoint.Name = name
Expand All @@ -1718,18 +1725,10 @@ func (mgr *ContainerManager) markStoppedAndRelease(c *Container, m *ctrd.Message
// not found"" as an error type
if !strings.Contains(err.Error(), "not found") {
logrus.Errorf("failed to remove endpoint: %v", err)
c.Unlock()
return err
}
}
}
c.Unlock()

// update meta
if err := c.Write(mgr.Store); err != nil {
logrus.Errorf("failed to update meta of container %s: %v", c.ID, err)
return err
}

return nil
}
Expand Down

0 comments on commit b7b7643

Please sign in to comment.