mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Revert "Fix implicit DeviceMapper selection"
This reverts commit 0a376291b2
.
Signed-off-by: David Calavera <david.calavera@gmail.com>
This commit is contained in:
parent
a14b1f1e9d
commit
9af7afb9eb
5 changed files with 164 additions and 77 deletions
|
@ -30,7 +30,8 @@ var (
|
|||
DefaultDataLoopbackSize int64 = 100 * 1024 * 1024 * 1024
|
||||
DefaultMetaDataLoopbackSize int64 = 2 * 1024 * 1024 * 1024
|
||||
DefaultBaseFsSize uint64 = 10 * 1024 * 1024 * 1024
|
||||
DefaultThinpBlockSize uint32 = 128 // 64K = 128 512b sectors
|
||||
DefaultThinpBlockSize uint32 = 128 // 64K = 128 512b sectors
|
||||
DefaultUdevSyncOverride bool = false
|
||||
MaxDeviceId int = 0xffffff // 24 bit, pool limit
|
||||
DeviceIdMapSz int = (MaxDeviceId + 1) / 8
|
||||
// We retry device removal so many a times that even error messages
|
||||
|
@ -89,22 +90,23 @@ type DeviceSet struct {
|
|||
deviceIdMap []byte
|
||||
|
||||
// Options
|
||||
dataLoopbackSize int64
|
||||
metaDataLoopbackSize int64
|
||||
baseFsSize uint64
|
||||
filesystem string
|
||||
mountOptions string
|
||||
mkfsArgs []string
|
||||
dataDevice string // block or loop dev
|
||||
dataLoopFile string // loopback file, if used
|
||||
metadataDevice string // block or loop dev
|
||||
metadataLoopFile string // loopback file, if used
|
||||
doBlkDiscard bool
|
||||
thinpBlockSize uint32
|
||||
thinPoolDevice string
|
||||
Transaction `json:"-"`
|
||||
deferredRemove bool // use deferred removal
|
||||
BaseDeviceUUID string //save UUID of base device
|
||||
dataLoopbackSize int64
|
||||
metaDataLoopbackSize int64
|
||||
baseFsSize uint64
|
||||
filesystem string
|
||||
mountOptions string
|
||||
mkfsArgs []string
|
||||
dataDevice string // block or loop dev
|
||||
dataLoopFile string // loopback file, if used
|
||||
metadataDevice string // block or loop dev
|
||||
metadataLoopFile string // loopback file, if used
|
||||
doBlkDiscard bool
|
||||
thinpBlockSize uint32
|
||||
thinPoolDevice string
|
||||
Transaction `json:"-"`
|
||||
overrideUdevSyncCheck bool
|
||||
deferredRemove bool // use deferred removal
|
||||
BaseDeviceUUID string //save UUID of base device
|
||||
}
|
||||
|
||||
type DiskUsage struct {
|
||||
|
@ -1104,7 +1106,10 @@ func (devices *DeviceSet) initDevmapper(doInit bool) error {
|
|||
|
||||
// https://github.com/docker/docker/issues/4036
|
||||
if supported := devicemapper.UdevSetSyncSupport(true); !supported {
|
||||
logrus.Warn("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")
|
||||
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")
|
||||
if !devices.overrideUdevSyncCheck {
|
||||
return graphdriver.ErrNotSupported
|
||||
}
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(devices.metadataDir(), 0700); err != nil && !os.IsExist(err) {
|
||||
|
@ -1786,15 +1791,16 @@ func NewDeviceSet(root string, doInit bool, options []string) (*DeviceSet, error
|
|||
devicemapper.SetDevDir("/dev")
|
||||
|
||||
devices := &DeviceSet{
|
||||
root: root,
|
||||
MetaData: MetaData{Devices: make(map[string]*DevInfo)},
|
||||
dataLoopbackSize: DefaultDataLoopbackSize,
|
||||
metaDataLoopbackSize: DefaultMetaDataLoopbackSize,
|
||||
baseFsSize: DefaultBaseFsSize,
|
||||
filesystem: "ext4",
|
||||
doBlkDiscard: true,
|
||||
thinpBlockSize: DefaultThinpBlockSize,
|
||||
deviceIdMap: make([]byte, DeviceIdMapSz),
|
||||
root: root,
|
||||
MetaData: MetaData{Devices: make(map[string]*DevInfo)},
|
||||
dataLoopbackSize: DefaultDataLoopbackSize,
|
||||
metaDataLoopbackSize: DefaultMetaDataLoopbackSize,
|
||||
baseFsSize: DefaultBaseFsSize,
|
||||
overrideUdevSyncCheck: DefaultUdevSyncOverride,
|
||||
filesystem: "ext4",
|
||||
doBlkDiscard: true,
|
||||
thinpBlockSize: DefaultThinpBlockSize,
|
||||
deviceIdMap: make([]byte, DeviceIdMapSz),
|
||||
}
|
||||
|
||||
foundBlkDiscard := false
|
||||
|
@ -1851,6 +1857,12 @@ func NewDeviceSet(root string, doInit bool, options []string) (*DeviceSet, error
|
|||
}
|
||||
// convert to 512b sectors
|
||||
devices.thinpBlockSize = uint32(size) >> 9
|
||||
case "dm.override_udev_sync_check":
|
||||
devices.overrideUdevSyncCheck, err = strconv.ParseBool(val)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
case "dm.use_deferred_removal":
|
||||
EnableDeferredRemoval, err = strconv.ParseBool(val)
|
||||
if err != nil {
|
||||
|
|
|
@ -13,6 +13,7 @@ func init() {
|
|||
DefaultDataLoopbackSize = 300 * 1024 * 1024
|
||||
DefaultMetaDataLoopbackSize = 200 * 1024 * 1024
|
||||
DefaultBaseFsSize = 300 * 1024 * 1024
|
||||
DefaultUdevSyncOverride = true
|
||||
if err := graphtest.InitLoopbacks(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/autogen/dockerversion"
|
||||
"github.com/docker/docker/pkg/archive"
|
||||
)
|
||||
|
||||
|
@ -23,10 +22,9 @@ var (
|
|||
// All registred drivers
|
||||
drivers map[string]InitFunc
|
||||
|
||||
ErrNotSupported = errors.New("driver not supported")
|
||||
ErrPrerequisites = errors.New("prerequisites for driver not satisfied (wrong filesystem?)")
|
||||
ErrIncompatibleFS = fmt.Errorf("backing file system is unsupported for this graph driver")
|
||||
ErrDeviceMapperWithStaticDocker = fmt.Errorf("devicemapper storage driver cannot reliably be used with a statically linked docker binary: please either pick a different storage driver, install a dynamically linked docker binary, or force this unreliable setup anyway by specifying --storage-driver=devicemapper")
|
||||
ErrNotSupported = errors.New("driver not supported")
|
||||
ErrPrerequisites = errors.New("prerequisites for driver not satisfied (wrong filesystem?)")
|
||||
ErrIncompatibleFS = fmt.Errorf("backing file system is unsupported for this graph driver")
|
||||
)
|
||||
|
||||
type InitFunc func(root string, options []string) (Driver, error)
|
||||
|
@ -115,35 +113,36 @@ func New(root string, options []string) (driver Driver, err error) {
|
|||
}
|
||||
|
||||
// Guess for prior driver
|
||||
priorDriver, err := scanPriorDrivers(root)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(priorDriver) != 0 {
|
||||
// Do not allow devicemapper when it's not explicit and the Docker binary was built statically.
|
||||
if staticWithDeviceMapper(priorDriver) {
|
||||
return nil, ErrDeviceMapperWithStaticDocker
|
||||
priorDrivers := scanPriorDrivers(root)
|
||||
for _, name := range priority {
|
||||
if name == "vfs" {
|
||||
// don't use vfs even if there is state present.
|
||||
continue
|
||||
}
|
||||
|
||||
driver, err = GetDriver(priorDriver, root, options)
|
||||
if err != nil {
|
||||
// unlike below, we will return error here, because there is prior
|
||||
// state, and now it is no longer supported/prereq/compatible, so
|
||||
// something changed and needs attention. Otherwise the daemon's
|
||||
// images would just "disappear".
|
||||
logrus.Errorf("[graphdriver] prior storage driver %q failed: %s", priorDriver, err)
|
||||
return nil, err
|
||||
for _, prior := range priorDrivers {
|
||||
// of the state found from prior drivers, check in order of our priority
|
||||
// which we would prefer
|
||||
if prior == name {
|
||||
driver, err = GetDriver(name, root, options)
|
||||
if err != nil {
|
||||
// unlike below, we will return error here, because there is prior
|
||||
// state, and now it is no longer supported/prereq/compatible, so
|
||||
// something changed and needs attention. Otherwise the daemon's
|
||||
// images would just "disappear".
|
||||
logrus.Errorf("[graphdriver] prior storage driver %q failed: %s", name, err)
|
||||
return nil, err
|
||||
}
|
||||
if err := checkPriorDriver(name, root); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
logrus.Infof("[graphdriver] using prior storage driver %q", name)
|
||||
return driver, nil
|
||||
}
|
||||
}
|
||||
logrus.Infof("[graphdriver] using prior storage driver %q", priorDriver)
|
||||
return driver, nil
|
||||
}
|
||||
|
||||
// Check for priority drivers first
|
||||
for _, name := range priority {
|
||||
if staticWithDeviceMapper(name) {
|
||||
continue
|
||||
}
|
||||
driver, err = GetDriver(name, root, options)
|
||||
if err != nil {
|
||||
if err == ErrNotSupported || err == ErrPrerequisites || err == ErrIncompatibleFS {
|
||||
|
@ -155,10 +154,7 @@ func New(root string, options []string) (driver Driver, err error) {
|
|||
}
|
||||
|
||||
// Check all registered drivers if no priority driver is found
|
||||
for name, initFunc := range drivers {
|
||||
if staticWithDeviceMapper(name) {
|
||||
continue
|
||||
}
|
||||
for _, initFunc := range drivers {
|
||||
if driver, err = initFunc(root, options); err != nil {
|
||||
if err == ErrNotSupported || err == ErrPrerequisites || err == ErrIncompatibleFS {
|
||||
continue
|
||||
|
@ -170,31 +166,31 @@ func New(root string, options []string) (driver Driver, err error) {
|
|||
return nil, fmt.Errorf("No supported storage backend found")
|
||||
}
|
||||
|
||||
// scanPriorDrivers returns a previosly used driver.
|
||||
// it returns an error when there are several drivers scanned.
|
||||
func scanPriorDrivers(root string) (string, error) {
|
||||
var priorDrivers []string
|
||||
// scanPriorDrivers returns an un-ordered scan of directories of prior storage drivers
|
||||
func scanPriorDrivers(root string) []string {
|
||||
priorDrivers := []string{}
|
||||
for driver := range drivers {
|
||||
p := filepath.Join(root, driver)
|
||||
if _, err := os.Stat(p); err == nil && driver != "vfs" {
|
||||
if _, err := os.Stat(p); err == nil {
|
||||
priorDrivers = append(priorDrivers, driver)
|
||||
}
|
||||
}
|
||||
return priorDrivers
|
||||
}
|
||||
|
||||
if len(priorDrivers) > 1 {
|
||||
return "", multipleDriversError(root, priorDrivers)
|
||||
func checkPriorDriver(name, root string) error {
|
||||
priorDrivers := []string{}
|
||||
for _, prior := range scanPriorDrivers(root) {
|
||||
if prior != name && prior != "vfs" {
|
||||
if _, err := os.Stat(filepath.Join(root, prior)); err == nil {
|
||||
priorDrivers = append(priorDrivers, prior)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(priorDrivers) == 0 {
|
||||
return "", nil
|
||||
if len(priorDrivers) > 0 {
|
||||
|
||||
return errors.New(fmt.Sprintf("%q contains other graphdrivers: %s; Please cleanup or explicitly choose storage driver (-s <DRIVER>)", root, strings.Join(priorDrivers, ",")))
|
||||
}
|
||||
return priorDrivers[0], nil
|
||||
}
|
||||
|
||||
func multipleDriversError(root string, drivers []string) error {
|
||||
return fmt.Errorf("%q contains several graphdrivers: %s; Please cleanup or explicitly choose storage driver (--storage-driver <DRIVER>)", root, strings.Join(drivers, ", "))
|
||||
}
|
||||
|
||||
func staticWithDeviceMapper(name string) bool {
|
||||
return name == "devicemapper" && dockerversion.IAMSTATIC == "true"
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -323,6 +323,45 @@ options for `zfs` start with `zfs`.
|
|||
|
||||
$ docker -d --storage-opt dm.blkdiscard=false
|
||||
|
||||
* `dm.override_udev_sync_check`
|
||||
|
||||
Overrides the `udev` synchronization checks between `devicemapper` and `udev`.
|
||||
`udev` is the device manager for the Linux kernel.
|
||||
|
||||
To view the `udev` sync support of a Docker daemon that is using the
|
||||
`devicemapper` driver, run:
|
||||
|
||||
$ docker info
|
||||
[...]
|
||||
Udev Sync Supported: true
|
||||
[...]
|
||||
|
||||
When `udev` sync support is `true`, then `devicemapper` and udev can
|
||||
coordinate the activation and deactivation of devices for containers.
|
||||
|
||||
When `udev` sync support is `false`, a race condition occurs between
|
||||
the`devicemapper` and `udev` during create and cleanup. The race condition
|
||||
results in errors and failures. (For information on these failures, see
|
||||
[docker#4036](https://github.com/docker/docker/issues/4036))
|
||||
|
||||
To allow the `docker` daemon to start, regardless of `udev` sync not being
|
||||
supported, set `dm.override_udev_sync_check` to true:
|
||||
|
||||
$ docker -d --storage-opt dm.override_udev_sync_check=true
|
||||
|
||||
When this value is `true`, the `devicemapper` continues and simply warns
|
||||
you the errors are happening.
|
||||
|
||||
> **Note:**
|
||||
> The ideal is to pursue a `docker` daemon and environment that does
|
||||
> support synchronizing with `udev`. For further discussion on this
|
||||
> topic, see [docker#4036](https://github.com/docker/docker/issues/4036).
|
||||
> Otherwise, set this flag for migrating existing Docker daemons to
|
||||
> a daemon with a supported environment.
|
||||
|
||||
|
||||
## Docker execdriver option
|
||||
|
||||
Currently supported options of `zfs`:
|
||||
|
||||
* `zfs.fsname`
|
||||
|
|
|
@ -451,6 +451,45 @@ removed.
|
|||
|
||||
Example use: `docker -d --storage-opt dm.blkdiscard=false`
|
||||
|
||||
#### dm.override_udev_sync_check
|
||||
|
||||
By default, the devicemapper backend attempts to synchronize with the
|
||||
`udev` device manager for the Linux kernel. This option allows
|
||||
disabling that synchronization, to continue even though the
|
||||
configuration may be buggy.
|
||||
|
||||
To view the `udev` sync support of a Docker daemon that is using the
|
||||
`devicemapper` driver, run:
|
||||
|
||||
$ docker info
|
||||
[...]
|
||||
Udev Sync Supported: true
|
||||
[...]
|
||||
|
||||
When `udev` sync support is `true`, then `devicemapper` and `udev` can
|
||||
coordinate the activation and deactivation of devices for containers.
|
||||
|
||||
When `udev` sync support is `false`, a race condition occurs between
|
||||
the`devicemapper` and `udev` during create and cleanup. The race
|
||||
condition results in errors and failures. (For information on these
|
||||
failures, see
|
||||
[docker#4036](https://github.com/docker/docker/issues/4036))
|
||||
|
||||
To allow the `docker` daemon to start, regardless of whether `udev` sync is
|
||||
`false`, set `dm.override_udev_sync_check` to true:
|
||||
|
||||
$ docker -d --storage-opt dm.override_udev_sync_check=true
|
||||
|
||||
When this value is `true`, the driver continues and simply warns you
|
||||
the errors are happening.
|
||||
|
||||
**Note**: The ideal is to pursue a `docker` daemon and environment
|
||||
that does support synchronizing with `udev`. For further discussion on
|
||||
this topic, see
|
||||
[docker#4036](https://github.com/docker/docker/issues/4036).
|
||||
Otherwise, set this flag for migrating existing Docker daemons to a
|
||||
daemon with a supported environment.
|
||||
|
||||
# EXEC DRIVER OPTIONS
|
||||
|
||||
Use the **--exec-opt** flags to specify options to the exec-driver. The only
|
||||
|
|
Loading…
Reference in a new issue