提交 bbddbefa 编写于 作者: P Peter Krempa

virtio-rng: allow multiple RNG devices

qemu supports adding multiple RNG devices. This patch allows libvirt to
support this.
上级 99ff49ee
...@@ -874,8 +874,8 @@ virDomainAuditStart(virDomainObjPtr vm, const char *reason, bool success) ...@@ -874,8 +874,8 @@ virDomainAuditStart(virDomainObjPtr vm, const char *reason, bool success)
for (i = 0; i < vm->def->nsmartcards; i++) for (i = 0; i < vm->def->nsmartcards; i++)
virDomainAuditSmartcard(vm, vm->def->smartcards[i], "start", true); virDomainAuditSmartcard(vm, vm->def->smartcards[i], "start", true);
if (vm->def->rng) for (i = 0; i < vm->def->nrngs; i++)
virDomainAuditRNG(vm, NULL, vm->def->rng, "start", true); virDomainAuditRNG(vm, NULL, vm->def->rngs[i], "start", true);
if (vm->def->tpm) if (vm->def->tpm)
virDomainAuditTPM(vm, vm->def->tpm, "start", true); virDomainAuditTPM(vm, vm->def->tpm, "start", true);
......
...@@ -2057,7 +2057,9 @@ void virDomainDefFree(virDomainDefPtr def) ...@@ -2057,7 +2057,9 @@ void virDomainDefFree(virDomainDefPtr def)
virDomainRedirdevDefFree(def->redirdevs[i]); virDomainRedirdevDefFree(def->redirdevs[i]);
VIR_FREE(def->redirdevs); 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); virDomainTPMDefFree(def->tpm);
...@@ -2745,10 +2747,10 @@ virDomainDeviceInfoIterateInternal(virDomainDefPtr def, ...@@ -2745,10 +2747,10 @@ virDomainDeviceInfoIterateInternal(virDomainDefPtr def,
if (cb(def, &device, &def->memballoon->info, opaque) < 0) if (cb(def, &device, &def->memballoon->info, opaque) < 0)
return -1; return -1;
} }
if (def->rng) { device.type = VIR_DOMAIN_DEVICE_RNG;
device.type = VIR_DOMAIN_DEVICE_RNG; for (i = 0; i < def->nrngs; i++) {
device.data.rng = def->rng; device.data.rng = def->rngs[i];
if (cb(def, &device, &def->rng->info, opaque) < 0) if (cb(def, &device, &def->rngs[i]->info, opaque) < 0)
return -1; return -1;
} }
if (def->nvram) { if (def->nvram) {
...@@ -12821,20 +12823,19 @@ virDomainDefParseXML(xmlDocPtr xml, ...@@ -12821,20 +12823,19 @@ virDomainDefParseXML(xmlDocPtr xml,
VIR_FREE(nodes); VIR_FREE(nodes);
} }
/* Parse the RNG device */ /* Parse the RNG devices */
if ((n = virXPathNodeSet("./devices/rng", ctxt, &nodes)) < 0) if ((n = virXPathNodeSet("./devices/rng", ctxt, &nodes)) < 0)
goto error; goto error;
if (n && VIR_ALLOC_N(def->rngs, n) < 0)
if (n > 1) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("only a single RNG device is supported"));
goto error; goto error;
} for (i = 0; i < n; i++) {
virDomainRNGDefPtr rng = virDomainRNGDefParseXML(nodes[i],
if (n > 0) { ctxt,
if (!(def->rng = virDomainRNGDefParseXML(nodes[0], ctxt, flags))) flags);
if (!rng)
goto error; goto error;
VIR_FREE(nodes);
def->rngs[def->nrngs++] = rng;
} }
VIR_FREE(nodes); VIR_FREE(nodes);
...@@ -13864,17 +13865,6 @@ static bool ...@@ -13864,17 +13865,6 @@ static bool
virDomainRNGDefCheckABIStability(virDomainRNGDefPtr src, virDomainRNGDefCheckABIStability(virDomainRNGDefPtr src,
virDomainRNGDefPtr dst) 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) { if (src->model != dst->model) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Target RNG model '%s' does not match source '%s'"), _("Target RNG model '%s' does not match source '%s'"),
...@@ -14439,8 +14429,16 @@ virDomainDefCheckABIStability(virDomainDefPtr src, ...@@ -14439,8 +14429,16 @@ virDomainDefCheckABIStability(virDomainDefPtr src,
dst->memballoon)) dst->memballoon))
goto error; 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; 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)) if (!virDomainPanicCheckABIStability(src->panic, dst->panic))
goto error; goto error;
...@@ -18020,8 +18018,10 @@ virDomainDefFormatInternal(virDomainDefPtr def, ...@@ -18020,8 +18018,10 @@ virDomainDefFormatInternal(virDomainDefPtr def,
if (def->memballoon) if (def->memballoon)
virDomainMemballoonDefFormat(buf, def->memballoon, flags); virDomainMemballoonDefFormat(buf, def->memballoon, flags);
if (def->rng) for (n = 0; n < def->nrngs; n++) {
virDomainRNGDefFormat(buf, def->rng, flags); if (virDomainRNGDefFormat(buf, def->rngs[n], flags))
goto error;
}
if (def->nvram) if (def->nvram)
virDomainNVRAMDefFormat(buf, def->nvram, flags); virDomainNVRAMDefFormat(buf, def->nvram, flags);
......
...@@ -1981,6 +1981,9 @@ struct _virDomainDef { ...@@ -1981,6 +1981,9 @@ struct _virDomainDef {
size_t nseclabels; size_t nseclabels;
virSecurityLabelDefPtr *seclabels; virSecurityLabelDefPtr *seclabels;
size_t nrngs;
virDomainRNGDefPtr *rngs;
/* Only 1 */ /* Only 1 */
virDomainWatchdogDefPtr watchdog; virDomainWatchdogDefPtr watchdog;
virDomainMemballoonDefPtr memballoon; virDomainMemballoonDefPtr memballoon;
...@@ -1989,7 +1992,6 @@ struct _virDomainDef { ...@@ -1989,7 +1992,6 @@ struct _virDomainDef {
virCPUDefPtr cpu; virCPUDefPtr cpu;
virSysinfoDefPtr sysinfo; virSysinfoDefPtr sysinfo;
virDomainRedirFilterDefPtr redirfilter; virDomainRedirFilterDefPtr redirfilter;
virDomainRNGDefPtr rng;
virDomainPanicDefPtr panic; virDomainPanicDefPtr panic;
void *namespaceData; void *namespaceData;
......
...@@ -584,22 +584,23 @@ qemuSetupDevicesCgroup(virQEMUDriverPtr driver, ...@@ -584,22 +584,23 @@ qemuSetupDevicesCgroup(virQEMUDriverPtr driver,
goto cleanup; goto cleanup;
} }
if (vm->def->rng && for (i = 0; i < vm->def->nrngs; i++) {
(vm->def->rng->backend == VIR_DOMAIN_RNG_BACKEND_RANDOM)) { if (vm->def->rngs[i]->backend == VIR_DOMAIN_RNG_BACKEND_RANDOM) {
VIR_DEBUG("Setting Cgroup ACL for RNG device"); VIR_DEBUG("Setting Cgroup ACL for RNG device");
const char *rngpath = vm->def->rng->source.file; const char *rngpath = vm->def->rngs[i]->source.file;
/* fix path when using the default */ /* fix path when using the default */
if (!rngpath) if (!rngpath)
rngpath = "/dev/random"; rngpath = "/dev/random";
rv = virCgroupAllowDevicePath(priv->cgroup, rngpath, rv = virCgroupAllowDevicePath(priv->cgroup, rngpath,
VIR_CGROUP_DEVICE_RW); VIR_CGROUP_DEVICE_RW);
virDomainAuditCgroupPath(vm, priv->cgroup, "allow", virDomainAuditCgroupPath(vm, priv->cgroup, "allow",
rngpath, "rw", rv == 0); rngpath, "rw", rv == 0);
if (rv < 0 && if (rv < 0 &&
!virLastErrorIsSystemErrno(ENOENT)) !virLastErrorIsSystemErrno(ENOENT))
goto cleanup; goto cleanup;
}
} }
ret = 0; ret = 0;
......
...@@ -1050,8 +1050,8 @@ qemuAssignDeviceAliases(virDomainDefPtr def, virQEMUCapsPtr qemuCaps) ...@@ -1050,8 +1050,8 @@ qemuAssignDeviceAliases(virDomainDefPtr def, virQEMUCapsPtr qemuCaps)
if (virAsprintf(&def->memballoon->info.alias, "balloon%d", 0) < 0) if (virAsprintf(&def->memballoon->info.alias, "balloon%d", 0) < 0)
return -1; return -1;
} }
if (def->rng) { for (i = 0; i < def->nrngs; i++) {
if (virAsprintf(&def->rng->info.alias, "rng%d", 0) < 0) if (virAsprintf(&def->rngs[i]->info.alias, "rng%zu", i) < 0)
return -1; return -1;
} }
if (def->tpm) { if (def->tpm) {
...@@ -1102,10 +1102,11 @@ qemuDomainPrimeVirtioDeviceAddresses(virDomainDefPtr def, ...@@ -1102,10 +1102,11 @@ qemuDomainPrimeVirtioDeviceAddresses(virDomainDefPtr def,
def->memballoon->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) def->memballoon->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
def->memballoon->info.type = type; def->memballoon->info.type = type;
if (def->rng && for (i = 0; i < def->nrngs; i++) {
def->rng->model == VIR_DOMAIN_RNG_MODEL_VIRTIO && if (def->rngs[i]->model == VIR_DOMAIN_RNG_MODEL_VIRTIO &&
def->rng->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) def->rngs[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
def->rng->info.type = type; def->rngs[i]->info.type = type;
}
} }
...@@ -2232,11 +2233,13 @@ qemuAssignDevicePCISlots(virDomainDefPtr def, ...@@ -2232,11 +2233,13 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
} }
/* VirtIO RNG */ /* VirtIO RNG */
if (def->rng && for (i = 0; i < def->nrngs; i++) {
def->rng->model == VIR_DOMAIN_RNG_MODEL_VIRTIO && if (def->rngs[i]->model != VIR_DOMAIN_RNG_MODEL_VIRTIO ||
def->rng->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { def->rngs[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
continue;
if (virDomainPCIAddressReserveNextSlot(addrs, if (virDomainPCIAddressReserveNextSlot(addrs,
&def->rng->info, flags) < 0) &def->rngs[i]->info, flags) < 0)
goto error; goto error;
} }
...@@ -9163,13 +9166,13 @@ qemuBuildCommandLine(virConnectPtr conn, ...@@ -9163,13 +9166,13 @@ qemuBuildCommandLine(virConnectPtr conn,
} }
} }
if (def->rng) { for (i = 0; i < def->nrngs; i++) {
/* add the RNG source backend */ /* add the RNG source backend */
if (qemuBuildRNGBackendArgs(cmd, def->rng, qemuCaps) < 0) if (qemuBuildRNGBackendArgs(cmd, def->rngs[i], qemuCaps) < 0)
goto error; goto error;
/* add the device */ /* add the device */
if (qemuBuildRNGDeviceArgs(cmd, def, def->rng, qemuCaps) < 0) if (qemuBuildRNGDeviceArgs(cmd, def, def->rngs[i], qemuCaps) < 0)
goto error; goto error;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册