[libvirt] [PATCH 11/12] qemu: Implement RNG device hotplug on live level
lhuang
lhuang at redhat.com
Tue Jan 6 06:15:25 UTC 2015
On 01/05/2015 11:48 PM, Peter Krempa wrote:
> On 01/03/15 06:06, Luyao Huang wrote:
>> We have enough patches for hotplug RNG device, maybe we can
>> implement live hotplug of a RNG device.
>>
>> Signed-off-by: Luyao Huang <lhuang at redhat.com>
>> ---
>> src/qemu/qemu_driver.c | 8 ++++-
>> src/qemu/qemu_hotplug.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++
>> src/qemu/qemu_hotplug.h | 3 ++
>> 3 files changed, 102 insertions(+), 1 deletion(-)
>>
>> diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
>> index f9327b4..7f1e612 100644
>> --- a/src/qemu/qemu_hotplug.c
>> +++ b/src/qemu/qemu_hotplug.c
>> @@ -1523,6 +1523,98 @@ qemuDomainRNGRemove(virDomainDefPtr vmdef,
>> return ret;
>> }
>>
>> +int qemuDomainAttachRNGDevice(virQEMUDriverPtr driver,
>> + virDomainObjPtr vm,
>> + virDomainRNGDefPtr rng)
>> +{
>> + int ret = -1;
>> + qemuDomainObjPrivatePtr priv = vm->privateData;
>> + virDomainDefPtr vmdef = vm->def;
>> + char *devstr = NULL;
>> + char *charAlias = NULL;
>> + char *objAlias = NULL;
>> + bool need_remove = false;
>> + bool releaseaddr = false;
>> +
>> + if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
>> + virReportError(VIR_ERR_OPERATION_INVALID, "%s",
>> + _("qemu does not support -device"));
>> + return ret;
>> + }
> Additionally to the -device support, qemu also needs to support chardev
> hotplug and the rng device with the appropriate backends, we already
> have capability bits for them so you need to check them here.
Thanks for your review.
Yes, i forgot these check in this place and i found
QEMU_CAPS_OBJECT_RNG_RANDOM
and QEMU_CAPS_OBJECT_RNG_EGD for random and egd backend RNG device.
But i cannot found a capability bit for "support chardev hotplug", maybe
this one? QEMU_CAPS_CHARDEV
>> +
>> + if (qemuAssignDeviceRNGAlias(vmdef, rng, -1) < 0)
>> + return ret;
>> +
>> + if (rng->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
>> + if (STRPREFIX(vm->def->os.machine, "s390-ccw") &&
>> + virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW)) {
>> + rng->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW;
>> + } else if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_S390)) {
>> + rng->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390;
>> + }
>> + }
>> +
>> + if (rng->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE ||
>> + rng->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
>> + if (virDomainPCIAddressEnsureAddr(priv->pciaddrs, &rng->info) < 0)
>> + return ret;
>> + } else if (rng->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
>> + if (virDomainCCWAddressAssign(&rng->info, priv->ccwaddrs,
>> + !rng->info.addr.ccw.assigned) < 0)
> Line above is misaligned.
Thanks
>
>> + return ret;
>> + }
>> + releaseaddr = true;
>> + if (!(devstr = qemuBuildRNGDevStr(vmdef, rng, priv->qemuCaps)))
>> + return ret;
> After you set releaseaddr to true you need to jump to cleanup in case of
> error so that the address gets cleared.
Yes, i have made a mistake here. I will fix it in next version.
>> +
>> + if (virAsprintf(&objAlias, "obj%s", rng->info.alias) < 0)
>> + goto cleanup;
>> +
>> + if (rng->backend == VIR_DOMAIN_RNG_BACKEND_EGD) {
>> + if (virAsprintf(&charAlias, "char%s", rng->info.alias) < 0)
>> + goto cleanup;
>> +
>> + qemuDomainObjEnterMonitor(driver, vm);
>> + if (qemuMonitorAttachCharDev(priv->mon, charAlias, rng->source.chardev) < 0) {
>> + qemuDomainObjExitMonitor(driver, vm);
>> + goto audit;
>> + }
>> + need_remove = true;
> This variable should be named "remove_chardev" so that it's clear what
> it's used to.
>
Okay, thanks
>> + } else {
>> + qemuDomainObjEnterMonitor(driver, vm);
>> + }
>> +
>> + if (qemuMonitorAttachRNGDev(priv->mon, charAlias, objAlias, rng) < 0) {
>> + if (need_remove)
>> + qemuMonitorDetachCharDev(priv->mon, charAlias);
>> + qemuDomainObjExitMonitor(driver, vm);
>> + goto audit;
>> + }
>> +
>> + if (devstr && qemuMonitorAddDevice(priv->mon, devstr) < 0) {
>> + qemuMonitorDetachRNGDev(priv->mon, objAlias);
>> + if (need_remove)
>> + qemuMonitorDetachCharDev(priv->mon, charAlias);
>> + qemuDomainObjExitMonitor(driver, vm);
>> + goto audit;
>> + }
>> + qemuDomainObjExitMonitor(driver, vm);
>> +
>> + if (qemuDomainRNGInsert(vmdef, rng) < 0)
>> + goto cleanup;
>> +
>> + ret = 0;
>> + audit:
>> + virDomainAuditRNG(vm, NULL, rng, "attach", ret == 0);
>> + cleanup:
>> + if (releaseaddr)
>> + qemuDomainReleaseDeviceAddress(vm, &rng->info, NULL);
>> + VIR_FREE(charAlias);
>> + VIR_FREE(objAlias);
>> + VIR_FREE(devstr);
>> + return ret;
>> +}
>> +
>>
>> static int
>> qemuDomainAttachHostUSBDevice(virQEMUDriverPtr driver,
>
> The rest looks good.
>
> Peter
>
>
More information about the libvir-list
mailing list