Sfoglia il codice sorgente

Merge pull request #8266 from cpuguy83/fix_race_in_createing_volumes

Fix potential race in volume creation
Andrea Luzzardi 10 anni fa
parent
commit
3f2e4e94d7
2 ha cambiato i file con 26 aggiunte e 12 eliminazioni
  1. 4 7
      daemon/volumes.go
  2. 22 5
      volumes/repository.go

+ 4 - 7
daemon/volumes.go

@@ -111,12 +111,9 @@ func (container *Container) parseVolumeMountConfig() (map[string]*Mount, error)
 			return nil, err
 			return nil, err
 		}
 		}
 		// Check if a volume already exists for this and use it
 		// Check if a volume already exists for this and use it
-		vol := container.daemon.volumes.Get(path)
-		if vol == nil {
-			vol, err = container.daemon.volumes.NewVolume(path, writable)
-			if err != nil {
-				return nil, err
-			}
+		vol, err := container.daemon.volumes.FindOrCreateVolume(path, writable)
+		if err != nil {
+			return nil, err
 		}
 		}
 		mounts[mountToPath] = &Mount{container: container, volume: vol, MountToPath: mountToPath, Writable: writable}
 		mounts[mountToPath] = &Mount{container: container, volume: vol, MountToPath: mountToPath, Writable: writable}
 	}
 	}
@@ -128,7 +125,7 @@ func (container *Container) parseVolumeMountConfig() (map[string]*Mount, error)
 			continue
 			continue
 		}
 		}
 
 
-		vol, err := container.daemon.volumes.NewVolume("", true)
+		vol, err := container.daemon.volumes.FindOrCreateVolume("", true)
 		if err != nil {
 		if err != nil {
 			return nil, err
 			return nil, err
 		}
 		}

+ 22 - 5
volumes/repository.go

@@ -38,7 +38,7 @@ func NewRepository(configPath string, driver graphdriver.Driver) (*Repository, e
 	return repo, repo.restore()
 	return repo, repo.restore()
 }
 }
 
 
-func (r *Repository) NewVolume(path string, writable bool) (*Volume, error) {
+func (r *Repository) newVolume(path string, writable bool) (*Volume, error) {
 	var (
 	var (
 		isBindMount bool
 		isBindMount bool
 		err         error
 		err         error
@@ -73,10 +73,8 @@ func (r *Repository) NewVolume(path string, writable bool) (*Volume, error) {
 	if err := v.initialize(); err != nil {
 	if err := v.initialize(); err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
-	if err := r.Add(v); err != nil {
-		return nil, err
-	}
-	return v, nil
+
+	return v, r.add(v)
 }
 }
 
 
 func (r *Repository) restore() error {
 func (r *Repository) restore() error {
@@ -113,6 +111,10 @@ func (r *Repository) get(path string) *Volume {
 func (r *Repository) Add(volume *Volume) error {
 func (r *Repository) Add(volume *Volume) error {
 	r.lock.Lock()
 	r.lock.Lock()
 	defer r.lock.Unlock()
 	defer r.lock.Unlock()
+	return r.add(volume)
+}
+
+func (r *Repository) add(volume *Volume) error {
 	if vol := r.get(volume.Path); vol != nil {
 	if vol := r.get(volume.Path); vol != nil {
 		return fmt.Errorf("Volume exists: %s", volume.ID)
 		return fmt.Errorf("Volume exists: %s", volume.ID)
 	}
 	}
@@ -175,3 +177,18 @@ func (r *Repository) createNewVolumePath(id string) (string, error) {
 
 
 	return path, nil
 	return path, nil
 }
 }
+
+func (r *Repository) FindOrCreateVolume(path string, writable bool) (*Volume, error) {
+	r.lock.Lock()
+	defer r.lock.Unlock()
+
+	if path == "" {
+		return r.newVolume(path, writable)
+	}
+
+	if v := r.get(path); v != nil {
+		return v, nil
+	}
+
+	return r.newVolume(path, writable)
+}