mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-10-05 05:45:46 +00: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;
|
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,
|
virDomainUSBAddressEnsure(virDomainUSBAddressSetPtr addrs,
|
||||||
virDomainDeviceInfoPtr info)
|
virDomainDeviceInfoPtr info)
|
||||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
||||||
|
|
||||||
|
int
|
||||||
|
virDomainUSBAddressRelease(virDomainUSBAddressSetPtr addrs,
|
||||||
|
virDomainDeviceInfoPtr info)
|
||||||
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
||||||
#endif /* __DOMAIN_ADDR_H__ */
|
#endif /* __DOMAIN_ADDR_H__ */
|
||||||
|
@ -112,6 +112,7 @@ virDomainUSBAddressEnsure;
|
|||||||
virDomainUSBAddressPortFormat;
|
virDomainUSBAddressPortFormat;
|
||||||
virDomainUSBAddressPortFormatBuf;
|
virDomainUSBAddressPortFormatBuf;
|
||||||
virDomainUSBAddressPortIsValid;
|
virDomainUSBAddressPortIsValid;
|
||||||
|
virDomainUSBAddressRelease;
|
||||||
virDomainUSBAddressReserve;
|
virDomainUSBAddressReserve;
|
||||||
virDomainUSBAddressSetAddControllers;
|
virDomainUSBAddressSetAddControllers;
|
||||||
virDomainUSBAddressSetAddHub;
|
virDomainUSBAddressSetAddHub;
|
||||||
|
@ -1772,4 +1772,9 @@ qemuDomainReleaseDeviceAddress(virDomainObjPtr vm,
|
|||||||
virDomainVirtioSerialAddrRelease(priv->vioserialaddrs, info) < 0)
|
virDomainVirtioSerialAddrRelease(priv->vioserialaddrs, info) < 0)
|
||||||
VIR_WARN("Unable to release virtio-serial address on %s",
|
VIR_WARN("Unable to release virtio-serial address on %s",
|
||||||
NULLSTR(devstr));
|
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;
|
char *devstr = NULL;
|
||||||
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
||||||
const char *src = virDomainDiskGetSource(disk);
|
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)
|
if (qemuDomainPrepareDisk(driver, vm, disk, NULL, false) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -756,6 +763,8 @@ qemuDomainAttachUSBMassStorageDevice(virQEMUDriverPtr driver,
|
|||||||
virDomainDiskInsertPreAlloced(vm->def, disk);
|
virDomainDiskInsertPreAlloced(vm->def, disk);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
if (ret < 0 && releaseaddr)
|
||||||
|
virDomainUSBAddressRelease(priv->usbaddrs, &disk->info);
|
||||||
VIR_FREE(devstr);
|
VIR_FREE(devstr);
|
||||||
VIR_FREE(drivestr);
|
VIR_FREE(drivestr);
|
||||||
virObjectUnref(cfg);
|
virObjectUnref(cfg);
|
||||||
@ -1557,6 +1566,12 @@ qemuDomainAttachChrDeviceAssignAddr(qemuDomainObjPrivatePtr priv,
|
|||||||
return -1;
|
return -1;
|
||||||
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 &&
|
} else if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL &&
|
||||||
chr->targetType == VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO) {
|
chr->targetType == VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO) {
|
||||||
if (virDomainVirtioSerialAddrAutoAssign(NULL, priv->vioserialaddrs,
|
if (virDomainVirtioSerialAddrAutoAssign(NULL, priv->vioserialaddrs,
|
||||||
@ -1900,11 +1915,18 @@ qemuDomainAttachHostUSBDevice(virQEMUDriverPtr driver,
|
|||||||
{
|
{
|
||||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||||
char *devstr = NULL;
|
char *devstr = NULL;
|
||||||
|
bool releaseaddr = false;
|
||||||
bool added = false;
|
bool added = false;
|
||||||
bool teardowncgroup = false;
|
bool teardowncgroup = false;
|
||||||
bool teardownlabel = false;
|
bool teardownlabel = false;
|
||||||
int ret = -1;
|
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)
|
if (qemuHostdevPrepareUSBDevices(driver, vm->def->name, &hostdev, 1, 0) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
@ -1950,6 +1972,8 @@ qemuDomainAttachHostUSBDevice(virQEMUDriverPtr driver,
|
|||||||
VIR_WARN("Unable to restore host device labelling on hotplug fail");
|
VIR_WARN("Unable to restore host device labelling on hotplug fail");
|
||||||
if (added)
|
if (added)
|
||||||
qemuHostdevReAttachUSBDevices(driver, vm->def->name, &hostdev, 1);
|
qemuHostdevReAttachUSBDevices(driver, vm->def->name, &hostdev, 1);
|
||||||
|
if (releaseaddr)
|
||||||
|
virDomainUSBAddressRelease(priv->usbaddrs, hostdev->info);
|
||||||
}
|
}
|
||||||
VIR_FREE(devstr);
|
VIR_FREE(devstr);
|
||||||
return ret;
|
return ret;
|
||||||
@ -2988,6 +3012,8 @@ qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver,
|
|||||||
dev.type = VIR_DOMAIN_DEVICE_DISK;
|
dev.type = VIR_DOMAIN_DEVICE_DISK;
|
||||||
dev.data.disk = disk;
|
dev.data.disk = disk;
|
||||||
ignore_value(qemuRemoveSharedDevice(driver, &dev, vm->def->name));
|
ignore_value(qemuRemoveSharedDevice(driver, &dev, vm->def->name));
|
||||||
|
if (priv->usbaddrs)
|
||||||
|
virDomainUSBAddressRelease(priv->usbaddrs, &disk->info);
|
||||||
|
|
||||||
virDomainDiskDefFree(disk);
|
virDomainDiskDefFree(disk);
|
||||||
return 0;
|
return 0;
|
||||||
@ -3084,6 +3110,7 @@ qemuDomainRemoveUSBHostDevice(virQEMUDriverPtr driver,
|
|||||||
virDomainHostdevDefPtr hostdev)
|
virDomainHostdevDefPtr hostdev)
|
||||||
{
|
{
|
||||||
qemuHostdevReAttachUSBDevices(driver, vm->def->name, &hostdev, 1);
|
qemuHostdevReAttachUSBDevices(driver, vm->def->name, &hostdev, 1);
|
||||||
|
qemuDomainReleaseDeviceAddress(vm, hostdev->info, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
<readonly/>
|
<readonly/>
|
||||||
<shareable/>
|
<shareable/>
|
||||||
<alias name='usb-disk16'/>
|
<alias name='usb-disk16'/>
|
||||||
|
<address type='usb' bus='0' port='1'/>
|
||||||
</disk>
|
</disk>
|
||||||
<controller type='usb' index='0'>
|
<controller type='usb' index='0'>
|
||||||
<alias name='usb'/>
|
<alias name='usb'/>
|
||||||
|
Loading…
Reference in New Issue
Block a user