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);
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);
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) {
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);
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'"),
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;
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);
size_t nseclabels;
virSecurityLabelDefPtr *seclabels;
+ size_t nrngs;
+ virDomainRNGDefPtr *rngs;
+
/* Only 1 */
virDomainWatchdogDefPtr watchdog;
virDomainMemballoonDefPtr memballoon;
virCPUDefPtr cpu;
virSysinfoDefPtr sysinfo;
virDomainRedirFilterDefPtr redirfilter;
- virDomainRNGDefPtr rng;
virDomainPanicDefPtr panic;
void *namespaceData;
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;
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) {
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;
+ }
}
}
/* 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;
}
}
}
- 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;
}