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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list