Qemu's implementation of virtio RNG supports rate limiting of the entropy used. This patch exposes the option to tune this functionality. 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> ... --- Notes: Version 5: - adjust after forbiding arbitrary name passthrough - rebase to master Version 4: - Reword docs - state it is available since 1.0.4 as the tree is frozen and this was actually never acked before Version 3: - State the time unit in docs Version 2: - qemu uses bytes/period, adapt the value according to that docs/formatdomain.html.in | 14 ++++++++++++++ docs/schemas/domaincommon.rng | 18 +++++++++++++++++- src/conf/domain_conf.c | 17 +++++++++++++++++ src/conf/domain_conf.h | 2 ++ src/qemu/qemu_command.c | 9 +++++++++ .../qemuxml2argv-virtio-rng-random.args | 2 +- .../qemuxml2argv-virtio-rng-random.xml | 1 + 7 files changed, 61 insertions(+), 2 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 4cafc92..b8eb53d 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -4280,6 +4280,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'> @@ -4302,6 +4303,19 @@ 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 optional <code>rate</code> element allows limiting the rate at + which entropy can be consumed from the source. An optional + <code>period</code> attribute specifies the duration of a period in + milliseconds; if omitted, the period is taken as 1000 milliseconds + (1 second). The element contents specify how many bits are permitted + per period. Drivers may enforce a minimum rate, and may round the + rate down to a minimum granularity. + <span class='since'>Since 1.0.4</span> + </p> + </dd> <dt><code>backend</code></dt> <dd> <p> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 4b60885..dc45af1 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -3500,7 +3500,12 @@ <value>virtio</value> </choice> </attribute> - <ref name="rng-backend"/> + <interleave> + <ref name="rng-backend"/> + <optional> + <ref name="rng-rate"/> + </optional> + </interleave> </element> </define> @@ -3527,6 +3532,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 739bd72..8a02375 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -7400,6 +7400,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; @@ -13715,6 +13726,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 2509193..e19b5c0 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1721,6 +1721,8 @@ enum virDomainRNGBackend { struct _virDomainRNGDef { int model; int backend; + unsigned int rate; /* bits per period */ + unsigned int period; /* milliseconds */ union { char *file; /* file name for 'random' source */ diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 201fac1..c0f8dd2 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4255,6 +4255,15 @@ qemuBuildRNGDeviceArgs(virCommandPtr cmd, virBufferAsprintf(&buf, "virtio-rng-pci,rng=%s", dev->info.alias); + if (dev->rate > 0) { + /* qemu uses bytes */ + virBufferAsprintf(&buf, ",max-bytes=%u", dev->rate / 8); + 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 7ab9dbc..33b5adc 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-random.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-random.args @@ -3,4 +3,4 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu \ -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=/dev/hwrng \ --device virtio-rng-pci,rng=rng0,bus=pci.0,addr=0x4 +-device virtio-rng-pci,rng=rng0,max-bytes=100,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 1e2c4be..813e42e 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'>800</rate> <backend model='random'>/dev/hwrng</backend> </rng> </devices> -- 1.8.1.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list