diff --git a/devicemapper/devmapper.go b/devicemapper/devmapper.go index 42876d6..04ad912 100644 --- a/devicemapper/devmapper.go +++ b/devicemapper/devmapper.go @@ -70,9 +70,11 @@ var ( ErrLoopbackSetCapacity = errors.New("Unable set loopback capacity") ErrBusy = errors.New("Device is Busy") ErrDeviceIdExists = errors.New("Device Id Exists") + ErrEnxio = errors.New("No such device or address") dmSawBusy bool dmSawExist bool + dmSawEnxio bool // No Such Device or Address ) type ( @@ -391,6 +393,36 @@ func RemoveDeviceDeferred(name string) error { return nil } +// Useful helper for cleanup +func CancelDeferredRemove(deviceName string) error { + task, err := TaskCreateNamed(DeviceTargetMsg, deviceName) + if task == nil { + return err + } + + if err := task.SetSector(0); err != nil { + return fmt.Errorf("Can't set sector %s", err) + } + + if err := task.SetMessage(fmt.Sprintf("@cancel_deferred_remove")); err != nil { + return fmt.Errorf("Can't set message %s", err) + } + + dmSawBusy = false + dmSawEnxio = false + if err := task.Run(); err != nil { + // A device might be being deleted already + if dmSawBusy { + return ErrBusy + } else if dmSawEnxio { + return ErrEnxio + } + return fmt.Errorf("Error running CancelDeferredRemove %s", err) + + } + return nil +} + func GetBlockDeviceSize(file *os.File) (uint64, error) { size, err := ioctlBlkGetSize64(file.Fd()) if err != nil { diff --git a/devicemapper/devmapper_log.go b/devicemapper/devmapper_log.go index d6550bd..f66a208 100644 --- a/devicemapper/devmapper_log.go +++ b/devicemapper/devmapper_log.go @@ -22,6 +22,10 @@ func DevmapperLogCallback(level C.int, file *C.char, line C.int, dm_errno_or_cla if strings.Contains(msg, "File exists") { dmSawExist = true } + + if strings.Contains(msg, "No such device or address") { + dmSawEnxio = true + } } if dmLogger != nil {