浏览代码

Merge pull request #18329 from liusdu/mount_err

Fix rm container error in aufs and devicemapper after daemon crash
Tibor Vass 9 年之前
父节点
当前提交
ba77a5b46f
共有 3 个文件被更改,包括 23 次插入9 次删除
  1. 8 0
      daemon/graphdriver/aufs/aufs.go
  2. 11 6
      daemon/graphdriver/devmapper/deviceset.go
  3. 4 3
      daemon/graphdriver/devmapper/driver.go

+ 8 - 0
daemon/graphdriver/aufs/aufs.go

@@ -332,6 +332,14 @@ func (a *Driver) Put(id string) error {
 
 	m := a.active[id]
 	if m == nil {
+		// but it might be still here
+		if a.Exists(id) {
+			path := path.Join(a.rootPath(), "mnt", id)
+			err := Unmount(path)
+			if err != nil {
+				logrus.Debugf("Failed to unmount %s aufs: %v", id, err)
+			}
+		}
 		return nil
 	}
 	if count := m.referenceCount; count > 1 {

+ 11 - 6
daemon/graphdriver/devmapper/deviceset.go

@@ -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")

+ 4 - 3
daemon/graphdriver/devmapper/driver.go

@@ -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)
 	}