A lot of time device mapper devices leak across mount namespace which docker
does not know about and when docker tries to deactivate/delete device,
operation fails as device is open in some mount namespace.
Create a mechanism where one can defer the device deactivation/deletion
so that docker operation does not fail and device automatically goes
away when last reference to it is dropped.
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
| ... | ... |
@@ -55,6 +55,7 @@ var ( |
| 55 | 55 |
ErrTaskGetDeps = errors.New("dm_task_get_deps failed")
|
| 56 | 56 |
ErrTaskGetInfo = errors.New("dm_task_get_info failed")
|
| 57 | 57 |
ErrTaskGetDriverVersion = errors.New("dm_task_get_driver_version failed")
|
| 58 |
+ ErrTaskDeferredRemove = errors.New("dm_task_deferred_remove failed")
|
|
| 58 | 59 |
ErrTaskSetCookie = errors.New("dm_task_set_cookie failed")
|
| 59 | 60 |
ErrNilCookie = errors.New("cookie ptr can't be nil")
|
| 60 | 61 |
ErrAttachLoopbackDevice = errors.New("loopback mounting failed")
|
| ... | ... |
@@ -371,6 +372,25 @@ func RemoveDevice(name string) error {
|
| 371 | 371 |
return nil |
| 372 | 372 |
} |
| 373 | 373 |
|
| 374 |
+func RemoveDeviceDeferred(name string) error {
|
|
| 375 |
+ logrus.Debugf("[devmapper] RemoveDeviceDeferred START(%s)", name)
|
|
| 376 |
+ defer logrus.Debugf("[devmapper] RemoveDeviceDeferred END(%s)", name)
|
|
| 377 |
+ task, err := TaskCreateNamed(DeviceRemove, name) |
|
| 378 |
+ if task == nil {
|
|
| 379 |
+ return err |
|
| 380 |
+ } |
|
| 381 |
+ |
|
| 382 |
+ if err := DmTaskDeferredRemove(task.unmanaged); err != 1 {
|
|
| 383 |
+ return ErrTaskDeferredRemove |
|
| 384 |
+ } |
|
| 385 |
+ |
|
| 386 |
+ if err = task.Run(); err != nil {
|
|
| 387 |
+ return fmt.Errorf("Error running RemoveDeviceDeferred %s", err)
|
|
| 388 |
+ } |
|
| 389 |
+ |
|
| 390 |
+ return nil |
|
| 391 |
+} |
|
| 392 |
+ |
|
| 374 | 393 |
func GetBlockDeviceSize(file *os.File) (uint64, error) {
|
| 375 | 394 |
size, err := ioctlBlkGetSize64(file.Fd()) |
| 376 | 395 |
if err != nil {
|
| 118 | 119 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,15 @@ |
| 0 |
+// +build linux,!libdm_no_deferred_remove |
|
| 1 |
+ |
|
| 2 |
+package devicemapper |
|
| 3 |
+ |
|
| 4 |
+/* |
|
| 5 |
+#cgo LDFLAGS: -L. -ldevmapper |
|
| 6 |
+#include <libdevmapper.h> |
|
| 7 |
+*/ |
|
| 8 |
+import "C" |
|
| 9 |
+ |
|
| 10 |
+const LibraryDeferredRemovalSupport = true |
|
| 11 |
+ |
|
| 12 |
+func dmTaskDeferredRemoveFct(task *CDmTask) int {
|
|
| 13 |
+ return int(C.dm_task_deferred_remove((*C.struct_dm_task)(task))) |
|
| 14 |
+} |