|
@@ -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)
|
|
|
- }
|
|
|
-
|
|
|
- if len(priorDrivers) == 0 {
|
|
|
- return "", nil
|
|
|
+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)
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
- 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, ", "))
|
|
|
-}
|
|
|
+ if len(priorDrivers) > 0 {
|
|
|
|
|
|
-func staticWithDeviceMapper(name string) bool {
|
|
|
- return name == "devicemapper" && dockerversion.IAMSTATIC == "true"
|
|
|
+ return errors.New(fmt.Sprintf("%q contains other graphdrivers: %s; Please cleanup or explicitly choose storage driver (-s <DRIVER>)", root, strings.Join(priorDrivers, ",")))
|
|
|
+ }
|
|
|
+ return nil
|
|
|
}
|