We have enough patches for hotunplug RNG device, maybe we can implement live hotunplug of a RNG device. Signed-off-by: Luyao Huang <lhuang@xxxxxxxxxx> --- src/libvirt_private.syms | 1 + src/qemu/qemu_driver.c | 4 +- src/qemu/qemu_hotplug.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++- src/qemu/qemu_hotplug.h | 4 +- 4 files changed, 103 insertions(+), 3 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 4947401..a1a72e3 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -377,6 +377,7 @@ virDomainPMSuspendedReasonTypeToString; virDomainRedirdevBusTypeFromString; virDomainRedirdevBusTypeToString; virDomainRNGBackendTypeToString; +virDomainRNGDefFree; virDomainRNGEquals; virDomainRNGFind; virDomainRNGInsert; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index f9d404b..86bed7e 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -7033,6 +7033,9 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm, case VIR_DOMAIN_DEVICE_CHR: ret = qemuDomainDetachChrDevice(driver, vm, dev->data.chr); break; + case VIR_DOMAIN_DEVICE_RNG: + ret = qemuDomainDetachRNGDevice(driver, vm, dev->data.rng); + break; case VIR_DOMAIN_DEVICE_FS: case VIR_DOMAIN_DEVICE_INPUT: case VIR_DOMAIN_DEVICE_SOUND: @@ -7043,7 +7046,6 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm, case VIR_DOMAIN_DEVICE_SMARTCARD: case VIR_DOMAIN_DEVICE_MEMBALLOON: case VIR_DOMAIN_DEVICE_NVRAM: - case VIR_DOMAIN_DEVICE_RNG: case VIR_DOMAIN_DEVICE_SHMEM: case VIR_DOMAIN_DEVICE_REDIRDEV: case VIR_DOMAIN_DEVICE_NONE: diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index afa9618..60b1818 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -2930,6 +2930,52 @@ qemuDomainRemoveChrDevice(virQEMUDriverPtr driver, return ret; } +static int +qemuDomainRemoveRNGDevice(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainRNGDefPtr rng) +{ + virObjectEventPtr event; + char *charAlias = NULL; + char *objAlias = NULL; + qemuDomainObjPrivatePtr priv = vm->privateData; + int ret = -1; + int rc; + + VIR_DEBUG("Removing RNG device %s from domain %p %s", + rng->info.alias, vm, vm->def->name); + + if (virAsprintf(&objAlias, "obj%s", rng->info.alias) < 0) + goto cleanup; + + if (virAsprintf(&charAlias, "char%s", rng->info.alias) < 0) + goto cleanup; + + qemuDomainObjEnterMonitor(driver, vm); + rc = qemuMonitorDetachRNGDev(priv->mon, objAlias); + if (rc == 0 && rng->backend == VIR_DOMAIN_RNG_BACKEND_EGD) + ignore_value(qemuMonitorDetachCharDev(priv->mon, charAlias)); + qemuDomainObjExitMonitor(driver, vm); + + virDomainAuditRNG(vm, rng, NULL, "detach", rc == 0); + + if (rc < 0) + goto cleanup; + + event = virDomainEventDeviceRemovedNewFromObj(vm, rng->info.alias); + if (event) + qemuDomainEventQueue(driver, event); + + qemuDomainRNGRemove(vm->def, rng); + qemuDomainReleaseDeviceAddress(vm, &rng->info, NULL); + virDomainRNGDefFree(rng); + ret = 0; + + cleanup: + VIR_FREE(charAlias); + VIR_FREE(objAlias); + return ret; +} void qemuDomainRemoveDevice(virQEMUDriverPtr driver, @@ -2953,6 +2999,9 @@ qemuDomainRemoveDevice(virQEMUDriverPtr driver, case VIR_DOMAIN_DEVICE_CHR: qemuDomainRemoveChrDevice(driver, vm, dev->data.chr); break; + case VIR_DOMAIN_DEVICE_RNG: + qemuDomainRemoveRNGDevice(driver, vm, dev->data.rng); + break; case VIR_DOMAIN_DEVICE_NONE: case VIR_DOMAIN_DEVICE_LEASE: @@ -2967,7 +3016,6 @@ qemuDomainRemoveDevice(virQEMUDriverPtr driver, case VIR_DOMAIN_DEVICE_SMARTCARD: case VIR_DOMAIN_DEVICE_MEMBALLOON: case VIR_DOMAIN_DEVICE_NVRAM: - case VIR_DOMAIN_DEVICE_RNG: case VIR_DOMAIN_DEVICE_SHMEM: case VIR_DOMAIN_DEVICE_TPM: case VIR_DOMAIN_DEVICE_PANIC: @@ -3839,3 +3887,50 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver, VIR_FREE(devstr); return ret; } + +int qemuDomainDetachRNGDevice(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainRNGDefPtr rng) +{ + int ret = -1; + qemuDomainObjPrivatePtr priv = vm->privateData; + virDomainDefPtr vmdef = vm->def; + virDomainRNGDefPtr tmpRNG; + int rc; + + if (!(tmpRNG = virDomainRNGFind(vmdef, rng))) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("device not present in domain configuration")); + return ret; + } + + if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("qemu does not support -device")); + return ret; + } + + if (!tmpRNG->info.alias && qemuAssignDeviceRNGAlias(vmdef, tmpRNG, -1) < 0) + return ret; + + sa_assert(tmpRNG->info.alias); + + qemuDomainMarkDeviceForRemoval(vm, &tmpRNG->info); + + qemuDomainObjEnterMonitor(driver, vm); + if (qemuMonitorDelDevice(priv->mon, tmpRNG->info.alias) < 0) { + qemuDomainObjExitMonitor(driver, vm); + goto cleanup; + } + qemuDomainObjExitMonitor(driver, vm); + + rc = qemuDomainWaitForDeviceRemoval(vm); + if (rc == 0 || rc == 1) + ret = qemuDomainRemoveRNGDevice(driver, vm, tmpRNG); + else + ret = 0; + + cleanup: + qemuDomainResetDeviceRemoval(vm); + return ret; +} diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h index d66853b..202c5a2 100644 --- a/src/qemu/qemu_hotplug.h +++ b/src/qemu/qemu_hotplug.h @@ -101,7 +101,9 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver, int qemuDomainAttachRNGDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainRNGDefPtr rng); - +int qemuDomainDetachRNGDevice(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainRNGDefPtr rng); int qemuDomainChrInsert(virDomainDefPtr vmdef, -- 1.8.3.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list