|
@@ -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)
|
|
|
+}
|