Browse Source

Remove volume references when container creation fails.

Volumes are accounted when a container is created.
If the creation fails we should remove the reference from the counter.
Do not log ErrVolumeInUse as an error, having other volume references is
not an error.

Signed-off-by: David Calavera <david.calavera@gmail.com>
David Calavera 9 years ago
parent
commit
2c6c07752c
4 changed files with 22 additions and 5 deletions
  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

@@ -1208,14 +1208,19 @@ func (container *Container) removeMountPoints(rm bool) error {
 		}
 		}
 		container.daemon.volumes.Decrement(m.Volume)
 		container.daemon.volumes.Decrement(m.Volume)
 		if rm {
 		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 {
 	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
 	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 {
 	if err := daemon.setHostConfig(container, hostConfig); err != nil {
 		return nil, nil, err
 		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 {
 	if err := container.Mount(); err != nil {
 		return nil, nil, err
 		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 {
 	if err := container.removeMountPoints(config.RemoveVolume); err != nil {
-		logrus.Errorf("%v", err)
+		logrus.Error(err)
 	}
 	}
 
 
 	return nil
 	return nil

+ 5 - 0
daemon/volumes.go

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