qemu: reuse hostdev interfaces to avoid duplicate

Same logic of preparing/reattaching hostdevs could be used in attach/detach
hotplug places, so reuse hostdev interfaces to avoid duplicate, also for later
extracting general code to common library.
This commit is contained in:
Chunyan Liu 2014-03-05 14:33:30 +08:00 committed by Daniel P. Berrange
parent 95fa4906b2
commit 802c59d4b9
3 changed files with 18 additions and 60 deletions

View File

@ -991,7 +991,7 @@ out:
}
static int
int
qemuPrepareHostUSBDevices(virQEMUDriverPtr driver,
const char *name,
virDomainHostdevDefPtr *hostdevs,
@ -1334,7 +1334,7 @@ cleanup:
}
static void
void
qemuDomainReAttachHostUsbDevices(virQEMUDriverPtr driver,
const char *name,
virDomainHostdevDefPtr *hostdevs,

View File

@ -47,6 +47,12 @@ int qemuFindHostdevUSBDevice(virDomainHostdevDefPtr hostdev,
int qemuPrepareHostdevUSBDevices(virQEMUDriverPtr driver,
const char *name,
virUSBDeviceListPtr list);
int
qemuPrepareHostUSBDevices(virQEMUDriverPtr driver,
const char *name,
virDomainHostdevDefPtr *hostdevs,
int nhostdevs,
bool coldBoot);
int qemuPrepareHostdevSCSIDevices(virQEMUDriverPtr driver,
const char *name,
virDomainHostdevDefPtr *hostdevs,
@ -55,6 +61,11 @@ int qemuPrepareHostDevices(virQEMUDriverPtr driver,
virDomainDefPtr def,
virQEMUCapsPtr qemuCaps,
bool coldBoot);
void
qemuDomainReAttachHostUsbDevices(virQEMUDriverPtr driver,
const char *name,
virDomainHostdevDefPtr *hostdevs,
int nhostdevs);
void qemuDomainReAttachHostScsiDevices(virQEMUDriverPtr driver,
const char *name,
virDomainHostdevDefPtr *hostdevs,

View File

@ -1461,28 +1461,16 @@ qemuDomainAttachHostUsbDevice(virQEMUDriverPtr driver,
virDomainHostdevDefPtr hostdev)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
virUSBDeviceList *list = NULL;
virUSBDevicePtr usb = NULL;
char *devstr = NULL;
bool added = false;
bool teardowncgroup = false;
bool teardownlabel = false;
int ret = -1;
if (qemuFindHostdevUSBDevice(hostdev, true, &usb) < 0)
return -1;
if (!(list = virUSBDeviceListNew()))
goto cleanup;
if (virUSBDeviceListAdd(list, usb) < 0)
goto cleanup;
if (qemuPrepareHostdevUSBDevices(driver, vm->def->name, list) < 0)
if (qemuPrepareHostUSBDevices(driver, vm->def->name, &hostdev, 1, 0) < 0)
goto cleanup;
added = true;
virUSBDeviceListSteal(list, usb);
if (qemuSetupHostdevCGroup(vm, hostdev) < 0)
goto cleanup;
@ -1527,13 +1515,8 @@ cleanup:
vm->def, hostdev, NULL) < 0)
VIR_WARN("Unable to restore host device labelling on hotplug fail");
if (added)
virUSBDeviceListSteal(driver->activeUsbHostdevs, usb);
qemuDomainReAttachHostUsbDevices(driver, vm->def->name, &hostdev, 1);
}
if (list && usb &&
!virUSBDeviceListFind(list, usb) &&
!virUSBDeviceListFind(driver->activeUsbHostdevs, usb))
virUSBDeviceFree(usb);
virObjectUnref(list);
VIR_FREE(devstr);
return ret;
}
@ -2538,50 +2521,16 @@ qemuDomainRemovePCIHostDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm,
virDomainHostdevDefPtr hostdev)
{
virDomainHostdevSubsysPtr subsys = &hostdev->source.subsys;
virPCIDevicePtr pci;
virPCIDevicePtr activePci;
virObjectLock(driver->activePciHostdevs);
virObjectLock(driver->inactivePciHostdevs);
pci = virPCIDeviceNew(subsys->u.pci.addr.domain, subsys->u.pci.addr.bus,
subsys->u.pci.addr.slot, subsys->u.pci.addr.function);
if (pci) {
activePci = virPCIDeviceListSteal(driver->activePciHostdevs, pci);
if (activePci &&
virPCIDeviceReset(activePci, driver->activePciHostdevs,
driver->inactivePciHostdevs) == 0) {
qemuReattachPciDevice(activePci, driver);
} else {
/* reset of the device failed, treat it as if it was returned */
virPCIDeviceFree(activePci);
}
virPCIDeviceFree(pci);
}
virObjectUnlock(driver->activePciHostdevs);
virObjectUnlock(driver->inactivePciHostdevs);
qemuDomainReAttachHostdevDevices(driver, vm->def->name, &hostdev, 1);
qemuDomainReleaseDeviceAddress(vm, hostdev->info, NULL);
}
static void
qemuDomainRemoveUSBHostDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
virDomainHostdevDefPtr hostdev)
{
virDomainHostdevSubsysPtr subsys = &hostdev->source.subsys;
virUSBDevicePtr usb;
usb = virUSBDeviceNew(subsys->u.usb.bus, subsys->u.usb.device, NULL);
if (usb) {
virObjectLock(driver->activeUsbHostdevs);
virUSBDeviceListDel(driver->activeUsbHostdevs, usb);
virObjectUnlock(driver->activeUsbHostdevs);
virUSBDeviceFree(usb);
} else {
VIR_WARN("Unable to find device %03d.%03d in list of used USB devices",
subsys->u.usb.bus, subsys->u.usb.device);
}
qemuDomainReAttachHostUsbDevices(driver, vm->def->name, &hostdev, 1);
}
static void
@ -2629,8 +2578,6 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver,
virDomainAuditHostdev(vm, hostdev, "detach", true);
qemuDomainHostdevNetConfigRestore(hostdev, cfg->stateDir);
switch ((enum virDomainHostdevSubsysType) hostdev->source.subsys.type) {
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
qemuDomainRemovePCIHostDevice(driver, vm, hostdev);