mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-21 19:02:25 +00:00
qemu: Rollback on used USB devices
One of our latest USB device handling patches 05abd1507d66aabb6cad12eeafeb4c4d1911c585 introduced a regression. That is, we first create a temporary list of all USB devices that are to be used by domain just starting up. Then we iterate over and check if a device from the list is in the global list of currently assigned devices (activeUsbHostdevs). If not, we add it there and continue with next iteration then. But if a device from temporary list is either taken already or adding to the activeUsbHostdevs fails, we remove all devices in temp list from the activeUsbHostdevs list. Therefore, if a device is already taken we remove it from activeUsbHostdevs even if we should not. Thus, next time we allow the device to be assigned to another domain.
This commit is contained in:
parent
7ba66ef285
commit
2f5fdc886e
@ -567,7 +567,7 @@ qemuPrepareHostdevUSBDevices(struct qemud_driver *driver,
|
||||
const char *name,
|
||||
usbDeviceList *list)
|
||||
{
|
||||
int i;
|
||||
int i, j;
|
||||
unsigned int count;
|
||||
usbDevice *tmp;
|
||||
|
||||
@ -586,7 +586,7 @@ qemuPrepareHostdevUSBDevices(struct qemud_driver *driver,
|
||||
qemuReportError(VIR_ERR_OPERATION_INVALID,
|
||||
_("USB device %s is already in use"),
|
||||
usbDeviceGetName(tmp));
|
||||
return -1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
usbDeviceSetUsedBy(usb, name);
|
||||
@ -598,9 +598,16 @@ qemuPrepareHostdevUSBDevices(struct qemud_driver *driver,
|
||||
* perform rollback on failure.
|
||||
*/
|
||||
if (usbDeviceListAdd(driver->activeUsbHostdevs, usb) < 0)
|
||||
return -1;
|
||||
goto error;
|
||||
}
|
||||
return 0;
|
||||
|
||||
error:
|
||||
for (j = 0; j < i; j++) {
|
||||
tmp = usbDeviceListGet(list, i);
|
||||
usbDeviceListSteal(driver->activeUsbHostdevs, tmp);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -621,8 +628,7 @@ qemuPrepareHostUSBDevices(struct qemud_driver *driver,
|
||||
if (!(list = usbDeviceListNew()))
|
||||
goto cleanup;
|
||||
|
||||
/* Loop 1: build temporary list and validate no usb device
|
||||
* is already taken
|
||||
/* Loop 1: build temporary list
|
||||
*/
|
||||
for (i = 0 ; i < nhostdevs ; i++) {
|
||||
virDomainHostdevDefPtr hostdev = hostdevs[i];
|
||||
@ -678,7 +684,7 @@ qemuPrepareHostUSBDevices(struct qemud_driver *driver,
|
||||
* wrong, perform rollback.
|
||||
*/
|
||||
if (qemuPrepareHostdevUSBDevices(driver, def->name, list) < 0)
|
||||
goto inactivedevs;
|
||||
goto cleanup;
|
||||
|
||||
/* Loop 2: Temporary list was successfully merged with
|
||||
* driver list, so steal all items to avoid freeing them
|
||||
@ -690,16 +696,6 @@ qemuPrepareHostUSBDevices(struct qemud_driver *driver,
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
goto cleanup;
|
||||
|
||||
inactivedevs:
|
||||
/* Steal devices from driver->activeUsbHostdevs.
|
||||
* We will free them later.
|
||||
*/
|
||||
for (i = 0; i < usbDeviceListCount(list); i++) {
|
||||
tmp = usbDeviceListGet(list, i);
|
||||
usbDeviceListSteal(driver->activeUsbHostdevs, tmp);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
usbDeviceListFree(list);
|
||||
|
Loading…
x
Reference in New Issue
Block a user