[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