[libvirt] [PATCH 4/6] qemu: Implement support for the RNG device and the random backend

John Ferlan jferlan at redhat.com
Tue Feb 19 13:20:38 UTC 2013


On 02/13/2013 05:59 AM, Peter Krempa wrote:
> This patch implements support for the virtio-rng-pci device and the
> rng-random backend in qemu.
> 
> Two capabilities bits are added to track support for those:
> 
> QEMU_CAPS_DEVICE_VIRTIO_RNG - for the device support and
> QEMU_CAPS_OBJECT_RNG_RANDOM - for the backend support.
> 
> qemu is invoked with these additional parameters if the device is
> enabled:
> 
> -object rng-random,id=rng0,filename=/test/phile (to add the backend)
> -device virtio-rng-pci,rng=rng0,bus=pci.0,addr=0x4 (to add the device)
> ---
>  src/qemu/qemu_capabilities.c |   5 ++-
>  src/qemu/qemu_capabilities.h |   3 ++
>  src/qemu/qemu_command.c      | 100 +++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 107 insertions(+), 1 deletion(-)
> 
> diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
> index 4efe052..a316a56 100644
> --- a/src/qemu/qemu_capabilities.c
> +++ b/src/qemu/qemu_capabilities.c
> @@ -205,7 +205,8 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
>                "usb-serial", /* 125 */
>                "usb-net",
>                "add-fd",
> -
> +              "virtio-rng",
> +              "rng-random",
>      );
> 
>  struct _virQEMUCaps {
> @@ -1354,6 +1355,8 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = {
>      { "vmware-svga", QEMU_CAPS_DEVICE_VMWARE_SVGA },
>      { "usb-serial", QEMU_CAPS_DEVICE_USB_SERIAL},
>      { "usb-net", QEMU_CAPS_DEVICE_USB_NET},
> +    { "virtio-rng-pci", QEMU_CAPS_DEVICE_VIRTIO_RNG },
> +    { "rng-random", QEMU_CAPS_OBJECT_RNG_RANDOM },
>  };
> 
> 
> diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
> index e69d558..ee0d0ca 100644
> --- a/src/qemu/qemu_capabilities.h
> +++ b/src/qemu/qemu_capabilities.h
> @@ -166,6 +166,9 @@ enum virQEMUCapsFlags {
>      QEMU_CAPS_DEVICE_USB_SERIAL  = 125, /* -device usb-serial */
>      QEMU_CAPS_DEVICE_USB_NET     = 126, /* -device usb-net */
>      QEMU_CAPS_ADD_FD             = 127, /* -add-fd */
> +    QEMU_CAPS_DEVICE_VIRTIO_RNG  = 128, /* virtio-rng device */
> +    QEMU_CAPS_OBJECT_RNG_RANDOM  = 129, /* the rng-random backend for
> +                                           virtio rng */
> 
>      QEMU_CAPS_LAST,                   /* this must always be the last item */
>  };
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index 6c28123..7ffa6ab 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -787,6 +787,10 @@ qemuAssignDeviceAliases(virDomainDefPtr def, virQEMUCapsPtr qemuCaps)
>          if (virAsprintf(&def->memballoon->info.alias, "balloon%d", 0) < 0)
>              goto no_memory;
>      }
> +    if (def->rng) {
> +        if (virAsprintf(&def->rng->info.alias, "rng%d", 0) < 0)
> +            goto no_memory;
> +    }
> 
>      return 0;
> 
> @@ -1701,6 +1705,14 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
>              goto error;
>      }
> 
> +    /* VirtIO RNG */
> +    if (def->rng &&
> +        def->rng->model == VIR_DOMAIN_RNG_MODEL_VIRTIO &&
> +        def->rng->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
> +        if (qemuDomainPCIAddressSetNextAddr(addrs, &def->rng->info) < 0)
> +            goto error;
> +    }
> +
>      /* A watchdog - skip IB700, it is not a PCI device */
>      if (def->watchdog &&
>          def->watchdog->model != VIR_DOMAIN_WATCHDOG_MODEL_IB700 &&
> @@ -4206,6 +4218,84 @@ error:
>      return NULL;
>  }
> 
> +
> +static int
> +qemuBuildRNGBackendArgs(virCommandPtr cmd,
> +                        virDomainRNGDefPtr dev,
> +                        virQEMUCapsPtr qemuCaps)
> +{
> +    virBuffer buf = VIR_BUFFER_INITIALIZER;
> +    int ret = -1;
> +
> +    switch ((enum virDomainRNGBackend) dev->backend) {
> +    case VIR_DOMAIN_RNG_BACKEND_RANDOM:
> +        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_RNG_RANDOM)) {
> +            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> +                           _("this qemu doesn't support the rng-random "
> +                             " backend"));
> +            goto cleanup;
> +        }
> +
> +        virBufferAsprintf(&buf, "rng-random,id=%s", dev->info.alias);
> +        if (dev->source.file)
> +            virBufferAsprintf(&buf, ",filename=%s", dev->source.file);
> +
> +        virCommandAddArg(cmd, "-object");
> +        virCommandAddArgBuffer(cmd, &buf);
> +        break;
> +
> +    case VIR_DOMAIN_RNG_BACKEND_EGD:
> +        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                       _("egd RNG backend not yet implemented"));
> +        goto cleanup;
> +        break;
> +
> +    case VIR_DOMAIN_RNG_BACKEND_LAST:
> +        break;
> +    }
> +
> +    ret = 0;
> +
> +cleanup:
> +    virBufferFreeAndReset(&buf);
> +    return ret;
> +}
> +
> +
> +static int
> +qemuBuildRNGDeviceArgs(virCommandPtr cmd,
> +                       virDomainRNGDefPtr dev,
> +                       virQEMUCapsPtr qemuCaps)
> +{
> +    virBuffer buf = VIR_BUFFER_INITIALIZER;
> +    int ret = -1;
> +
> +    if (dev->model != VIR_DOMAIN_RNG_MODEL_VIRTIO ||
> +        !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_RNG)) {
> +        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> +                       _("RNG device type '%s' is not supported "
> +                         "by this of qemu"),
s/of //

another thought - keep your messages similar - like above:

"this qemu doesn't support RNG device type '%s'"

> +                       virDomainRNGModelTypeToString(dev->model));
> +        goto cleanup;
> +    }
> +
> +    virBufferAsprintf(&buf, "virtio-rng-pci,rng=%s", dev->info.alias);
> +
> +    if (qemuBuildDeviceAddressStr(&buf, &dev->info, qemuCaps) < 0)
> +        goto cleanup;
> +
> +    virCommandAddArg(cmd, "-device");
> +    virCommandAddArgBuffer(cmd, &buf);
> +
> +    ret = 0;
> +
> +cleanup:
> +    virBufferFreeAndReset(&buf);
> +    return ret;
> +}
> +
> +
> +
>  static char *qemuBuildSmbiosBiosStr(virSysinfoDefPtr def)
>  {
>      virBuffer buf = VIR_BUFFER_INITIALIZER;
> @@ -7047,6 +7137,16 @@ qemuBuildCommandLine(virConnectPtr conn,
>          }
>      }
> 
> +    if (def->rng) {
> +        /* add the RNG source backend */
> +        if (qemuBuildRNGBackendArgs(cmd, def->rng, qemuCaps) < 0)
> +            goto error;
> +
> +        /* add the device */
> +        if (qemuBuildRNGDeviceArgs(cmd, def->rng, qemuCaps) < 0)
> +            goto error;
> +    }
> +
>      if (snapshot)
>          virCommandAddArgList(cmd, "-loadvm", snapshot->def->name, NULL);
> 




More information about the libvir-list mailing list