[libvirt] [PATCH 1/4] virtio-rng: allow multiple RNG devices

Peter Krempa pkrempa at redhat.com
Mon Feb 25 22:31:11 UTC 2013


qemu supports adding multiple RNG devices. This patch allows libvirt to
support this.
---
 src/conf/domain_conf.c  | 61 +++++++++++++++++++++++++------------------------
 src/conf/domain_conf.h  |  4 +++-
 src/qemu/qemu_command.c | 19 +++++++--------
 3 files changed, 44 insertions(+), 40 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index b65e52a..40eded6 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1775,7 +1775,9 @@ void virDomainDefFree(virDomainDefPtr def)
         virDomainRedirdevDefFree(def->redirdevs[i]);
     VIR_FREE(def->redirdevs);

-    virDomainRNGDefFree(def->rng);
+    for (i = 0; i < def->nrngs; i++)
+        virDomainRNGDefFree(def->rngs[i]);
+    VIR_FREE(def->rngs);

     VIR_FREE(def->os.type);
     VIR_FREE(def->os.machine);
@@ -2357,10 +2359,10 @@ int virDomainDeviceInfoIterate(virDomainDefPtr def,
         if (cb(def, &device, &def->memballoon->info, opaque) < 0)
             return -1;
     }
-    if (def->rng) {
-        device.type = VIR_DOMAIN_DEVICE_RNG;
-        device.data.rng = def->rng;
-        if (cb(def, &device, &def->rng->info, opaque) < 0)
+    device.type = VIR_DOMAIN_DEVICE_RNG;
+    for (i = 0; i < def->nrngs; i++) {
+        device.data.rng = def->rngs[i];
+        if (cb(def, &device, &def->rngs[i]->info, opaque) < 0)
             return -1;
     }
     device.type = VIR_DOMAIN_DEVICE_HUB;
@@ -10733,21 +10735,21 @@ virDomainDefParseXML(virCapsPtr caps,
         }
     }

-    /* Parse the RNG device */
+    /* Parse the RNG devices */
     if ((n = virXPathNodeSet("./devices/rng", ctxt, &nodes)) < 0)
         goto error;
-
-    if (n > 1) {
-        virReportError(VIR_ERR_XML_ERROR, "%s",
-                       _("only a single RNG device is supported"));
-        goto error;
-    }
-
-    if (n > 0) {
-        if (!(def->rng = virDomainRNGDefParseXML(nodes[0], ctxt, flags)))
+    if (n && VIR_ALLOC_N(def->rngs, n) < 0)
+        goto no_memory;
+    for (i = 0; i < n; i++) {
+        virDomainRNGDefPtr rng = virDomainRNGDefParseXML(nodes[i],
+                                                         ctxt,
+                                                         flags);
+        if (!rng)
             goto error;
-        VIR_FREE(nodes);
+
+        def->rngs[def->nrngs++] = rng;
     }
+    VIR_FREE(nodes);

     /* analysis of the hub devices */
     if ((n = virXPathNodeSet("./devices/hub", ctxt, &nodes)) < 0) {
@@ -11702,17 +11704,6 @@ static bool
 virDomainRNGDefCheckABIStability(virDomainRNGDefPtr src,
                                  virDomainRNGDefPtr dst)
 {
-    if (!src && !dst)
-        return true;
-
-    if (!src || !dst) {
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                       _("Target domain RNG device count '%d' "
-                         "does not match source count '%d'"),
-                       src ? 1 : 0, dst ? 1 : 0);
-        return false;
-    }
-
     if (src->model != dst->model) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                        _("Target RNG model '%s' does not match source '%s'"),
@@ -12129,8 +12120,16 @@ virDomainDefCheckABIStability(virDomainDefPtr src,
                                                  dst->memballoon))
         return false;

-    if (!virDomainRNGDefCheckABIStability(src->rng, dst->rng))
+    if (src->nrngs != dst->nrngs) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("Target domain RNG device count %zu "
+                         "does not match source %zu"), dst->nrngs, src->nrngs);
         return false;
+    }
+
+    for (i = 0 ; i < src->nrngs ; i++)
+        if (!virDomainRNGDefCheckABIStability(src->rngs[i], dst->rngs[i]))
+            return false;

     return true;
 }
@@ -15054,8 +15053,10 @@ virDomainDefFormatInternal(virDomainDefPtr def,
     if (def->memballoon)
         virDomainMemballoonDefFormat(buf, def->memballoon, flags);

-    if (def->rng)
-        virDomainRNGDefFormat(buf, def->rng, flags);
+    for (n = 0; n < def->nrngs; n++) {
+        if (virDomainRNGDefFormat(buf, def->rngs[n], flags))
+            goto error;
+    }

     virBufferAddLit(buf, "  </devices>\n");

diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 0828954..5dc3400 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1878,13 +1878,15 @@ struct _virDomainDef {
     size_t nseclabels;
     virSecurityLabelDefPtr *seclabels;

+    size_t nrngs;
+    virDomainRNGDefPtr *rngs;
+
     /* Only 1 */
     virDomainWatchdogDefPtr watchdog;
     virDomainMemballoonDefPtr memballoon;
     virCPUDefPtr cpu;
     virSysinfoDefPtr sysinfo;
     virDomainRedirFilterDefPtr redirfilter;
-    virDomainRNGDefPtr rng;

     void *namespaceData;
     virDomainXMLNamespace ns;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 1c9bfc9..9270258 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -787,8 +787,8 @@ 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)
+    for (i = 0; i < def->nrngs ; i++) {
+        if (virAsprintf(&def->rngs[i]->info.alias, "rng%d", i) < 0)
             goto no_memory;
     }

@@ -1665,10 +1665,11 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
     }

     /* 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)
+    for (i = 0; i < def->nrngs; i++) {
+        if (def->rngs[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
+            continue;
+
+        if (qemuDomainPCIAddressSetNextAddr(addrs, &def->rngs[i]->info) < 0)
             goto error;
     }

@@ -7110,13 +7111,13 @@ qemuBuildCommandLine(virConnectPtr conn,
         }
     }

-    if (def->rng) {
+    for (i = 0; i < def->nrngs; i++) {
         /* add the RNG source backend */
-        if (qemuBuildRNGBackendArgs(cmd, def->rng, qemuCaps) < 0)
+        if (qemuBuildRNGBackendArgs(cmd, def->rngs[i], qemuCaps) < 0)
             goto error;

         /* add the device */
-        if (qemuBuildRNGDeviceArgs(cmd, def->rng, qemuCaps) < 0)
+        if (qemuBuildRNGDeviceArgs(cmd, def->rngs[i], qemuCaps) < 0)
             goto error;
     }

-- 
1.8.1.1




More information about the libvir-list mailing list