This patch implements live hotplug of a memory device.
Signed-off-by: Zhu Guihua <zhugh.fnst(a)cn.fujitsu.com>
---
src/qemu/qemu_driver.c | 6 +++++
src/qemu/qemu_hotplug.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_hotplug.h | 5 ++++
3 files changed, 81 insertions(+)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index a7a50e0..76ff7b5 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6992,6 +6992,12 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm,
break;
case VIR_DOMAIN_DEVICE_DIMM:
+ ret = qemuDomainAttachDimmDevice(driver, vm,
+ dev->data.dimm);
+ if (!ret)
+ dev->data.dimm = NULL;
+ break;
+
case VIR_DOMAIN_DEVICE_NONE:
case VIR_DOMAIN_DEVICE_FS:
case VIR_DOMAIN_DEVICE_INPUT:
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index f83cb1c..b7ca41e 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1776,6 +1776,76 @@ static virDomainNetDefPtr *qemuDomainFindNet(virDomainObjPtr vm,
static int
+qemuDomainDimmInsert(virDomainDefPtr vmdef,
+ virDomainDimmDefPtr dimm)
+{
+ if (virDomainDimmFind(vmdef, dimm)) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("pc-dimm already exists"));
+ return -1;
+ }
+
+ if (virDomainDimmInsert(vmdef, dimm) < 0)
+ return -1;
+
+ return 0;
+}
+
+int qemuDomainAttachDimmDevice(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ virDomainDimmDefPtr dimm)
+{
+ int ret = -1;
+ char *devstr = NULL;
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+ virDomainDefPtr vmdef = vm->def;
+ char *objAlias = NULL;
+
+ if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("qemu does not support -device"));
+ goto cleanup;;
+ }
+
+ if (qemuAssignDeviceDimmAlias(vmdef, dimm, -1) < 0)
+ goto cleanup;
+
+ if (virAsprintf(&objAlias, "obj%s", dimm->info.alias) < 0)
+ goto cleanup;
+
+ if (qemuBuildDimmDeviceStr(&devstr, dimm, priv->qemuCaps) < 0)
+ goto cleanup;
+
+ if (qemuDomainDimmInsert(vmdef, dimm) < 0)
+ goto cleanup;
+
+ qemuDomainObjEnterMonitor(driver, vm);
+
+ if (qemuMonitorAddMemoryBackend(priv->mon, objAlias, dimm) < 0) {
+ qemuDomainObjExitMonitor(driver, vm);
+ goto cleanup;
+ }
+
+ if (devstr && qemuMonitorAddDevice(priv->mon, devstr) < 0) {
+ qemuDomainObjExitMonitor(driver, vm);
+ goto cleanup;
+ }
+
+ qemuDomainObjExitMonitor(driver, vm);
+ virDomainAuditMemory(vm, vm->def->mem.cur_balloon,
+ vm->def->mem.cur_balloon + dimm->backend.size,
+ "update", true);
+
+ ignore_value(virBitmapSetBit(vm->def->mem.dimm_slot_map, dimm->slot));
+ ret = 0;
+
+ cleanup:
+ VIR_FREE(devstr);
+ VIR_FREE(objAlias);
+ return ret;
+}
+
+static int
qemuDomainChangeNetBridge(virDomainObjPtr vm,
virDomainNetDefPtr olddev,
virDomainNetDefPtr newdev)
diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h
index 19ab9a0..1e9f7b3 100644
--- a/src/qemu/qemu_hotplug.h
+++ b/src/qemu/qemu_hotplug.h
@@ -107,6 +107,11 @@ virDomainChrDefPtr
qemuDomainChrRemove(virDomainDefPtr vmdef,
virDomainChrDefPtr chr);
+int
+qemuDomainAttachDimmDevice(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ virDomainDimmDefPtr dimm);
+
int qemuDomainRemoveDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm,
virDomainDeviceDefPtr dev);
--
1.9.3