|
|
3e5111 |
From 2122aadba5eb30ae466a3e825bbe9ed75b8d9735 Mon Sep 17 00:00:00 2001
|
|
|
3e5111 |
Message-Id: <2122aadba5eb30ae466a3e825bbe9ed75b8d9735@dist-git>
|
|
|
3e5111 |
From: Erik Skultety <eskultet@redhat.com>
|
|
|
3e5111 |
Date: Thu, 4 May 2017 13:50:00 +0200
|
|
|
3e5111 |
Subject: [PATCH] mdev: Fix daemon crash on domain shutdown after reconnect
|
|
|
3e5111 |
|
|
|
3e5111 |
The problem resides in virHostdevUpdateActiveMediatedDevices which gets
|
|
|
3e5111 |
called during qemuProcessReconnect. The issue here is that
|
|
|
3e5111 |
virMediatedDeviceListAdd takes a pointer to the item to be added to the
|
|
|
3e5111 |
list to which VIR_APPEND_ELEMENT is used, which also clears the pointer.
|
|
|
3e5111 |
However, in this case only the local copy of the pointer got cleared,
|
|
|
3e5111 |
leaving the original pointing to valid memory. To sum it up, during
|
|
|
3e5111 |
cleanup phase, the original pointer is freed and the daemon crashes
|
|
|
3e5111 |
basically any time it would access it.
|
|
|
3e5111 |
|
|
|
3e5111 |
Backtrace:
|
|
|
3e5111 |
0x00007ffff3ccdeba in __strcmp_sse2_unaligned
|
|
|
3e5111 |
0x00007ffff72a444a in virMediatedDeviceListFindIndex
|
|
|
3e5111 |
0x00007ffff7241446 in virHostdevReAttachMediatedDevices
|
|
|
3e5111 |
0x00007fffc60215d9 in qemuHostdevReAttachMediatedDevices
|
|
|
3e5111 |
0x00007fffc60216dc in qemuHostdevReAttachDomainDevices
|
|
|
3e5111 |
0x00007fffc6046e6f in qemuProcessStop
|
|
|
3e5111 |
0x00007fffc6091596 in processMonitorEOFEvent
|
|
|
3e5111 |
0x00007fffc6091793 in qemuProcessEventHandler
|
|
|
3e5111 |
0x00007ffff7294bf5 in virThreadPoolWorker
|
|
|
3e5111 |
0x00007ffff7294184 in virThreadHelper
|
|
|
3e5111 |
0x00007ffff3fdc3c4 in start_thread () from /lib64/libpthread.so.0
|
|
|
3e5111 |
0x00007ffff3d269cf in clone () from /lib64/libc.so.6
|
|
|
3e5111 |
|
|
|
3e5111 |
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1446455
|
|
|
3e5111 |
|
|
|
3e5111 |
Signed-off-by: Erik Skultety <eskultet@redhat.com>
|
|
|
3e5111 |
Reviewed-by: Laine Stump <laine@laine.org>
|
|
|
3e5111 |
(cherry picked from commit 92e30a4dace54d06433f763e1acba0a81bb5c82e)
|
|
|
3e5111 |
Signed-off-by: Erik Skultety <eskultet@redhat.com>
|
|
|
3e5111 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
3e5111 |
---
|
|
|
3e5111 |
src/util/virhostdev.c | 4 ++--
|
|
|
3e5111 |
src/util/virmdev.c | 13 ++++++++-----
|
|
|
3e5111 |
src/util/virmdev.h | 2 +-
|
|
|
3e5111 |
3 files changed, 11 insertions(+), 8 deletions(-)
|
|
|
3e5111 |
|
|
|
3e5111 |
diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
|
|
|
3e5111 |
index 2c557f5bb..579563c3f 100644
|
|
|
3e5111 |
--- a/src/util/virhostdev.c
|
|
|
3e5111 |
+++ b/src/util/virhostdev.c
|
|
|
3e5111 |
@@ -1294,7 +1294,7 @@ virHostdevUpdateActiveMediatedDevices(virHostdevManagerPtr mgr,
|
|
|
3e5111 |
|
|
|
3e5111 |
virMediatedDeviceSetUsedBy(mdev, drv_name, dom_name);
|
|
|
3e5111 |
|
|
|
3e5111 |
- if (virMediatedDeviceListAdd(mgr->activeMediatedHostdevs, mdev) < 0)
|
|
|
3e5111 |
+ if (virMediatedDeviceListAdd(mgr->activeMediatedHostdevs, &mdev) < 0)
|
|
|
3e5111 |
goto cleanup;
|
|
|
3e5111 |
}
|
|
|
3e5111 |
|
|
|
3e5111 |
@@ -1790,7 +1790,7 @@ virHostdevPrepareMediatedDevices(virHostdevManagerPtr mgr,
|
|
|
3e5111 |
if (!(mdev = virMediatedDeviceNew(src->uuidstr, src->model)))
|
|
|
3e5111 |
goto cleanup;
|
|
|
3e5111 |
|
|
|
3e5111 |
- if (virMediatedDeviceListAdd(list, mdev) < 0) {
|
|
|
3e5111 |
+ if (virMediatedDeviceListAdd(list, &mdev) < 0) {
|
|
|
3e5111 |
virMediatedDeviceFree(mdev);
|
|
|
3e5111 |
goto cleanup;
|
|
|
3e5111 |
}
|
|
|
3e5111 |
diff --git a/src/util/virmdev.c b/src/util/virmdev.c
|
|
|
3e5111 |
index c1499d238..c861d21c9 100644
|
|
|
3e5111 |
--- a/src/util/virmdev.c
|
|
|
3e5111 |
+++ b/src/util/virmdev.c
|
|
|
3e5111 |
@@ -312,16 +312,19 @@ virMediatedDeviceListDispose(void *obj)
|
|
|
3e5111 |
}
|
|
|
3e5111 |
|
|
|
3e5111 |
|
|
|
3e5111 |
+/* The reason for @dev to be double pointer is that VIR_APPEND_ELEMENT clears
|
|
|
3e5111 |
+ * the pointer and we need to clear the original not a copy on the stack
|
|
|
3e5111 |
+ */
|
|
|
3e5111 |
int
|
|
|
3e5111 |
virMediatedDeviceListAdd(virMediatedDeviceListPtr list,
|
|
|
3e5111 |
- virMediatedDevicePtr dev)
|
|
|
3e5111 |
+ virMediatedDevicePtr *dev)
|
|
|
3e5111 |
{
|
|
|
3e5111 |
- if (virMediatedDeviceListFind(list, dev)) {
|
|
|
3e5111 |
+ if (virMediatedDeviceListFind(list, *dev)) {
|
|
|
3e5111 |
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
3e5111 |
- _("device %s is already in use"), dev->path);
|
|
|
3e5111 |
+ _("device %s is already in use"), (*dev)->path);
|
|
|
3e5111 |
return -1;
|
|
|
3e5111 |
}
|
|
|
3e5111 |
- return VIR_APPEND_ELEMENT(list->devs, list->count, dev);
|
|
|
3e5111 |
+ return VIR_APPEND_ELEMENT(list->devs, list->count, *dev);
|
|
|
3e5111 |
}
|
|
|
3e5111 |
|
|
|
3e5111 |
|
|
|
3e5111 |
@@ -457,7 +460,7 @@ virMediatedDeviceListMarkDevices(virMediatedDeviceListPtr dst,
|
|
|
3e5111 |
* - caller is responsible for NOT freeing devices in @src on success
|
|
|
3e5111 |
* - we're responsible for performing a rollback on failure
|
|
|
3e5111 |
*/
|
|
|
3e5111 |
- if (virMediatedDeviceListAdd(dst, mdev) < 0)
|
|
|
3e5111 |
+ if (virMediatedDeviceListAdd(dst, &mdev) < 0)
|
|
|
3e5111 |
goto rollback;
|
|
|
3e5111 |
|
|
|
3e5111 |
VIR_DEBUG("'%s' added to list of active mediated devices used by '%s'",
|
|
|
3e5111 |
diff --git a/src/util/virmdev.h b/src/util/virmdev.h
|
|
|
3e5111 |
index 2f3d6bb84..8bb46b9c5 100644
|
|
|
3e5111 |
--- a/src/util/virmdev.h
|
|
|
3e5111 |
+++ b/src/util/virmdev.h
|
|
|
3e5111 |
@@ -86,7 +86,7 @@ virMediatedDeviceListNew(void);
|
|
|
3e5111 |
|
|
|
3e5111 |
int
|
|
|
3e5111 |
virMediatedDeviceListAdd(virMediatedDeviceListPtr list,
|
|
|
3e5111 |
- virMediatedDevicePtr dev);
|
|
|
3e5111 |
+ virMediatedDevicePtr *dev);
|
|
|
3e5111 |
|
|
|
3e5111 |
virMediatedDevicePtr
|
|
|
3e5111 |
virMediatedDeviceListGet(virMediatedDeviceListPtr list,
|
|
|
3e5111 |
--
|
|
|
3e5111 |
2.13.0
|
|
|
3e5111 |
|