diff --git a/disk/disk_linux.go b/disk/disk_linux.go index 6539250..a6e5ee3 100644 --- a/disk/disk_linux.go +++ b/disk/disk_linux.go @@ -8,13 +8,13 @@ import ( "context" "fmt" "io/ioutil" + "os" "path/filepath" "strconv" "strings" - "golang.org/x/sys/unix" - "github.com/shirou/gopsutil/internal/common" + "golang.org/x/sys/unix" ) const ( @@ -224,7 +224,7 @@ func Partitions(all bool) ([]PartitionStat, error) { } func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) { - filename := common.HostProc("self/mounts") + filename := common.HostProc("self/mountinfo") lines, err := common.ReadLines(filename) if err != nil { return nil, err @@ -238,18 +238,45 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro ret := make([]PartitionStat, 0, len(lines)) for _, line := range lines { - fields := strings.Fields(line) + // a line of self/mountinfo has the following structure: + // 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) + + // split the mountinfo line by the separator hyphen + parts := strings.Split(line, " - ") + if len(parts) != 2 { + return nil, fmt.Errorf("found invalid mountinfo line in file %s: %s ", filename, line) + } + + fields := strings.Fields(parts[0]) + blockDeviceID := fields[2] + mountPoint := fields[4] + mountOpts := fields[5] + + fields = strings.Fields(parts[1]) + fstype := fields[0] + device := fields[1] + d := PartitionStat{ - Device: fields[0], - Mountpoint: unescapeFstab(fields[1]), - Fstype: fields[2], - Opts: fields[3], + Device: device, + Mountpoint: mountPoint, + Fstype: fstype, + Opts: mountOpts, } if all == false { if d.Device == "none" || !common.StringsHas(fs, d.Fstype) { continue } } + // /dev/root is not the real device name + // so we get the real device name from its major/minor number + if d.Device == "/dev/root" { + devpath, err := os.Readlink(common.HostSys("/dev/block/" + blockDeviceID)) + if err != nil { + return nil, err + } + d.Device = strings.Replace(d.Device, "root", filepath.Base(devpath), 1) + } ret = append(ret, d) }