]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
virtio-rng: Add rate limiting options for virtio-RNG
authorPeter Krempa <pkrempa@redhat.com>
Wed, 13 Feb 2013 14:37:39 +0000 (15:37 +0100)
committerPeter Krempa <pkrempa@redhat.com>
Thu, 14 Mar 2013 12:28:10 +0000 (13:28 +0100)
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 bytes='123' period='1234'/>
    <backend model='random'/>
  </rng>
  ...

docs/formatdomain.html.in
docs/schemas/domaincommon.rng
src/conf/domain_conf.c
src/conf/domain_conf.h
src/qemu/qemu_command.c
tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-random.args
tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-random.xml

index 35b47f2dd79f459e0fb9ac71f7de4e0b43718442..1ef80b06caeda6bff236da0a4f12ed4701641e78 100644 (file)
@@ -4294,6 +4294,7 @@ qemu-kvm -net nic,model=? /dev/null
   ...
   &lt;devices&gt;
     &lt;rng model='virtio'&gt;
+      &lt;rate period="2000" bytes="1234"/&gt;
       &lt;backend model='random'&gt;/dev/random&lt;/backend&gt;
       &lt;!-- OR --&gt;
       &lt;backend model='egd' type='udp'&gt;
@@ -4316,6 +4317,18 @@ qemu-kvm -net nic,model=? /dev/null
           <li>'virtio' &mdash; 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.  The mandatory
+          attribute <code>bytes</code> specifies how many bytes are permitted
+          to be consumed per period.  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).
+          <span class='since'>Since 1.0.4</span>
+        </p>
+      </dd>
       <dt><code>backend</code></dt>
       <dd>
         <p>
index c40263c76bdac1a30150b3485d0de7258af4bf40..97920653dfcf009c6a46a9f9562df8049d840337 100644 (file)
           <value>virtio</value>
         </choice>
       </attribute>
-      <ref name="rng-backend"/>
+      <interleave>
+        <ref name="rng-backend"/>
+        <optional>
+          <ref name="rng-rate"/>
+        </optional>
+      </interleave>
     </element>
   </define>
 
     </element>
   </define>
 
+  <define name="rng-rate">
+    <element name="rate">
+      <attribute name="bytes">
+        <ref name="positiveInteger"/>
+      </attribute>
+      <optional>
+        <attribute name="period">
+          <ref name="positiveInteger"/>
+        </attribute>
+      </optional>
+      <empty/>
+    </element>
+  </define>
+
   <define name="usbmaster">
     <element name="master">
       <attribute name="startport">
index 95d2ff22b8f39c4dd70252750d81554d58bb31c4..3278e9c15ec5751f8a5fb6c6eebbe1f5d4cdf6f1 100644 (file)
@@ -7570,6 +7570,19 @@ virDomainRNGDefParseXML(const xmlNodePtr node,
 
     ctxt->node = node;
 
+    if (virXPathUInt("string(./rate/@bytes)", ctxt, &def->rate) < -1) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("invalid RNG rate bytes value"));
+        goto error;
+    }
+
+    if (def->rate > 0 &&
+        virXPathUInt("string(./rate/@period)", ctxt, &def->period) < -1) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("invalid RNG rate period value"));
+        goto error;
+    }
+
     if ((nbackends = virXPathNodeSet("./backend", ctxt, &backends)) < 0)
         goto error;
 
@@ -13897,6 +13910,12 @@ virDomainRNGDefFormat(virBufferPtr buf,
     const char *backend = virDomainRNGBackendTypeToString(def->backend);
 
     virBufferAsprintf(buf, "    <rng model='%s'>\n", model);
+    if (def->rate) {
+        virBufferAsprintf(buf, "      <rate bytes='%u'", def->rate);
+        if (def->period)
+            virBufferAsprintf(buf, " period='%u'", def->period);
+        virBufferAddLit(buf, "/>\n");
+    }
     virBufferAsprintf(buf, "      <backend model='%s'", backend);
 
     switch ((enum virDomainRNGBackend) def->backend) {
index 0fe43c5869689b76283b8ac94f9105342879d971..96f11ba76d46590d9c4bd0431cc204cb85447ad5 100644 (file)
@@ -1736,6 +1736,8 @@ enum virDomainRNGBackend {
 struct _virDomainRNGDef {
     int model;
     int backend;
+    unsigned int rate; /* bytes per period */
+    unsigned int period; /* milliseconds */
 
     union {
         char *file; /* file name for 'random' source */
index e7f232579aef4423a382e2bda759cfd37cf856d0..78c5cfc4f5295e9b64f05ae0939bb5cfab4c14e8 100644 (file)
@@ -4492,6 +4492,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;
 
index 7ab9dbc0c02de1c1787a8107ebebe50b0b218f9e..5d296e825e0deb5c9f98020ac5dbdf4227a85540 100644 (file)
@@ -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=123,period=1234,bus=pci.0,addr=0x4
index 1e2c4be95a6f51eb35311713513e815aa96c26e2..354ae42932b9d8b7c8fd3352c901d1d3cf9287d5 100644 (file)
@@ -17,6 +17,7 @@
     <controller type='usb' index='0'/>
     <memballoon model='virtio'/>
     <rng model='virtio'>
+      <rate bytes='123' period='1234'/>
       <backend model='random'>/dev/hwrng</backend>
     </rng>
   </devices>