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, qemuPrepareHostUSBDevices(virQEMUDriverPtr driver,
const char *name, const char *name,
virDomainHostdevDefPtr *hostdevs, virDomainHostdevDefPtr *hostdevs,
@ -1334,7 +1334,7 @@ cleanup:
} }
static void void
qemuDomainReAttachHostUsbDevices(virQEMUDriverPtr driver, qemuDomainReAttachHostUsbDevices(virQEMUDriverPtr driver,
const char *name, const char *name,
virDomainHostdevDefPtr *hostdevs, virDomainHostdevDefPtr *hostdevs,

View File

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

View File

@ -1461,28 +1461,16 @@ qemuDomainAttachHostUsbDevice(virQEMUDriverPtr driver,
virDomainHostdevDefPtr hostdev) virDomainHostdevDefPtr hostdev)
{ {
qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjPrivatePtr priv = vm->privateData;
virUSBDeviceList *list = NULL;
virUSBDevicePtr usb = NULL;
char *devstr = NULL; char *devstr = NULL;
bool added = false; bool added = false;
bool teardowncgroup = false; bool teardowncgroup = false;
bool teardownlabel = false; bool teardownlabel = false;
int ret = -1; int ret = -1;
if (qemuFindHostdevUSBDevice(hostdev, true, &usb) < 0) if (qemuPrepareHostUSBDevices(driver, vm->def->name, &hostdev, 1, 0) < 0)
return -1;
if (!(list = virUSBDeviceListNew()))
goto cleanup;
if (virUSBDeviceListAdd(list, usb) < 0)
goto cleanup;
if (qemuPrepareHostdevUSBDevices(driver, vm->def->name, list) < 0)
goto cleanup; goto cleanup;
added = true; added = true;
virUSBDeviceListSteal(list, usb);
if (qemuSetupHostdevCGroup(vm, hostdev) < 0) if (qemuSetupHostdevCGroup(vm, hostdev) < 0)
goto cleanup; goto cleanup;
@ -1527,13 +1515,8 @@ cleanup:
vm->def, hostdev, NULL) < 0) vm->def, hostdev, NULL) < 0)
VIR_WARN("Unable to restore host device labelling on hotplug fail"); VIR_WARN("Unable to restore host device labelling on hotplug fail");
if (added) 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); VIR_FREE(devstr);
return ret; return ret;
} }
@ -2538,50 +2521,16 @@ qemuDomainRemovePCIHostDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virDomainHostdevDefPtr hostdev) virDomainHostdevDefPtr hostdev)
{ {
virDomainHostdevSubsysPtr subsys = &hostdev->source.subsys; qemuDomainReAttachHostdevDevices(driver, vm->def->name, &hostdev, 1);
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);
qemuDomainReleaseDeviceAddress(vm, hostdev->info, NULL); qemuDomainReleaseDeviceAddress(vm, hostdev->info, NULL);
} }
static void static void
qemuDomainRemoveUSBHostDevice(virQEMUDriverPtr driver, qemuDomainRemoveUSBHostDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm ATTRIBUTE_UNUSED, virDomainObjPtr vm,
virDomainHostdevDefPtr hostdev) virDomainHostdevDefPtr hostdev)
{ {
virDomainHostdevSubsysPtr subsys = &hostdev->source.subsys; qemuDomainReAttachHostUsbDevices(driver, vm->def->name, &hostdev, 1);
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);
}
} }
static void static void
@ -2629,8 +2578,6 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver,
virDomainAuditHostdev(vm, hostdev, "detach", true); virDomainAuditHostdev(vm, hostdev, "detach", true);
qemuDomainHostdevNetConfigRestore(hostdev, cfg->stateDir);
switch ((enum virDomainHostdevSubsysType) hostdev->source.subsys.type) { switch ((enum virDomainHostdevSubsysType) hostdev->source.subsys.type) {
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
qemuDomainRemovePCIHostDevice(driver, vm, hostdev); qemuDomainRemovePCIHostDevice(driver, vm, hostdev);