From 0434a2ce64c0ce07e97e9a516cef226be67d5f5b Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Tue, 1 Apr 2014 15:41:25 +0200 Subject: [PATCH] devmapper: Add blkdiscard option and disable it on raw devices The blkdiscard hack we do on container/image delete is pretty slow, but required to restore space to the "host" root filesystem. However, it is pretty useless on raw devices, and you may not need it in development either. In a simple test of the devicemapper backend on loopback the time to delete 20 container went from 11 seconds to 0.4 seconds with --storage-opt blkdiscard=false. Docker-DCO-1.1-Signed-off-by: Alexander Larsson (github: alexlarsson) --- daemon/graphdriver/devmapper/README.md | 16 +++++++++++++ daemon/graphdriver/devmapper/deviceset.go | 28 ++++++++++++++++++----- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/daemon/graphdriver/devmapper/README.md b/daemon/graphdriver/devmapper/README.md index 53b7174dba..ccff3f021b 100644 --- a/daemon/graphdriver/devmapper/README.md +++ b/daemon/graphdriver/devmapper/README.md @@ -125,3 +125,19 @@ Here is the list of supported options: Example use: ``docker -d --storage-opt dm.datadev=/dev/sdb1 --storage-opt dm.metadatadev=/dev/sdc1`` + + * `dm.blkdiscard` + + Enables or disables the use of blkdiscard when removing + devicemapper devices. This is enabled by default (only) if using + loopback devices and is required to res-parsify the loopback file + on image/container removal. + + Disabling this on loopback can lead to *much* faster container + removal times, but will make the space used in /var/lib/docker + directory not be returned to the system for other use when + containers are removed. + + Example use: + + ``docker -d --storage-opt dm.blkdiscard=false`` diff --git a/daemon/graphdriver/devmapper/deviceset.go b/daemon/graphdriver/devmapper/deviceset.go index 497e1102c2..a930bf2b96 100644 --- a/daemon/graphdriver/devmapper/deviceset.go +++ b/daemon/graphdriver/devmapper/deviceset.go @@ -77,6 +77,7 @@ type DeviceSet struct { mkfsArgs []string dataDevice string metadataDevice string + doBlkDiscard bool } type DiskUsage struct { @@ -713,12 +714,14 @@ func (devices *DeviceSet) AddDevice(hash, baseHash string) error { } func (devices *DeviceSet) deleteDevice(info *DevInfo) error { - // 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(info); err == nil { - if err := BlockDeviceDiscard(info.DevName()); err != nil { - utils.Debugf("Error discarding block on device: %s (ignoring)\n", err) + if devices.doBlkDiscard { + // 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(info); err == nil { + if err := BlockDeviceDiscard(info.DevName()); err != nil { + utils.Debugf("Error discarding block on device: %s (ignoring)\n", err) + } } } @@ -1174,8 +1177,10 @@ func NewDeviceSet(root string, doInit bool, options []string) (*DeviceSet, error metaDataLoopbackSize: DefaultMetaDataLoopbackSize, baseFsSize: DefaultBaseFsSize, filesystem: "ext4", + doBlkDiscard: true, } + foundBlkDiscard := false for _, option := range options { key, val, err := utils.ParseKeyValueOpt(option) if err != nil { @@ -1214,11 +1219,22 @@ func NewDeviceSet(root string, doInit bool, options []string) (*DeviceSet, error devices.metadataDevice = val case "dm.datadev": devices.dataDevice = val + case "dm.blkdiscard": + foundBlkDiscard = true + devices.doBlkDiscard, err = strconv.ParseBool(val) + if err != nil { + return nil, err + } default: return nil, fmt.Errorf("Unknown option %s\n", key) } } + // By default, don't do blk discard hack on raw devices, its rarely useful and is expensive + if !foundBlkDiscard && devices.dataDevice != "" { + devices.doBlkDiscard = false + } + if err := devices.initDevmapper(doInit); err != nil { return nil, err }