If device is being reactivated before it could go away and deferred
deactivation is scheduled on it, cancel it.
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
| ... | ... |
@@ -438,6 +438,12 @@ func (devices *DeviceSet) registerDevice(id int, hash string, size uint64, trans |
| 438 | 438 |
func (devices *DeviceSet) activateDeviceIfNeeded(info *DevInfo) error {
|
| 439 | 439 |
logrus.Debugf("activateDeviceIfNeeded(%v)", info.Hash)
|
| 440 | 440 |
|
| 441 |
+ // Make sure deferred removal on device is canceled, if one was |
|
| 442 |
+ // scheduled. |
|
| 443 |
+ if err := devices.cancelDeferredRemoval(info); err != nil {
|
|
| 444 |
+ return fmt.Errorf("Deivce Deferred Removal Cancellation Failed: %s", err)
|
|
| 445 |
+ } |
|
| 446 |
+ |
|
| 441 | 447 |
if devinfo, _ := devicemapper.GetInfo(info.Name()); devinfo != nil && devinfo.Exists != 0 {
|
| 442 | 448 |
return nil |
| 443 | 449 |
} |
| ... | ... |
@@ -1331,6 +1337,45 @@ func (devices *DeviceSet) removeDevice(devname string) error {
|
| 1331 | 1331 |
return err |
| 1332 | 1332 |
} |
| 1333 | 1333 |
|
| 1334 |
+func (devices *DeviceSet) cancelDeferredRemoval(info *DevInfo) error {
|
|
| 1335 |
+ if !devices.deferredRemove {
|
|
| 1336 |
+ return nil |
|
| 1337 |
+ } |
|
| 1338 |
+ |
|
| 1339 |
+ logrus.Debugf("[devmapper] cancelDeferredRemoval START(%s)", info.Name())
|
|
| 1340 |
+ defer logrus.Debugf("[devmapper] cancelDeferredRemoval END(%s)", info.Name)
|
|
| 1341 |
+ |
|
| 1342 |
+ devinfo, err := devicemapper.GetInfoWithDeferred(info.Name()) |
|
| 1343 |
+ |
|
| 1344 |
+ if devinfo != nil && devinfo.DeferredRemove == 0 {
|
|
| 1345 |
+ return nil |
|
| 1346 |
+ } |
|
| 1347 |
+ |
|
| 1348 |
+ // Cancel deferred remove |
|
| 1349 |
+ for i := 0; i < 100; i++ {
|
|
| 1350 |
+ err = devicemapper.CancelDeferredRemove(info.Name()) |
|
| 1351 |
+ if err == nil {
|
|
| 1352 |
+ break |
|
| 1353 |
+ } |
|
| 1354 |
+ |
|
| 1355 |
+ if err == devicemapper.ErrEnxio {
|
|
| 1356 |
+ // Device is probably already gone. Return success. |
|
| 1357 |
+ return nil |
|
| 1358 |
+ } |
|
| 1359 |
+ |
|
| 1360 |
+ if err != devicemapper.ErrBusy {
|
|
| 1361 |
+ return err |
|
| 1362 |
+ } |
|
| 1363 |
+ |
|
| 1364 |
+ // If we see EBUSY it may be a transient error, |
|
| 1365 |
+ // sleep a bit a retry a few times. |
|
| 1366 |
+ devices.Unlock() |
|
| 1367 |
+ time.Sleep(100 * time.Millisecond) |
|
| 1368 |
+ devices.Lock() |
|
| 1369 |
+ } |
|
| 1370 |
+ return err |
|
| 1371 |
+} |
|
| 1372 |
+ |
|
| 1334 | 1373 |
func (devices *DeviceSet) Shutdown() error {
|
| 1335 | 1374 |
logrus.Debugf("[deviceset %s] Shutdown()", devices.devicePrefix)
|
| 1336 | 1375 |
logrus.Debugf("[devmapper] Shutting down DeviceSet: %s", devices.root)
|