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

Peter Krempa pkrempa at redhat.com
Wed Feb 13 10:59:05 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.

qemu is invoked with these additional parameters if the device is
enabled:

-object rng-random,id=rng0,filename=/test/phile (to add the backend)
-device virtio-rng-pci,rng=rng0,bus=pci.0,addr=0x4 (to add the device)
---
 src/qemu/qemu_capabilities.c |   5 ++-
 src/qemu/qemu_capabilities.h |   3 ++
 src/qemu/qemu_command.c      | 100 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 107 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 4efe052..a316a56 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -205,7 +205,8 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
               "usb-serial", /* 125 */
               "usb-net",
               "add-fd",
-
+              "virtio-rng",
+              "rng-random",
     );

 struct _virQEMUCaps {
@@ -1354,6 +1355,8 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = {
     { "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 e69d558..ee0d0ca 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -166,6 +166,9 @@ enum virQEMUCapsFlags {
     QEMU_CAPS_DEVICE_USB_SERIAL  = 125, /* -device usb-serial */
     QEMU_CAPS_DEVICE_USB_NET     = 126, /* -device usb-net */
     QEMU_CAPS_ADD_FD             = 127, /* -add-fd */
+    QEMU_CAPS_DEVICE_VIRTIO_RNG  = 128, /* virtio-rng device */
+    QEMU_CAPS_OBJECT_RNG_RANDOM  = 129, /* 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 6c28123..7ffa6ab 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -787,6 +787,10 @@ qemuAssignDeviceAliases(virDomainDefPtr def, virQEMUCapsPtr qemuCaps)
         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;

@@ -1701,6 +1705,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 &&
@@ -4206,6 +4218,84 @@ error:
     return NULL;
 }

+
+static int
+qemuBuildRNGBackendArgs(virCommandPtr cmd,
+                        virDomainRNGDefPtr dev,
+                        virQEMUCapsPtr qemuCaps)
+{
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+    int ret = -1;
+
+    switch ((enum virDomainRNGBackend) dev->backend) {
+    case VIR_DOMAIN_RNG_BACKEND_RANDOM:
+        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_RNG_RANDOM)) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                           _("this qemu doesn't support the rng-random "
+                             " backend"));
+            goto cleanup;
+        }
+
+        virBufferAsprintf(&buf, "rng-random,id=%s", dev->info.alias);
+        if (dev->source.file)
+            virBufferAsprintf(&buf, ",filename=%s", dev->source.file);
+
+        virCommandAddArg(cmd, "-object");
+        virCommandAddArgBuffer(cmd, &buf);
+        break;
+
+    case VIR_DOMAIN_RNG_BACKEND_EGD:
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("egd RNG backend not yet implemented"));
+        goto cleanup;
+        break;
+
+    case VIR_DOMAIN_RNG_BACKEND_LAST:
+        break;
+    }
+
+    ret = 0;
+
+cleanup:
+    virBufferFreeAndReset(&buf);
+    return ret;
+}
+
+
+static int
+qemuBuildRNGDeviceArgs(virCommandPtr cmd,
+                       virDomainRNGDefPtr dev,
+                       virQEMUCapsPtr qemuCaps)
+{
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+    int ret = -1;
+
+    if (dev->model != VIR_DOMAIN_RNG_MODEL_VIRTIO ||
+        !virQEMUCapsGet(qemuCaps, 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 cleanup;
+    }
+
+    virBufferAsprintf(&buf, "virtio-rng-pci,rng=%s", dev->info.alias);
+
+    if (qemuBuildDeviceAddressStr(&buf, &dev->info, qemuCaps) < 0)
+        goto cleanup;
+
+    virCommandAddArg(cmd, "-device");
+    virCommandAddArgBuffer(cmd, &buf);
+
+    ret = 0;
+
+cleanup:
+    virBufferFreeAndReset(&buf);
+    return ret;
+}
+
+
+
 static char *qemuBuildSmbiosBiosStr(virSysinfoDefPtr def)
 {
     virBuffer buf = VIR_BUFFER_INITIALIZER;
@@ -7047,6 +7137,16 @@ qemuBuildCommandLine(virConnectPtr conn,
         }
     }

+    if (def->rng) {
+        /* add the RNG source backend */
+        if (qemuBuildRNGBackendArgs(cmd, def->rng, qemuCaps) < 0)
+            goto error;
+
+        /* add the device */
+        if (qemuBuildRNGDeviceArgs(cmd, def->rng, qemuCaps) < 0)
+            goto error;
+    }
+
     if (snapshot)
         virCommandAddArgList(cmd, "-loadvm", snapshot->def->name, NULL);

-- 
1.8.1.1




More information about the libvir-list mailing list