Add code to hot-remove memory devices from qemu. Unfortunately QEMU
doesn't support this right now, so this is just for completenes.
---
Notes:
Version 3:
- moved check for the "-device" capability before any other code
Version 2:
- no change
src/qemu/qemu_driver.c | 4 ++-
src/qemu/qemu_hotplug.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++-
src/qemu/qemu_hotplug.h | 3 ++
3 files changed, 96 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index cbdf279..9731b5f 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7733,7 +7733,9 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm,
ret = qemuDomainDetachRNGDevice(driver, vm, dev->data.rng);
break;
case VIR_DOMAIN_DEVICE_MEMORY:
- /* TODO: Implement later */
+ ret = qemuDomainDetachMemoryDevice(driver, vm, dev->data.memory);
+ break;
+
case VIR_DOMAIN_DEVICE_FS:
case VIR_DOMAIN_DEVICE_INPUT:
case VIR_DOMAIN_DEVICE_SOUND:
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 88c5e3c..3365982 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -2828,6 +2828,44 @@ qemuDomainRemoveControllerDevice(virQEMUDriverPtr driver,
}
+static int
+qemuDomainRemoveMemoryDevice(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ virDomainMemoryDefPtr mem)
+{
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+ virObjectEventPtr event;
+ char *backendAlias = NULL;
+ int rc;
+ int idx;
+
+ VIR_DEBUG("Removing memory device %s from domain %p %s",
+ mem->info.alias, vm, vm->def->name);
+
+ if ((event = virDomainEventDeviceRemovedNewFromObj(vm, mem->info.alias)))
+ qemuDomainEventQueue(driver, event);
+
+ if (virAsprintf(&backendAlias, "mem%s", mem->info.alias) < 0)
+ goto error;
+
+ qemuDomainObjEnterMonitor(driver, vm);
+ rc = qemuMonitorDelObject(priv->mon, backendAlias);
+ if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
+ goto error;
+
+ if ((idx = virDomainMemoryFindByDef(vm->def, mem)) >= 0)
+ virDomainMemoryRemove(vm->def, idx);
+
+ virDomainMemoryDefFree(mem);
+ VIR_FREE(backendAlias);
+ return 0;
+
+ error:
+ VIR_FREE(backendAlias);
+ return -1;
+}
+
+
static void
qemuDomainRemovePCIHostDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm,
@@ -3165,8 +3203,9 @@ qemuDomainRemoveDevice(virQEMUDriverPtr driver,
qemuDomainRemoveRNGDevice(driver, vm, dev->data.rng);
break;
- /* TODO: implement later */
case VIR_DOMAIN_DEVICE_MEMORY:
+ ret = qemuDomainRemoveMemoryDevice(driver, vm, dev->data.memory);
+ break;
case VIR_DOMAIN_DEVICE_NONE:
case VIR_DOMAIN_DEVICE_LEASE:
@@ -4118,3 +4157,53 @@ qemuDomainDetachRNGDevice(virQEMUDriverPtr driver,
qemuDomainResetDeviceRemoval(vm);
return ret;
}
+
+
+int
+qemuDomainDetachMemoryDevice(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ virDomainMemoryDefPtr memdef)
+{
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+ virDomainMemoryDefPtr mem;
+ int idx;
+ int rc;
+ int ret = -1;
+
+ if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("qemu does not support -device"));
+ return -1;
+ }
+
+ if ((idx = virDomainMemoryFindByDef(vm->def, memdef)) < 0) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("device not present in domain configuration"));
+ return -1;
+ }
+
+ mem = vm->def->mems[idx];
+
+ if (!mem->info.alias) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("alias for the memory device was not found"));
+ return -1;
+ }
+
+ qemuDomainMarkDeviceForRemoval(vm, &mem->info);
+
+ qemuDomainObjEnterMonitor(driver, vm);
+ rc = qemuMonitorDelDevice(priv->mon, mem->info.alias);
+ if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
+ goto cleanup;
+
+ rc = qemuDomainWaitForDeviceRemoval(vm);
+ if (rc == 0 || rc == 1)
+ ret = qemuDomainRemoveMemoryDevice(driver, vm, mem);
+ else
+ ret = 0;
+
+ cleanup:
+ qemuDomainResetDeviceRemoval(vm);
+ return ret;
+}
diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h
index ad4ff38..4140da3 100644
--- a/src/qemu/qemu_hotplug.h
+++ b/src/qemu/qemu_hotplug.h
@@ -60,6 +60,9 @@ int qemuDomainFindGraphicsIndex(virDomainDefPtr def,
int qemuDomainAttachMemory(virQEMUDriverPtr driver,
virDomainObjPtr vm,
virDomainMemoryDefPtr mem);
+int qemuDomainDetachMemoryDevice(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ virDomainMemoryDefPtr memdef);
int qemuDomainChangeGraphics(virQEMUDriverPtr driver,
virDomainObjPtr vm,
virDomainGraphicsDefPtr dev);
--
2.2.2