|
|
|
@ -5,58 +5,58 @@ package disk
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"unsafe"
|
|
|
|
|
"unsafe"
|
|
|
|
|
|
|
|
|
|
"github.com/shirou/gopsutil/v3/internal/common"
|
|
|
|
|
"golang.org/x/sys/unix"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
// see sys/fstypes.h and `man 5 statvfs`
|
|
|
|
|
MNT_RDONLY = 0x00000001 /* read only filesystem */
|
|
|
|
|
MNT_SYNCHRONOUS = 0x00000002 /* file system written synchronously */
|
|
|
|
|
MNT_NOEXEC = 0x00000004 /* can't exec from filesystem */
|
|
|
|
|
MNT_NOSUID = 0x00000008 /* don't honor setuid bits on fs */
|
|
|
|
|
MNT_NODEV = 0x00000010 /* don't interpret special files */
|
|
|
|
|
MNT_ASYNC = 0x00000040 /* file system written asynchronously */
|
|
|
|
|
MNT_NOATIME = 0x04000000 /* Never update access times in fs */
|
|
|
|
|
MNT_SOFTDEP = 0x80000000 /* Use soft dependencies */
|
|
|
|
|
// see sys/fstypes.h and `man 5 statvfs`
|
|
|
|
|
MNT_RDONLY = 0x00000001 /* read only filesystem */
|
|
|
|
|
MNT_SYNCHRONOUS = 0x00000002 /* file system written synchronously */
|
|
|
|
|
MNT_NOEXEC = 0x00000004 /* can't exec from filesystem */
|
|
|
|
|
MNT_NOSUID = 0x00000008 /* don't honor setuid bits on fs */
|
|
|
|
|
MNT_NODEV = 0x00000010 /* don't interpret special files */
|
|
|
|
|
MNT_ASYNC = 0x00000040 /* file system written asynchronously */
|
|
|
|
|
MNT_NOATIME = 0x04000000 /* Never update access times in fs */
|
|
|
|
|
MNT_SOFTDEP = 0x80000000 /* Use soft dependencies */
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) {
|
|
|
|
|
var ret []PartitionStat
|
|
|
|
|
|
|
|
|
|
flag := uint64(1) // ST_WAIT/MNT_WAIT, see sys/fstypes.h
|
|
|
|
|
|
|
|
|
|
// get required buffer size
|
|
|
|
|
emptyBufSize := 0
|
|
|
|
|
r, _, err := unix.Syscall(
|
|
|
|
|
483, // SYS___getvfsstat90 syscall
|
|
|
|
|
uintptr(unsafe.Pointer(nil)),
|
|
|
|
|
uintptr(unsafe.Pointer(&emptyBufSize)),
|
|
|
|
|
uintptr(unsafe.Pointer(&flag)),
|
|
|
|
|
)
|
|
|
|
|
if err != 0 {
|
|
|
|
|
return ret, err
|
|
|
|
|
}
|
|
|
|
|
mountedFsCount := uint64(r)
|
|
|
|
|
|
|
|
|
|
// calculate the buffer size
|
|
|
|
|
bufSize := sizeOfStatvfs * mountedFsCount
|
|
|
|
|
buf := make([]Statvfs, mountedFsCount)
|
|
|
|
|
|
|
|
|
|
// request agian to get desired mount data
|
|
|
|
|
_, _, err = unix.Syscall(
|
|
|
|
|
483, // SYS___getvfsstat90 syscall
|
|
|
|
|
uintptr(unsafe.Pointer(&buf[0])),
|
|
|
|
|
uintptr(unsafe.Pointer(&bufSize)),
|
|
|
|
|
uintptr(unsafe.Pointer(&flag)),
|
|
|
|
|
)
|
|
|
|
|
if err != 0 {
|
|
|
|
|
return ret, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, stat := range buf {
|
|
|
|
|
|
|
|
|
|
flag := uint64(1) // ST_WAIT/MNT_WAIT, see sys/fstypes.h
|
|
|
|
|
|
|
|
|
|
// get required buffer size
|
|
|
|
|
emptyBufSize := 0
|
|
|
|
|
r, _, err := unix.Syscall(
|
|
|
|
|
483, // SYS___getvfsstat90 syscall
|
|
|
|
|
uintptr(unsafe.Pointer(nil)),
|
|
|
|
|
uintptr(unsafe.Pointer(&emptyBufSize)),
|
|
|
|
|
uintptr(unsafe.Pointer(&flag)),
|
|
|
|
|
)
|
|
|
|
|
if err != 0 {
|
|
|
|
|
return ret, err
|
|
|
|
|
}
|
|
|
|
|
mountedFsCount := uint64(r)
|
|
|
|
|
|
|
|
|
|
// calculate the buffer size
|
|
|
|
|
bufSize := sizeOfStatvfs * mountedFsCount
|
|
|
|
|
buf := make([]Statvfs, mountedFsCount)
|
|
|
|
|
|
|
|
|
|
// request agian to get desired mount data
|
|
|
|
|
_, _, err = unix.Syscall(
|
|
|
|
|
483, // SYS___getvfsstat90 syscall
|
|
|
|
|
uintptr(unsafe.Pointer(&buf[0])),
|
|
|
|
|
uintptr(unsafe.Pointer(&bufSize)),
|
|
|
|
|
uintptr(unsafe.Pointer(&flag)),
|
|
|
|
|
)
|
|
|
|
|
if err != 0 {
|
|
|
|
|
return ret, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, stat := range buf {
|
|
|
|
|
opts := []string{"rw"}
|
|
|
|
|
if stat.Flag&MNT_RDONLY != 0 {
|
|
|
|
|
opts = []string{"rw"}
|
|
|
|
@ -102,26 +102,26 @@ func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOC
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) {
|
|
|
|
|
stat := Statvfs{}
|
|
|
|
|
flag := uint64(1) // ST_WAIT/MNT_WAIT, see sys/fstypes.h
|
|
|
|
|
|
|
|
|
|
_path, e := unix.BytePtrFromString(path)
|
|
|
|
|
if e != nil {
|
|
|
|
|
return nil, e
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_, _, err := unix.Syscall(
|
|
|
|
|
484, // SYS___statvfs190, see sys/syscall.h
|
|
|
|
|
uintptr(unsafe.Pointer(_path)),
|
|
|
|
|
uintptr(unsafe.Pointer(&stat)),
|
|
|
|
|
uintptr(unsafe.Pointer(&flag)),
|
|
|
|
|
)
|
|
|
|
|
if err != 0 {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// frsize is the real block size on NetBSD. See discuss here: https://bugzilla.samba.org/show_bug.cgi?id=11810
|
|
|
|
|
bsize := stat.Frsize
|
|
|
|
|
stat := Statvfs{}
|
|
|
|
|
flag := uint64(1) // ST_WAIT/MNT_WAIT, see sys/fstypes.h
|
|
|
|
|
|
|
|
|
|
_path, e := unix.BytePtrFromString(path)
|
|
|
|
|
if e != nil {
|
|
|
|
|
return nil, e
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_, _, err := unix.Syscall(
|
|
|
|
|
484, // SYS___statvfs190, see sys/syscall.h
|
|
|
|
|
uintptr(unsafe.Pointer(_path)),
|
|
|
|
|
uintptr(unsafe.Pointer(&stat)),
|
|
|
|
|
uintptr(unsafe.Pointer(&flag)),
|
|
|
|
|
)
|
|
|
|
|
if err != 0 {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// frsize is the real block size on NetBSD. See discuss here: https://bugzilla.samba.org/show_bug.cgi?id=11810
|
|
|
|
|
bsize := stat.Frsize
|
|
|
|
|
ret := &UsageStat{
|
|
|
|
|
Path: path,
|
|
|
|
|
Fstype: getFsType(stat),
|
|
|
|
|