Refactor Shutdown a little to reduce indentation

Also make daemon.netController.Stop() regardless of container existance.

Signed-off-by: Alexander Morozov <lk4d4@docker.com>
This commit is contained in:
Alexander Morozov 2015-10-29 15:11:35 -07:00
parent 8d62f243c7
commit ace5854f65
1 changed files with 55 additions and 48 deletions

View File

@ -830,6 +830,45 @@ func NewDaemon(config *Config, registryService *registry.Service) (daemon *Daemo
return d, nil
}
func stopContainer(c *Container) error {
// TODO(windows): Handle docker restart with paused containers
if c.isPaused() {
// To terminate a process in freezer cgroup, we should send
// SIGTERM to this process then unfreeze it, and the process will
// force to terminate immediately.
logrus.Debugf("Found container %s is paused, sending SIGTERM before unpause it", c.ID)
sig, ok := signal.SignalMap["TERM"]
if !ok {
return fmt.Errorf("System doesn not support SIGTERM")
}
if err := c.daemon.kill(c, int(sig)); err != nil {
return fmt.Errorf("sending SIGTERM to container %s with error: %v", c.ID, err)
}
if err := c.unpause(); err != nil {
return fmt.Errorf("Failed to unpause container %s with error: %v", c.ID, err)
}
if _, err := c.WaitStop(10 * time.Second); err != nil {
logrus.Debugf("container %s failed to exit in 10 second of SIGTERM, sending SIGKILL to force", c.ID)
sig, ok := signal.SignalMap["KILL"]
if !ok {
return fmt.Errorf("System does not support SIGKILL")
}
if err := c.daemon.kill(c, int(sig)); err != nil {
logrus.Errorf("Failed to SIGKILL container %s", c.ID)
}
c.WaitStop(-1 * time.Second)
return err
}
}
// If container failed to exit in 10 seconds of SIGTERM, then using the force
if err := c.Stop(10); err != nil {
return fmt.Errorf("Stop container %s with error: %v", c.ID, err)
}
c.WaitStop(-1 * time.Second)
return nil
}
// Shutdown stops the daemon.
func (daemon *Daemon) Shutdown() error {
daemon.shutdown = true
@ -837,58 +876,26 @@ func (daemon *Daemon) Shutdown() error {
group := sync.WaitGroup{}
logrus.Debug("starting clean shutdown of all containers...")
for _, container := range daemon.List() {
c := container
if c.IsRunning() {
logrus.Debugf("stopping %s", c.ID)
group.Add(1)
go func() {
defer group.Done()
// TODO(windows): Handle docker restart with paused containers
if c.isPaused() {
// To terminate a process in freezer cgroup, we should send
// SIGTERM to this process then unfreeze it, and the process will
// force to terminate immediately.
logrus.Debugf("Found container %s is paused, sending SIGTERM before unpause it", c.ID)
sig, ok := signal.SignalMap["TERM"]
if !ok {
logrus.Warnf("System does not support SIGTERM")
return
}
if err := daemon.kill(c, int(sig)); err != nil {
logrus.Debugf("sending SIGTERM to container %s with error: %v", c.ID, err)
return
}
if err := c.unpause(); err != nil {
logrus.Debugf("Failed to unpause container %s with error: %v", c.ID, err)
return
}
if _, err := c.WaitStop(10 * time.Second); err != nil {
logrus.Debugf("container %s failed to exit in 10 second of SIGTERM, sending SIGKILL to force", c.ID)
sig, ok := signal.SignalMap["KILL"]
if !ok {
logrus.Warnf("System does not support SIGKILL")
return
}
daemon.kill(c, int(sig))
}
} else {
// If container failed to exit in 10 seconds of SIGTERM, then using the force
if err := c.Stop(10); err != nil {
logrus.Errorf("Stop container %s with error: %v", c.ID, err)
}
}
c.WaitStop(-1 * time.Second)
logrus.Debugf("container stopped %s", c.ID)
}()
if !container.IsRunning() {
continue
}
logrus.Debugf("stopping %s", container.ID)
group.Add(1)
go func(c *Container) {
defer group.Done()
if err := stopContainer(c); err != nil {
logrus.Errorf("Stop container error: %v", err)
return
}
logrus.Debugf("container stopped %s", c.ID)
}(container)
}
group.Wait()
}
// trigger libnetwork Stop only if it's initialized
if daemon.netController != nil {
daemon.netController.Stop()
}
// trigger libnetwork Stop only if it's initialized
if daemon.netController != nil {
daemon.netController.Stop()
}
if daemon.containerGraphDB != nil {