qemu/qmp: support query-memory-devices qmp command.

Implement query qemu memory devices function and testcase.

Signed-off-by: Clare Chen <clare.chenhui@huawei.com>
This commit is contained in:
Clare Chen 2018-08-28 22:18:51 -04:00
parent 1a16b5f98f
commit b16291cfab
2 changed files with 76 additions and 0 deletions

View File

@ -160,6 +160,24 @@ type HotpluggableCPU struct {
QOMPath string `json:"qom-path"` QOMPath string `json:"qom-path"`
} }
// MemoryDevicesData cotains the data describes a memory device
type MemoryDevicesData struct {
Slot int `json:"slot"`
Node int `json:"node"`
Addr uint64 `json:"addr"`
Memdev string `json:"memdev"`
ID string `json:"id"`
Hotpluggable bool `json:"hotpluggable"`
Hotplugged bool `json:"hotplugged"`
Size uint64 `json:"size"`
}
// MemoryDevices represents memory devices of vm
type MemoryDevices struct {
Data MemoryDevicesData `json:"data"`
Type string `json:"type"`
}
func (q *QMP) readLoop(fromVMCh chan<- []byte) { func (q *QMP) readLoop(fromVMCh chan<- []byte) {
scanner := bufio.NewScanner(q.conn) scanner := bufio.NewScanner(q.conn)
for scanner.Scan() { for scanner.Scan() {
@ -989,6 +1007,28 @@ func (q *QMP) ExecSetMigrateArguments(ctx context.Context, url string) error {
return q.executeCommand(ctx, "migrate", args, nil) return q.executeCommand(ctx, "migrate", args, nil)
} }
// ExecQueryMemoryDevices returns a slice with the list of memory devices
func (q *QMP) ExecQueryMemoryDevices(ctx context.Context) ([]MemoryDevices, error) {
response, err := q.executeCommandWithResponse(ctx, "query-memory-devices", nil, nil, nil)
if err != nil {
return nil, err
}
// convert response to json
data, err := json.Marshal(response)
if err != nil {
return nil, fmt.Errorf("Unable to extract memory devices information: %v", err)
}
var memoryDevices []MemoryDevices
// convert json to []MemoryDevices
if err = json.Unmarshal(data, &memoryDevices); err != nil {
return nil, fmt.Errorf("unable to convert json to memory devices: %v", err)
}
return memoryDevices, nil
}
// ExecHotplugMemory adds size of MiB memory to the guest // ExecHotplugMemory adds size of MiB memory to the guest
func (q *QMP) ExecHotplugMemory(ctx context.Context, qomtype, id, mempath string, size int) error { func (q *QMP) ExecHotplugMemory(ctx context.Context, qomtype, id, mempath string, size int) error {
args := map[string]interface{}{ args := map[string]interface{}{

View File

@ -1055,6 +1055,42 @@ func TestQMPExecuteQueryHotpluggableCPUs(t *testing.T) {
<-disconnectedCh <-disconnectedCh
} }
// Checks that memory devices are listed correctly
func TestQMPExecuteQueryMemoryDevices(t *testing.T) {
connectedCh := make(chan *QMPVersion)
disconnectedCh := make(chan struct{})
buf := newQMPTestCommandBuffer(t)
memoryDevices := MemoryDevices{
Type: "dimm",
Data: MemoryDevicesData{
Slot: 1,
Node: 0,
Addr: 1234,
Memdev: "dimm1",
ID: "mem1",
Hotpluggable: true,
Hotplugged: false,
Size: 1234,
},
}
buf.AddCommand("query-memory-devices", nil, "return", []interface{}{memoryDevices})
cfg := QMPConfig{Logger: qmpTestLogger{}}
q := startQMPLoop(buf, cfg, connectedCh, disconnectedCh)
checkVersion(t, connectedCh)
memDevices, err := q.ExecQueryMemoryDevices(context.Background())
if err != nil {
t.Fatalf("Unexpected error: %v\n", err)
}
if len(memDevices) != 1 {
t.Fatalf("Expected memory devices length equals to 1\n")
}
if reflect.DeepEqual(memDevices[0], memoryDevices) == false {
t.Fatalf("Expected %v equals to %v\n", memDevices[0], memoryDevices)
}
q.Shutdown()
<-disconnectedCh
}
// Checks that migrate capabilities can be set // Checks that migrate capabilities can be set
func TestExecSetMigrationCaps(t *testing.T) { func TestExecSetMigrationCaps(t *testing.T) {
connectedCh := make(chan *QMPVersion) connectedCh := make(chan *QMPVersion)