When daemon is in startup process, could not start container

Description:
 When docker is in startup process and containerd sends an "process exit" event to docker.
 If the container config '--restart=always', restartmanager will start this container very soon.

 But some initialization is not done, e.g. `daemon.netController`,when visit, docker would panic.

Signed-off-by: Wentao Zhang <zhangwentao234@huawei.com>
This commit is contained in:
Wentao Zhang 2017-06-08 18:55:20 +08:00
parent 9c446a4d00
commit 5b0993d6c7
2 changed files with 14 additions and 1 deletions

View file

@ -116,6 +116,7 @@ type Daemon struct {
diskUsageRunning int32
pruneRunning int32
hosts map[string]bool // hosts stores the addresses the daemon is listening on
startupDone chan struct{}
}
// StoreHosts stores the addresses the daemon is listening on
@ -543,7 +544,10 @@ func NewDaemon(config *config.Config, registryService registry.Service, containe
}
os.Setenv("TMPDIR", realTmp)
d := &Daemon{configStore: config}
d := &Daemon{
configStore: config,
startupDone: make(chan struct{}),
}
// Ensure the daemon is properly shutdown if there is a failure during
// initialization
defer func() {
@ -740,6 +744,7 @@ func NewDaemon(config *config.Config, registryService registry.Service, containe
if err := d.restore(); err != nil {
return nil, err
}
close(d.startupDone)
// FIXME: this method never returns an error
info, _ := d.SystemInfo()
@ -760,6 +765,10 @@ func NewDaemon(config *config.Config, registryService registry.Service, containe
return d, nil
}
func (daemon *Daemon) waitForStartupDone() {
<-daemon.startupDone
}
func (daemon *Daemon) shutdownContainer(c *container.Container) error {
stopTimeout := c.StopTimeout()
// TODO(windows): Handle docker restart with paused containers

View file

@ -69,6 +69,10 @@ func (daemon *Daemon) StateChanged(id string, e libcontainerd.StateInfo) error {
go func() {
err := <-wait
if err == nil {
// daemon.netController is initialized when daemon is restoring containers.
// But containerStart will use daemon.netController segment.
// So to avoid panic at startup process, here must wait util daemon restore done.
daemon.waitForStartupDone()
if err = daemon.containerStart(c, "", "", false); err != nil {
logrus.Debugf("failed to restart container: %+v", err)
}