Explorar el Código

devicemapper: Probe what filesystem to use when mounting

Docker-DCO-1.1-Signed-off-by: Alexander Larsson <alexl@redhat.com> (github: alexlarsson)
Alexander Larsson hace 11 años
padre
commit
10083f4140

+ 7 - 2
daemon/graphdriver/devmapper/deviceset.go

@@ -921,11 +921,16 @@ func (devices *DeviceSet) MountDevice(hash, path, mountLabel string) error {
 
 	var flags uintptr = syscall.MS_MGC_VAL
 
+	fstype, err := ProbeFsType(info.DevName())
+	if err != nil {
+		return err
+	}
+
 	mountOptions := label.FormatMountLabel("discard", mountLabel)
-	err = syscall.Mount(info.DevName(), path, "ext4", flags, mountOptions)
+	err = syscall.Mount(info.DevName(), path, fstype, flags, mountOptions)
 	if err != nil && err == syscall.EINVAL {
 		mountOptions = label.FormatMountLabel("", mountLabel)
-		err = syscall.Mount(info.DevName(), path, "ext4", flags, mountOptions)
+		err = syscall.Mount(info.DevName(), path, fstype, flags, mountOptions)
 	}
 	if err != nil {
 		return fmt.Errorf("Error mounting '%s' on '%s': %s", info.DevName(), path, err)

+ 47 - 0
daemon/graphdriver/devmapper/mount.go

@@ -3,6 +3,8 @@
 package devmapper
 
 import (
+	"bytes"
+	"fmt"
 	"os"
 	"path/filepath"
 	"syscall"
@@ -27,3 +29,48 @@ func Mounted(mountpoint string) (bool, error) {
 	parentSt := parent.Sys().(*syscall.Stat_t)
 	return mntpointSt.Dev != parentSt.Dev, nil
 }
+
+type probeData struct {
+	fsName string
+	magic  string
+	offset uint64
+}
+
+func ProbeFsType(device string) (string, error) {
+	probes := []probeData{
+		{"btrfs", "_BHRfS_M", 0x10040},
+		{"ext4", "\123\357", 0x438},
+		{"xfs", "XFSB", 0},
+	}
+
+	maxLen := uint64(0)
+	for _, p := range probes {
+		l := p.offset + uint64(len(p.magic))
+		if l > maxLen {
+			maxLen = l
+		}
+	}
+
+	file, err := os.Open(device)
+	if err != nil {
+		return "", err
+	}
+
+	buffer := make([]byte, maxLen)
+	l, err := file.Read(buffer)
+	if err != nil {
+		return "", err
+	}
+	file.Close()
+	if uint64(l) != maxLen {
+		return "", fmt.Errorf("unable to detect filesystem type of %s, short read", device)
+	}
+
+	for _, p := range probes {
+		if bytes.Equal([]byte(p.magic), buffer[p.offset:p.offset+uint64(len(p.magic))]) {
+			return p.fsName, nil
+		}
+	}
+
+	return "", fmt.Errorf("Unknown filesystem type on %s", device)
+}