disk_unix.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. //go:build freebsd || linux || darwin || (aix && !cgo)
  2. // +build freebsd linux darwin aix,!cgo
  3. package disk
  4. import (
  5. "context"
  6. "strconv"
  7. "golang.org/x/sys/unix"
  8. )
  9. func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) {
  10. stat := unix.Statfs_t{}
  11. err := unix.Statfs(path, &stat)
  12. if err != nil {
  13. return nil, err
  14. }
  15. bsize := stat.Bsize
  16. ret := &UsageStat{
  17. Path: unescapeFstab(path),
  18. Fstype: getFsType(stat),
  19. Total: (uint64(stat.Blocks) * uint64(bsize)),
  20. Free: (uint64(stat.Bavail) * uint64(bsize)),
  21. InodesTotal: (uint64(stat.Files)),
  22. InodesFree: (uint64(stat.Ffree)),
  23. }
  24. ret.Used = (uint64(stat.Blocks) - uint64(stat.Bfree)) * uint64(bsize)
  25. if (ret.Used + ret.Free) == 0 {
  26. ret.UsedPercent = 0
  27. } else {
  28. // We don't use ret.Total to calculate percent.
  29. // see https://github.com/shirou/gopsutil/issues/562
  30. ret.UsedPercent = (float64(ret.Used) / float64(ret.Used+ret.Free)) * 100.0
  31. }
  32. // if could not get InodesTotal, return empty
  33. if ret.InodesTotal < ret.InodesFree {
  34. return ret, nil
  35. }
  36. ret.InodesUsed = (ret.InodesTotal - ret.InodesFree)
  37. if ret.InodesTotal == 0 {
  38. ret.InodesUsedPercent = 0
  39. } else {
  40. ret.InodesUsedPercent = (float64(ret.InodesUsed) / float64(ret.InodesTotal)) * 100.0
  41. }
  42. return ret, nil
  43. }
  44. // Unescape escaped octal chars (like space 040, ampersand 046 and backslash 134) to their real value in fstab fields issue#555
  45. func unescapeFstab(path string) string {
  46. escaped, err := strconv.Unquote(`"` + path + `"`)
  47. if err != nil {
  48. return path
  49. }
  50. return escaped
  51. }