Qemu's implementation of virtio RNG supports rate limiting of the entropy used. This patch exposes the option to tune this fucntionality. This patch is based on qemu commit 904d6f588063fb5ad2b61998acdf1e73fb4 The rate limiting is exported in the XML as: <devices> ... <rng model='virtio'> <rate period='1234'>4321</rate> <backend model='random'/> </rng> ... --- docs/formatdomain.html.in | 9 +++++++++ docs/schemas/domaincommon.rng | 18 +++++++++++++++++- src/conf/domain_conf.c | 17 +++++++++++++++++ src/conf/domain_conf.h | 2 ++ src/qemu/qemu_command.c | 8 ++++++++ .../qemuxml2argv-virtio-rng-random.args | 2 +- .../qemuxml2argv-virtio-rng-random.xml | 1 + 7 files changed, 55 insertions(+), 2 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index e8cd086..b264460 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -4293,6 +4293,7 @@ qemu-kvm -net nic,model=? /dev/null ... <devices> <rng model='virtio'> + <rate period="2000">1234</rate> <backend model='random'>/dev/random</backend> <!-- OR --> <backend model='egd' type='udp'> @@ -4315,6 +4316,14 @@ qemu-kvm -net nic,model=? /dev/null <li>'virtio' — supported by qemu and virtio-rng kernel module</li> </ul> </dd> + <dt><code>rate</code></dt> + <dd> + <p> + The rate parameter allows to limit the rate that the entropy can be + read from the source. The value is in bits that the device is allowed + to read in the selected period. The default period is 1000ms or 1 second. + </p> + </dd> <dt><code>backend</code></dt> <dd> <p> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 8330a50..da53095 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -3522,7 +3522,12 @@ <value>virtio</value> </choice> </attribute> - <ref name="rng-backend"/> + <interleave> + <ref name="rng-backend"/> + <optional> + <ref name="rng-rate"/> + </optional> + </interleave> </element> </define> @@ -3546,6 +3551,17 @@ </element> </define> + <define name="rng-rate"> + <element name="rate"> + <optional> + <attribute name="period"> + <ref name="positiveInteger"/> + </attribute> + </optional> + <ref name="positiveInteger"/> + </element> + </define> + <define name="usbmaster"> <element name="master"> <attribute name="startport"> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 53c6b2f..023e92c 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -7445,6 +7445,17 @@ virDomainRNGDefParseXML(const xmlNodePtr node, ctxt->node = node; + if (virXPathUInt("string(./rate)", ctxt, &def->rate) < -1) { + virReportError(VIR_ERR_XML_ERROR, "%s", _("invalid RNG rate value")); + goto error; + } + + if (def->rate > 0 && + virXPathUInt("string(./rate/@period)", ctxt, &def->period) < -1) { + virReportError(VIR_ERR_XML_ERROR, "%s", _("invalid RNG period value")); + goto error; + } + if ((nbackends = virXPathNodeSet("./backend", ctxt, &backends)) < 0) goto error; @@ -13792,6 +13803,12 @@ virDomainRNGDefFormat(virBufferPtr buf, const char *backend = virDomainRNGBackendTypeToString(def->backend); virBufferAsprintf(buf, " <rng model='%s'>\n", model); + if (def->rate) { + virBufferAddLit(buf, " <rate"); + if (def->period) + virBufferAsprintf(buf, " period='%u'", def->period); + virBufferAsprintf(buf, ">%u</rate>\n", def->rate); + } virBufferAsprintf(buf, " <backend model='%s'", backend); switch ((enum virDomainRNGBackend) def->backend) { diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index b78a04c..b34484c 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1736,6 +1736,8 @@ enum virDomainRNGBackend { struct _virDomainRNGDef { int model; int backend; + unsigned int rate; + unsigned int period; union { char *file; /* file name for 'random' source */ diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index d3a9b70..14d8f6d 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4297,6 +4297,14 @@ qemuBuildRNGDeviceArgs(virCommandPtr cmd, virBufferAsprintf(&buf, "virtio-rng-pci,rng=%s", dev->info.alias); + if (dev->rate > 0) { + virBufferAsprintf(&buf, ",max-bytes=%u", dev->rate); + if (dev->period) + virBufferAsprintf(&buf, ",period=%u", dev->period); + else + virBufferAddLit(&buf, ",period=1000"); + } + if (qemuBuildDeviceAddressStr(&buf, &dev->info, qemuCaps) < 0) goto cleanup; diff --git a/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-random.args b/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-random.args index 4611ae5..428804b 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-random.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-random.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 -object rng-random,id=rng0,filename=/test/phile -device virtio-rng-pci,rng=rng0,bus=pci.0,addr=0x4 +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 -object rng-random,id=rng0,filename=/test/phile -device virtio-rng-pci,rng=rng0,max-bytes=1337,period=1234,bus=pci.0,addr=0x4 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-random.xml b/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-random.xml index ab1f38c..73e77cd 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-random.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-random.xml @@ -17,6 +17,7 @@ <controller type='usb' index='0'/> <memballoon model='virtio'/> <rng model='virtio'> + <rate period='1234'>1337</rate> <backend model='random'>/test/phile</backend> </rng> </devices> -- 1.8.1.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list