提交 f2a781ce 编写于 作者: J Ján Tomko

Assign addresses on USB device hotplug

USB disks, redirected devices, host devices and serial devices
are supported.
上级 bf182078
......@@ -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'/>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册