diff --git a/disk/disk_aix_nocgo.go b/disk/disk_aix_nocgo.go index 17e2b9c..20e0ce3 100644 --- a/disk/disk_aix_nocgo.go +++ b/disk/disk_aix_nocgo.go @@ -6,6 +6,7 @@ package disk import ( "context" "regexp" + "strconv" "strings" "github.com/shirou/gopsutil/v3/internal/common" @@ -79,3 +80,105 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro func getFsType(stat unix.Statfs_t) string { return FSType[int(stat.Vfstype)] } + +func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) { + var ret []UsageStat + out, err := invoke.CommandWithContext(ctx, "df", "-v") + if err != nil { + return nil, err + } + + blocksize := uint64(512) + lines := strings.Split(string(out), "\n") + if len(lines) < 2 { + return []UsageStat{}, common.ErrNotImplementedError + } + + hf := strings.Fields(strings.Replace(lines[0], "Mounted on", "Path", -1)) // headers + for line := 1; line < len(lines); line++ { + fs := strings.Fields(lines[line]) // values + us := &UsageStat{} + for i, header := range hf { + // We're done in any of these use cases + if i >= len(fs) { + break + } + + switch header { + case `Filesystem`: + // This is not a valid fs for us to parse + if fs[i] == "/proc" || fs[i] == "/ahafs" { + continue + } + + us.Fstype, err = GetMountFSType(fs[i]) + if err != nil { + return nil, err + } + case `Path`: + us.Path = fs[i] + case `512-blocks`: + us.Total, err = strconv.Atoi(fs[i]) + if err != nil { + return nil, err + } + case `Used`: + us.Used, err = strconv.Atoi(fs[i]) + if err != nil { + return nil, err + } + case `Free`: + us.Free, err = strconv.Atoi(fs[i]) + if err != nil { + return nil, err + } + case `%Used`: + us.UsedPercent, err = strconv.ParseFloat(fs[i]) + if err != nil { + return nil, err + } + case `Ifree`: + us.InodesFree, err = strconv.Atoi(fs[i]) + if err != nil { + return nil, err + } + case `Iused`: + us.InodesUsed, err = strconv.Atoi(fs[i]) + if err != nil { + return nil, err + } + case `%Iused`: + us.InodesUsedPercent, err = strconv.ParseFloat(fs[i]) + if err != nil { + return nil, err + } + } + } + + // Calculated value, since it isn't returned by the command + us.InodesTotal = us.InodesUsed + us.InodesFree + + // Valid Usage data, so append it + ret = append(ret, *us) + } + + return *ret, nil +} + +func GetMountFSType(mp string) (string, error) { + out, err := invoke.CommandWithContext(ctx, "mount") + if err != nil { + return "", err + } + + // Kind of inefficient, but it works + lines := strings.Split(string(out[:]), "\n") + for line := 1; line < len(lines); line++ { + fields := strings.Fields(lines[line]) + if strings.TrimSpace(fields[0]) == mp { + return fields[2], nil + } + } + + return "", nil +}