mirror of
https://github.com/containers/podman.git
synced 2025-09-19 12:56:57 +08:00
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:
@ -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 {
|
||||||
|
Reference in New Issue
Block a user