Browse code

bugfix: report "destroy" after all volumes of container destroy

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>

Zhang Wei authored on 2016/08/17 12:02:16
Showing 2 changed files
... ...
@@ -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
 	}()