func GetProcMounts(pid int) ([]*MountInfo, error) {
	data, err := util.ReadFileNoStat(fmt.Sprintf("/proc/%d/mountinfo", pid))
	if err != nil {
		return nil, err
	}
	return parseMountInfo(data)
}
GetProcMounts retrieves mountinfo information from a processes' `/proc/<pid>/mountinfo`.
package procfs
import (
	"bufio"
	"bytes"
	"fmt"
	"strconv"
	"strings"
	"github.com/prometheus/procfs/internal/util"
)
type MountInfo struct {
	MountID int
	ParentID int
	MajorMinorVer string
	Root string
	MountPoint string
	Options map[string]string
	OptionalFields map[string]string
	FSType string
	Source string
	SuperOptions map[string]string
}
func parseMountInfo(info []byte) ([]*MountInfo, error) {
	mounts := []*MountInfo{}
	scanner := bufio.NewScanner(bytes.NewReader(info))
	for scanner.Scan() {
		mountString := scanner.Text()
		parsedMounts, err := parseMountInfoString(mountString)
		if err != nil {
			return nil, err
		}
		mounts = append(mounts, parsedMounts)
	}
	err := scanner.Err()
	return mounts, err
}
func parseMountInfoString(mountString string) (*MountInfo, error) {
	var err error
	mountInfo := strings.Split(mountString, " ")
	mountInfoLength := len(mountInfo)
	if mountInfoLength < 10 {
		return nil, fmt.Errorf("couldn't find enough fields in mount string: %s", mountString)
	}
	if mountInfo[mountInfoLength-4] != "-" {
		return nil, fmt.Errorf("couldn't find separator in expected field: %s", mountInfo[mountInfoLength-4])
	}
	mount := &MountInfo{
		MajorMinorVer:  mountInfo[2],
		Root:           mountInfo[3],
		MountPoint:     mountInfo[4],
		Options:        mountOptionsParser(mountInfo[5]),
		OptionalFields: nil,
		FSType:         mountInfo[mountInfoLength-3],
		Source:         mountInfo[mountInfoLength-2],
		SuperOptions:   mountOptionsParser(mountInfo[mountInfoLength-1]),
	}
	mount.MountID, err = strconv.Atoi(mountInfo[0])
	if err != nil {
		return nil, fmt.Errorf("failed to parse mount ID")
	}
	mount.ParentID, err = strconv.Atoi(mountInfo[1])
	if err != nil {
		return nil, fmt.Errorf("failed to parse parent ID")
	}
	if mountInfo[6] != "" {
		mount.OptionalFields, err = mountOptionsParseOptionalFields(mountInfo[6 : mountInfoLength-4])
		if err != nil {
			return nil, err
		}
	}
	return mount, nil
}
func mountOptionsIsValidField(s string) bool {
	switch s {
	case
		"shared",
		"master",
		"propagate_from",
		"unbindable":
		return true
	}
	return false
}
func mountOptionsParseOptionalFields(o []string) (map[string]string, error) {
	optionalFields := make(map[string]string)
	for _, field := range o {
		optionSplit := strings.SplitN(field, ":", 2)
		value := ""
		if len(optionSplit) == 2 {
			value = optionSplit[1]
		}
		if mountOptionsIsValidField(optionSplit[0]) {
			optionalFields[optionSplit[0]] = value
		}
	}
	return optionalFields, nil
}
func mountOptionsParser(mountOptions string) map[string]string {
	opts := make(map[string]string)
	options := strings.Split(mountOptions, ",")
	for _, opt := range options {
		splitOption := strings.Split(opt, "=")
		if len(splitOption) < 2 {
			key := splitOption[0]
			opts[key] = ""
		} else {
			key, value := splitOption[0], splitOption[1]
			opts[key] = value
		}
	}
	return opts
}
func GetMounts() ([]*MountInfo, error) {
	data, err := util.ReadFileNoStat("/proc/self/mountinfo")
	if err != nil {
		return nil, err
	}
	return parseMountInfo(data)
}