-
Notifications
You must be signed in to change notification settings - Fork 0
/
mountinfo.go
79 lines (69 loc) · 2.2 KB
/
mountinfo.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
package mount
import (
"bufio"
"fmt"
"io"
"os"
"strings"
)
const (
/* 36 35 98:0 /mnt1 /mnt2 rw,noatime master:1 - ext3 /dev/root rw,errors=continue
(1)(2)(3) (4) (5) (6) (7) (8) (9) (10) (11)
(1) mount ID: unique identifier of the mount (may be reused after umount)
(2) parent ID: ID of parent (or of self for the top of the mount tree)
(3) major:minor: value of st_dev for files on filesystem
(4) root: root of the mount within the filesystem
(5) mount point: mount point relative to the process's root
(6) mount options: per mount options
(7) optional fields: zero or more fields of the form "tag[:value]"
(8) separator: marks the end of the optional fields
(9) filesystem type: name of filesystem of the form "type[.subtype]"
(10) mount source: filesystem specific information or "none"
(11) super options: per super block options*/
mountinfoFormat = "%d %d %d:%d %s %s %s "
)
type MountInfo struct {
Id, Parent, Major, Minor int
Root, Mountpoint, Opts string
Fstype, Source, VfsOpts string
}
// Parse /proc/self/mountinfo because comparing Dev and ino does not work from bind mounts
func parseMountTable() ([]*MountInfo, error) {
f, err := os.Open("/proc/self/mountinfo")
if err != nil {
return nil, err
}
defer f.Close()
return parseInfoFile(f)
}
func parseInfoFile(r io.Reader) ([]*MountInfo, error) {
var (
s = bufio.NewScanner(r)
out = []*MountInfo{}
)
for s.Scan() {
if err := s.Err(); err != nil {
return nil, err
}
var (
p = &MountInfo{}
text = s.Text()
)
if _, err := fmt.Sscanf(text, mountinfoFormat,
&p.Id, &p.Parent, &p.Major, &p.Minor,
&p.Root, &p.Mountpoint, &p.Opts); err != nil {
return nil, fmt.Errorf("Scanning '%s' failed: %s", text, err)
}
// Safe as mountinfo encodes mountpoints with spaces as \040.
index := strings.Index(text, " - ")
postSeparatorFields := strings.Fields(text[index+3:])
if len(postSeparatorFields) != 3 {
return nil, fmt.Errorf("Error did not find 3 fields post '-' in '%s'", text)
}
p.Fstype = postSeparatorFields[0]
p.Source = postSeparatorFields[1]
p.VfsOpts = postSeparatorFields[2]
out = append(out, p)
}
return out, nil
}