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:
parent
6964ab94be
commit
15c158b207
2 changed files with 83 additions and 2 deletions
|
@ -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``
|
||||
|
||||
|
|
|
@ -38,6 +38,8 @@ var (
|
|||
// will fill up console during normal operation. So only log Fatal
|
||||
// messages by default.
|
||||
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)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue