Browse code

devmapper: Cancel deferred deactivation if device is reactivated

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>

Vivek Goyal authored on 2015/04/22 07:14:59
Showing 1 changed files
... ...
@@ -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)