fixes #25766
If a container's AutoRemove is enabled, client will wait until it's
removed after container exits, this is implemented based on "destroy"
event.
Currently an "AutoRemove" container will report "destroy" event to
notify a hanging client to exit before all volumes are removed, this is
wrong, we should wait container until everything is cleaned up.
Signed-off-by: Zhang Wei <zhangwei555@huawei.com>
| ... | ... |
@@ -90,7 +90,7 @@ func (daemon *Daemon) create(params types.ContainerCreateConfig, managed bool) ( |
| 90 | 90 |
} |
| 91 | 91 |
defer func() {
|
| 92 | 92 |
if retErr != nil {
|
| 93 |
- if err := daemon.cleanupContainer(container, true); err != nil {
|
|
| 93 |
+ if err := daemon.cleanupContainer(container, true, true); err != nil {
|
|
| 94 | 94 |
logrus.Errorf("failed to cleanup container on create error: %v", err)
|
| 95 | 95 |
} |
| 96 | 96 |
} |
| ... | ... |
@@ -118,13 +118,6 @@ func (daemon *Daemon) create(params types.ContainerCreateConfig, managed bool) ( |
| 118 | 118 |
if err := daemon.setHostConfig(container, params.HostConfig); err != nil {
|
| 119 | 119 |
return nil, err |
| 120 | 120 |
} |
| 121 |
- defer func() {
|
|
| 122 |
- if retErr != nil {
|
|
| 123 |
- if err := daemon.removeMountPoints(container, true); err != nil {
|
|
| 124 |
- logrus.Error(err) |
|
| 125 |
- } |
|
| 126 |
- } |
|
| 127 |
- }() |
|
| 128 | 121 |
|
| 129 | 122 |
if err := daemon.createContainerPlatformSpecificSettings(container, params.Config, params.HostConfig); err != nil {
|
| 130 | 123 |
return nil, err |
| ... | ... |
@@ -39,14 +39,7 @@ func (daemon *Daemon) ContainerRm(name string, config *types.ContainerRmConfig) |
| 39 | 39 |
return daemon.rmLink(container, name) |
| 40 | 40 |
} |
| 41 | 41 |
|
| 42 |
- err = daemon.cleanupContainer(container, config.ForceRemove) |
|
| 43 |
- if err == nil || config.ForceRemove {
|
|
| 44 |
- if e := daemon.removeMountPoints(container, config.RemoveVolume); e != nil {
|
|
| 45 |
- logrus.Error(e) |
|
| 46 |
- } |
|
| 47 |
- } |
|
| 48 |
- |
|
| 49 |
- return err |
|
| 42 |
+ return daemon.cleanupContainer(container, config.ForceRemove, config.RemoveVolume) |
|
| 50 | 43 |
} |
| 51 | 44 |
|
| 52 | 45 |
func (daemon *Daemon) rmLink(container *container.Container, name string) error {
|
| ... | ... |
@@ -77,7 +70,7 @@ func (daemon *Daemon) rmLink(container *container.Container, name string) error |
| 77 | 77 |
|
| 78 | 78 |
// cleanupContainer unregisters a container from the daemon, stops stats |
| 79 | 79 |
// collection and cleanly removes contents and metadata from the filesystem. |
| 80 |
-func (daemon *Daemon) cleanupContainer(container *container.Container, forceRemove bool) (err error) {
|
|
| 80 |
+func (daemon *Daemon) cleanupContainer(container *container.Container, forceRemove, removeVolume bool) (err error) {
|
|
| 81 | 81 |
if container.IsRunning() {
|
| 82 | 82 |
if !forceRemove {
|
| 83 | 83 |
err := fmt.Errorf("You cannot remove a running container %s. Stop the container before attempting removal or use -f", container.ID)
|
| ... | ... |
@@ -115,6 +108,9 @@ func (daemon *Daemon) cleanupContainer(container *container.Container, forceRemo |
| 115 | 115 |
selinuxFreeLxcContexts(container.ProcessLabel) |
| 116 | 116 |
daemon.idIndex.Delete(container.ID) |
| 117 | 117 |
daemon.containers.Delete(container.ID) |
| 118 |
+ if e := daemon.removeMountPoints(container, removeVolume); e != nil {
|
|
| 119 |
+ logrus.Error(e) |
|
| 120 |
+ } |
|
| 118 | 121 |
daemon.LogContainerEvent(container, "destroy") |
| 119 | 122 |
} |
| 120 | 123 |
}() |