Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 95 additions & 24 deletions disk/disk_aix_nocgo.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package disk

import (
"context"
"fmt"
"regexp"
"strconv"
"strings"
Expand All @@ -26,8 +27,46 @@ var (
}
)

func IOCountersWithContext(_ context.Context, _ ...string) (map[string]IOCountersStat, error) {
return nil, common.ErrNotImplementedError
func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) {
out, err := invoke.CommandWithContext(ctx, "iostat", "-d")
if err != nil {
return nil, err
}

ret := make(map[string]IOCountersStat)
lines := strings.Split(string(out), "\n")
for _, line := range lines {
fields := strings.Fields(line)
if len(fields) < 6 {
continue
}
// Skip the header line
if fields[0] == "Disks:" {
continue
}

name := fields[0]
if len(names) > 0 && !common.StringsHas(names, name) {
continue
}

kbRead, err := strconv.ParseUint(fields[4], 10, 64)
if err != nil {
continue
}
kbWritten, err := strconv.ParseUint(fields[5], 10, 64)
if err != nil {
continue
}

ret[name] = IOCountersStat{
Name: name,
ReadBytes: kbRead * 1024,
WriteBytes: kbWritten * 1024,
}
}

return ret, nil
}

func PartitionsWithContext(ctx context.Context, _ bool) ([]PartitionStat, error) {
Expand Down Expand Up @@ -94,85 +133,117 @@ func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) {
return nil, err
}

ret := &UsageStat{}

blocksize := uint64(512)
lines := strings.Split(string(out), "\n")
if len(lines) < 2 {
return &UsageStat{}, common.ErrNotImplementedError
return nil, common.ErrNotImplementedError
}

hf := strings.Fields(strings.ReplaceAll(lines[0], "Mounted on", "Path")) // headers

// Find the Path column index once before the loop.
pathIdx := -1
for i, header := range hf {
if header == "Path" {
pathIdx = i
break
}
}

for line := 1; line < len(lines); line++ {
fs := strings.Fields(lines[line]) // values
if len(fs) < len(hf) {
continue
}

if pathIdx < 0 || fs[pathIdx] != path {
continue
}

ret := &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" || fs[i] != path {
break
}

ret.Fstype, err = GetMountFSTypeWithContext(ctx, fs[i])
if err != nil {
return nil, err
}
case `Path`:
ret.Path = fs[i]
case `512-blocks`:
if fs[i] == "-" {
continue
}
total, err := strconv.ParseUint(fs[i], 10, 64)
ret.Total = total * blocksize
if err != nil {
return nil, err
}
ret.Total = total * blocksize
case `Used`:
ret.Used, err = strconv.ParseUint(fs[i], 10, 64)
if fs[i] == "-" {
continue
}
used, err := strconv.ParseUint(fs[i], 10, 64)
if err != nil {
return nil, err
}
ret.Used = used * blocksize
case `Free`:
ret.Free, err = strconv.ParseUint(fs[i], 10, 64)
if fs[i] == "-" {
continue
}
free, err := strconv.ParseUint(fs[i], 10, 64)
if err != nil {
return nil, err
}
ret.Free = free * blocksize
case `%Used`:
if fs[i] == "-" {
continue
}
val, err := strconv.ParseInt(strings.ReplaceAll(fs[i], "%", ""), 10, 32)
if err != nil {
return nil, err
}
ret.UsedPercent = float64(val) / float64(100)
ret.UsedPercent = float64(val)
case `Ifree`:
if fs[i] == "-" {
continue
}
ret.InodesFree, err = strconv.ParseUint(fs[i], 10, 64)
if err != nil {
return nil, err
}
case `Iused`:
if fs[i] == "-" {
continue
}
ret.InodesUsed, err = strconv.ParseUint(fs[i], 10, 64)
if err != nil {
return nil, err
}
case `%Iused`:
if fs[i] == "-" {
continue
}
val, err := strconv.ParseInt(strings.ReplaceAll(fs[i], "%", ""), 10, 32)
if err != nil {
return nil, err
}
ret.InodesUsedPercent = float64(val) / float64(100)
ret.InodesUsedPercent = float64(val)
}
}

// Calculated value, since it isn't returned by the command
ret.InodesTotal = ret.InodesUsed + ret.InodesFree

// Valid Usage data, so append it
var statfs unix.Statfs_t
if err := unix.Statfs(path, &statfs); err == nil {
ret.Fstype = getFsType(statfs)
}

return ret, nil
}

return ret, nil
return nil, fmt.Errorf("mountpoint %s not found", path)
}

func GetMountFSTypeWithContext(ctx context.Context, mp string) (string, error) {
Expand Down
Loading