devicemapper: Add helper functions to allow deferred device removal
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>
This commit is contained in:
parent
1b9b5095ac
commit
64ffdbc701
4 changed files with 46 additions and 0 deletions
|
@ -55,6 +55,7 @@ var (
|
|||
ErrTaskGetDeps = errors.New("dm_task_get_deps failed")
|
||||
ErrTaskGetInfo = errors.New("dm_task_get_info failed")
|
||||
ErrTaskGetDriverVersion = errors.New("dm_task_get_driver_version failed")
|
||||
ErrTaskDeferredRemove = errors.New("dm_task_deferred_remove failed")
|
||||
ErrTaskSetCookie = errors.New("dm_task_set_cookie failed")
|
||||
ErrNilCookie = errors.New("cookie ptr can't be nil")
|
||||
ErrAttachLoopbackDevice = errors.New("loopback mounting failed")
|
||||
|
@ -371,6 +372,25 @@ func RemoveDevice(name string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func RemoveDeviceDeferred(name string) error {
|
||||
logrus.Debugf("[devmapper] RemoveDeviceDeferred START(%s)", name)
|
||||
defer logrus.Debugf("[devmapper] RemoveDeviceDeferred END(%s)", name)
|
||||
task, err := TaskCreateNamed(DeviceRemove, name)
|
||||
if task == nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := DmTaskDeferredRemove(task.unmanaged); err != 1 {
|
||||
return ErrTaskDeferredRemove
|
||||
}
|
||||
|
||||
if err = task.Run(); err != nil {
|
||||
return fmt.Errorf("Error running RemoveDeviceDeferred %s", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetBlockDeviceSize(file *os.File) (uint64, error) {
|
||||
size, err := ioctlBlkGetSize64(file.Fd())
|
||||
if err != nil {
|
||||
|
|
|
@ -112,6 +112,7 @@ var (
|
|||
DmUdevGetSyncSupport = dmUdevGetSyncSupportFct
|
||||
DmCookieSupported = dmCookieSupportedFct
|
||||
LogWithErrnoInit = logWithErrnoInitFct
|
||||
DmTaskDeferredRemove = dmTaskDeferredRemoveFct
|
||||
)
|
||||
|
||||
func free(p *C.char) {
|
||||
|
|
15
devicemapper/devmapper_wrapper_deferred_remove.go
Normal file
15
devicemapper/devmapper_wrapper_deferred_remove.go
Normal file
|
@ -0,0 +1,15 @@
|
|||
// +build linux,!libdm_no_deferred_remove
|
||||
|
||||
package devicemapper
|
||||
|
||||
/*
|
||||
#cgo LDFLAGS: -L. -ldevmapper
|
||||
#include <libdevmapper.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
const LibraryDeferredRemovalSupport = true
|
||||
|
||||
func dmTaskDeferredRemoveFct(task *CDmTask) int {
|
||||
return int(C.dm_task_deferred_remove((*C.struct_dm_task)(task)))
|
||||
}
|
10
devicemapper/devmapper_wrapper_no_deferred_remove.go
Normal file
10
devicemapper/devmapper_wrapper_no_deferred_remove.go
Normal file
|
@ -0,0 +1,10 @@
|
|||
// +build linux,libdm_no_deferred_remove
|
||||
|
||||
package devicemapper
|
||||
|
||||
const LibraryDeferredRemovalSupport = false
|
||||
|
||||
func dmTaskDeferredRemoveFct(task *CDmTask) int {
|
||||
// Error. Nobody should be calling it.
|
||||
return -1
|
||||
}
|
Loading…
Reference in a new issue