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); > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list