fix race condition between list and remove volume

This was done by making List not populate the cache.

fixes #21403

Signed-off-by: Viktor Stanchev <me@viktorstanchev.com>
(cherry picked from commit 800b9c5a26)
This commit is contained in:
Viktor Stanchev 2016-03-22 13:24:09 -07:00 committed by Tibor Vass
parent ea799625bd
commit f04334ea04
2 changed files with 8 additions and 8 deletions

View File

@ -127,9 +127,8 @@ func (s *VolumeStore) List() ([]volume.Volume, []string, error) {
s.locks.Lock(name) s.locks.Lock(name)
storedV, exists := s.getNamed(name) storedV, exists := s.getNamed(name)
if !exists { // Note: it's not safe to populate the cache here because the volume may have been
s.setNamed(v, "") // deleted before we acquire a lock on its name
}
if exists && storedV.DriverName() != v.DriverName() { if exists && storedV.DriverName() != v.DriverName() {
logrus.Warnf("Volume name %s already exists for driver %s, not including volume returned by %s", v.Name(), storedV.DriverName(), v.DriverName()) logrus.Warnf("Volume name %s already exists for driver %s, not including volume returned by %s", v.Name(), storedV.DriverName(), v.DriverName())
s.locks.Unlock(v.Name()) s.locks.Unlock(v.Name())

View File

@ -26,19 +26,20 @@ func (NoopVolume) Unmount() error { return nil }
// FakeVolume is a fake volume with a random name // FakeVolume is a fake volume with a random name
type FakeVolume struct { type FakeVolume struct {
name string name string
driverName string
} }
// NewFakeVolume creates a new fake volume for testing // NewFakeVolume creates a new fake volume for testing
func NewFakeVolume(name string) volume.Volume { func NewFakeVolume(name string, driverName string) volume.Volume {
return FakeVolume{name: name} return FakeVolume{name: name, driverName: driverName}
} }
// Name is the name of the volume // Name is the name of the volume
func (f FakeVolume) Name() string { return f.name } func (f FakeVolume) Name() string { return f.name }
// DriverName is the name of the driver // DriverName is the name of the driver
func (FakeVolume) DriverName() string { return "fake" } func (f FakeVolume) DriverName() string { return f.driverName }
// Path is the filesystem path to the volume // Path is the filesystem path to the volume
func (FakeVolume) Path() string { return "fake" } func (FakeVolume) Path() string { return "fake" }
@ -72,7 +73,7 @@ func (d *FakeDriver) Create(name string, opts map[string]string) (volume.Volume,
if opts != nil && opts["error"] != "" { if opts != nil && opts["error"] != "" {
return nil, fmt.Errorf(opts["error"]) return nil, fmt.Errorf(opts["error"])
} }
v := NewFakeVolume(name) v := NewFakeVolume(name, d.name)
d.vols[name] = v d.vols[name] = v
return v, nil return v, nil
} }