Merge pull request #3256 from alexlarsson/blkdiscard

Discard all data on devicemapper devices when deleting them
This commit is contained in:
Michael Crosby 2014-01-18 10:12:10 -08:00
commit a60f0a0754
5 changed files with 49 additions and 0 deletions

View File

@ -568,6 +568,15 @@ func (devices *DeviceSet) removeDevice(hash string) error {
return fmt.Errorf("hash %s doesn't exists", hash) return fmt.Errorf("hash %s doesn't exists", hash)
} }
// This is a workaround for the kernel not discarding block so
// on the thin pool when we remove a thinp device, so we do it
// manually
if err := devices.activateDeviceIfNeeded(hash); err == nil {
if err := BlockDeviceDiscard(info.DevName()); err != nil {
utils.Debugf("Error discarding block on device: %s (ignoring)\n", err)
}
}
devinfo, _ := getInfo(info.Name()) devinfo, _ := getInfo(info.Name())
if devinfo != nil && devinfo.Exists != 0 { if devinfo != nil && devinfo.Exists != 0 {
if err := removeDevice(info.Name()); err != nil { if err := removeDevice(info.Name()); err != nil {

View File

@ -7,6 +7,7 @@ import (
"fmt" "fmt"
"github.com/dotcloud/docker/utils" "github.com/dotcloud/docker/utils"
"runtime" "runtime"
"syscall"
) )
type DevmapperLogger interface { type DevmapperLogger interface {
@ -288,6 +289,29 @@ func GetBlockDeviceSize(file *osFile) (uint64, error) {
return uint64(size), nil return uint64(size), nil
} }
func BlockDeviceDiscard(path string) error {
file, err := osOpenFile(path, osORdWr, 0)
if err != nil {
return err
}
defer file.Close()
size, err := GetBlockDeviceSize(file)
if err != nil {
return err
}
if err := ioctlBlkDiscard(file.Fd(), 0, size); err != nil {
return err
}
// Without this sometimes the remove of the device that happens after
// discard fails with EBUSY.
syscall.Sync()
return nil
}
// This is the programmatic example of "dmsetup create" // This is the programmatic example of "dmsetup create"
func createPool(poolName string, dataFile, metadataFile *osFile) error { func createPool(poolName string, dataFile, metadataFile *osFile) error {
task, err := createTask(DeviceCreate, poolName) task, err := createTask(DeviceCreate, poolName)

View File

@ -66,6 +66,7 @@ type (
// IOCTL consts // IOCTL consts
const ( const (
BlkGetSize64 = C.BLKGETSIZE64 BlkGetSize64 = C.BLKGETSIZE64
BlkDiscard = C.BLKDISCARD
LoopSetFd = C.LOOP_SET_FD LoopSetFd = C.LOOP_SET_FD
LoopCtlGetFree = C.LOOP_CTL_GET_FREE LoopCtlGetFree = C.LOOP_CTL_GET_FREE

View File

@ -641,6 +641,10 @@ func TestDriverRemove(t *testing.T) {
"DmTaskSetMessage", "DmTaskSetMessage",
"DmTaskCreate", "DmTaskCreate",
"DmTaskGetInfo", "DmTaskGetInfo",
"DmTaskSetCookie",
"DmTaskSetTarget",
"DmTaskSetAddNode",
"DmUdevWait",
"Mounted", "Mounted",
"sysUnmount", "sysUnmount",
) )

View File

@ -58,3 +58,14 @@ func ioctlBlkGetSize64(fd uintptr) (int64, error) {
} }
return size, nil return size, nil
} }
func ioctlBlkDiscard(fd uintptr, offset, length uint64) error {
var r [2]uint64
r[0] = offset
r[1] = length
if _, _, err := sysSyscall(sysSysIoctl, fd, BlkDiscard, uintptr(unsafe.Pointer(&r[0]))); err != 0 {
return err
}
return nil
}