diff options
author | Michael Hofmann <michael.hofmann@bitgestalt.com> | 2019-07-03 19:52:22 +0300 |
---|---|---|
committer | John Cai <jcai@gitlab.com> | 2019-07-03 19:52:22 +0300 |
commit | a8ec7642d55878c00dacfb7b3a7f6672c93f26ab (patch) | |
tree | 8068b86448dabead6ab4817fad860652b886de15 | |
parent | 1729ccd20b04e687e6c1c8cc06750b541a3ace44 (diff) |
Fix file system type detection on *BSD and Darwin.
This commit adds support for DragonFly BSD, FreeBSD and OpenBSD to the
internal/helper/fstype package and fixes the implementation on Darwin.
On each of these platforms, fstype.FileSystem will call statfs(2) and
use the f_fstypename member of struct statfs to determine the file
system type. Unfortunately, the Go wrapper for this struct uses
differently named fields on OpenBSD and the other supported systems. For
this reason, a separate implementation for OpenBSD is included.
-rw-r--r-- | internal/helper/fstype/detect_darwin.go | 15 | ||||
-rw-r--r-- | internal/helper/fstype/detect_linux.go | 99 | ||||
-rw-r--r-- | internal/helper/fstype/detect_openbsd.go | 24 | ||||
-rw-r--r-- | internal/helper/fstype/detect_unix.go | 26 | ||||
-rw-r--r-- | internal/helper/fstype/fstype.go | 103 |
5 files changed, 148 insertions, 119 deletions
diff --git a/internal/helper/fstype/detect_darwin.go b/internal/helper/fstype/detect_darwin.go deleted file mode 100644 index d82e26f80..000000000 --- a/internal/helper/fstype/detect_darwin.go +++ /dev/null @@ -1,15 +0,0 @@ -package fstype - -// syscall should not be included in the linux package given that runs in -// production. -// See: https://docs.google.com/document/d/1QXzI9I1pOfZPujQzxhyRy6EeHYTQitKKjHfpq0zpxZs -import "syscall" - -func statFileSystemType(path string) (int64, error) { - var stat syscall.Statfs_t - if err := syscall.Statfs(path, &stat); err != nil { - return 0, err - } - - return int64(stat.Type), nil -} diff --git a/internal/helper/fstype/detect_linux.go b/internal/helper/fstype/detect_linux.go index 98c7b1b8a..87ef046a9 100644 --- a/internal/helper/fstype/detect_linux.go +++ b/internal/helper/fstype/detect_linux.go @@ -2,13 +2,106 @@ package fstype import "golang.org/x/sys/unix" -func statFileSystemType(path string) (int64, error) { +func detectFileSystem(path string) string { var stat unix.Statfs_t if err := unix.Statfs(path, &stat); err != nil { - return 0, err + return unknownFS } // This explicit cast to int64 is required for systems where the syscall // returns an int32 instead. - return int64(stat.Type), nil + fsType, found := magicMap[int64(stat.Type)] + if !found { + return unknownFS + } + + return fsType } + +// This map has been collected from `man 2 statfs` and is non-exhaustive +// The values of EXT2, EXT3, and EXT4 have been renamed to a generic EXT as their +// key values were duplicate. This value is now called EXT_2_3_4 +var ( + magicMap = map[int64]string{ + 0xadf5: "ADFS", + 0xadff: "AFFS", + 0x5346414f: "AFS", + 0x09041934: "ANON_INODE_FS", + 0x0187: "AUTOFS", + 0x62646576: "BDEVFS", + 0x42465331: "BEFS", + 0x1badface: "BFS", + 0x42494e4d: "BINFMTFS", + 0xcafe4a11: "BPF_FS", + 0x9123683e: "BTRFS", + 0x73727279: "BTRFS_TEST", + 0x27e0eb: "CGROUP", + 0x63677270: "CGROUP2", + 0xff534d42: "CIFS_NUMBER", + 0x73757245: "CODA", + 0x012ff7b7: "COH", + 0x28cd3d45: "CRAMFS", + 0x64626720: "DEBUGFS", + 0x1373: "DEVFS", + 0x1cd1: "DEVPTS", + 0xf15f: "ECRYPTFS", + 0xde5e81e4: "EFIVARFS", + 0x00414a53: "EFS", + 0x137d: "EXT", + 0xef51: "EXT2_OLD", + 0xef53: "EXT_2_3_4", + 0xf2f52010: "F2FS", + 0x65735546: "FUSE", + 0xbad1dea: "FUTEXFS", + 0x4244: "HFS", + 0x00c0ffee: "HOSTFS", + 0xf995e849: "HPFS", + 0x958458f6: "HUGETLBFS", + 0x9660: "ISOFS", + 0x72b6: "JFFS2", + 0x3153464a: "JFS", + 0x137f: "MINIX", + 0x138f: "MINIX2", + 0x2468: "MINIX2", + 0x2478: "MINIX22", + 0x4d5a: "MINIX3", + 0x19800202: "MQUEUE", + 0x4d44: "MSDOS", + 0x11307854: "MTD_INODE_FS", + 0x564c: "NCP", + 0x6969: "NFS", + 0x3434: "NILFS", + 0x6e736673: "NSFS", + 0x5346544e: "NTFS_SB", + 0x7461636f: "OCFS2", + 0x9fa1: "OPENPROM", + 0x794c7630: "OVERLAYFS", + 0x50495045: "PIPEFS", + 0x9fa0: "PROC", + 0x6165676c: "PSTOREFS", + 0x002f: "QNX4", + 0x68191122: "QNX6", + 0x858458f6: "RAMFS", + 0x52654973: "REISERFS", + 0x7275: "ROMFS", + 0x73636673: "SECURITYFS", + 0xf97cff8c: "SELINUX", + 0x43415d53: "SMACK", + 0x517b: "SMB", + 0x534f434b: "SOCKFS", + 0x73717368: "SQUASHFS", + 0x62656572: "SYSFS", + 0x012ff7b6: "SYSV2", + 0x012ff7b5: "SYSV4", + 0x01021994: "TMPFS", + 0x74726163: "TRACEFS", + 0x15013346: "UDF", + 0x00011954: "UFS", + 0x9fa2: "USBDEVICE", + 0x01021997: "V9FS", + 0xa501fcf5: "VXFS", + 0xabba1974: "XENFS", + 0x012ff7b4: "XENIX", + 0x58465342: "XFS", + } +) diff --git a/internal/helper/fstype/detect_openbsd.go b/internal/helper/fstype/detect_openbsd.go new file mode 100644 index 000000000..bf01ada1b --- /dev/null +++ b/internal/helper/fstype/detect_openbsd.go @@ -0,0 +1,24 @@ +package fstype + +import "golang.org/x/sys/unix" + +func detectFileSystem(path string) string { + var stat unix.Statfs_t + if err := unix.Statfs(path, &stat); err != nil { + return unknownFS + } + + var buf []byte + for _, c := range stat.F_fstypename { + if c == 0 { + break + } + buf = append(buf, byte(c)) + } + + if len(buf) == 0 { + return unknownFS + } + + return string(buf) +} diff --git a/internal/helper/fstype/detect_unix.go b/internal/helper/fstype/detect_unix.go new file mode 100644 index 000000000..f946002e0 --- /dev/null +++ b/internal/helper/fstype/detect_unix.go @@ -0,0 +1,26 @@ +// +build darwin dragonfly freebsd + +package fstype + +import "golang.org/x/sys/unix" + +func detectFileSystem(path string) string { + var stat unix.Statfs_t + if err := unix.Statfs(path, &stat); err != nil { + return unknownFS + } + + var buf []byte + for _, c := range stat.Fstypename { + if c == 0 { + break + } + buf = append(buf, byte(c)) + } + + if len(buf) == 0 { + return unknownFS + } + + return string(buf) +} diff --git a/internal/helper/fstype/fstype.go b/internal/helper/fstype/fstype.go index 84860e720..5561f7f59 100644 --- a/internal/helper/fstype/fstype.go +++ b/internal/helper/fstype/fstype.go @@ -2,106 +2,7 @@ package fstype const unknownFS = "unknown" -// FileSystem will return the type of filesystem is being used at the passed path +// FileSystem will return the type of filesystem being used at the passed path func FileSystem(path string) string { - kind, err := statFileSystemType(path) - if err != nil { - return unknownFS - } - - fsType, ok := magicMap[kind] - if !ok { - return unknownFS - } - - return fsType - + return detectFileSystem(path) } - -// This map has been collected from `man 2 statfs` and is non-exhaustive -// The values of EXT2, EXT3, and EXT4 have been renamed to a generic EXT as their -// key values were duplicate. This value is now called EXT_2_3_4 -var ( - magicMap = map[int64]string{ - 0xadf5: "ADFS", - 0xadff: "AFFS", - 0x5346414f: "AFS", - 0x09041934: "ANON_INODE_FS", - 0x0187: "AUTOFS", - 0x62646576: "BDEVFS", - 0x42465331: "BEFS", - 0x1badface: "BFS", - 0x42494e4d: "BINFMTFS", - 0xcafe4a11: "BPF_FS", - 0x9123683e: "BTRFS", - 0x73727279: "BTRFS_TEST", - 0x27e0eb: "CGROUP", - 0x63677270: "CGROUP2", - 0xff534d42: "CIFS_NUMBER", - 0x73757245: "CODA", - 0x012ff7b7: "COH", - 0x28cd3d45: "CRAMFS", - 0x64626720: "DEBUGFS", - 0x1373: "DEVFS", - 0x1cd1: "DEVPTS", - 0xf15f: "ECRYPTFS", - 0xde5e81e4: "EFIVARFS", - 0x00414a53: "EFS", - 0x137d: "EXT", - 0xef51: "EXT2_OLD", - 0xef53: "EXT_2_3_4", - 0xf2f52010: "F2FS", - 0x65735546: "FUSE", - 0xbad1dea: "FUTEXFS", - 0x4244: "HFS", - 0x00c0ffee: "HOSTFS", - 0xf995e849: "HPFS", - 0x958458f6: "HUGETLBFS", - 0x9660: "ISOFS", - 0x72b6: "JFFS2", - 0x3153464a: "JFS", - 0x137f: "MINIX", - 0x138f: "MINIX2", - 0x2468: "MINIX2", - 0x2478: "MINIX22", - 0x4d5a: "MINIX3", - 0x19800202: "MQUEUE", - 0x4d44: "MSDOS", - 0x11307854: "MTD_INODE_FS", - 0x564c: "NCP", - 0x6969: "NFS", - 0x3434: "NILFS", - 0x6e736673: "NSFS", - 0x5346544e: "NTFS_SB", - 0x7461636f: "OCFS2", - 0x9fa1: "OPENPROM", - 0x794c7630: "OVERLAYFS", - 0x50495045: "PIPEFS", - 0x9fa0: "PROC", - 0x6165676c: "PSTOREFS", - 0x002f: "QNX4", - 0x68191122: "QNX6", - 0x858458f6: "RAMFS", - 0x52654973: "REISERFS", - 0x7275: "ROMFS", - 0x73636673: "SECURITYFS", - 0xf97cff8c: "SELINUX", - 0x43415d53: "SMACK", - 0x517b: "SMB", - 0x534f434b: "SOCKFS", - 0x73717368: "SQUASHFS", - 0x62656572: "SYSFS", - 0x012ff7b6: "SYSV2", - 0x012ff7b5: "SYSV4", - 0x01021994: "TMPFS", - 0x74726163: "TRACEFS", - 0x15013346: "UDF", - 0x00011954: "UFS", - 0x9fa2: "USBDEVICE", - 0x01021997: "V9FS", - 0xa501fcf5: "VXFS", - 0xabba1974: "XENFS", - 0x012ff7b4: "XENIX", - 0x58465342: "XFS", - } -) |