1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

devmapper: Provide a new parameter dm.deferred_device_removal

Provide a new command line knob dm.deferred_device_removal which will enable
deferred device deactivation if driver and library support it.

This patch also checks for library support and driver version.

Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
This commit is contained in:
Vivek Goyal 2015-04-21 18:14:59 -04:00
parent 6964ab94be
commit 15c158b207
2 changed files with 83 additions and 2 deletions

View file

@ -252,3 +252,23 @@ Here is the list of supported options:
> Otherwise, set this flag for migrating existing Docker daemons to a
> daemon with a supported environment.
* `dm.use_deferred_removal`
Enables use of deferred device removal if libdm and kernel driver
support the mechanism.
Deferred device removal means that if device is busy when devices is
being removed/deactivated, then a deferred removal is scheduled on
device. And devices automatically goes away when last user of device
exits.
For example, when contianer exits, its associated thin device is
removed. If that devices has leaked into some other mount namespace
can can't be removed now, container exit will still be successful
and this option will just schedule device for deferred removal and
will not wait in a loop trying to remove a busy device.
Example use:
``docker -d --storage-opt dm.use_deferred_device_removal=true``

View file

@ -37,7 +37,9 @@ var (
// We retry device removal so many a times that even error messages
// will fill up console during normal operation. So only log Fatal
// messages by default.
DMLogLevel int = devicemapper.LogLevelFatal
DMLogLevel int = devicemapper.LogLevelFatal
DriverDeferredRemovalSupport bool = false
EnableDeferredRemoval bool = false
)
const deviceSetMetaFile string = "deviceset-metadata"
@ -103,6 +105,7 @@ type DeviceSet struct {
thinPoolDevice string
Transaction `json:"-"`
overrideUdevSyncCheck bool
deferredRemove bool // use deferred removal
}
type DiskUsage struct {
@ -960,16 +963,67 @@ func (devices *DeviceSet) closeTransaction() error {
return nil
}
func determineDriverCapabilities(version string) error {
/*
* Driver version 4.27.0 and greater support deferred activation
* feature.
*/
logrus.Debugf("devicemapper: driver version is %s", version)
versionSplit := strings.Split(version, ".")
major, err := strconv.Atoi(versionSplit[0])
if err != nil {
return graphdriver.ErrNotSupported
}
if major > 4 {
DriverDeferredRemovalSupport = true
return nil
}
if major < 4 {
return nil
}
minor, err := strconv.Atoi(versionSplit[1])
if err != nil {
return graphdriver.ErrNotSupported
}
/*
* If major is 4 and minor is 27, then there is no need to
* check for patch level as it can not be less than 0.
*/
if minor >= 27 {
DriverDeferredRemovalSupport = true
return nil
}
return nil
}
func (devices *DeviceSet) initDevmapper(doInit bool) error {
// give ourselves to libdm as a log handler
devicemapper.LogInit(devices)
_, err := devicemapper.GetDriverVersion()
version, err := devicemapper.GetDriverVersion()
if err != nil {
// Can't even get driver version, assume not supported
return graphdriver.ErrNotSupported
}
if err := determineDriverCapabilities(version); err != nil {
return graphdriver.ErrNotSupported
}
// If user asked for deferred removal and both library and driver
// supports deferred removal use it.
if EnableDeferredRemoval && DriverDeferredRemovalSupport && devicemapper.LibraryDeferredRemovalSupport == true {
logrus.Debugf("devmapper: Deferred removal support enabled.")
devices.deferredRemove = true
}
// https://github.com/docker/docker/issues/4036
if supported := devicemapper.UdevSetSyncSupport(true); !supported {
logrus.Errorf("Udev sync is not supported. This will lead to unexpected behavior, data loss and errors. For more information, see https://docs.docker.com/reference/commandline/cli/#daemon-storage-driver-option")
@ -1671,6 +1725,13 @@ func NewDeviceSet(root string, doInit bool, options []string) (*DeviceSet, error
if err != nil {
return nil, err
}
case "dm.use_deferred_removal":
EnableDeferredRemoval, err = strconv.ParseBool(val)
if err != nil {
return nil, err
}
default:
return nil, fmt.Errorf("Unknown option %s\n", key)
}