qemu: Implement startupPolicy for USB passed through devices

This commit is contained in:
Jiri Denemark 2012-10-04 16:18:16 +02:00
parent 059aff6b98
commit edc9269a2a
5 changed files with 35 additions and 12 deletions

View File

@ -289,6 +289,8 @@ int qemuSetupCgroup(struct qemud_driver *driver,
continue;
if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
continue;
if (hostdev->missing)
continue;
if ((usb = usbGetDevice(hostdev->source.subsys.u.usb.bus,
hostdev->source.subsys.u.usb.device)) == NULL)

View File

@ -3507,17 +3507,21 @@ qemuBuildUSBHostdevDevStr(virDomainHostdevDefPtr dev,
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
if (!dev->source.subsys.u.usb.bus &&
if (!dev->missing &&
!dev->source.subsys.u.usb.bus &&
!dev->source.subsys.u.usb.device) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("USB host device is missing bus/device information"));
return NULL;
}
virBufferAsprintf(&buf, "usb-host,hostbus=%d,hostaddr=%d,id=%s",
dev->source.subsys.u.usb.bus,
dev->source.subsys.u.usb.device,
dev->info->alias);
virBufferAddLit(&buf, "usb-host");
if (!dev->missing) {
virBufferAsprintf(&buf, ",hostbus=%d,hostaddr=%d",
dev->source.subsys.u.usb.bus,
dev->source.subsys.u.usb.device);
}
virBufferAsprintf(&buf, ",id=%s", dev->info->alias);
if (qemuBuildDeviceAddressStr(&buf, dev->info, caps) < 0)
goto error;
@ -3577,6 +3581,12 @@ qemuBuildUSBHostdevUsbDevStr(virDomainHostdevDefPtr dev)
{
char *ret = NULL;
if (dev->missing) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("This QEMU doesn't not support missing USB devices"));
return NULL;
}
if (!dev->source.subsys.u.usb.bus &&
!dev->source.subsys.u.usb.device) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",

View File

@ -696,7 +696,8 @@ out:
static int
qemuPrepareHostUSBDevices(struct qemud_driver *driver,
virDomainDefPtr def)
virDomainDefPtr def,
bool coldBoot)
{
int i, ret = -1;
usbDeviceList *list;
@ -716,6 +717,7 @@ qemuPrepareHostUSBDevices(struct qemud_driver *driver,
*/
for (i = 0 ; i < nhostdevs ; i++) {
virDomainHostdevDefPtr hostdev = hostdevs[i];
bool required = true;
usbDevice *usb;
if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
@ -723,10 +725,15 @@ qemuPrepareHostUSBDevices(struct qemud_driver *driver,
if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
continue;
if (qemuFindHostdevUSBDevice(hostdev, true, &usb) < 0)
if (hostdev->startupPolicy == VIR_DOMAIN_STARTUP_POLICY_OPTIONAL ||
(hostdev->startupPolicy == VIR_DOMAIN_STARTUP_POLICY_REQUISITE &&
!coldBoot))
required = false;
if (qemuFindHostdevUSBDevice(hostdev, required, &usb) < 0)
goto cleanup;
if (usbDeviceListAdd(list, usb) < 0) {
if (usb && usbDeviceListAdd(list, usb) < 0) {
usbFreeDevice(usb);
goto cleanup;
}
@ -756,7 +763,8 @@ cleanup:
}
int qemuPrepareHostDevices(struct qemud_driver *driver,
virDomainDefPtr def)
virDomainDefPtr def,
bool coldBoot)
{
if (!def->nhostdevs)
return 0;
@ -764,7 +772,7 @@ int qemuPrepareHostDevices(struct qemud_driver *driver,
if (qemuPrepareHostPCIDevices(driver, def) < 0)
return -1;
if (qemuPrepareHostUSBDevices(driver, def) < 0)
if (qemuPrepareHostUSBDevices(driver, def, coldBoot) < 0)
return -1;
return 0;
@ -891,6 +899,8 @@ qemuDomainReAttachHostUsbDevices(struct qemud_driver *driver,
continue;
if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
continue;
if (hostdev->missing)
continue;
usb = usbGetDevice(hostdev->source.subsys.u.usb.bus,
hostdev->source.subsys.u.usb.device);

View File

@ -43,7 +43,8 @@ int qemuPrepareHostdevUSBDevices(struct qemud_driver *driver,
const char *name,
usbDeviceList *list);
int qemuPrepareHostDevices(struct qemud_driver *driver,
virDomainDefPtr def);
virDomainDefPtr def,
bool coldBoot);
void qemuReattachPciDevice(pciDevice *dev, struct qemud_driver *driver);
void qemuDomainReAttachHostdevDevices(struct qemud_driver *driver,
const char *name,

View File

@ -3384,7 +3384,7 @@ int qemuProcessStart(virConnectPtr conn,
/* Must be run before security labelling */
VIR_DEBUG("Preparing host devices");
if (qemuPrepareHostDevices(driver, vm->def) < 0)
if (qemuPrepareHostDevices(driver, vm->def, !migrateFrom) < 0)
goto cleanup;
VIR_DEBUG("Preparing chr devices");