瀏覽代碼

Merge pull request #33877 from rhvgoyal/sync-removal

devicemapper: Wait for device removal if deferredRemoval=true and deferredDeletion=…
Sebastiaan van Stijn 8 年之前
父節點
當前提交
e04dbe5ac2
共有 2 個文件被更改,包括 33 次插入8 次删除
  1. 25 8
      daemon/graphdriver/devmapper/deviceset.go
  2. 8 0
      pkg/devicemapper/devmapper.go

+ 25 - 8
daemon/graphdriver/devmapper/deviceset.go

@@ -2087,7 +2087,16 @@ func (devices *DeviceSet) deleteDevice(info *devInfo, syncDelete bool) error {
 	}
 	}
 
 
 	// Try to deactivate device in case it is active.
 	// Try to deactivate device in case it is active.
-	if err := devices.deactivateDevice(info); err != nil {
+	// If deferred removal is enabled and deferred deletion is disabled
+	// then make sure device is removed synchronously. There have been
+	// some cases of device being busy for short duration and we would
+	// rather busy wait for device removal to take care of these cases.
+	deferredRemove := devices.deferredRemove
+	if !devices.deferredDelete {
+		deferredRemove = false
+	}
+
+	if err := devices.deactivateDeviceMode(info, deferredRemove); err != nil {
 		logrus.Debugf("devmapper: Error deactivating device: %s", err)
 		logrus.Debugf("devmapper: Error deactivating device: %s", err)
 		return err
 		return err
 	}
 	}
@@ -2144,6 +2153,11 @@ func (devices *DeviceSet) deactivatePool() error {
 }
 }
 
 
 func (devices *DeviceSet) deactivateDevice(info *devInfo) error {
 func (devices *DeviceSet) deactivateDevice(info *devInfo) error {
+	return devices.deactivateDeviceMode(info, devices.deferredRemove)
+}
+
+func (devices *DeviceSet) deactivateDeviceMode(info *devInfo, deferredRemove bool) error {
+	var err error
 	logrus.Debugf("devmapper: deactivateDevice START(%s)", info.Hash)
 	logrus.Debugf("devmapper: deactivateDevice START(%s)", info.Hash)
 	defer logrus.Debugf("devmapper: deactivateDevice END(%s)", info.Hash)
 	defer logrus.Debugf("devmapper: deactivateDevice END(%s)", info.Hash)
 
 
@@ -2156,14 +2170,17 @@ func (devices *DeviceSet) deactivateDevice(info *devInfo) error {
 		return nil
 		return nil
 	}
 	}
 
 
-	if devices.deferredRemove {
-		if err := devicemapper.RemoveDeviceDeferred(info.Name()); err != nil {
-			return err
-		}
+	if deferredRemove {
+		err = devicemapper.RemoveDeviceDeferred(info.Name())
 	} else {
 	} else {
-		if err := devices.removeDevice(info.Name()); err != nil {
-			return err
-		}
+		err = devices.removeDevice(info.Name())
+	}
+
+	// This function's semantics is such that it does not return an
+	// error if device does not exist. So if device went away by
+	// the time we actually tried to remove it, do not return error.
+	if err != devicemapper.ErrEnxio {
+		return err
 	}
 	}
 	return nil
 	return nil
 }
 }

+ 8 - 0
pkg/devicemapper/devmapper.go

@@ -336,10 +336,14 @@ func RemoveDevice(name string) error {
 	defer UdevWait(cookie)
 	defer UdevWait(cookie)
 
 
 	dmSawBusy = false // reset before the task is run
 	dmSawBusy = false // reset before the task is run
+	dmSawEnxio = false
 	if err = task.run(); err != nil {
 	if err = task.run(); err != nil {
 		if dmSawBusy {
 		if dmSawBusy {
 			return ErrBusy
 			return ErrBusy
 		}
 		}
+		if dmSawEnxio {
+			return ErrEnxio
+		}
 		return fmt.Errorf("devicemapper: Error running RemoveDevice %s", err)
 		return fmt.Errorf("devicemapper: Error running RemoveDevice %s", err)
 	}
 	}
 
 
@@ -380,7 +384,11 @@ func RemoveDeviceDeferred(name string) error {
 	// by udev, what UdevWait is just cleaning up the semaphore.
 	// by udev, what UdevWait is just cleaning up the semaphore.
 	defer UdevWait(cookie)
 	defer UdevWait(cookie)
 
 
+	dmSawEnxio = false
 	if err = task.run(); err != nil {
 	if err = task.run(); err != nil {
+		if dmSawEnxio {
+			return ErrEnxio
+		}
 		return fmt.Errorf("devicemapper: Error running RemoveDeviceDeferred %s", err)
 		return fmt.Errorf("devicemapper: Error running RemoveDeviceDeferred %s", err)
 	}
 	}