|
|
43fe83 |
From 0309361905e9b9ee674b740610f49ae273862939 Mon Sep 17 00:00:00 2001
|
|
|
43fe83 |
Message-Id: <0309361905e9b9ee674b740610f49ae273862939.1377873641.git.jdenemar@redhat.com>
|
|
|
43fe83 |
From: Peter Krempa <pkrempa@redhat.com>
|
|
|
43fe83 |
Date: Thu, 29 Aug 2013 19:21:11 +0200
|
|
|
43fe83 |
Subject: [PATCH] qemu: Remove hostdev entry when freeing the depending network
|
|
|
43fe83 |
entry
|
|
|
43fe83 |
|
|
|
43fe83 |
When using a <interface type="network"> that points to a network with
|
|
|
43fe83 |
hostdev forwarding mode a hostdev alias is created for the network. This
|
|
|
43fe83 |
allias is inserted into the hostdev list, but is backed with a part of
|
|
|
43fe83 |
the network object that it is connected to.
|
|
|
43fe83 |
|
|
|
43fe83 |
When a VM is being stopped qemuProcessStop() calls
|
|
|
43fe83 |
networkReleaseActualDevice() which eventually frees the memory for the
|
|
|
43fe83 |
hostdev object. Afterwards when the domain definition is being freed by
|
|
|
43fe83 |
virDomainDefFree() an invalid pointer is accessed by
|
|
|
43fe83 |
virDomainHostdevDefFree() and may cause a crash of the daemon.
|
|
|
43fe83 |
|
|
|
43fe83 |
This patch removes the entry in the hostdev list before freeing the
|
|
|
43fe83 |
depending memory to avoid this issue.
|
|
|
43fe83 |
|
|
|
43fe83 |
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1002669 [7.0]
|
|
|
43fe83 |
https://bugzilla.redhat.com/show_bug.cgi?id=1000973 [6.5]
|
|
|
43fe83 |
(cherry picked from commit 50348e6edfa10ddb61929bf95a1c4820a9614e19)
|
|
|
43fe83 |
---
|
|
|
43fe83 |
src/conf/domain_conf.c | 26 ++++++++++++++++++--------
|
|
|
43fe83 |
src/conf/domain_conf.h | 1 +
|
|
|
43fe83 |
src/libvirt_private.syms | 1 +
|
|
|
43fe83 |
src/qemu/qemu_hotplug.c | 5 +++++
|
|
|
43fe83 |
src/qemu/qemu_process.c | 2 ++
|
|
|
43fe83 |
5 files changed, 27 insertions(+), 8 deletions(-)
|
|
|
43fe83 |
|
|
|
43fe83 |
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
|
|
|
43fe83 |
index 01f9bd0..1a20232 100644
|
|
|
43fe83 |
--- a/src/conf/domain_conf.c
|
|
|
43fe83 |
+++ b/src/conf/domain_conf.c
|
|
|
43fe83 |
@@ -9936,26 +9936,36 @@ virDomainNetFindIdx(virDomainDefPtr def, virDomainNetDefPtr net)
|
|
|
43fe83 |
return matchidx;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
-virDomainNetDefPtr
|
|
|
43fe83 |
-virDomainNetRemove(virDomainDefPtr def, size_t i)
|
|
|
43fe83 |
-{
|
|
|
43fe83 |
- virDomainNetDefPtr net = def->nets[i];
|
|
|
43fe83 |
|
|
|
43fe83 |
+void
|
|
|
43fe83 |
+virDomainNetRemoveHostdev(virDomainDefPtr def,
|
|
|
43fe83 |
+ virDomainNetDefPtr net)
|
|
|
43fe83 |
+{
|
|
|
43fe83 |
if (net->type == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
|
|
|
43fe83 |
/* hostdev net devices are normally also be in the hostdevs
|
|
|
43fe83 |
* array, but might have already been removed by the time we
|
|
|
43fe83 |
* get here.
|
|
|
43fe83 |
*/
|
|
|
43fe83 |
virDomainHostdevDefPtr hostdev = &net->data.hostdev.def;
|
|
|
43fe83 |
- size_t h;
|
|
|
43fe83 |
+ size_t i;
|
|
|
43fe83 |
|
|
|
43fe83 |
- for (h = 0; h < def->nhostdevs; h++) {
|
|
|
43fe83 |
- if (def->hostdevs[h] == hostdev) {
|
|
|
43fe83 |
- virDomainHostdevRemove(def, h);
|
|
|
43fe83 |
+ for (i = 0; i < def->nhostdevs; i++) {
|
|
|
43fe83 |
+ if (def->hostdevs[i] == hostdev) {
|
|
|
43fe83 |
+ virDomainHostdevRemove(def, i);
|
|
|
43fe83 |
break;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
}
|
|
|
43fe83 |
}
|
|
|
43fe83 |
+}
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+virDomainNetDefPtr
|
|
|
43fe83 |
+virDomainNetRemove(virDomainDefPtr def, size_t i)
|
|
|
43fe83 |
+{
|
|
|
43fe83 |
+ virDomainNetDefPtr net = def->nets[i];
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ virDomainNetRemoveHostdev(def, net);
|
|
|
43fe83 |
+
|
|
|
43fe83 |
if (def->nnets > 1) {
|
|
|
43fe83 |
memmove(def->nets + i,
|
|
|
43fe83 |
def->nets + i + 1,
|
|
|
43fe83 |
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
|
|
|
43fe83 |
index 536fc96..29ef0f8 100644
|
|
|
43fe83 |
--- a/src/conf/domain_conf.h
|
|
|
43fe83 |
+++ b/src/conf/domain_conf.h
|
|
|
43fe83 |
@@ -2360,6 +2360,7 @@ int virDomainNetFindIdx(virDomainDefPtr def, virDomainNetDefPtr net);
|
|
|
43fe83 |
virDomainNetDefPtr virDomainNetFind(virDomainDefPtr def, const char *device);
|
|
|
43fe83 |
int virDomainNetInsert(virDomainDefPtr def, virDomainNetDefPtr net);
|
|
|
43fe83 |
virDomainNetDefPtr virDomainNetRemove(virDomainDefPtr def, size_t i);
|
|
|
43fe83 |
+void virDomainNetRemoveHostdev(virDomainDefPtr def, virDomainNetDefPtr net);
|
|
|
43fe83 |
|
|
|
43fe83 |
int virDomainHostdevInsert(virDomainDefPtr def, virDomainHostdevDefPtr hostdev);
|
|
|
43fe83 |
virDomainHostdevDefPtr
|
|
|
43fe83 |
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
|
|
|
43fe83 |
index faa67ad..e6c23e4 100644
|
|
|
43fe83 |
--- a/src/libvirt_private.syms
|
|
|
43fe83 |
+++ b/src/libvirt_private.syms
|
|
|
43fe83 |
@@ -302,6 +302,7 @@ virDomainNetGetActualVirtPortProfile;
|
|
|
43fe83 |
virDomainNetGetActualVlan;
|
|
|
43fe83 |
virDomainNetInsert;
|
|
|
43fe83 |
virDomainNetRemove;
|
|
|
43fe83 |
+virDomainNetRemoveHostdev;
|
|
|
43fe83 |
virDomainNetTypeToString;
|
|
|
43fe83 |
virDomainNostateReasonTypeFromString;
|
|
|
43fe83 |
virDomainNostateReasonTypeToString;
|
|
|
43fe83 |
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
|
|
|
43fe83 |
index 7a6946e..cbe7072 100644
|
|
|
43fe83 |
--- a/src/qemu/qemu_hotplug.c
|
|
|
43fe83 |
+++ b/src/qemu/qemu_hotplug.c
|
|
|
43fe83 |
@@ -940,6 +940,8 @@ cleanup:
|
|
|
43fe83 |
virDomainNetGetActualBridgeName(net), net->ifname));
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
+ virDomainNetRemoveHostdev(vm->def, net);
|
|
|
43fe83 |
+
|
|
|
43fe83 |
networkReleaseActualDevice(net);
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
@@ -1978,6 +1980,9 @@ qemuDomainChangeNet(virQEMUDriverPtr driver,
|
|
|
43fe83 |
/* the changes above warrant replacing olddev with newdev in
|
|
|
43fe83 |
* the domain's nets list.
|
|
|
43fe83 |
*/
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ /* this function doesn't work with HOSTDEV networks yet, thus
|
|
|
43fe83 |
+ * no need to change the pointer in the hostdev structure */
|
|
|
43fe83 |
networkReleaseActualDevice(olddev);
|
|
|
43fe83 |
virDomainNetDefFree(olddev);
|
|
|
43fe83 |
/* move newdev into the nets list, and NULL it out from the
|
|
|
43fe83 |
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
|
|
|
43fe83 |
index 0dccac3..6a28356 100644
|
|
|
43fe83 |
--- a/src/qemu/qemu_process.c
|
|
|
43fe83 |
+++ b/src/qemu/qemu_process.c
|
|
|
43fe83 |
@@ -4234,6 +4234,8 @@ void qemuProcessStop(virQEMUDriverPtr driver,
|
|
|
43fe83 |
virDomainNetGetActualBridgeName(net),
|
|
|
43fe83 |
net->ifname));
|
|
|
43fe83 |
|
|
|
43fe83 |
+ /* kick the device out of the hostdev list too */
|
|
|
43fe83 |
+ virDomainNetRemoveHostdev(def, net);
|
|
|
43fe83 |
networkReleaseActualDevice(net);
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
--
|
|
|
43fe83 |
1.8.3.2
|
|
|
43fe83 |
|