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")
|
ErrTaskGetDeps = errors.New("dm_task_get_deps failed")
|
||||||
ErrTaskGetInfo = errors.New("dm_task_get_info failed")
|
ErrTaskGetInfo = errors.New("dm_task_get_info failed")
|
||||||
ErrTaskGetDriverVersion = errors.New("dm_task_get_driver_version 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")
|
ErrTaskSetCookie = errors.New("dm_task_set_cookie failed")
|
||||||
ErrNilCookie = errors.New("cookie ptr can't be nil")
|
ErrNilCookie = errors.New("cookie ptr can't be nil")
|
||||||
ErrAttachLoopbackDevice = errors.New("loopback mounting failed")
|
ErrAttachLoopbackDevice = errors.New("loopback mounting failed")
|
||||||
|
@ -371,6 +372,25 @@ func RemoveDevice(name string) error {
|
||||||
return nil
|
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) {
|
func GetBlockDeviceSize(file *os.File) (uint64, error) {
|
||||||
size, err := ioctlBlkGetSize64(file.Fd())
|
size, err := ioctlBlkGetSize64(file.Fd())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -112,6 +112,7 @@ var (
|
||||||
DmUdevGetSyncSupport = dmUdevGetSyncSupportFct
|
DmUdevGetSyncSupport = dmUdevGetSyncSupportFct
|
||||||
DmCookieSupported = dmCookieSupportedFct
|
DmCookieSupported = dmCookieSupportedFct
|
||||||
LogWithErrnoInit = logWithErrnoInitFct
|
LogWithErrnoInit = logWithErrnoInitFct
|
||||||
|
DmTaskDeferredRemove = dmTaskDeferredRemoveFct
|
||||||
)
|
)
|
||||||
|
|
||||||
func free(p *C.char) {
|
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