瀏覽代碼

Merge pull request #16285 from calavera/cleanup_volumes_when_create_fails

Remove volume references when container creation fails.
Brian Goff 9 年之前
父節點
當前提交
59311faaed
共有 4 個文件被更改,包括 22 次插入5 次删除
  1. 9 4
      daemon/container_unix.go
  2. 7 0
      daemon/create.go
  3. 1 1
      daemon/delete.go
  4. 5 0
      daemon/volumes.go

+ 9 - 4
daemon/container_unix.go

@@ -1188,14 +1188,19 @@ func (container *Container) removeMountPoints(rm bool) error {
 		}
 		container.daemon.volumes.Decrement(m.Volume)
 		if rm {
-			if err := container.daemon.volumes.Remove(m.Volume); err != nil {
-				rmErrors = append(rmErrors, fmt.Sprintf("%v\n", err))
-				continue
+			err := container.daemon.volumes.Remove(m.Volume)
+			// ErrVolumeInUse is ignored because having this
+			// volume being referenced by othe container is
+			// not an error, but an implementation detail.
+			// This prevents docker from logging "ERROR: Volume in use"
+			// where there is another container using the volume.
+			if err != nil && err != ErrVolumeInUse {
+				rmErrors = append(rmErrors, err.Error())
 			}
 		}
 	}
 	if len(rmErrors) > 0 {
-		return fmt.Errorf("Error removing volumes:\n%v", rmErrors)
+		return fmt.Errorf("Error removing volumes:\n%v", strings.Join(rmErrors, "\n"))
 	}
 	return nil
 }

+ 7 - 0
daemon/create.go

@@ -101,6 +101,13 @@ func (daemon *Daemon) Create(config *runconfig.Config, hostConfig *runconfig.Hos
 	if err := daemon.setHostConfig(container, hostConfig); err != nil {
 		return nil, nil, err
 	}
+	defer func() {
+		if retErr != nil {
+			if err := container.removeMountPoints(true); err != nil {
+				logrus.Error(err)
+			}
+		}
+	}()
 	if err := container.Mount(); err != nil {
 		return nil, nil, err
 	}

+ 1 - 1
daemon/delete.go

@@ -56,7 +56,7 @@ func (daemon *Daemon) ContainerRm(name string, config *ContainerRmConfig) error
 	}
 
 	if err := container.removeMountPoints(config.RemoveVolume); err != nil {
-		logrus.Errorf("%v", err)
+		logrus.Error(err)
 	}
 
 	return nil

+ 5 - 0
daemon/volumes.go

@@ -9,6 +9,7 @@ import (
 	"strings"
 	"sync"
 
+	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/pkg/chrootarchive"
 	"github.com/docker/docker/pkg/system"
@@ -139,6 +140,7 @@ func (s *volumeStore) Create(name, driverName string, opts map[string]string) (v
 		return v, nil
 	}
 	s.mu.Unlock()
+	logrus.Debugf("Registering new volume reference: driver %s, name %s", driverName, name)
 
 	vd, err := getVolumeDriver(driverName)
 	if err != nil {
@@ -173,6 +175,7 @@ func (s *volumeStore) Remove(v volume.Volume) error {
 	s.mu.Lock()
 	defer s.mu.Unlock()
 	name := v.Name()
+	logrus.Debugf("Removing volume reference: driver %s, name %s", v.DriverName(), name)
 	vc, exists := s.vols[name]
 	if !exists {
 		return ErrNoSuchVolume
@@ -197,6 +200,7 @@ func (s *volumeStore) Remove(v volume.Volume) error {
 func (s *volumeStore) Increment(v volume.Volume) {
 	s.mu.Lock()
 	defer s.mu.Unlock()
+	logrus.Debugf("Incrementing volume reference: driver %s, name %s", v.DriverName(), v.Name())
 
 	vc, exists := s.vols[v.Name()]
 	if !exists {
@@ -211,6 +215,7 @@ func (s *volumeStore) Increment(v volume.Volume) {
 func (s *volumeStore) Decrement(v volume.Volume) {
 	s.mu.Lock()
 	defer s.mu.Unlock()
+	logrus.Debugf("Decrementing volume reference: driver %s, name %s", v.DriverName(), v.Name())
 
 	vc, exists := s.vols[v.Name()]
 	if !exists {