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