mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-22 11:22:23 +00:00
hostdev: Maintain a driver list of active mediated devices
Keep track of the assigned mediated devices the same way we do it for the rest of hostdevs. Methods like 'Prepare', 'Update', and 'ReAttach' are introduced by this patch. Signed-off-by: Erik Skultety <eskultet@redhat.com>
This commit is contained in:
parent
9c5fdc3e18
commit
a4a39d90ab
@ -1736,16 +1736,19 @@ virHostdevPCINodeDeviceDetach;
|
||||
virHostdevPCINodeDeviceReAttach;
|
||||
virHostdevPCINodeDeviceReset;
|
||||
virHostdevPrepareDomainDevices;
|
||||
virHostdevPrepareMediatedDevices;
|
||||
virHostdevPreparePCIDevices;
|
||||
virHostdevPrepareSCSIDevices;
|
||||
virHostdevPrepareSCSIVHostDevices;
|
||||
virHostdevPrepareUSBDevices;
|
||||
virHostdevReAttachDomainDevices;
|
||||
virHostdevReAttachMediatedDevices;
|
||||
virHostdevReAttachPCIDevices;
|
||||
virHostdevReAttachSCSIDevices;
|
||||
virHostdevReAttachSCSIVHostDevices;
|
||||
virHostdevReAttachUSBDevices;
|
||||
virHostdevUpdateActiveDomainDevices;
|
||||
virHostdevUpdateActiveMediatedDevices;
|
||||
virHostdevUpdateActivePCIDevices;
|
||||
virHostdevUpdateActiveSCSIDevices;
|
||||
virHostdevUpdateActiveUSBDevices;
|
||||
|
@ -83,6 +83,22 @@ qemuHostdevUpdateActiveSCSIDevices(virQEMUDriverPtr driver,
|
||||
QEMU_DRIVER_NAME, def->name);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
qemuHostdevUpdateActiveMediatedDevices(virQEMUDriverPtr driver,
|
||||
virDomainDefPtr def)
|
||||
{
|
||||
virHostdevManagerPtr mgr = driver->hostdevMgr;
|
||||
|
||||
if (!def->nhostdevs)
|
||||
return 0;
|
||||
|
||||
return virHostdevUpdateActiveMediatedDevices(mgr, def->hostdevs,
|
||||
def->nhostdevs,
|
||||
QEMU_DRIVER_NAME, def->name);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
qemuHostdevUpdateActiveDomainDevices(virQEMUDriverPtr driver,
|
||||
virDomainDefPtr def)
|
||||
@ -99,6 +115,9 @@ qemuHostdevUpdateActiveDomainDevices(virQEMUDriverPtr driver,
|
||||
if (qemuHostdevUpdateActiveSCSIDevices(driver, def) < 0)
|
||||
return -1;
|
||||
|
||||
if (qemuHostdevUpdateActiveMediatedDevices(driver, def) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -304,6 +323,24 @@ qemuHostdevPrepareSCSIVHostDevices(virQEMUDriverPtr driver,
|
||||
name, hostdevs, nhostdevs);
|
||||
}
|
||||
|
||||
int
|
||||
qemuHostdevPrepareMediatedDevices(virQEMUDriverPtr driver,
|
||||
const char *name,
|
||||
virDomainHostdevDefPtr *hostdevs,
|
||||
int nhostdevs)
|
||||
{
|
||||
virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr;
|
||||
|
||||
if (!qemuHostdevHostSupportsPassthroughVFIO()) {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
_("host doesn't support VFIO PCI interface"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return virHostdevPrepareMediatedDevices(hostdev_mgr, QEMU_DRIVER_NAME,
|
||||
name, hostdevs, nhostdevs);
|
||||
}
|
||||
|
||||
int
|
||||
qemuHostdevPrepareDomainDevices(virQEMUDriverPtr driver,
|
||||
virDomainDefPtr def,
|
||||
@ -330,6 +367,10 @@ qemuHostdevPrepareDomainDevices(virQEMUDriverPtr driver,
|
||||
def->hostdevs, def->nhostdevs) < 0)
|
||||
return -1;
|
||||
|
||||
if (qemuHostdevPrepareMediatedDevices(driver, def->name,
|
||||
def->hostdevs, def->nhostdevs) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -396,6 +437,18 @@ qemuHostdevReAttachSCSIVHostDevices(virQEMUDriverPtr driver,
|
||||
name, hostdevs, nhostdevs);
|
||||
}
|
||||
|
||||
void
|
||||
qemuHostdevReAttachMediatedDevices(virQEMUDriverPtr driver,
|
||||
const char *name,
|
||||
virDomainHostdevDefPtr *hostdevs,
|
||||
int nhostdevs)
|
||||
{
|
||||
virHostdevManagerPtr hostdev_mgr = driver->hostdevMgr;
|
||||
|
||||
virHostdevReAttachMediatedDevices(hostdev_mgr, QEMU_DRIVER_NAME,
|
||||
name, hostdevs, nhostdevs);
|
||||
}
|
||||
|
||||
void
|
||||
qemuHostdevReAttachDomainDevices(virQEMUDriverPtr driver,
|
||||
virDomainDefPtr def)
|
||||
@ -414,4 +467,7 @@ qemuHostdevReAttachDomainDevices(virQEMUDriverPtr driver,
|
||||
|
||||
qemuHostdevReAttachSCSIVHostDevices(driver, def->name, def->hostdevs,
|
||||
def->nhostdevs);
|
||||
|
||||
qemuHostdevReAttachMediatedDevices(driver, def->name, def->hostdevs,
|
||||
def->nhostdevs);
|
||||
}
|
||||
|
@ -30,6 +30,8 @@
|
||||
bool qemuHostdevHostSupportsPassthroughLegacy(void);
|
||||
bool qemuHostdevHostSupportsPassthroughVFIO(void);
|
||||
|
||||
int qemuHostdevUpdateActiveMediatedDevices(virQEMUDriverPtr driver,
|
||||
virDomainDefPtr def);
|
||||
int qemuHostdevUpdateActivePCIDevices(virQEMUDriverPtr driver,
|
||||
virDomainDefPtr def);
|
||||
int qemuHostdevUpdateActiveUSBDevices(virQEMUDriverPtr driver,
|
||||
@ -59,6 +61,10 @@ int qemuHostdevPrepareSCSIVHostDevices(virQEMUDriverPtr driver,
|
||||
const char *name,
|
||||
virDomainHostdevDefPtr *hostdevs,
|
||||
int nhostdevs);
|
||||
int qemuHostdevPrepareMediatedDevices(virQEMUDriverPtr driver,
|
||||
const char *name,
|
||||
virDomainHostdevDefPtr *hostdevs,
|
||||
int nhostdevs);
|
||||
int qemuHostdevPrepareDomainDevices(virQEMUDriverPtr driver,
|
||||
virDomainDefPtr def,
|
||||
virQEMUCapsPtr qemuCaps,
|
||||
@ -80,6 +86,10 @@ void qemuHostdevReAttachSCSIVHostDevices(virQEMUDriverPtr driver,
|
||||
const char *name,
|
||||
virDomainHostdevDefPtr *hostdevs,
|
||||
int nhostdevs);
|
||||
void qemuHostdevReAttachMediatedDevices(virQEMUDriverPtr driver,
|
||||
const char *name,
|
||||
virDomainHostdevDefPtr *hostdevs,
|
||||
int nhostdevs);
|
||||
void qemuHostdevReAttachDomainDevices(virQEMUDriverPtr driver,
|
||||
virDomainDefPtr def);
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* virhostdev.c: hostdev management
|
||||
*
|
||||
* Copyright (C) 2006-2007, 2009-2016 Red Hat, Inc.
|
||||
* Copyright (C) 2006-2007, 2009-2017 Red Hat, Inc.
|
||||
* Copyright (C) 2006 Daniel P. Berrange
|
||||
* Copyright (C) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany.
|
||||
*
|
||||
@ -147,6 +147,7 @@ virHostdevManagerDispose(void *obj)
|
||||
virObjectUnref(hostdevMgr->activeUSBHostdevs);
|
||||
virObjectUnref(hostdevMgr->activeSCSIHostdevs);
|
||||
virObjectUnref(hostdevMgr->activeSCSIVHostHostdevs);
|
||||
virObjectUnref(hostdevMgr->activeMediatedHostdevs);
|
||||
VIR_FREE(hostdevMgr->stateDir);
|
||||
}
|
||||
|
||||
@ -174,6 +175,9 @@ virHostdevManagerNew(void)
|
||||
if (!(hostdevMgr->activeSCSIVHostHostdevs = virSCSIVHostDeviceListNew()))
|
||||
goto error;
|
||||
|
||||
if (!(hostdevMgr->activeMediatedHostdevs = virMediatedDeviceListNew()))
|
||||
goto error;
|
||||
|
||||
if (privileged) {
|
||||
if (VIR_STRDUP(hostdevMgr->stateDir, HOSTDEV_STATE_DIR) < 0)
|
||||
goto error;
|
||||
@ -1165,6 +1169,50 @@ virHostdevUpdateActiveSCSIDevices(virHostdevManagerPtr mgr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
virHostdevUpdateActiveMediatedDevices(virHostdevManagerPtr mgr,
|
||||
virDomainHostdevDefPtr *hostdevs,
|
||||
int nhostdevs,
|
||||
const char *drv_name,
|
||||
const char *dom_name)
|
||||
{
|
||||
int ret = -1;
|
||||
size_t i;
|
||||
virMediatedDevicePtr mdev = NULL;
|
||||
|
||||
if (nhostdevs == 0)
|
||||
return 0;
|
||||
|
||||
virObjectLock(mgr->activeMediatedHostdevs);
|
||||
for (i = 0; i < nhostdevs; i++) {
|
||||
virDomainHostdevDefPtr hostdev = hostdevs[i];
|
||||
virDomainHostdevSubsysMediatedDevPtr mdevsrc;
|
||||
|
||||
mdevsrc = &hostdev->source.subsys.u.mdev;
|
||||
|
||||
if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
|
||||
hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(mdev = virMediatedDeviceNew(mdevsrc->uuidstr, mdevsrc->model)))
|
||||
goto cleanup;
|
||||
|
||||
virMediatedDeviceSetUsedBy(mdev, drv_name, dom_name);
|
||||
|
||||
if (virMediatedDeviceListAdd(mgr->activeMediatedHostdevs, mdev) < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
cleanup:
|
||||
virMediatedDeviceFree(mdev);
|
||||
virObjectUnlock(mgr->activeMediatedHostdevs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virHostdevMarkUSBDevices(virHostdevManagerPtr mgr,
|
||||
const char *drv_name,
|
||||
@ -1613,6 +1661,70 @@ virHostdevPrepareSCSIVHostDevices(virHostdevManagerPtr mgr,
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
virHostdevPrepareMediatedDevices(virHostdevManagerPtr mgr,
|
||||
const char *drv_name,
|
||||
const char *dom_name,
|
||||
virDomainHostdevDefPtr *hostdevs,
|
||||
int nhostdevs)
|
||||
{
|
||||
size_t i;
|
||||
int ret = -1;
|
||||
virMediatedDeviceListPtr list;
|
||||
|
||||
if (!nhostdevs)
|
||||
return 0;
|
||||
|
||||
/* To prevent situation where mediated device is assigned to multiple
|
||||
* domains we maintain a driver list of currently assigned mediated devices.
|
||||
* A device is appended to the driver list after a series of preparations.
|
||||
*/
|
||||
if (!(list = virMediatedDeviceListNew()))
|
||||
goto cleanup;
|
||||
|
||||
/* Loop 1: Build a temporary list of ALL mediated devices. */
|
||||
for (i = 0; i < nhostdevs; i++) {
|
||||
virDomainHostdevDefPtr hostdev = hostdevs[i];
|
||||
virDomainHostdevSubsysMediatedDevPtr src = &hostdev->source.subsys.u.mdev;
|
||||
virMediatedDevicePtr mdev;
|
||||
|
||||
if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
|
||||
continue;
|
||||
if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV)
|
||||
continue;
|
||||
|
||||
if (!(mdev = virMediatedDeviceNew(src->uuidstr, src->model)))
|
||||
goto cleanup;
|
||||
|
||||
if (virMediatedDeviceListAdd(list, mdev) < 0) {
|
||||
virMediatedDeviceFree(mdev);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
/* Mark the devices in the list as used by @drv_name-@dom_name and copy the
|
||||
* references to the driver list
|
||||
*/
|
||||
if (virMediatedDeviceListMarkDevices(mgr->activeMediatedHostdevs,
|
||||
list, drv_name, dom_name) < 0)
|
||||
goto cleanup;
|
||||
|
||||
/* Loop 2: Temporary list was successfully merged with
|
||||
* driver list, so steal all items to avoid freeing them
|
||||
* in cleanup label.
|
||||
*/
|
||||
while (virMediatedDeviceListCount(list) > 0) {
|
||||
virMediatedDevicePtr tmp = virMediatedDeviceListGet(list, 0);
|
||||
virMediatedDeviceListSteal(list, tmp);
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
cleanup:
|
||||
virObjectUnref(list);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
virHostdevReAttachUSBDevices(virHostdevManagerPtr mgr,
|
||||
const char *drv_name,
|
||||
@ -1807,6 +1919,64 @@ virHostdevReAttachSCSIVHostDevices(virHostdevManagerPtr mgr,
|
||||
virObjectUnlock(mgr->activeSCSIVHostHostdevs);
|
||||
}
|
||||
|
||||
/* TODO: Rename this function along with all virHostdevReAttach* functions that
|
||||
* have nothing to do with an explicit re-attachment of a device back to the
|
||||
* host driver (like PCI).
|
||||
* Despite what the function name suggests, there's nothing to be re-attached
|
||||
* for mediated devices, the function merely removes a mediated device from the
|
||||
* list of active host devices.
|
||||
*/
|
||||
void
|
||||
virHostdevReAttachMediatedDevices(virHostdevManagerPtr mgr,
|
||||
const char *drv_name,
|
||||
const char *dom_name,
|
||||
virDomainHostdevDefPtr *hostdevs,
|
||||
int nhostdevs)
|
||||
{
|
||||
const char *used_by_drvname = NULL;
|
||||
const char *used_by_domname = NULL;
|
||||
size_t i;
|
||||
|
||||
if (nhostdevs == 0)
|
||||
return;
|
||||
|
||||
virObjectLock(mgr->activeMediatedHostdevs);
|
||||
for (i = 0; i < nhostdevs; i++) {
|
||||
virMediatedDevicePtr mdev, tmp;
|
||||
virDomainHostdevSubsysMediatedDevPtr mdevsrc;
|
||||
virDomainHostdevDefPtr hostdev = hostdevs[i];
|
||||
|
||||
mdevsrc = &hostdev->source.subsys.u.mdev;
|
||||
|
||||
if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
|
||||
hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(mdev = virMediatedDeviceNew(mdevsrc->uuidstr,
|
||||
mdevsrc->model)))
|
||||
continue;
|
||||
|
||||
/* Remove from the list only mdevs assigned to @drv_name/@dom_name */
|
||||
|
||||
tmp = virMediatedDeviceListFind(mgr->activeMediatedHostdevs, mdev);
|
||||
virMediatedDeviceFree(mdev);
|
||||
|
||||
/* skip inactive devices */
|
||||
if (!tmp)
|
||||
continue;
|
||||
|
||||
virMediatedDeviceGetUsedBy(tmp, &used_by_drvname, &used_by_domname);
|
||||
if (STREQ_NULLABLE(drv_name, used_by_drvname) &&
|
||||
STREQ_NULLABLE(dom_name, used_by_domname)) {
|
||||
VIR_DEBUG("Removing %s dom=%s from activeMediatedHostdevs",
|
||||
mdevsrc->uuidstr, dom_name);
|
||||
virMediatedDeviceListDel(mgr->activeMediatedHostdevs, tmp);
|
||||
}
|
||||
}
|
||||
virObjectUnlock(mgr->activeMediatedHostdevs);
|
||||
}
|
||||
|
||||
int
|
||||
virHostdevPCINodeDeviceDetach(virHostdevManagerPtr mgr,
|
||||
virPCIDevicePtr pci)
|
||||
|
@ -32,6 +32,7 @@
|
||||
# include "virscsi.h"
|
||||
# include "virscsivhost.h"
|
||||
# include "conf/domain_conf.h"
|
||||
# include "virmdev.h"
|
||||
|
||||
typedef enum {
|
||||
VIR_HOSTDEV_STRICT_ACS_CHECK = (1 << 0), /* strict acs check */
|
||||
@ -55,6 +56,7 @@ struct _virHostdevManager {
|
||||
virUSBDeviceListPtr activeUSBHostdevs;
|
||||
virSCSIDeviceListPtr activeSCSIHostdevs;
|
||||
virSCSIVHostDeviceListPtr activeSCSIVHostHostdevs;
|
||||
virMediatedDeviceListPtr activeMediatedHostdevs;
|
||||
};
|
||||
|
||||
virHostdevManagerPtr virHostdevManagerGetDefault(void);
|
||||
@ -96,6 +98,13 @@ virHostdevPrepareSCSIVHostDevices(virHostdevManagerPtr hostdev_mgr,
|
||||
virDomainHostdevDefPtr *hostdevs,
|
||||
int nhostdevs)
|
||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
|
||||
int
|
||||
virHostdevPrepareMediatedDevices(virHostdevManagerPtr hostdev_mgr,
|
||||
const char *drv_name,
|
||||
const char *dom_name,
|
||||
virDomainHostdevDefPtr *hostdevs,
|
||||
int nhostdevs)
|
||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
|
||||
void
|
||||
virHostdevReAttachPCIDevices(virHostdevManagerPtr hostdev_mgr,
|
||||
const char *drv_name,
|
||||
@ -125,6 +134,13 @@ virHostdevReAttachSCSIVHostDevices(virHostdevManagerPtr hostdev_mgr,
|
||||
virDomainHostdevDefPtr *hostdevs,
|
||||
int nhostdevs)
|
||||
ATTRIBUTE_NONNULL(1);
|
||||
void
|
||||
virHostdevReAttachMediatedDevices(virHostdevManagerPtr hostdev_mgr,
|
||||
const char *drv_name,
|
||||
const char *dom_name,
|
||||
virDomainHostdevDefPtr *hostdevs,
|
||||
int nhostdevs)
|
||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
|
||||
int
|
||||
virHostdevUpdateActivePCIDevices(virHostdevManagerPtr mgr,
|
||||
virDomainHostdevDefPtr *hostdevs,
|
||||
@ -147,6 +163,13 @@ virHostdevUpdateActiveSCSIDevices(virHostdevManagerPtr mgr,
|
||||
const char *dom_name)
|
||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5);
|
||||
int
|
||||
virHostdevUpdateActiveMediatedDevices(virHostdevManagerPtr mgr,
|
||||
virDomainHostdevDefPtr *hostdevs,
|
||||
int nhostdevs,
|
||||
const char *drv_name,
|
||||
const char *dom_name)
|
||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5);
|
||||
int
|
||||
virHostdevUpdateActiveDomainDevices(virHostdevManagerPtr mgr,
|
||||
const char *driver,
|
||||
virDomainDefPtr def,
|
||||
|
Loading…
x
Reference in New Issue
Block a user