|
@@ -21,10 +21,12 @@ import (
|
|
|
"github.com/docker/docker/daemon/graphdriver"
|
|
|
"github.com/docker/docker/dockerversion"
|
|
|
"github.com/docker/docker/pkg/devicemapper"
|
|
|
+ "github.com/docker/docker/pkg/dmesg"
|
|
|
"github.com/docker/docker/pkg/idtools"
|
|
|
"github.com/docker/docker/pkg/loopback"
|
|
|
"github.com/docker/docker/pkg/mount"
|
|
|
"github.com/docker/docker/pkg/parsers"
|
|
|
+ "github.com/docker/docker/pkg/parsers/kernel"
|
|
|
units "github.com/docker/go-units"
|
|
|
"github.com/opencontainers/selinux/go-selinux/label"
|
|
|
"github.com/pkg/errors"
|
|
@@ -533,11 +535,11 @@ func (devices *DeviceSet) activateDeviceIfNeeded(info *devInfo, ignoreDeleted bo
|
|
|
return devicemapper.ActivateDevice(devices.getPoolDevName(), info.Name(), info.DeviceID, info.Size)
|
|
|
}
|
|
|
|
|
|
-// Return true only if kernel supports xfs and mkfs.xfs is available
|
|
|
-func xfsSupported() bool {
|
|
|
+// xfsSupported checks if xfs is supported, returns nil if it is, otherwise an error
|
|
|
+func xfsSupported() error {
|
|
|
// Make sure mkfs.xfs is available
|
|
|
if _, err := exec.LookPath("mkfs.xfs"); err != nil {
|
|
|
- return false
|
|
|
+ return err // error text is descriptive enough
|
|
|
}
|
|
|
|
|
|
// Check if kernel supports xfs filesystem or not.
|
|
@@ -545,40 +547,47 @@ func xfsSupported() bool {
|
|
|
|
|
|
f, err := os.Open("/proc/filesystems")
|
|
|
if err != nil {
|
|
|
- logrus.Warnf("devmapper: Could not check if xfs is supported: %v", err)
|
|
|
- return false
|
|
|
+ return errors.Wrapf(err, "error checking for xfs support")
|
|
|
}
|
|
|
defer f.Close()
|
|
|
|
|
|
s := bufio.NewScanner(f)
|
|
|
for s.Scan() {
|
|
|
if strings.HasSuffix(s.Text(), "\txfs") {
|
|
|
- return true
|
|
|
+ return nil
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if err := s.Err(); err != nil {
|
|
|
- logrus.Warnf("devmapper: Could not check if xfs is supported: %v", err)
|
|
|
+ return errors.Wrapf(err, "error checking for xfs support")
|
|
|
}
|
|
|
- return false
|
|
|
+
|
|
|
+ return errors.New(`kernel does not support xfs, or "modprobe xfs" failed`)
|
|
|
}
|
|
|
|
|
|
func determineDefaultFS() string {
|
|
|
- if xfsSupported() {
|
|
|
+ err := xfsSupported()
|
|
|
+ if err == nil {
|
|
|
return "xfs"
|
|
|
}
|
|
|
|
|
|
- logrus.Warn("devmapper: XFS is not supported in your system. Either the kernel doesn't support it or mkfs.xfs is not in your PATH. Defaulting to ext4 filesystem")
|
|
|
+ logrus.Warnf("devmapper: XFS is not supported in your system (%v). Defaulting to ext4 filesystem", err)
|
|
|
return "ext4"
|
|
|
}
|
|
|
|
|
|
-func (devices *DeviceSet) createFilesystem(info *devInfo) (err error) {
|
|
|
- devname := info.DevName()
|
|
|
+// mkfsOptions tries to figure out whether some additional mkfs options are required
|
|
|
+func mkfsOptions(fs string) []string {
|
|
|
+ if fs == "xfs" && !kernel.CheckKernelVersion(3, 16, 0) {
|
|
|
+ // For kernels earlier than 3.16 (and newer xfsutils),
|
|
|
+ // some xfs features need to be explicitly disabled.
|
|
|
+ return []string{"-m", "crc=0,finobt=0"}
|
|
|
+ }
|
|
|
|
|
|
- args := []string{}
|
|
|
- args = append(args, devices.mkfsArgs...)
|
|
|
+ return []string{}
|
|
|
+}
|
|
|
|
|
|
- args = append(args, devname)
|
|
|
+func (devices *DeviceSet) createFilesystem(info *devInfo) (err error) {
|
|
|
+ devname := info.DevName()
|
|
|
|
|
|
if devices.filesystem == "" {
|
|
|
devices.filesystem = determineDefaultFS()
|
|
@@ -587,7 +596,11 @@ func (devices *DeviceSet) createFilesystem(info *devInfo) (err error) {
|
|
|
return err
|
|
|
}
|
|
|
|
|
|
- logrus.Infof("devmapper: Creating filesystem %s on device %s", devices.filesystem, info.Name())
|
|
|
+ args := mkfsOptions(devices.filesystem)
|
|
|
+ args = append(args, devices.mkfsArgs...)
|
|
|
+ args = append(args, devname)
|
|
|
+
|
|
|
+ logrus.Infof("devmapper: Creating filesystem %s on device %s, mkfs args: %v", devices.filesystem, info.Name(), args)
|
|
|
defer func() {
|
|
|
if err != nil {
|
|
|
logrus.Infof("devmapper: Error while creating filesystem %s on device %s: %v", devices.filesystem, info.Name(), err)
|
|
@@ -1188,7 +1201,7 @@ func (devices *DeviceSet) growFS(info *devInfo) error {
|
|
|
options = joinMountOptions(options, devices.mountOptions)
|
|
|
|
|
|
if err := mount.Mount(info.DevName(), fsMountPoint, devices.BaseDeviceFilesystem, options); err != nil {
|
|
|
- return fmt.Errorf("Error mounting '%s' on '%s': %s", info.DevName(), fsMountPoint, err)
|
|
|
+ return fmt.Errorf("Error mounting '%s' on '%s': %s\n%v", info.DevName(), fsMountPoint, err, string(dmesg.Dmesg(256)))
|
|
|
}
|
|
|
|
|
|
defer unix.Unmount(fsMountPoint, unix.MNT_DETACH)
|
|
@@ -2379,7 +2392,7 @@ func (devices *DeviceSet) MountDevice(hash, path, mountLabel string) error {
|
|
|
options = joinMountOptions(options, label.FormatMountLabel("", mountLabel))
|
|
|
|
|
|
if err := mount.Mount(info.DevName(), path, fstype, options); err != nil {
|
|
|
- return fmt.Errorf("devmapper: Error mounting '%s' on '%s': %s", info.DevName(), path, err)
|
|
|
+ return fmt.Errorf("devmapper: Error mounting '%s' on '%s': %s\n%v", info.DevName(), path, err, string(dmesg.Dmesg(256)))
|
|
|
}
|
|
|
|
|
|
if fstype == "xfs" && devices.xfsNospaceRetries != "" {
|