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