[libvirt] [RFC] Support for qemu's virtio-rng

Peter Krempa pkrempa at redhat.com
Fri Dec 14 16:46:44 UTC 2012


Commit 16c915ba42b45df7a64a6908287f03bfa3764bed in the qemu.git tree
introduced support for emulating a virtio-rng device used to pass-through
entropy to the guests.

Qemu provides two backends to gather entropy from:
1) Default chardev backend
    This backend supports reading non-blocking character devices that provide
    entropy such as /dev/random (by default) or others according to
    configuration.

    This backend also supports basic rate limiting of the entropy read from
    the source. Unfortunately as the rate limiting is done just on a per-guest
    basis this cannot protect the host from being starved of entropy by
    multiple guests although their individual rates are limited.

2) EGD backend
    This backend uses the EGD protocol to communicate with a daemon that
    servers entropy.

    The EGD protocol is a simple protocol that was introduced by the entropy
    gathering daemon (a substitute for /dev/random on machines that don't
    support it). This protocol can be used for centralized management of
    entropy allocation to the hosts.

    This by itself isn't really useful as implementations of EGD daemons are
    trying to create the entropy instead of using available sources and
    multiplexing/rate-limiting them. For this functionality we will (probably)
    need a separate server to serve the entropy to the guests but more on this
    topic later.

To represent the configuration of the virtio-rng device to the guest I propose
the following domain XML snipped to be used:

For the first use case I propose:
<domain>
  [...]
  <devices>
    [...]
    <rng model='virtio'>
      <rate bytes='1024' period='1000'/>
      <source type='char'>/dev/urandom</source>
        -- or --
      <source type='char'/>
        -- for the default source --
    </rng>
  </devices>
</domain>

For the EGD backend used manually (without any managed server) I propose:
    <rng model='virtio'>
      <rate bytes='1024' period='1000'/>
      <source type='egd'>
        <remote type='unix'>/path/to/socket</remote>
            -- or --
        <remote type='tcp' port='12345'>host.addr</remote>
           -- optionally or even more options, but they don't seem useful
      </source>
    </rng>


Now these solutions are mere envelopes on top of the qemu functionality and
don't really let us do any advanced configuration or management and they don't
protect the host or guests by themselves from starving others from entropy.

The solution for the problem described above is to have a central point where
guests can request entropy and this central point will do all the rate
limiting. To do this we will need to add a daemon that will talk the EGD
protocol. This daemon will need to read entropy on request from the kernel
software entropy device (/dev/random) or possibly a hardware RNG and
distribute it to the hosts.

To enable concurrent access and avoid starvation the daemon will implement a
"shaping protocol" based on the hierarchical token bucket approach used to
rate-limit network flows. For implementation details on this one I'll send a
separate RFC.

To allow configuration of the groups and sources I propose to create a
separate driver with infrastructure similar to the network driver. This will
allow to start multiple entropy distribution daemons with different sources
and define the hierarchical classes to allow guest grouping.

With this infrastructure you will be able to specify the rng device as
follows:
    <rng model='virtio'>
      <source type='pool' pool='default'>classname</source>
    </rng>

This will auto-configure all parameters according to the configuration of the
pool and ensure that te guest gets classified correctly.

As the start I'll implement the two basic options and then I'll propose
another RFC how I will approach the second part more closely.

Peter




More information about the libvir-list mailing list