mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 17:34:18 +03:00
Assign addresses on USB device hotplug
USB disks, redirected devices, host devices and serial devices are supported.
This commit is contained in:
parent
bf182078d9
commit
f2a781ceb0
@ -1735,3 +1735,33 @@ virDomainUSBAddressEnsure(virDomainUSBAddressSetPtr addrs,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
virDomainUSBAddressRelease(virDomainUSBAddressSetPtr addrs,
|
||||
virDomainDeviceInfoPtr info)
|
||||
{
|
||||
virDomainUSBAddressHubPtr targetHub = NULL;
|
||||
char *portStr = NULL;
|
||||
int targetPort;
|
||||
int ret = -1;
|
||||
|
||||
if (info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB ||
|
||||
!virDomainUSBAddressPortIsValid(info->addr.usb.port))
|
||||
return 0;
|
||||
|
||||
portStr = virDomainUSBAddressPortFormat(info->addr.usb.port);
|
||||
VIR_DEBUG("Releasing USB addr bus=%u port=%s", info->addr.usb.bus, portStr);
|
||||
|
||||
if (!(targetHub = virDomainUSBAddressFindPort(addrs, info, &targetPort,
|
||||
portStr)))
|
||||
goto cleanup;
|
||||
|
||||
ignore_value(virBitmapClearBit(targetHub->portmap, targetPort));
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
VIR_FREE(portStr);
|
||||
return ret;
|
||||
}
|
||||
|
@ -293,4 +293,9 @@ int
|
||||
virDomainUSBAddressEnsure(virDomainUSBAddressSetPtr addrs,
|
||||
virDomainDeviceInfoPtr info)
|
||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
||||
|
||||
int
|
||||
virDomainUSBAddressRelease(virDomainUSBAddressSetPtr addrs,
|
||||
virDomainDeviceInfoPtr info)
|
||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
||||
#endif /* __DOMAIN_ADDR_H__ */
|
||||
|
@ -112,6 +112,7 @@ virDomainUSBAddressEnsure;
|
||||
virDomainUSBAddressPortFormat;
|
||||
virDomainUSBAddressPortFormatBuf;
|
||||
virDomainUSBAddressPortIsValid;
|
||||
virDomainUSBAddressRelease;
|
||||
virDomainUSBAddressReserve;
|
||||
virDomainUSBAddressSetAddControllers;
|
||||
virDomainUSBAddressSetAddHub;
|
||||
|
@ -1772,4 +1772,9 @@ 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));
|
||||
}
|
||||
|
@ -711,6 +711,13 @@ qemuDomainAttachUSBMassStorageDevice(virQEMUDriverPtr driver,
|
||||
char *devstr = NULL;
|
||||
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
||||
const char *src = virDomainDiskGetSource(disk);
|
||||
bool releaseaddr = false;
|
||||
|
||||
if (priv->usbaddrs) {
|
||||
if (virDomainUSBAddressEnsure(priv->usbaddrs, &disk->info) < 0)
|
||||
goto cleanup;
|
||||
releaseaddr = true;
|
||||
}
|
||||
|
||||
if (qemuDomainPrepareDisk(driver, vm, disk, NULL, false) < 0)
|
||||
goto cleanup;
|
||||
@ -756,6 +763,8 @@ qemuDomainAttachUSBMassStorageDevice(virQEMUDriverPtr driver,
|
||||
virDomainDiskInsertPreAlloced(vm->def, disk);
|
||||
|
||||
cleanup:
|
||||
if (ret < 0 && releaseaddr)
|
||||
virDomainUSBAddressRelease(priv->usbaddrs, &disk->info);
|
||||
VIR_FREE(devstr);
|
||||
VIR_FREE(drivestr);
|
||||
virObjectUnref(cfg);
|
||||
@ -1557,6 +1566,12 @@ 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 (virDomainUSBAddressEnsure(priv->usbaddrs, &chr->info) < 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,
|
||||
@ -1900,11 +1915,18 @@ 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 (virDomainUSBAddressEnsure(priv->usbaddrs, hostdev->info) < 0)
|
||||
goto cleanup;
|
||||
releaseaddr = true;
|
||||
}
|
||||
|
||||
if (qemuHostdevPrepareUSBDevices(driver, vm->def->name, &hostdev, 1, 0) < 0)
|
||||
goto cleanup;
|
||||
|
||||
@ -1950,6 +1972,8 @@ qemuDomainAttachHostUSBDevice(virQEMUDriverPtr driver,
|
||||
VIR_WARN("Unable to restore host device labelling on hotplug fail");
|
||||
if (added)
|
||||
qemuHostdevReAttachUSBDevices(driver, vm->def->name, &hostdev, 1);
|
||||
if (releaseaddr)
|
||||
virDomainUSBAddressRelease(priv->usbaddrs, hostdev->info);
|
||||
}
|
||||
VIR_FREE(devstr);
|
||||
return ret;
|
||||
@ -2988,6 +3012,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;
|
||||
@ -3084,6 +3110,7 @@ qemuDomainRemoveUSBHostDevice(virQEMUDriverPtr driver,
|
||||
virDomainHostdevDefPtr hostdev)
|
||||
{
|
||||
qemuHostdevReAttachUSBDevices(driver, vm->def->name, &hostdev, 1);
|
||||
qemuDomainReleaseDeviceAddress(vm, hostdev->info, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -27,6 +27,7 @@
|
||||
<readonly/>
|
||||
<shareable/>
|
||||
<alias name='usb-disk16'/>
|
||||
<address type='usb' bus='0' port='1'/>
|
||||
</disk>
|
||||
<controller type='usb' index='0'>
|
||||
<alias name='usb'/>
|
||||
|
Loading…
Reference in New Issue
Block a user