[libvirt] [PATCH 9/9] Assign addresses on USB device hotplug
John Ferlan
jferlan at redhat.com
Wed Aug 12 22:18:46 UTC 2015
On 08/12/2015 10:52 AM, Ján Tomko wrote:
> USB disks, redirected devices, host devices and serial devices
> are supported.
> ---
> src/conf/domain_addr.c | 34 +++++++++++++++++++
> src/conf/domain_addr.h | 4 +++
> src/libvirt_private.syms | 1 +
> src/qemu/qemu_command.c | 5 +++
> src/qemu/qemu_hotplug.c | 39 ++++++++++++++++++++++
> .../qemuhotplug-hotplug-base+disk-usb.xml | 1 +
> 6 files changed, 84 insertions(+)
>
I ran all the changes through my Coverity checker - figured I'd post
this data first...
> diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c
> index 15f4753..42c0837 100644
> --- a/src/conf/domain_addr.c
> +++ b/src/conf/domain_addr.c
> @@ -1522,3 +1522,37 @@ virDomainUSBAddressReserve(virDomainDefPtr def ATTRIBUTE_UNUSED,
> VIR_FREE(portstr);
> return ret;
> }
> +
> +
> +int
> +virDomainUSBAddressRelease(virDomainUSBAddressSetPtr addrs,
> + virDomainDeviceInfoPtr info)
> +{
> + virDomainUSBAddressHubPtr *port = NULL;
> + char *portstr = NULL;
> + int ret = -1;
> +
> + if (info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB)
> + return 0;
> +
> + portstr = virDomainUSBAddressGetPortString(info->addr.usb.port);
> + VIR_DEBUG("Releasing USB addr bus=%u port=%s", info->addr.usb.bus, portstr);
> +
> + if (virDomainUSBAddressFindPort(&port, addrs, info) < 0)
> + goto cleanup;
> +
> + if (!*port) {
> + if ((*port)->nports) {
Coverity complains here ... checking (!*port) and then using (*port) is
counter-productive. I assume you meant "if (!port)"
> + virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> + _("usb-hub hotunplug is not yet implemented"));
> + goto cleanup;
> + }
> + VIR_FREE(*port);
> + }
> +
> + ret = 0;
> +
> + cleanup:
> + VIR_FREE(portstr);
> + return ret;
> +}
> diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h
> index 8ecf588..fbd9557 100644
> --- a/src/conf/domain_addr.h
> +++ b/src/conf/domain_addr.h
> @@ -281,4 +281,8 @@ virDomainUSBAddressReserve(virDomainDefPtr def,
> virDomainDeviceInfoPtr info,
> void *data)
> ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4);
> +int
> +virDomainUSBAddressRelease(virDomainUSBAddressSetPtr addrs,
> + virDomainDeviceInfoPtr info)
> + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
> #endif /* __DOMAIN_ADDR_H__ */
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index 048ec68..9c53b13 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -109,6 +109,7 @@ virDomainPCIAddressValidate;
> virDomainUSBAddressAssign;
> virDomainUSBAddressGetPortBuf;
> virDomainUSBAddressGetPortString;
> +virDomainUSBAddressRelease;
> virDomainUSBAddressReserve;
> virDomainUSBAddressSetAddControllers;
> virDomainUSBAddressSetCreate;
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index 9df542e..277e431 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -2106,6 +2106,11 @@ qemuDomainReleaseDeviceAddress(virDomainObjPtr vm,
> virDomainVirtioSerialAddrRelease(priv->vioserialaddrs, info) < 0)
> VIR_WARN("Unable to release virtio-serial address on %s",
> NULLSTR(devstr));
> + if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB &&
> + priv->usbaddrs &&
> + virDomainUSBAddressRelease(priv->usbaddrs, info) < 0)
> + VIR_WARN("Unable to release usb address on %s",
> + NULLSTR(devstr));
> }
>
>
> diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
> index 8e38153..e72237a 100644
> --- a/src/qemu/qemu_hotplug.c
> +++ b/src/qemu/qemu_hotplug.c
> @@ -669,6 +669,7 @@ qemuDomainAttachUSBMassStorageDevice(virConnectPtr conn,
> char *devstr = NULL;
> virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
> const char *src = virDomainDiskGetSource(disk);
> + bool releaseaddr;
Not initialized for all paths to cleanup - if initialized to false will
remove 2 Coverity issues...
>
> for (i = 0; i < vm->def->ndisks; i++) {
> if (STREQ(vm->def->disks[i]->dst, disk->dst)) {
> @@ -678,6 +679,16 @@ qemuDomainAttachUSBMassStorageDevice(virConnectPtr conn,
> }
> }
>
> + if (priv->usbaddrs) {
Because you check for priv->usbaddrs here...
> + if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) {
> + if (virDomainUSBAddressReserve(NULL, NULL, &disk->info, priv->usbaddrs) < 0)
> + goto cleanup;
> + } else if (virDomainUSBAddressAssign(priv->usbaddrs, &disk->info, false) < 0) {
> + goto cleanup;
> + }
> + releaseaddr = true;
> + }
> +
> if (qemuDomainPrepareDisk(driver, vm, disk, NULL, false) < 0)
> goto cleanup;
>
> @@ -728,6 +739,8 @@ qemuDomainAttachUSBMassStorageDevice(virConnectPtr conn,
> virDomainDiskInsertPreAlloced(vm->def, disk);
>
> cleanup:
> + if (ret < 0 && releaseaddr)
> + virDomainUSBAddressRelease(priv->usbaddrs, &disk->info);
... coverity complains here since priv->usbaddrs was checked for NULL,
but if releaseaddr was initialized to false, then both issues are cleared.
> VIR_FREE(devstr);
> VIR_FREE(drivestr);
> virObjectUnref(cfg);
> @@ -1536,6 +1549,16 @@ qemuDomainAttachChrDeviceAssignAddr(qemuDomainObjPrivatePtr priv,
> return -1;
> return 1;
>
> + } else if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL &&
> + chr->targetType == VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_USB) {
> + if (chr->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) {
> + if (virDomainUSBAddressReserve(NULL, NULL, &chr->info, priv->usbaddrs) < 0)
> + return -1;
> + } else if (virDomainUSBAddressAssign(priv->usbaddrs, &chr->info, false) < 0) {
> + return -1;
> + }
> + return 1;
> +
> } else if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL &&
> chr->targetType == VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO) {
> if (virDomainVirtioSerialAddrAutoAssign(NULL, priv->vioserialaddrs,
> @@ -1845,11 +1868,22 @@ qemuDomainAttachHostUSBDevice(virQEMUDriverPtr driver,
> {
> qemuDomainObjPrivatePtr priv = vm->privateData;
> char *devstr = NULL;
> + bool releaseaddr = false;
> bool added = false;
> bool teardowncgroup = false;
> bool teardownlabel = false;
> int ret = -1;
>
> + if (priv->usbaddrs) {
> + if (hostdev->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) {
> + if (virDomainUSBAddressReserve(NULL, NULL, hostdev->info, priv->usbaddrs) < 0)
> + return -1;
> + } else if (virDomainUSBAddressAssign(priv->usbaddrs, hostdev->info, false) < 0) {
> + goto cleanup;
> + }
> + releaseaddr = true;
> + }
> +
> if (qemuPrepareHostUSBDevices(driver, vm->def->name, &hostdev, 1, 0) < 0)
> goto cleanup;
>
> @@ -1902,6 +1936,8 @@ qemuDomainAttachHostUSBDevice(virQEMUDriverPtr driver,
> VIR_WARN("Unable to restore host device labelling on hotplug fail");
> if (added)
> qemuDomainReAttachHostUSBDevices(driver, vm->def->name, &hostdev, 1);
> + if (releaseaddr)
> + virDomainUSBAddressRelease(priv->usbaddrs, hostdev->info);
> }
> VIR_FREE(devstr);
> return ret;
> @@ -2856,6 +2892,8 @@ qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver,
> dev.type = VIR_DOMAIN_DEVICE_DISK;
> dev.data.disk = disk;
> ignore_value(qemuRemoveSharedDevice(driver, &dev, vm->def->name));
> + if (priv->usbaddrs)
> + virDomainUSBAddressRelease(priv->usbaddrs, &disk->info);
>
> virDomainDiskDefFree(disk);
> return 0;
> @@ -2949,6 +2987,7 @@ qemuDomainRemoveUSBHostDevice(virQEMUDriverPtr driver,
> virDomainHostdevDefPtr hostdev)
> {
> qemuDomainReAttachHostUSBDevices(driver, vm->def->name, &hostdev, 1);
> + qemuDomainReleaseDeviceAddress(vm, hostdev->info, NULL);
> }
>
> static void
> diff --git a/tests/qemuhotplugtestdata/qemuhotplug-hotplug-base+disk-usb.xml b/tests/qemuhotplugtestdata/qemuhotplug-hotplug-base+disk-usb.xml
> index 7904c4f..ac69490 100644
> --- a/tests/qemuhotplugtestdata/qemuhotplug-hotplug-base+disk-usb.xml
> +++ b/tests/qemuhotplugtestdata/qemuhotplug-hotplug-base+disk-usb.xml
> @@ -25,6 +25,7 @@
> <target dev='sdq' bus='usb'/>
> <readonly/>
> <shareable/>
> + <address type='usb' bus='0' port='1'/>
> </disk>
> <controller type='usb' index='0'>
> <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
>
More information about the libvir-list
mailing list