From b7b7643381834134081e9dcbf1e5b4c11f563887 Mon Sep 17 00:00:00 2001 From: Allen Sun Date: Mon, 11 Jun 2018 15:13:29 +0800 Subject: [PATCH] fix: lock the whole markStoppendAndRelease to be automic Signed-off-by: Allen Sun --- daemon/mgr/container.go | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/daemon/mgr/container.go b/daemon/mgr/container.go index f3dc83059d..5d3e492b46 100644 --- a/daemon/mgr/container.go +++ b/daemon/mgr/container.go @@ -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()) @@ -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) } @@ -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 @@ -1689,13 +1704,6 @@ 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() @@ -1703,12 +1711,11 @@ func (mgr *ContainerManager) markStoppedAndRelease(c *Container, m *ctrd.Message } // 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 @@ -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 }