in mount_helper_unix.go [93:157]
func ParseMountInfo(filename string) ([]MountInfo, error) {
content, err := utilio.ConsistentRead(filename, maxListTries)
if err != nil {
return []MountInfo{}, err
}
contentStr := string(content)
infos := []MountInfo{}
for _, line := range strings.Split(contentStr, "\n") {
if line == "" {
// the last split() item is empty string following the last \n
continue
}
// See `man proc` for authoritative description of format of the file.
fields := strings.Fields(line)
if len(fields) < expectedAtLeastNumFieldsPerMountInfo {
return nil, fmt.Errorf("wrong number of fields in (expected at least %d, got %d): %s", expectedAtLeastNumFieldsPerMountInfo, len(fields), line)
}
id, err := strconv.Atoi(fields[0])
if err != nil {
return nil, err
}
parentID, err := strconv.Atoi(fields[1])
if err != nil {
return nil, err
}
mm := strings.Split(fields[2], ":")
if len(mm) != 2 {
return nil, fmt.Errorf("parsing '%s' failed: unexpected minor:major pair %s", line, mm)
}
major, err := strconv.Atoi(mm[0])
if err != nil {
return nil, fmt.Errorf("parsing '%s' failed: unable to parse major device id, err:%v", mm[0], err)
}
minor, err := strconv.Atoi(mm[1])
if err != nil {
return nil, fmt.Errorf("parsing '%s' failed: unable to parse minor device id, err:%v", mm[1], err)
}
info := MountInfo{
ID: id,
ParentID: parentID,
Major: major,
Minor: minor,
Root: fields[3],
MountPoint: fields[4],
MountOptions: strings.Split(fields[5], ","),
}
// All fields until "-" are "optional fields".
i := 6
for ; i < len(fields) && fields[i] != "-"; i++ {
info.OptionalFields = append(info.OptionalFields, fields[i])
}
// Parse the rest 3 fields.
i++
if len(fields)-i < 3 {
return nil, fmt.Errorf("expect 3 fields in %s, got %d", line, len(fields)-i)
}
info.FsType = fields[i]
info.Source = fields[i+1]
info.SuperOptions = strings.Split(fields[i+2], ",")
infos = append(infos, info)
}
return infos, nil
}