From aee0845b2e2d41ac66259fe254e993fba7790c99 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Sat, 17 Oct 2015 16:45:42 -0700 Subject: [PATCH] Add disk package Implements - Stat returns total and free disk space supported across platforms - Type returns type of the filesystem underneath --- pkg/disk/disk_test.go | 41 ++++++++++++++++++++++++ pkg/disk/stat_nix.go | 35 ++++++++++++++++++++ pkg/disk/stat_windows.go | 69 ++++++++++++++++++++++++++++++++++++++++ pkg/disk/type_darwin.go | 49 ++++++++++++++++++++++++++++ pkg/disk/type_linux.go | 60 ++++++++++++++++++++++++++++++++++ 5 files changed, 254 insertions(+) create mode 100644 pkg/disk/disk_test.go create mode 100644 pkg/disk/stat_nix.go create mode 100644 pkg/disk/stat_windows.go create mode 100644 pkg/disk/type_darwin.go create mode 100644 pkg/disk/type_linux.go diff --git a/pkg/disk/disk_test.go b/pkg/disk/disk_test.go new file mode 100644 index 000000000..b4649d7b5 --- /dev/null +++ b/pkg/disk/disk_test.go @@ -0,0 +1,41 @@ +/* + * Minio Cloud Storage, (C) 2015 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package disk_test + +import ( + "io/ioutil" + "os" + "testing" + + "github.com/minio/minio/pkg/disk" + + . "gopkg.in/check.v1" +) + +func Test(t *testing.T) { TestingT(t) } + +type MySuite struct{} + +var _ = Suite(&MySuite{}) + +func (s *MySuite) TestFree(c *C) { + path, err := ioutil.TempDir(os.TempDir(), "minio-") + c.Check(err, IsNil) + + _, _, err = disk.Stat(path) + c.Check(err, IsNil) +} diff --git a/pkg/disk/stat_nix.go b/pkg/disk/stat_nix.go new file mode 100644 index 000000000..aa7078179 --- /dev/null +++ b/pkg/disk/stat_nix.go @@ -0,0 +1,35 @@ +// +build darwin dragonfly freebsd linux netbsd openbsd + +/* + * Minio Cloud Storage, (C) 2015 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package disk + +import ( + "syscall" +) + +// Stat returns total and free bytes available in a directory, e.g. `/`. +func Stat(path string) (total, free int64, err error) { + s := syscall.Statfs_t{} + err = syscall.Statfs(path, &s) + if err != nil { + return + } + total = int64(s.Bsize) * int64(s.Blocks) + free = int64(s.Bsize) * int64(s.Bfree) + return +} diff --git a/pkg/disk/stat_windows.go b/pkg/disk/stat_windows.go new file mode 100644 index 000000000..c8f60e8a7 --- /dev/null +++ b/pkg/disk/stat_windows.go @@ -0,0 +1,69 @@ +// +build windows + +/* + * Minio Cloud Storage, (C) 2015 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package disk + +import ( + "syscall" + "unsafe" +) + +// Stat returns total and free bytes available in a directory, e.g. `C:\`. +// It returns free space available to the user (including quota limitations) +// +// https://msdn.microsoft.com/en-us/library/windows/desktop/aa364937(v=vs.85).aspx +func Stat(path string) (total, free int64, err error) { + kernel32, err := syscall.LoadLibrary("Kernel32.dll") + if err != nil { + return 0, 0, err + } + defer syscall.FreeLibrary(kernel32) + // https://msdn.microsoft.com/en-us/library/windows/desktop/aa364937(v=vs.85).aspx + // Retrieves information about the amount of space that is available on a disk volume, + // which is the total amount of space, the total amount of free space, and the total + // amount of free space available to the user that is associated with the calling thread. + GetDiskFreeSpaceEx, err := syscall.GetProcAddress(syscall.Handle(kernel32), "GetDiskFreeSpaceExW") + if err != nil { + return 0, 0, err + } + lpFreeBytesAvailable := int64(0) + lpTotalNumberOfBytes := int64(0) + lpTotalNumberOfFreeBytes := int64(0) + + // Extract values safely + // BOOL WINAPI GetDiskFreeSpaceEx( + // _In_opt_ LPCTSTR lpDirectoryName, + // _Out_opt_ PULARGE_INTEGER lpFreeBytesAvailable, + // _Out_opt_ PULARGE_INTEGER lpTotalNumberOfBytes, + // _Out_opt_ PULARGE_INTEGER lpTotalNumberOfFreeBytes + // ); + r1, _, e1 := syscall.Syscall6(uintptr(GetDiskFreeSpaceEx), 4, + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(path))), + uintptr(unsafe.Pointer(&lpFreeBytesAvailable)), + uintptr(unsafe.Pointer(&lpTotalNumberOfBytes)), + uintptr(unsafe.Pointer(&lpTotalNumberOfFreeBytes)), 0, 0) + if e1 != 0 { + return 0, 0, error(e1) + } + if r1 == 0 { + return 0, 0, syscall.EINVAL + } + total = int64(lpTotalNumberOfBytes) + free = int64(lpFreeBytesAvailable) + return total, free, nil +} diff --git a/pkg/disk/type_darwin.go b/pkg/disk/type_darwin.go new file mode 100644 index 000000000..66293679e --- /dev/null +++ b/pkg/disk/type_darwin.go @@ -0,0 +1,49 @@ +// +build darwin + +/* + * Minio Cloud Storage, (C) 2015 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package disk + +import ( + "strconv" + "syscall" +) + +// fsType2StrinMap - list of filesystems supported by donut +var fsType2StringMap = map[string]string{ + "11": "HFS", +} + +// FSType returns the filesystem type of the underlying mounted filesystem +func FSType(path string) (string, error) { + s := syscall.Statfs_t{} + err := syscall.Statfs(path, &s) + if err != nil { + return "", err + } + return getFSType(s.Type), nil +} + +// getFSType - get filesystem type +func getFSType(fsType uint32) string { + fsTypeHex := strconv.FormatUint(uint64(fsType), 16) + fsTypeString, ok := fsType2StringMap[fsTypeHex] + if ok == false { + return "UNKNOWN" + } + return fsTypeString +} diff --git a/pkg/disk/type_linux.go b/pkg/disk/type_linux.go new file mode 100644 index 000000000..339d28c8a --- /dev/null +++ b/pkg/disk/type_linux.go @@ -0,0 +1,60 @@ +// +build linux + +/* + * Minio Cloud Storage, (C) 2015 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package disk + +import ( + "strconv" + "syscall" +) + +// fsType2StringMap - list of filesystems supported by donut on linux +var fsType2StringMap = map[string]string{ + "1021994": "TMPFS", + "137d": "EXT", + "4244": "HFS", + "4d44": "MSDOS", + "52654973": "REISERFS", + "5346544e": "NTFS", + "58465342": "XFS", + "61756673": "AUFS", + "6969": "NFS", + "ef51": "EXT2OLD", + "ef53": "EXT4", + "f15f": "ecryptfs", +} + +// FSType returns the filesystem type of the underlying mounted filesystem +func FSType(path string) (string, error) { + s := syscall.Statfs_t{} + err := syscall.Statfs(path, &s) + if err != nil { + return "", err + } + return getFSType(s.Type), nil +} + +// getFSType - get filesystem type +func getFSType(fsType int64) string { + fsTypeHex := strconv.FormatInt(fsType, 16) + fsTypeString, ok := fsType2StringMap[fsTypeHex] + if ok == false { + return "UNKNOWN" + } + return fsTypeString +}