From e3dc4873289a6995f55d1187dc26e829b23832e0 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Tue, 22 Aug 2017 00:55:20 +0300 Subject: [PATCH] devmapper: show dmesg if mount fails If mount fails, the reason might be right there in the kernel log ring buffer. Let's include it in the error message, it might be of great help. Signed-off-by: Kir Kolyshkin Upstream-commit: 46833ee1c353c247e3ef817a08d5a35a2a43bdf3 Component: engine --- .../daemon/graphdriver/devmapper/deviceset.go | 5 +++-- components/engine/pkg/dmesg/dmesg_linux.go | 20 +++++++++++++++++++ .../engine/pkg/dmesg/dmesg_linux_test.go | 9 +++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 components/engine/pkg/dmesg/dmesg_linux.go create mode 100644 components/engine/pkg/dmesg/dmesg_linux_test.go diff --git a/components/engine/daemon/graphdriver/devmapper/deviceset.go b/components/engine/daemon/graphdriver/devmapper/deviceset.go index a933b7414f..ca43b30a08 100644 --- a/components/engine/daemon/graphdriver/devmapper/deviceset.go +++ b/components/engine/daemon/graphdriver/devmapper/deviceset.go @@ -21,6 +21,7 @@ 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" @@ -1199,7 +1200,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) @@ -2390,7 +2391,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 != "" { diff --git a/components/engine/pkg/dmesg/dmesg_linux.go b/components/engine/pkg/dmesg/dmesg_linux.go new file mode 100644 index 0000000000..7df7f3d436 --- /dev/null +++ b/components/engine/pkg/dmesg/dmesg_linux.go @@ -0,0 +1,20 @@ +// +build linux + +package dmesg + +import ( + "unsafe" + + "golang.org/x/sys/unix" +) + +// Dmesg returns last messages from the kernel log, up to size bytes +func Dmesg(size int) []byte { + t := uintptr(3) // SYSLOG_ACTION_READ_ALL + b := make([]byte, size) + amt, _, err := unix.Syscall(unix.SYS_SYSLOG, t, uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))) + if err != 0 { + return []byte{} + } + return b[:amt] +} diff --git a/components/engine/pkg/dmesg/dmesg_linux_test.go b/components/engine/pkg/dmesg/dmesg_linux_test.go new file mode 100644 index 0000000000..c5028aac1d --- /dev/null +++ b/components/engine/pkg/dmesg/dmesg_linux_test.go @@ -0,0 +1,9 @@ +package dmesg + +import ( + "testing" +) + +func TestDmesg(t *testing.T) { + t.Logf("dmesg output follows:\n%v", string(Dmesg(512))) +}