[libvirt] [PATCH 2/3] virtio-rng: allow multiple RNG devices

Peter Krempa pkrempa at redhat.com
Thu Jul 24 14:07:47 UTC 2014


qemu supports adding multiple RNG devices. This patch allows libvirt to
support this.
---
 src/conf/domain_audit.c |  4 ++--
 src/conf/domain_conf.c  | 58 ++++++++++++++++++++++++-------------------------
 src/conf/domain_conf.h  |  4 +++-
 src/qemu/qemu_cgroup.c  | 33 ++++++++++++++--------------
 src/qemu/qemu_command.c | 29 ++++++++++++++-----------
 5 files changed, 67 insertions(+), 61 deletions(-)

diff --git a/src/conf/domain_audit.c b/src/conf/domain_audit.c
index 3ad58b0..2d1b1fb 100644
--- a/src/conf/domain_audit.c
+++ b/src/conf/domain_audit.c
@@ -874,8 +874,8 @@ virDomainAuditStart(virDomainObjPtr vm, const char *reason, bool success)
     for (i = 0; i < vm->def->nsmartcards; i++)
         virDomainAuditSmartcard(vm, vm->def->smartcards[i], "start", true);

-    if (vm->def->rng)
-        virDomainAuditRNG(vm, NULL, vm->def->rng, "start", true);
+    for (i = 0; i < vm->def->nrngs; i++)
+        virDomainAuditRNG(vm, NULL, vm->def->rngs[i], "start", true);

     if (vm->def->tpm)
         virDomainAuditTPM(vm, vm->def->tpm, "start", true);
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 1b43a26..9c3cd8a 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2057,7 +2057,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);

     virDomainTPMDefFree(def->tpm);

@@ -2745,10 +2747,10 @@ virDomainDeviceInfoIterateInternal(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;
     }
     if (def->nvram) {
@@ -12821,20 +12823,19 @@ virDomainDefParseXML(xmlDocPtr xml,
         VIR_FREE(nodes);
     }

-    /* 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"));
+    if (n && VIR_ALLOC_N(def->rngs, n) < 0)
         goto error;
-    }
-
-    if (n > 0) {
-        if (!(def->rng = virDomainRNGDefParseXML(nodes[0], ctxt, flags)))
+    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);

@@ -13864,17 +13865,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'"),
@@ -14439,8 +14429,16 @@ virDomainDefCheckABIStability(virDomainDefPtr src,
                                                  dst->memballoon))
         goto error;

-    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);
         goto error;
+    }
+
+    for (i = 0; i < src->nrngs; i++)
+        if (!virDomainRNGDefCheckABIStability(src->rngs[i], dst->rngs[i]))
+            goto error;

     if (!virDomainPanicCheckABIStability(src->panic, dst->panic))
         goto error;
@@ -18020,8 +18018,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;
+    }

     if (def->nvram)
         virDomainNVRAMDefFormat(buf, def->nvram, flags);
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 55292e1..b988b17 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1981,6 +1981,9 @@ struct _virDomainDef {
     size_t nseclabels;
     virSecurityLabelDefPtr *seclabels;

+    size_t nrngs;
+    virDomainRNGDefPtr *rngs;
+
     /* Only 1 */
     virDomainWatchdogDefPtr watchdog;
     virDomainMemballoonDefPtr memballoon;
@@ -1989,7 +1992,6 @@ struct _virDomainDef {
     virCPUDefPtr cpu;
     virSysinfoDefPtr sysinfo;
     virDomainRedirFilterDefPtr redirfilter;
-    virDomainRNGDefPtr rng;
     virDomainPanicDefPtr panic;

     void *namespaceData;
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index f649d66..419be9a 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -584,22 +584,23 @@ qemuSetupDevicesCgroup(virQEMUDriverPtr driver,
             goto cleanup;
     }

-    if (vm->def->rng &&
-        (vm->def->rng->backend == VIR_DOMAIN_RNG_BACKEND_RANDOM)) {
-        VIR_DEBUG("Setting Cgroup ACL for RNG device");
-        const char *rngpath = vm->def->rng->source.file;
-
-        /* fix path when using the default */
-        if (!rngpath)
-            rngpath = "/dev/random";
-
-        rv = virCgroupAllowDevicePath(priv->cgroup, rngpath,
-                                      VIR_CGROUP_DEVICE_RW);
-        virDomainAuditCgroupPath(vm, priv->cgroup, "allow",
-                                 rngpath, "rw", rv == 0);
-        if (rv < 0 &&
-            !virLastErrorIsSystemErrno(ENOENT))
-            goto cleanup;
+    for (i = 0; i < vm->def->nrngs; i++) {
+        if (vm->def->rngs[i]->backend == VIR_DOMAIN_RNG_BACKEND_RANDOM) {
+            VIR_DEBUG("Setting Cgroup ACL for RNG device");
+            const char *rngpath = vm->def->rngs[i]->source.file;
+
+            /* fix path when using the default */
+            if (!rngpath)
+                rngpath = "/dev/random";
+
+            rv = virCgroupAllowDevicePath(priv->cgroup, rngpath,
+                                          VIR_CGROUP_DEVICE_RW);
+            virDomainAuditCgroupPath(vm, priv->cgroup, "allow",
+                                     rngpath, "rw", rv == 0);
+            if (rv < 0 &&
+                !virLastErrorIsSystemErrno(ENOENT))
+                goto cleanup;
+        }
     }

     ret = 0;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index c5e86b4..7f9357c 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1050,8 +1050,8 @@ qemuAssignDeviceAliases(virDomainDefPtr def, virQEMUCapsPtr qemuCaps)
         if (virAsprintf(&def->memballoon->info.alias, "balloon%d", 0) < 0)
             return -1;
     }
-    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%zu", i) < 0)
             return -1;
     }
     if (def->tpm) {
@@ -1102,10 +1102,11 @@ qemuDomainPrimeVirtioDeviceAddresses(virDomainDefPtr def,
         def->memballoon->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
         def->memballoon->info.type = type;

-    if (def->rng &&
-        def->rng->model == VIR_DOMAIN_RNG_MODEL_VIRTIO &&
-        def->rng->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
-        def->rng->info.type = type;
+    for (i = 0; i < def->nrngs; i++) {
+        if (def->rngs[i]->model == VIR_DOMAIN_RNG_MODEL_VIRTIO &&
+            def->rngs[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
+            def->rngs[i]->info.type = type;
+    }
 }


@@ -2232,11 +2233,13 @@ 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) {
+    for (i = 0; i < def->nrngs; i++) {
+        if (def->rngs[i]->model != VIR_DOMAIN_RNG_MODEL_VIRTIO ||
+            def->rngs[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
+            continue;
+
         if (virDomainPCIAddressReserveNextSlot(addrs,
-                                               &def->rng->info, flags) < 0)
+                                               &def->rngs[i]->info, flags) < 0)
             goto error;
     }

@@ -9163,13 +9166,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, def->rng, qemuCaps) < 0)
+        if (qemuBuildRNGDeviceArgs(cmd, def, def->rngs[i], qemuCaps) < 0)
             goto error;
     }

-- 
2.0.0




More information about the libvir-list mailing list