|
@@ -330,10 +330,15 @@ func (daemon *Daemon) restore() error {
|
|
|
|
|
|
daemon.setStateCounter(c)
|
|
daemon.setStateCounter(c)
|
|
|
|
|
|
- log.WithFields(logrus.Fields{
|
|
|
|
- "running": c.IsRunning(),
|
|
|
|
- "paused": c.IsPaused(),
|
|
|
|
- }).Debug("restoring container")
|
|
|
|
|
|
+ logger := func(c *container.Container) *logrus.Entry {
|
|
|
|
+ return log.WithFields(logrus.Fields{
|
|
|
|
+ "running": c.IsRunning(),
|
|
|
|
+ "paused": c.IsPaused(),
|
|
|
|
+ "restarting": c.IsRestarting(),
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ logger(c).Debug("restoring container")
|
|
|
|
|
|
var (
|
|
var (
|
|
err error
|
|
err error
|
|
@@ -345,16 +350,24 @@ func (daemon *Daemon) restore() error {
|
|
|
|
|
|
alive, _, process, err = daemon.containerd.Restore(context.Background(), c.ID, c.InitializeStdio)
|
|
alive, _, process, err = daemon.containerd.Restore(context.Background(), c.ID, c.InitializeStdio)
|
|
if err != nil && !errdefs.IsNotFound(err) {
|
|
if err != nil && !errdefs.IsNotFound(err) {
|
|
- log.WithError(err).Error("failed to restore container with containerd")
|
|
|
|
|
|
+ logger(c).WithError(err).Error("failed to restore container with containerd")
|
|
return
|
|
return
|
|
}
|
|
}
|
|
- if !alive && process != nil {
|
|
|
|
- ec, exitedAt, err = process.Delete(context.Background())
|
|
|
|
- if err != nil && !errdefs.IsNotFound(err) {
|
|
|
|
- log.WithError(err).Error("failed to delete container from containerd")
|
|
|
|
- return
|
|
|
|
|
|
+ logger(c).Debugf("alive: %v", alive)
|
|
|
|
+ if !alive {
|
|
|
|
+ // If process is not nil, cleanup dead container from containerd.
|
|
|
|
+ // If process is nil then the above `containerd.Restore` returned an errdefs.NotFoundError,
|
|
|
|
+ // and docker's view of the container state will be updated accorrdingly via SetStopped further down.
|
|
|
|
+ if process != nil {
|
|
|
|
+ logger(c).Debug("cleaning up dead container process")
|
|
|
|
+ ec, exitedAt, err = process.Delete(context.Background())
|
|
|
|
+ if err != nil && !errdefs.IsNotFound(err) {
|
|
|
|
+ logger(c).WithError(err).Error("failed to delete container from containerd")
|
|
|
|
+ return
|
|
|
|
+ }
|
|
}
|
|
}
|
|
} else if !daemon.configStore.LiveRestoreEnabled {
|
|
} else if !daemon.configStore.LiveRestoreEnabled {
|
|
|
|
+ logger(c).Debug("shutting down container considered alive by containerd")
|
|
if err := daemon.shutdownContainer(c); err != nil && !errdefs.IsNotFound(err) {
|
|
if err := daemon.shutdownContainer(c); err != nil && !errdefs.IsNotFound(err) {
|
|
log.WithError(err).Error("error shutting down container")
|
|
log.WithError(err).Error("error shutting down container")
|
|
return
|
|
return
|
|
@@ -363,14 +376,16 @@ func (daemon *Daemon) restore() error {
|
|
}
|
|
}
|
|
|
|
|
|
if c.IsRunning() || c.IsPaused() {
|
|
if c.IsRunning() || c.IsPaused() {
|
|
|
|
+ logger(c).Debug("syncing container on disk state with real state")
|
|
|
|
+
|
|
c.RestartManager().Cancel() // manually start containers because some need to wait for swarm networking
|
|
c.RestartManager().Cancel() // manually start containers because some need to wait for swarm networking
|
|
|
|
|
|
if c.IsPaused() && alive {
|
|
if c.IsPaused() && alive {
|
|
s, err := daemon.containerd.Status(context.Background(), c.ID)
|
|
s, err := daemon.containerd.Status(context.Background(), c.ID)
|
|
if err != nil {
|
|
if err != nil {
|
|
- log.WithError(err).Error("failed to get container status")
|
|
|
|
|
|
+ logger(c).WithError(err).Error("failed to get container status")
|
|
} else {
|
|
} else {
|
|
- log.WithField("state", s).Info("restored container paused")
|
|
|
|
|
|
+ logger(c).WithField("state", s).Info("restored container paused")
|
|
switch s {
|
|
switch s {
|
|
case containerd.Paused, containerd.Pausing:
|
|
case containerd.Paused, containerd.Pausing:
|
|
// nothing to do
|
|
// nothing to do
|
|
@@ -392,6 +407,7 @@ func (daemon *Daemon) restore() error {
|
|
}
|
|
}
|
|
|
|
|
|
if !alive {
|
|
if !alive {
|
|
|
|
+ logger(c).Debug("setting stopped state")
|
|
c.Lock()
|
|
c.Lock()
|
|
c.SetStopped(&container.ExitStatus{ExitCode: int(ec), ExitedAt: exitedAt})
|
|
c.SetStopped(&container.ExitStatus{ExitCode: int(ec), ExitedAt: exitedAt})
|
|
daemon.Cleanup(c)
|
|
daemon.Cleanup(c)
|
|
@@ -399,6 +415,7 @@ func (daemon *Daemon) restore() error {
|
|
log.WithError(err).Error("failed to update stopped container state")
|
|
log.WithError(err).Error("failed to update stopped container state")
|
|
}
|
|
}
|
|
c.Unlock()
|
|
c.Unlock()
|
|
|
|
+ logger(c).Debug("set stopped state")
|
|
}
|
|
}
|
|
|
|
|
|
// we call Mount and then Unmount to get BaseFs of the container
|
|
// we call Mount and then Unmount to get BaseFs of the container
|
|
@@ -409,10 +426,10 @@ func (daemon *Daemon) restore() error {
|
|
// stopped/restarted/removed.
|
|
// stopped/restarted/removed.
|
|
// See #29365 for related information.
|
|
// See #29365 for related information.
|
|
// The error is only logged here.
|
|
// The error is only logged here.
|
|
- log.WithError(err).Warn("failed to mount container to get BaseFs path")
|
|
|
|
|
|
+ logger(c).WithError(err).Warn("failed to mount container to get BaseFs path")
|
|
} else {
|
|
} else {
|
|
if err := daemon.Unmount(c); err != nil {
|
|
if err := daemon.Unmount(c); err != nil {
|
|
- log.WithError(err).Warn("failed to umount container to get BaseFs path")
|
|
|
|
|
|
+ logger(c).WithError(err).Warn("failed to umount container to get BaseFs path")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -420,7 +437,7 @@ func (daemon *Daemon) restore() error {
|
|
if !c.HostConfig.NetworkMode.IsContainer() && c.IsRunning() {
|
|
if !c.HostConfig.NetworkMode.IsContainer() && c.IsRunning() {
|
|
options, err := daemon.buildSandboxOptions(c)
|
|
options, err := daemon.buildSandboxOptions(c)
|
|
if err != nil {
|
|
if err != nil {
|
|
- log.WithError(err).Warn("failed to build sandbox option to restore container")
|
|
|
|
|
|
+ logger(c).WithError(err).Warn("failed to build sandbox option to restore container")
|
|
}
|
|
}
|
|
mapLock.Lock()
|
|
mapLock.Lock()
|
|
activeSandboxes[c.NetworkSettings.SandboxID] = options
|
|
activeSandboxes[c.NetworkSettings.SandboxID] = options
|
|
@@ -465,6 +482,7 @@ func (daemon *Daemon) restore() error {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
c.Unlock()
|
|
c.Unlock()
|
|
|
|
+ logger(c).Debug("done restoring container")
|
|
}(c)
|
|
}(c)
|
|
}
|
|
}
|
|
group.Wait()
|
|
group.Wait()
|