Make pod stop lock one container at a time

Signed-off-by: Matthew Heon <matthew.heon@gmail.com>

Closes: #600
Approved by: rhatdan
This commit is contained in:
Matthew Heon
2018-04-09 11:05:59 -04:00
committed by Atomic Bot
parent 542f8fe98d
commit 8b67fbb3f2

View File

@ -153,39 +153,40 @@ func startNode(node *containerNode, setError bool, ctrErrors map[string]error, c
return return
} }
// Going to start the container, mark us as visited // Going to try to start the container, mark us as visited
ctrsVisited[node.id] = true ctrsVisited[node.id] = true
// Lock before we start ctrErrored := false
node.container.lock.Lock()
// Check if dependencies are running // Check if dependencies are running
// Graph traversal means we should have started them // Graph traversal means we should have started them
// But they could have died before we got here // But they could have died before we got here
// Does not require that the container be locked, we only need to lock
// the dependencies
depsStopped, err := node.container.checkDependenciesRunning() depsStopped, err := node.container.checkDependenciesRunning()
if err != nil { if err != nil {
node.container.lock.Unlock()
ctrErrors[node.id] = err ctrErrors[node.id] = err
for _, successor := range node.dependedOn { ctrErrored = true
startNode(successor, true, ctrErrors, ctrsVisited)
}
return
} else if len(depsStopped) > 0 { } else if len(depsStopped) > 0 {
node.container.lock.Unlock()
// Our dependencies are not running // Our dependencies are not running
depsList := strings.Join(depsStopped, ",") depsList := strings.Join(depsStopped, ",")
ctrErrors[node.id] = errors.Wrapf(ErrCtrStateInvalid, "the following dependencies of container %s are not running: %s", node.id, depsList) ctrErrors[node.id] = errors.Wrapf(ErrCtrStateInvalid, "the following dependencies of container %s are not running: %s", node.id, depsList)
for _, successor := range node.dependedOn { ctrErrored = true
startNode(successor, true, ctrErrors, ctrsVisited) }
// Lock before we start
node.container.lock.Lock()
// Sync the container to pick up current state
if !ctrErrored {
if err := node.container.syncContainer(); err != nil {
ctrErrored = true
ctrErrors[node.id] = err
} }
return
} }
// Start the container (only if it is not running) // Start the container (only if it is not running)
ctrErrored := false if !ctrErrored && node.container.state.State != ContainerStateRunning {
if node.container.state.State != ContainerStateRunning {
if err := node.container.initAndStart(); err != nil { if err := node.container.initAndStart(); err != nil {
ctrErrored = true ctrErrored = true
ctrErrors[node.id] = err ctrErrors[node.id] = err
@ -230,16 +231,6 @@ func (p *Pod) Stop(cleanup bool) (map[string]error, error) {
return nil, err return nil, err
} }
// We need to lock all the containers
for _, ctr := range allCtrs {
ctr.lock.Lock()
defer ctr.lock.Unlock()
if err := ctr.syncContainer(); err != nil {
return nil, err
}
}
ctrErrors := make(map[string]error) ctrErrors := make(map[string]error)
// TODO: There may be cases where it makes sense to order stops based on // TODO: There may be cases where it makes sense to order stops based on
@ -247,12 +238,22 @@ func (p *Pod) Stop(cleanup bool) (map[string]error, error) {
// Stop to all containers // Stop to all containers
for _, ctr := range allCtrs { for _, ctr := range allCtrs {
ctr.lock.Lock()
if err := ctr.syncContainer(); err != nil {
ctr.lock.Unlock()
ctrErrors[ctr.ID()] = err
continue
}
// Ignore containers that are not running // Ignore containers that are not running
if ctr.state.State != ContainerStateRunning { if ctr.state.State != ContainerStateRunning {
ctr.lock.Unlock()
continue continue
} }
if err := ctr.stop(ctr.config.StopTimeout); err != nil { if err := ctr.stop(ctr.config.StopTimeout); err != nil {
ctr.lock.Unlock()
ctrErrors[ctr.ID()] = err ctrErrors[ctr.ID()] = err
continue continue
} }
@ -262,6 +263,8 @@ func (p *Pod) Stop(cleanup bool) (map[string]error, error) {
ctrErrors[ctr.ID()] = err ctrErrors[ctr.ID()] = err
} }
} }
ctr.lock.Unlock()
} }
if len(ctrErrors) > 0 { if len(ctrErrors) > 0 {