From 8d7c7bd2e3aba3bba72264d477c56444c5dc6350 Mon Sep 17 00:00:00 2001 From: Brian Goff Date: Fri, 26 Sep 2014 20:42:24 -0400 Subject: [PATCH] Fix potential race in volume creation Docker-DCO-1.1-Signed-off-by: Brian Goff (github: cpuguy83) --- daemon/volumes.go | 11 ++++------- volumes/repository.go | 27 ++++++++++++++++++++++----- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/daemon/volumes.go b/daemon/volumes.go index 4f83f6c513..71c2f18e4b 100644 --- a/daemon/volumes.go +++ b/daemon/volumes.go @@ -111,12 +111,9 @@ func (container *Container) parseVolumeMountConfig() (map[string]*Mount, error) return nil, err } // 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} } @@ -128,7 +125,7 @@ func (container *Container) parseVolumeMountConfig() (map[string]*Mount, error) continue } - vol, err := container.daemon.volumes.NewVolume("", true) + vol, err := container.daemon.volumes.FindOrCreateVolume("", true) if err != nil { return nil, err } diff --git a/volumes/repository.go b/volumes/repository.go index b09af8de26..06dbc8f0a4 100644 --- a/volumes/repository.go +++ b/volumes/repository.go @@ -38,7 +38,7 @@ func NewRepository(configPath string, driver graphdriver.Driver) (*Repository, e 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 ( isBindMount bool err error @@ -73,10 +73,8 @@ func (r *Repository) NewVolume(path string, writable bool) (*Volume, error) { if err := v.initialize(); err != nil { 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 { @@ -113,6 +111,10 @@ func (r *Repository) get(path string) *Volume { func (r *Repository) Add(volume *Volume) error { r.lock.Lock() defer r.lock.Unlock() + return r.add(volume) +} + +func (r *Repository) add(volume *Volume) error { if vol := r.get(volume.Path); vol != nil { return fmt.Errorf("Volume exists: %s", volume.ID) } @@ -175,3 +177,18 @@ func (r *Repository) createNewVolumePath(id string) (string, error) { 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) +}