| //go:build linux | |
| // +build linux | |
| package devmapper // import "github.com/docker/docker/daemon/graphdriver/devmapper" | |
| import ( | |
| "bytes" | |
| "fmt" | |
| "os" | |
| ) | |
| type probeData struct { | |
| fsName string | |
| magic string | |
| offset uint64 | |
| } | |
| // ProbeFsType returns the filesystem name for the given device id. | |
| 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 | |
| } | |
| defer file.Close() | |
| buffer := make([]byte, maxLen) | |
| l, err := file.Read(buffer) | |
| if err != nil { | |
| return "", err | |
| } | |
| if uint64(l) != maxLen { | |
| return "", fmt.Errorf("devmapper: 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("devmapper: Unknown filesystem type on %s", device) | |
| } | |
| func joinMountOptions(a, b string) string { | |
| if a == "" { | |
| return b | |
| } | |
| if b == "" { | |
| return a | |
| } | |
| return a + "," + b | |
| } |