提交 2f5fdc88 编写于 作者: M Michal Privoznik

qemu: Rollback on used USB devices

One of our latest USB device handling patches
05abd150 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.
上级 7ba66ef2
......@@ -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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册