diff --git a/qemu/qmp.go b/qemu/qmp.go index 9d27dbeefb..00e9fed279 100644 --- a/qemu/qmp.go +++ b/qemu/qmp.go @@ -1379,8 +1379,8 @@ func (q *QMP) ExecQueryCpusFast(ctx context.Context) ([]CPUInfoFast, error) { return cpuInfoFast, nil } -// ExecHotplugMemory adds size of MiB memory to the guest -func (q *QMP) ExecHotplugMemory(ctx context.Context, qomtype, id, mempath string, size int, share bool) error { +// ExecMemdevAdd adds size of MiB memory device to the guest +func (q *QMP) ExecMemdevAdd(ctx context.Context, qomtype, id, mempath string, size int, share bool, driver, driverID string) error { props := map[string]interface{}{"size": uint64(size) << 20} args := map[string]interface{}{ "qom-type": qomtype, @@ -1400,17 +1400,17 @@ func (q *QMP) ExecHotplugMemory(ctx context.Context, qomtype, id, mempath string defer func() { if err != nil { - q.cfg.Logger.Errorf("Unable to hotplug memory device: %v", err) + q.cfg.Logger.Errorf("Unable to add memory device %s: %v", id, err) err = q.executeCommand(ctx, "object-del", map[string]interface{}{"id": id}, nil) if err != nil { - q.cfg.Logger.Warningf("Unable to clean up memory object: %v", err) + q.cfg.Logger.Warningf("Unable to clean up memory object %s: %v", id, err) } } }() args = map[string]interface{}{ - "driver": "pc-dimm", - "id": "dimm" + id, + "driver": driver, + "id": driverID, "memdev": id, } err = q.executeCommand(ctx, "device_add", args, nil) @@ -1418,6 +1418,11 @@ func (q *QMP) ExecHotplugMemory(ctx context.Context, qomtype, id, mempath string return err } +// ExecHotplugMemory adds size of MiB memory to the guest +func (q *QMP) ExecHotplugMemory(ctx context.Context, qomtype, id, mempath string, size int, share bool) error { + return q.ExecMemdevAdd(ctx, qomtype, id, mempath, size, share, "pc-dimm", "dimm"+id) +} + // ExecuteNVDIMMDeviceAdd adds a block device to a QEMU instance using // a NVDIMM driver with the device_add command. // id is the id of the device to add. It must be a valid QMP identifier. @@ -1604,3 +1609,14 @@ func (q *QMP) ExecuteQueryStatus(ctx context.Context) (StatusInfo, error) { return status, nil } + +// ExecQomSet qom-set path property value +func (q *QMP) ExecQomSet(ctx context.Context, path, property string, value uint64) error { + args := map[string]interface{}{ + "path": path, + "property": property, + "value": value, + } + + return q.executeCommand(ctx, "qom-set", args, nil) +} diff --git a/qemu/qmp_test.go b/qemu/qmp_test.go index 71f97bcadd..fc1b2a875e 100644 --- a/qemu/qmp_test.go +++ b/qemu/qmp_test.go @@ -1294,6 +1294,24 @@ func TestExecSetMigrateArguments(t *testing.T) { <-disconnectedCh } +// Checks add memory device +func TestExecMemdevAdd(t *testing.T) { + connectedCh := make(chan *QMPVersion) + disconnectedCh := make(chan struct{}) + buf := newQMPTestCommandBuffer(t) + buf.AddCommand("object-add", nil, "return", nil) + buf.AddCommand("device_add", nil, "return", nil) + cfg := QMPConfig{Logger: qmpTestLogger{}} + q := startQMPLoop(buf, cfg, connectedCh, disconnectedCh) + checkVersion(t, connectedCh) + err := q.ExecMemdevAdd(context.Background(), "memory-backend-ram", "mem0", "", 128, true, "virtio-mem-pci", "virtiomem0") + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + q.Shutdown() + <-disconnectedCh +} + // Checks hotplug memory func TestExecHotplugMemory(t *testing.T) { connectedCh := make(chan *QMPVersion) @@ -1692,3 +1710,20 @@ func TestQMPExecQueryQmpStatus(t *testing.T) { q.Shutdown() <-disconnectedCh } + +// Checks qom-set +func TestExecQomSet(t *testing.T) { + connectedCh := make(chan *QMPVersion) + disconnectedCh := make(chan struct{}) + buf := newQMPTestCommandBuffer(t) + buf.AddCommand("qom-set", nil, "return", nil) + cfg := QMPConfig{Logger: qmpTestLogger{}} + q := startQMPLoop(buf, cfg, connectedCh, disconnectedCh) + checkVersion(t, connectedCh) + err := q.ExecQomSet(context.Background(), "virtiomem0", "requested-size", 1024) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + q.Shutdown() + <-disconnectedCh +}