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