[libvirt] [PATCH 4/4] qemu: Implement support for the RNG device and the random backend

Peter Krempa pkrempa at redhat.com
Fri Jan 11 17:00:44 UTC 2013


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




More information about the libvir-list mailing list