Skip to content

Commit

Permalink
numalign: add JSON output
Browse files Browse the repository at this point in the history
Signed-off-by: Francesco Romani <[email protected]>
  • Loading branch information
ffromani committed Sep 24, 2020
1 parent 801c86b commit 52d6463
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 33 deletions.
19 changes: 17 additions & 2 deletions cmd/numalign/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package main

import (
"fmt"
"io/ioutil"
"log"
"os"
Expand All @@ -33,6 +34,7 @@ func main() {

var sleepHoursParam = flag.StringP("sleep-hours", "S", "", "sleep hours once done.")
var scriptPathParam = flag.StringP("script-path", "P", "", "save test script to this path.")
var jsonOutput = flag.BoolP("json", "J", false, "output in JSON")
flag.Parse()

if _, ok := os.LookupEnv("NUMALIGN_DEBUG"); !ok {
Expand All @@ -59,7 +61,20 @@ func main() {
if err != nil {
log.Fatalf("%v", err)
}
ret := numalign.Validate(R)

rc := -1
res := R.CheckAlignment()
if res.Aligned {
rc = 0
}
if *jsonOutput {
fmt.Printf("%s", res.JSON())
} else {
fmt.Printf("%s", res.Text())
if !res.Aligned {
fmt.Printf("%s\n", R.String())
}
}

scriptPath := *scriptPathParam
if scriptPath == "" {
Expand All @@ -75,5 +90,5 @@ func main() {
}

time.Sleep(sleepTime)
os.Exit(ret)
os.Exit(rc)
}
79 changes: 48 additions & 31 deletions internal/pkg/numalign/numalign.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package numalign

import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
Expand Down Expand Up @@ -51,22 +52,50 @@ type Resources struct {
PCIDevsToNUMANode map[string]int
}

func (R *Resources) CheckAlignment() (int, bool) {
nodeNum := -1
type Result struct {
Aligned bool `json:"aligned"`
NUMACellID int `json:"numacellid"`
}

func (re Result) Text() string {
var b strings.Builder
fmt.Fprintf(&b, "STATUS ALIGNED=%v\n", re.Aligned)
fmt.Fprintf(&b, "NUMA NODE=%v\n", re.NUMACellID)
return b.String()
}

func (re Result) JSON() string {
var b strings.Builder
enc := json.NewEncoder(&b)
enc.Encode(re)
return b.String()
}

func (R *Resources) CheckAlignment() Result {
numacellID := -1
for _, cpuNode := range R.CPUToNUMANode {
if nodeNum == -1 {
nodeNum = cpuNode
} else if nodeNum != cpuNode {
return -1, false
if numacellID == -1 {
numacellID = cpuNode
} else if numacellID != cpuNode {
return Result{
Aligned: false,
NUMACellID: -1,
}
}
}
for _, devNode := range R.PCIDevsToNUMANode {
// TODO: explain -1
if devNode != -1 && nodeNum != devNode {
return -1, false
if devNode != -1 && numacellID != devNode {
return Result{
Aligned: false,
NUMACellID: -1,
}
}
}
return nodeNum, true
return Result{
Aligned: true,
NUMACellID: numacellID,
}
}

func (R *Resources) MakeValidationScript() string {
Expand Down Expand Up @@ -97,17 +126,17 @@ func (R *Resources) String() string {
}
sort.Ints(cpuKeys)
for _, k := range cpuKeys {
nodeNum := R.CPUToNUMANode[k]
b.WriteString(fmt.Sprintf("CPU cpu#%03d=%02d\n", k, nodeNum))
numacellID := R.CPUToNUMANode[k]
b.WriteString(fmt.Sprintf("CPU cpu#%03d=%02d\n", k, numacellID))
}
var pciKeys []string
for pk := range R.PCIDevsToNUMANode {
pciKeys = append(pciKeys, pk)
}
sort.Strings(pciKeys)
for _, k := range pciKeys {
nodeNum := R.PCIDevsToNUMANode[k]
b.WriteString(fmt.Sprintf("PCI %s=%02d\n", k, nodeNum))
numacellID := R.PCIDevsToNUMANode[k]
b.WriteString(fmt.Sprintf("PCI %s=%02d\n", k, numacellID))
}
return b.String()
}
Expand Down Expand Up @@ -181,11 +210,11 @@ func GetPCIDeviceNUMANode(sysPCIDir string, devs []string) (map[string]int, erro
if err != nil {
return nil, err
}
nodeNum, err := strconv.Atoi(strings.TrimSpace(string(content)))
numacellID, err := strconv.Atoi(strings.TrimSpace(string(content)))
if err != nil {
return nil, err
}
NUMAPerDev[dev] = nodeNum
NUMAPerDev[dev] = numacellID
}
return NUMAPerDev, nil
}
Expand All @@ -199,7 +228,7 @@ func GetCPUsPerNUMANode(sysfsdir string) (map[int][]int, error) {
cpusPerNUMA := make(map[int][]int)
for _, node := range nodes {
_, nodeID := filepath.Split(node)
nodeNum, err := strconv.Atoi(strings.TrimSpace(nodeID[4:]))
numacellID, err := strconv.Atoi(strings.TrimSpace(nodeID[4:]))
if err != nil {
return nil, err
}
Expand All @@ -212,16 +241,16 @@ func GetCPUsPerNUMANode(sysfsdir string) (map[int][]int, error) {
if err != nil {
return nil, err
}
cpusPerNUMA[nodeNum] = cpuSet
cpusPerNUMA[numacellID] = cpuSet
}
return cpusPerNUMA, nil
}

func GetCPUNUMANodes(cpusPerNUMA map[int][]int) map[int]int {
CPUToNUMANode := make(map[int]int)
for nodeNum, cpuSet := range cpusPerNUMA {
for numacellID, cpuSet := range cpusPerNUMA {
for _, cpu := range cpuSet {
CPUToNUMANode[cpu] = nodeNum
CPUToNUMANode[cpu] = numacellID
}
}
return CPUToNUMANode
Expand Down Expand Up @@ -291,15 +320,3 @@ func NewResources(pids []string) (*Resources, error) {
}, nil

}

func Validate(R *Resources) int {
nodeNum, aligned := R.CheckAlignment()
fmt.Printf("STATUS ALIGNED=%v\n", aligned)
if !aligned {
fmt.Printf("%s", R.String())
return 1
}

fmt.Printf("NUMA NODE=%v\n", nodeNum)
return 0
}

0 comments on commit 52d6463

Please sign in to comment.