From ba02bf31cbffe329e549516e0004cf113ab4517e Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Wed, 30 Sep 2015 15:21:22 -0400 Subject: [PATCH 1/3] devmapper: Do not load transaction meta file in device Hash map device has map (device.Devices), contains valid devices and we skip all the files which are not device files. transaction metadata file is not device file. Skip this file when devices files are being read and loaded into map. Signed-off-by: Vivek Goyal --- daemon/graphdriver/devmapper/deviceset.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/daemon/graphdriver/devmapper/deviceset.go b/daemon/graphdriver/devmapper/deviceset.go index b07906402..b3d3c6d69 100644 --- a/daemon/graphdriver/devmapper/deviceset.go +++ b/daemon/graphdriver/devmapper/deviceset.go @@ -388,6 +388,11 @@ func (devices *DeviceSet) deviceFileWalkFunction(path string, finfo os.FileInfo) return nil } + if finfo.Name() == transactionMetaFile { + logrus.Debugf("Skipping file %s", path) + return nil + } + logrus.Debugf("Loading data for file %s", path) hash := finfo.Name() From f5c0eb9ffe9a9d30ac6ff81fa1a4c216908189a6 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Wed, 30 Sep 2015 15:21:22 -0400 Subject: [PATCH 2/3] devmapper: Fix comments and for HasDevice() and Exists() Exists() and HasDevice() just check if device file exists or not. It does not say anything about if device is mounted or not. Fix comments. Signed-off-by: Vivek Goyal --- daemon/graphdriver/devmapper/deviceset.go | 2 +- daemon/graphdriver/devmapper/driver.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/daemon/graphdriver/devmapper/deviceset.go b/daemon/graphdriver/devmapper/deviceset.go index b3d3c6d69..c2488faa1 100644 --- a/daemon/graphdriver/devmapper/deviceset.go +++ b/daemon/graphdriver/devmapper/deviceset.go @@ -1786,7 +1786,7 @@ func (devices *DeviceSet) UnmountDevice(hash string) error { return nil } -// HasDevice returns true if the device is in the hash and mounted. +// HasDevice returns true if the device metadata exists. func (devices *DeviceSet) HasDevice(hash string) bool { devices.Lock() defer devices.Unlock() diff --git a/daemon/graphdriver/devmapper/driver.go b/daemon/graphdriver/devmapper/driver.go index 67657f65e..dc2647d11 100644 --- a/daemon/graphdriver/devmapper/driver.go +++ b/daemon/graphdriver/devmapper/driver.go @@ -196,7 +196,7 @@ func (d *Driver) Put(id string) error { return err } -// Exists checks to see if the device is mounted. +// Exists checks to see if the device exists. func (d *Driver) Exists(id string) bool { return d.DeviceSet.HasDevice(id) } From e97e46b7376c3195383636d305d832b2ba3f82c5 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Wed, 30 Sep 2015 15:21:22 -0400 Subject: [PATCH 3/3] devmapper: Fail device deletion early if device is still mounted If a device is still mounted at the time of DeleteDevice(), that means higher layers have not called Put() properly on the device and are trying to delete it. This is a bug in the code where Get() and Put() have not been properly paired up. Fail device deletion if it is still mounted. Signed-off-by: Vivek Goyal --- daemon/graphdriver/devmapper/deviceset.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/daemon/graphdriver/devmapper/deviceset.go b/daemon/graphdriver/devmapper/deviceset.go index c2488faa1..e96127a00 100644 --- a/daemon/graphdriver/devmapper/deviceset.go +++ b/daemon/graphdriver/devmapper/deviceset.go @@ -1521,6 +1521,13 @@ func (devices *DeviceSet) DeleteDevice(hash string) error { devices.Lock() defer devices.Unlock() + // If mountcount is not zero, that means devices is still in use + // or has not been Put() properly. Fail device deletion. + + if info.mountCount != 0 { + return fmt.Errorf("devmapper: Can't delete device %v as it is still mounted. mntCount=%v", info.Hash, info.mountCount) + } + return devices.deleteDevice(info) }