This patch implements support for the virtio-rng-pci device and the rng-random backend in qemu. Two capabilities bits are added to track support for those: QEMU_CAPS_DEVICE_VIRTIO_RNG - for the device support and QEMU_CAPS_OBJECT_RNG_RANDOM - for the backend support. --- src/qemu/qemu_capabilities.c | 5 +- src/qemu/qemu_capabilities.h | 3 ++ src/qemu/qemu_command.c | 108 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index b166dd6..4947a3a 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -203,7 +203,8 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST, "usb-serial", /* 125 */ "usb-net", - + "virtio-rng", + "rng-random", ); struct _qemuCaps { @@ -1351,6 +1352,8 @@ struct qemuCapsStringFlags qemuCapsObjectTypes[] = { { "vmware-svga", QEMU_CAPS_DEVICE_VMWARE_SVGA }, { "usb-serial", QEMU_CAPS_DEVICE_USB_SERIAL}, { "usb-net", QEMU_CAPS_DEVICE_USB_NET}, + { "virtio-rng-pci", QEMU_CAPS_DEVICE_VIRTIO_RNG }, + { "rng-random", QEMU_CAPS_OBJECT_RNG_RANDOM }, }; diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 089fa30..6139bc3 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -165,6 +165,9 @@ enum qemuCapsFlags { QEMU_CAPS_SCLP_S390 = 124, /* -device sclp* */ QEMU_CAPS_DEVICE_USB_SERIAL = 125, /* -device usb-serial */ QEMU_CAPS_DEVICE_USB_NET = 126, /* -device usb-net */ + QEMU_CAPS_DEVICE_VIRTIO_RNG = 127, /* virtio-rng device */ + QEMU_CAPS_OBJECT_RNG_RANDOM = 128, /* the rng-random backend for + virtio rng */ QEMU_CAPS_LAST, /* this must always be the last item */ }; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 981c692..847b060 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -781,6 +781,10 @@ qemuAssignDeviceAliases(virDomainDefPtr def, qemuCapsPtr caps) if (virAsprintf(&def->memballoon->info.alias, "balloon%d", 0) < 0) goto no_memory; } + if (def->rng) { + if (virAsprintf(&def->rng->info.alias, "rng%d", 0) < 0) + goto no_memory; + } return 0; @@ -1691,6 +1695,14 @@ qemuAssignDevicePCISlots(virDomainDefPtr def, goto error; } + /* VirtIO RNG */ + if (def->rng && + def->rng->model == VIR_DOMAIN_RNG_MODEL_VIRTIO && + def->rng->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { + if (qemuDomainPCIAddressSetNextAddr(addrs, &def->rng->info) < 0) + goto error; + } + /* A watchdog - skip IB700, it is not a PCI device */ if (def->watchdog && def->watchdog->model != VIR_DOMAIN_WATCHDOG_MODEL_IB700 && @@ -3392,6 +3404,80 @@ error: char * +qemuBuildRNGObjStr(virDomainRNGDefPtr dev, + qemuCapsPtr caps) +{ + virBuffer buf = VIR_BUFFER_INITIALIZER; + + switch ((enum virDomainRNGSource) dev->source) { + case VIR_DOMAIN_RNG_SOURCE_NONE: + case VIR_DOMAIN_RNG_SOURCE_LAST: + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("virtio-rng-pci doesn't support RNG source type '%s'"), + virDomainRNGSourceTypeToString(dev->source)); + goto error; + break; + + case VIR_DOMAIN_RNG_SOURCE_RANDOM: + if (qemuCapsGet(caps, QEMU_CAPS_OBJECT_RNG_RANDOM)) { + virBufferAsprintf(&buf, "rng-random,id=%s", dev->info.alias); + if (dev->address) + virBufferAsprintf(&buf, ",filename=%s", dev->address); + } else { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("this qemu doesn't support the rng-random " + " backend")); + goto error; + } + break; + } + + if (virBufferError(&buf)) { + virReportOOMError(); + goto error; + } + + return virBufferContentAndReset(&buf); + +error: + virBufferFreeAndReset(&buf); + return NULL; +} + + +char * +qemuBuildRNGDevStr(virDomainRNGDefPtr dev, + qemuCapsPtr caps) +{ + virBuffer buf = VIR_BUFFER_INITIALIZER; + + if (dev->model != VIR_DOMAIN_RNG_MODEL_VIRTIO || + !qemuCapsGet(caps, QEMU_CAPS_DEVICE_VIRTIO_RNG)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("RNG device type '%s' is not supported " + "by this of qemu"), + virDomainRNGModelTypeToString(dev->model)); + goto error; + } + + virBufferAsprintf(&buf, "virtio-rng-pci,rng=%s", dev->info.alias); + if (qemuBuildDeviceAddressStr(&buf, &dev->info, caps) < 0) + goto error; + + if (virBufferError(&buf)) { + virReportOOMError(); + goto error; + } + + return virBufferContentAndReset(&buf); + +error: + virBufferFreeAndReset(&buf); + return NULL; +} + + +char * qemuBuildMemballoonDevStr(virDomainMemballoonDefPtr dev, qemuCapsPtr caps) { @@ -6978,6 +7064,28 @@ qemuBuildCommandLine(virConnectPtr conn, } } + if (def->rng && + def->rng->model != VIR_DOMAIN_RNG_MODEL_NONE) { + char *optstr; + + /* create the source object string */ + virCommandAddArg(cmd, "-object"); + + if (!(optstr = qemuBuildRNGObjStr(def->rng, caps))) + goto error; + + virCommandAddArg(cmd, optstr); + VIR_FREE(optstr); + + /* device string */ + virCommandAddArg(cmd, "-device"); + + if (!(optstr = qemuBuildRNGDevStr(def->rng, caps))) + goto error; + virCommandAddArg(cmd, optstr); + VIR_FREE(optstr); + } + if (snapshot) virCommandAddArgList(cmd, "-loadvm", snapshot->def->name, NULL); -- 1.8.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list