-
Notifications
You must be signed in to change notification settings - Fork 83
/
Copy pathdfstat_linux.go
125 lines (108 loc) · 2.77 KB
/
dfstat_linux.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package nux
import (
"bufio"
"bytes"
"io"
"io/ioutil"
"math"
"strings"
"syscall"
"github.com/toolkits/file"
)
// return: [][$fsSpec, $fsFile, $fsVfstype]
func ListMountPoint() ([][3]string, error) {
contents, err := ioutil.ReadFile(Root() + "/proc/mounts")
if err != nil {
return nil, err
}
ret := make([][3]string, 0)
reader := bufio.NewReader(bytes.NewBuffer(contents))
for {
line, err := file.ReadLine(reader)
if err == io.EOF {
err = nil
break
} else if err != nil {
return nil, err
}
fields := strings.Fields(string(line))
// Docs come from the fstab(5)
// fsSpec # Mounted block special device or remote filesystem e.g. /dev/sda1
// fsFile # Mount point e.g. /data
// fsVfstype # File system type e.g. ext4
// fs_mntops # Mount options
// fs_freq # Dump(8) utility flags
// fs_passno # Order in which filesystem checks are done at reboot time
fsSpec := fields[0]
fsFile := fields[1]
fsVfstype := fields[2]
if _, exist := FSSPEC_IGNORE[fsSpec]; exist {
continue
}
if _, exist := FSTYPE_IGNORE[fsVfstype]; exist {
continue
}
if strings.HasPrefix(fsVfstype, "fuse") {
continue
}
if IgnoreFsFile(fsFile) {
continue
}
// keep /dev/xxx device with shorter fsFile (remove mount binds)
if strings.HasPrefix(fsSpec, Root()+"/dev") {
deviceFound := false
for idx := range ret {
if ret[idx][0] == fsSpec {
deviceFound = true
if len(fsFile) < len(ret[idx][1]) {
ret[idx][1] = fsFile
}
break
}
}
if !deviceFound {
ret = append(ret, [3]string{fsSpec, fsFile, fsVfstype})
}
} else {
ret = append(ret, [3]string{fsSpec, fsFile, fsVfstype})
}
}
return ret, nil
}
func BuildDeviceUsage(_fsSpec, _fsFile, _fsVfstype string) (*DeviceUsage, error) {
ret := &DeviceUsage{FsSpec: _fsSpec, FsFile: _fsFile, FsVfstype: _fsVfstype}
fs := syscall.Statfs_t{}
err := syscall.Statfs(_fsFile, &fs)
if err != nil {
return nil, err
}
// blocks
used := fs.Blocks - fs.Bfree
ret.BlocksAll = uint64(fs.Frsize) * fs.Blocks
ret.BlocksUsed = uint64(fs.Frsize) * used
ret.BlocksFree = uint64(fs.Frsize) * fs.Bavail
if fs.Blocks == 0 {
ret.BlocksUsedPercent = 0
ret.BlocksFreePercent = 0
} else {
ret.BlocksUsedPercent = float64(used) * 100.0 / float64(used+fs.Bavail)
ret.BlocksFreePercent = 100.0 - ret.BlocksUsedPercent
}
// inodes
ret.InodesAll = fs.Files
if fs.Ffree == math.MaxUint64 {
ret.InodesFree = 0
ret.InodesUsed = 0
} else {
ret.InodesFree = fs.Ffree
ret.InodesUsed = fs.Files - fs.Ffree
}
if fs.Files == 0 {
ret.InodesUsedPercent = 0
ret.InodesFreePercent = 0
} else {
ret.InodesUsedPercent = float64(ret.InodesUsed) * 100.0 / float64(ret.InodesAll)
ret.InodesFreePercent = 100.0 - ret.InodesUsedPercent
}
return ret, nil
}