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