79c4324644
Change-Id: I2d302dda68298877c65c99147f5bf22186a59aac
162 lines
6.3 KiB
Diff
162 lines
6.3 KiB
Diff
From 7b752336bd26048514d55bb222531c0b0183fa9c Mon Sep 17 00:00:00 2001
|
|
From: Erik Skultety <eskultet@redhat.com>
|
|
Date: Thu, 7 Jan 2021 16:53:21 +0100
|
|
Subject: [PATCH 079/108] hostdev: mdev: Lookup mdevs by sysfs path rather than
|
|
mdev struct
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
The lookup didn't do anything apart from comparing the sysfs paths
|
|
anyway since that's what makes each mdev unique.
|
|
The most ridiculous usage of the old logic was in
|
|
virHostdevReAttachMediatedDevices where in order to drop an mdev
|
|
hostdev from the list of active devices we first had to create a new
|
|
mdev and use it in the lookup call. Why couldn't we have used the
|
|
hostdev directly? Because the hostdev and mdev structures are
|
|
incompatible.
|
|
|
|
The way mdevs are currently removed is via a write to a specific sysfs
|
|
attribute. If you do it while the machine which has the mdev assigned
|
|
is running, the write call may block (with a new enough kernel, with
|
|
older kernels it would return a write error!) until the device
|
|
is no longer in use which is when the QEMU process exits.
|
|
|
|
The interesting part here comes afterwards when we're cleaning up and
|
|
call virHostdevReAttachMediatedDevices. The domain doesn't exist
|
|
anymore, so the list of active hostdevs needs to be updated and the
|
|
respective hostdevs removed from the list, but remember we had to
|
|
create an mdev object in the memory in order to find it in the list
|
|
first which will fail because the write to sysfs had already removed
|
|
the mdev instance from the host system.
|
|
And so the next time you try to start the same domain you'll get:
|
|
|
|
"Requested operation is not valid: mediated device <path> is in use by
|
|
driver QEMU, domain <name>"
|
|
|
|
Fixes: https://gitlab.com/libvirt/libvirt/-/issues/119
|
|
|
|
Signed-off-by: Erik Skultety <eskultet@redhat.com>
|
|
Reviewed-by: Ján Tomko <jtomko@redhat.com>
|
|
(cherry picked from commit 49cb59778a4e6c2d04bb9383a9d97fbbc83f9fce)
|
|
---
|
|
src/hypervisor/virhostdev.c | 10 ++++------
|
|
src/util/virmdev.c | 16 ++++++++--------
|
|
src/util/virmdev.h | 4 ++--
|
|
3 files changed, 14 insertions(+), 16 deletions(-)
|
|
|
|
diff --git a/src/hypervisor/virhostdev.c b/src/hypervisor/virhostdev.c
|
|
index c88c8bee0e..4057f7b25f 100644
|
|
--- a/src/hypervisor/virhostdev.c
|
|
+++ b/src/hypervisor/virhostdev.c
|
|
@@ -1981,7 +1981,7 @@ virHostdevReAttachMediatedDevices(virHostdevManagerPtr mgr,
|
|
|
|
virObjectLock(mgr->activeMediatedHostdevs);
|
|
for (i = 0; i < nhostdevs; i++) {
|
|
- g_autoptr(virMediatedDevice) mdev = NULL;
|
|
+ g_autofree char *sysfspath = NULL;
|
|
virMediatedDevicePtr tmp;
|
|
virDomainHostdevSubsysMediatedDevPtr mdevsrc;
|
|
virDomainHostdevDefPtr hostdev = hostdevs[i];
|
|
@@ -1990,14 +1990,12 @@ virHostdevReAttachMediatedDevices(virHostdevManagerPtr mgr,
|
|
continue;
|
|
|
|
mdevsrc = &hostdev->source.subsys.u.mdev;
|
|
-
|
|
- if (!(mdev = virMediatedDeviceNew(mdevsrc->uuidstr,
|
|
- mdevsrc->model)))
|
|
- continue;
|
|
+ sysfspath = virMediatedDeviceGetSysfsPath(mdevsrc->uuidstr);
|
|
|
|
/* Remove from the list only mdevs assigned to @drv_name/@dom_name */
|
|
|
|
- tmp = virMediatedDeviceListFind(mgr->activeMediatedHostdevs, mdev);
|
|
+ tmp = virMediatedDeviceListFind(mgr->activeMediatedHostdevs,
|
|
+ sysfspath);
|
|
|
|
/* skip inactive devices */
|
|
if (!tmp)
|
|
diff --git a/src/util/virmdev.c b/src/util/virmdev.c
|
|
index c2499c0a20..bae4a7d2c1 100644
|
|
--- a/src/util/virmdev.c
|
|
+++ b/src/util/virmdev.c
|
|
@@ -312,7 +312,7 @@ int
|
|
virMediatedDeviceListAdd(virMediatedDeviceListPtr list,
|
|
virMediatedDevicePtr *dev)
|
|
{
|
|
- if (virMediatedDeviceListFind(list, *dev)) {
|
|
+ if (virMediatedDeviceListFind(list, (*dev)->path)) {
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
_("device %s is already in use"), (*dev)->path);
|
|
return -1;
|
|
@@ -358,7 +358,7 @@ virMediatedDevicePtr
|
|
virMediatedDeviceListSteal(virMediatedDeviceListPtr list,
|
|
virMediatedDevicePtr dev)
|
|
{
|
|
- int idx = virMediatedDeviceListFindIndex(list, dev);
|
|
+ int idx = virMediatedDeviceListFindIndex(list, dev->path);
|
|
|
|
return virMediatedDeviceListStealIndex(list, idx);
|
|
}
|
|
@@ -374,13 +374,13 @@ virMediatedDeviceListDel(virMediatedDeviceListPtr list,
|
|
|
|
int
|
|
virMediatedDeviceListFindIndex(virMediatedDeviceListPtr list,
|
|
- virMediatedDevicePtr dev)
|
|
+ const char *sysfspath)
|
|
{
|
|
size_t i;
|
|
|
|
for (i = 0; i < list->count; i++) {
|
|
- virMediatedDevicePtr other = list->devs[i];
|
|
- if (STREQ(other->path, dev->path))
|
|
+ virMediatedDevicePtr dev = list->devs[i];
|
|
+ if (STREQ(sysfspath, dev->path))
|
|
return i;
|
|
}
|
|
return -1;
|
|
@@ -389,11 +389,11 @@ virMediatedDeviceListFindIndex(virMediatedDeviceListPtr list,
|
|
|
|
virMediatedDevicePtr
|
|
virMediatedDeviceListFind(virMediatedDeviceListPtr list,
|
|
- virMediatedDevicePtr dev)
|
|
+ const char *sysfspath)
|
|
{
|
|
int idx;
|
|
|
|
- if ((idx = virMediatedDeviceListFindIndex(list, dev)) >= 0)
|
|
+ if ((idx = virMediatedDeviceListFindIndex(list, sysfspath)) >= 0)
|
|
return list->devs[idx];
|
|
else
|
|
return NULL;
|
|
@@ -407,7 +407,7 @@ virMediatedDeviceIsUsed(virMediatedDevicePtr dev,
|
|
const char *drvname, *domname;
|
|
virMediatedDevicePtr tmp = NULL;
|
|
|
|
- if ((tmp = virMediatedDeviceListFind(list, dev))) {
|
|
+ if ((tmp = virMediatedDeviceListFind(list, dev->path))) {
|
|
virMediatedDeviceGetUsedBy(tmp, &drvname, &domname);
|
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
|
_("mediated device %s is in use by "
|
|
diff --git a/src/util/virmdev.h b/src/util/virmdev.h
|
|
index 51f7f608a2..1d97f7d44f 100644
|
|
--- a/src/util/virmdev.h
|
|
+++ b/src/util/virmdev.h
|
|
@@ -119,11 +119,11 @@ virMediatedDeviceListDel(virMediatedDeviceListPtr list,
|
|
|
|
virMediatedDevicePtr
|
|
virMediatedDeviceListFind(virMediatedDeviceListPtr list,
|
|
- virMediatedDevicePtr dev);
|
|
+ const char *sysfspath);
|
|
|
|
int
|
|
virMediatedDeviceListFindIndex(virMediatedDeviceListPtr list,
|
|
- virMediatedDevicePtr dev);
|
|
+ const char *sysfspath);
|
|
|
|
int
|
|
virMediatedDeviceListMarkDevices(virMediatedDeviceListPtr dst,
|
|
--
|
|
2.33.0
|
|
|