Fix Put without Get in devicemapper

Signed-off-by: Liu Hua <sdu.liu@huawei.com>
This commit is contained in:
Liu Hua 2015-12-03 22:22:25 +08:00
parent db6c4c99d8
commit f7bdb97357
2 changed files with 15 additions and 9 deletions

View File

@ -2115,7 +2115,7 @@ func (devices *DeviceSet) MountDevice(hash, path, mountLabel string) error {
}
// UnmountDevice unmounts the device and removes it from hash.
func (devices *DeviceSet) UnmountDevice(hash string) error {
func (devices *DeviceSet) UnmountDevice(hash, mountPath string) error {
logrus.Debugf("[devmapper] UnmountDevice(hash=%s)", hash)
defer logrus.Debugf("[devmapper] UnmountDevice(hash=%s) END", hash)
@ -2130,17 +2130,22 @@ func (devices *DeviceSet) UnmountDevice(hash string) error {
devices.Lock()
defer devices.Unlock()
if info.mountCount == 0 {
return fmt.Errorf("UnmountDevice: device not-mounted id %s", hash)
}
// If there are running containers when daemon crashes, during daemon
// restarting, it will kill running contaienrs and will finally call
// Put() without calling Get(). So info.MountCount may become negative.
// if info.mountCount goes negative, we do the unmount and assign
// it to 0.
info.mountCount--
if info.mountCount > 0 {
return nil
} else if info.mountCount < 0 {
logrus.Warnf("[devmapper] Mount count of device went negative. Put() called without matching Get(). Resetting count to 0")
info.mountCount = 0
}
logrus.Debugf("[devmapper] Unmount(%s)", info.mountPath)
if err := syscall.Unmount(info.mountPath, syscall.MNT_DETACH); err != nil {
logrus.Debugf("[devmapper] Unmount(%s)", mountPath)
if err := syscall.Unmount(mountPath, syscall.MNT_DETACH); err != nil {
return err
}
logrus.Debugf("[devmapper] Unmount done")

View File

@ -186,7 +186,7 @@ func (d *Driver) Get(id, mountLabel string) (string, error) {
rootFs := path.Join(mp, "rootfs")
if err := idtools.MkdirAllAs(rootFs, 0755, uid, gid); err != nil && !os.IsExist(err) {
d.DeviceSet.UnmountDevice(id)
d.DeviceSet.UnmountDevice(id, mp)
return "", err
}
@ -195,7 +195,7 @@ func (d *Driver) Get(id, mountLabel string) (string, error) {
// Create an "id" file with the container/image id in it to help reconscruct this in case
// of later problems
if err := ioutil.WriteFile(idFile, []byte(id), 0600); err != nil {
d.DeviceSet.UnmountDevice(id)
d.DeviceSet.UnmountDevice(id, mp)
return "", err
}
}
@ -205,7 +205,8 @@ func (d *Driver) Get(id, mountLabel string) (string, error) {
// Put unmounts a device and removes it.
func (d *Driver) Put(id string) error {
err := d.DeviceSet.UnmountDevice(id)
mp := path.Join(d.home, "mnt", id)
err := d.DeviceSet.UnmountDevice(id, mp)
if err != nil {
logrus.Errorf("Error unmounting device %s: %s", id, err)
}