devicemapper: Wait for device removal if deferredRemoval=true and deferredDeletion=…
| ... | ... |
@@ -2087,7 +2087,16 @@ func (devices *DeviceSet) deleteDevice(info *devInfo, syncDelete bool) error {
|
| 2087 | 2087 |
} |
| 2088 | 2088 |
|
| 2089 | 2089 |
// Try to deactivate device in case it is active. |
| 2090 |
- if err := devices.deactivateDevice(info); err != nil {
|
|
| 2090 |
+ // If deferred removal is enabled and deferred deletion is disabled |
|
| 2091 |
+ // then make sure device is removed synchronously. There have been |
|
| 2092 |
+ // some cases of device being busy for short duration and we would |
|
| 2093 |
+ // rather busy wait for device removal to take care of these cases. |
|
| 2094 |
+ deferredRemove := devices.deferredRemove |
|
| 2095 |
+ if !devices.deferredDelete {
|
|
| 2096 |
+ deferredRemove = false |
|
| 2097 |
+ } |
|
| 2098 |
+ |
|
| 2099 |
+ if err := devices.deactivateDeviceMode(info, deferredRemove); err != nil {
|
|
| 2091 | 2100 |
logrus.Debugf("devmapper: Error deactivating device: %s", err)
|
| 2092 | 2101 |
return err |
| 2093 | 2102 |
} |
| ... | ... |
@@ -2144,6 +2153,11 @@ func (devices *DeviceSet) deactivatePool() error {
|
| 2144 | 2144 |
} |
| 2145 | 2145 |
|
| 2146 | 2146 |
func (devices *DeviceSet) deactivateDevice(info *devInfo) error {
|
| 2147 |
+ return devices.deactivateDeviceMode(info, devices.deferredRemove) |
|
| 2148 |
+} |
|
| 2149 |
+ |
|
| 2150 |
+func (devices *DeviceSet) deactivateDeviceMode(info *devInfo, deferredRemove bool) error {
|
|
| 2151 |
+ var err error |
|
| 2147 | 2152 |
logrus.Debugf("devmapper: deactivateDevice START(%s)", info.Hash)
|
| 2148 | 2153 |
defer logrus.Debugf("devmapper: deactivateDevice END(%s)", info.Hash)
|
| 2149 | 2154 |
|
| ... | ... |
@@ -2156,14 +2170,17 @@ func (devices *DeviceSet) deactivateDevice(info *devInfo) error {
|
| 2156 | 2156 |
return nil |
| 2157 | 2157 |
} |
| 2158 | 2158 |
|
| 2159 |
- if devices.deferredRemove {
|
|
| 2160 |
- if err := devicemapper.RemoveDeviceDeferred(info.Name()); err != nil {
|
|
| 2161 |
- return err |
|
| 2162 |
- } |
|
| 2159 |
+ if deferredRemove {
|
|
| 2160 |
+ err = devicemapper.RemoveDeviceDeferred(info.Name()) |
|
| 2163 | 2161 |
} else {
|
| 2164 |
- if err := devices.removeDevice(info.Name()); err != nil {
|
|
| 2165 |
- return err |
|
| 2166 |
- } |
|
| 2162 |
+ err = devices.removeDevice(info.Name()) |
|
| 2163 |
+ } |
|
| 2164 |
+ |
|
| 2165 |
+ // This function's semantics is such that it does not return an |
|
| 2166 |
+ // error if device does not exist. So if device went away by |
|
| 2167 |
+ // the time we actually tried to remove it, do not return error. |
|
| 2168 |
+ if err != devicemapper.ErrEnxio {
|
|
| 2169 |
+ return err |
|
| 2167 | 2170 |
} |
| 2168 | 2171 |
return nil |
| 2169 | 2172 |
} |
| ... | ... |
@@ -336,10 +336,14 @@ func RemoveDevice(name string) error {
|
| 336 | 336 |
defer UdevWait(cookie) |
| 337 | 337 |
|
| 338 | 338 |
dmSawBusy = false // reset before the task is run |
| 339 |
+ dmSawEnxio = false |
|
| 339 | 340 |
if err = task.run(); err != nil {
|
| 340 | 341 |
if dmSawBusy {
|
| 341 | 342 |
return ErrBusy |
| 342 | 343 |
} |
| 344 |
+ if dmSawEnxio {
|
|
| 345 |
+ return ErrEnxio |
|
| 346 |
+ } |
|
| 343 | 347 |
return fmt.Errorf("devicemapper: Error running RemoveDevice %s", err)
|
| 344 | 348 |
} |
| 345 | 349 |
|
| ... | ... |
@@ -380,7 +384,11 @@ func RemoveDeviceDeferred(name string) error {
|
| 380 | 380 |
// by udev, what UdevWait is just cleaning up the semaphore. |
| 381 | 381 |
defer UdevWait(cookie) |
| 382 | 382 |
|
| 383 |
+ dmSawEnxio = false |
|
| 383 | 384 |
if err = task.run(); err != nil {
|
| 385 |
+ if dmSawEnxio {
|
|
| 386 |
+ return ErrEnxio |
|
| 387 |
+ } |
|
| 384 | 388 |
return fmt.Errorf("devicemapper: Error running RemoveDeviceDeferred %s", err)
|
| 385 | 389 |
} |
| 386 | 390 |
|