Skip to content

Commit a2c0070

Browse files
committed
spdksetup: add status subcommand
Signed-off-by: Derek Su <[email protected]>
1 parent ed87b0b commit a2c0070

File tree

2 files changed

+155
-1
lines changed

2 files changed

+155
-1
lines changed

app/cmd/spdksetup/spdksetup.go

+31-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ func Cmd() cli.Command {
2626
BindCmd(),
2727
UnbindCmd(),
2828
GetDeviceDriverCmd(),
29+
GetStatusCmd(),
2930
},
3031
}
3132
}
@@ -112,7 +113,36 @@ func getDeviceDriverCmd(c *cli.Context) error {
112113
return err
113114
}
114115

115-
logrus.Infof("Device driver of device %v is %v", deviceAddr, output)
116+
fmt.Println(output)
117+
118+
return nil
119+
}
120+
121+
func GetStatusCmd() cli.Command {
122+
return cli.Command{
123+
Name: "status",
124+
Flags: []cli.Flag{},
125+
Usage: "Get status of all SPDK-compatible devices on the system",
126+
Action: func(c *cli.Context) {
127+
if err := getStatusCmd(c); err != nil {
128+
logrus.WithError(err).Fatalf("Failed to get status of SPDK-compatible devices")
129+
}
130+
},
131+
}
132+
}
133+
134+
func getStatusCmd(c *cli.Context) error {
135+
executor, err := util.NewExecutor(c.GlobalString("host-proc"))
136+
if err != nil {
137+
return err
138+
}
139+
140+
output, err := spdksetup.GetStatus(executor)
141+
if err != nil {
142+
return err
143+
}
144+
145+
fmt.Println(output)
116146

117147
return nil
118148
}

pkg/spdk/setup/setup.go

+124
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package setup
22

33
import (
4+
"encoding/json"
45
"fmt"
56
"strings"
67

@@ -83,3 +84,126 @@ func extractJSON(outputStr string) (string, error) {
8384
}
8485
return "", fmt.Errorf("failed to extract JSON from output: %s", outputStr)
8586
}
87+
88+
// DeviceInfo represents information about a device
89+
type DeviceInfo struct {
90+
Type string `json:"type"`
91+
BDF string `json:"bdf"`
92+
Vendor string `json:"vendor"`
93+
Device string `json:"device"`
94+
NUMA string `json:"numa"`
95+
Driver string `json:"driver"`
96+
DeviceName string `json:"device_name"`
97+
BlockDevices string `json:"block_devices"`
98+
}
99+
100+
// HugepagesInfo represents information about Hugepages
101+
type HugepagesInfo struct {
102+
Node string `json:"node"`
103+
Hugesize string `json:"hugesize"`
104+
Free int `json:"free"`
105+
Total int `json:"total"`
106+
}
107+
108+
// StatusInfo represents the complete status information
109+
type StatusInfo struct {
110+
Hugepages []HugepagesInfo `json:"hugepages"`
111+
DeviceInfos []DeviceInfo `json:"device_infos"`
112+
}
113+
114+
func GetStatus(executor *commonNs.Executor) (string, error) {
115+
cmdArgs := []string{
116+
spdkSetupPath,
117+
"status",
118+
}
119+
120+
outputStr, err := executor.Execute(nil, "bash", cmdArgs, types.ExecuteTimeout)
121+
if err != nil {
122+
return "", err
123+
}
124+
125+
status := parseStatus(outputStr)
126+
jsonString, err := json.Marshal(status)
127+
if err != nil {
128+
return "", err
129+
}
130+
131+
return string(jsonString), nil
132+
}
133+
134+
func parseStatus(output string) StatusInfo {
135+
var status StatusInfo
136+
lines := strings.Split(output, "\n")
137+
138+
hugepagesIndex := -1
139+
deviceInfoIndex := -1
140+
141+
for i, line := range lines {
142+
if line == "Hugepages" {
143+
hugepagesIndex = i
144+
} else if line == "Type BDF Vendor Device NUMA Driver Device Block devices" {
145+
deviceInfoIndex = i
146+
break
147+
}
148+
}
149+
150+
if hugepagesIndex != -1 {
151+
status.Hugepages = parseHugepages(lines[hugepagesIndex+2:])
152+
}
153+
154+
if deviceInfoIndex != -1 {
155+
status.DeviceInfos = parseDeviceInfos(lines[deviceInfoIndex+1:])
156+
}
157+
158+
return status
159+
}
160+
161+
func parseHugepages(lines []string) []HugepagesInfo {
162+
var hugepages []HugepagesInfo
163+
164+
for _, line := range lines {
165+
fields := strings.Fields(line)
166+
if len(fields) != 5 {
167+
continue
168+
}
169+
170+
hugepages = append(hugepages, HugepagesInfo{
171+
Node: fields[0],
172+
Hugesize: fields[1],
173+
Free: parseInteger(fields[3]),
174+
Total: parseInteger(fields[5]),
175+
})
176+
}
177+
178+
return hugepages
179+
}
180+
181+
func parseDeviceInfos(lines []string) []DeviceInfo {
182+
var deviceInfos []DeviceInfo
183+
184+
for _, line := range lines {
185+
fields := strings.Fields(line)
186+
if len(fields) != 8 {
187+
continue
188+
}
189+
190+
deviceInfos = append(deviceInfos, DeviceInfo{
191+
Type: fields[0],
192+
BDF: fields[1],
193+
Vendor: fields[2],
194+
Device: fields[3],
195+
NUMA: fields[4],
196+
Driver: fields[5],
197+
DeviceName: fields[6],
198+
BlockDevices: fields[7],
199+
})
200+
}
201+
202+
return deviceInfos
203+
}
204+
205+
func parseInteger(s string) int {
206+
var num int
207+
fmt.Sscanf(s, "%d", &num)
208+
return num
209+
}

0 commit comments

Comments
 (0)