Browse code

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 <kolyshkin@gmail.com>

Kir Kolyshkin authored on 2017/08/22 06:55:20
Showing 3 changed files
... ...
@@ -21,6 +21,7 @@ import (
21 21
 	"github.com/docker/docker/daemon/graphdriver"
22 22
 	"github.com/docker/docker/dockerversion"
23 23
 	"github.com/docker/docker/pkg/devicemapper"
24
+	"github.com/docker/docker/pkg/dmesg"
24 25
 	"github.com/docker/docker/pkg/idtools"
25 26
 	"github.com/docker/docker/pkg/loopback"
26 27
 	"github.com/docker/docker/pkg/mount"
... ...
@@ -1199,7 +1200,7 @@ func (devices *DeviceSet) growFS(info *devInfo) error {
1199 1199
 	options = joinMountOptions(options, devices.mountOptions)
1200 1200
 
1201 1201
 	if err := mount.Mount(info.DevName(), fsMountPoint, devices.BaseDeviceFilesystem, options); err != nil {
1202
-		return fmt.Errorf("Error mounting '%s' on '%s': %s", info.DevName(), fsMountPoint, err)
1202
+		return fmt.Errorf("Error mounting '%s' on '%s': %s\n%v", info.DevName(), fsMountPoint, err, string(dmesg.Dmesg(256)))
1203 1203
 	}
1204 1204
 
1205 1205
 	defer unix.Unmount(fsMountPoint, unix.MNT_DETACH)
... ...
@@ -2390,7 +2391,7 @@ func (devices *DeviceSet) MountDevice(hash, path, mountLabel string) error {
2390 2390
 	options = joinMountOptions(options, label.FormatMountLabel("", mountLabel))
2391 2391
 
2392 2392
 	if err := mount.Mount(info.DevName(), path, fstype, options); err != nil {
2393
-		return fmt.Errorf("devmapper: Error mounting '%s' on '%s': %s", info.DevName(), path, err)
2393
+		return fmt.Errorf("devmapper: Error mounting '%s' on '%s': %s\n%v", info.DevName(), path, err, string(dmesg.Dmesg(256)))
2394 2394
 	}
2395 2395
 
2396 2396
 	if fstype == "xfs" && devices.xfsNospaceRetries != "" {
2397 2397
new file mode 100644
... ...
@@ -0,0 +1,20 @@
0
+// +build linux
1
+
2
+package dmesg
3
+
4
+import (
5
+	"unsafe"
6
+
7
+	"golang.org/x/sys/unix"
8
+)
9
+
10
+// Dmesg returns last messages from the kernel log, up to size bytes
11
+func Dmesg(size int) []byte {
12
+	t := uintptr(3) // SYSLOG_ACTION_READ_ALL
13
+	b := make([]byte, size)
14
+	amt, _, err := unix.Syscall(unix.SYS_SYSLOG, t, uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)))
15
+	if err != 0 {
16
+		return []byte{}
17
+	}
18
+	return b[:amt]
19
+}
0 20
new file mode 100644
... ...
@@ -0,0 +1,9 @@
0
+package dmesg
1
+
2
+import (
3
+	"testing"
4
+)
5
+
6
+func TestDmesg(t *testing.T) {
7
+	t.Logf("dmesg output follows:\n%v", string(Dmesg(512)))
8
+}