12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- 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
- }
|