We have to explicitly destroy TAP devices on FreeBSD because
they're not freed after being closed, otherwise we end up with
orphaned TAP devices after destroying a domain.
---
src/qemu/qemu_process.c | 14 ++++++++++++--
src/util/virnetdevtap.h | 6 ++++++
2 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index ffa939a..d1acafc 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4373,7 +4373,10 @@ void qemuProcessStop(virQEMUDriverPtr driver,
def = vm->def;
for (i = 0; i < def->nnets; i++) {
virDomainNetDefPtr net = def->nets[i];
- if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_DIRECT) {
+ vport = virDomainNetGetActualVirtPortProfile(net);
+
+ switch (virDomainNetGetActualType(net)) {
+ case VIR_DOMAIN_NET_TYPE_DIRECT:
ignore_value(virNetDevMacVLanDeleteWithVPortProfile(
net->ifname, &net->mac,
virDomainNetGetActualDirectDev(net),
@@ -4381,11 +4384,18 @@ void qemuProcessStop(virQEMUDriverPtr driver,
virDomainNetGetActualVirtPortProfile(net),
cfg->stateDir));
VIR_FREE(net->ifname);
+ break;
+ case VIR_DOMAIN_NET_TYPE_BRIDGE:
+ case VIR_DOMAIN_NET_TYPE_NETWORK:
+#ifdef VIR_NETDEV_TAP_REQUIRE_MANUAL_CLEANUP
+ if (!(vport && vport->virtPortType ==
VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH))
+ ignore_value(virNetDevTapDelete(net->ifname));
+#endif
+ break;
}
/* release the physical device (or any other resources used by
* this interface in the network driver
*/
- vport = virDomainNetGetActualVirtPortProfile(net);
if (vport && vport->virtPortType ==
VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH)
ignore_value(virNetDevOpenvswitchRemovePort(
virDomainNetGetActualBridgeName(net),
diff --git a/src/util/virnetdevtap.h b/src/util/virnetdevtap.h
index a762b31..1e5bd19 100644
--- a/src/util/virnetdevtap.h
+++ b/src/util/virnetdevtap.h
@@ -27,6 +27,12 @@
# include "virnetdevvportprofile.h"
# include "virnetdevvlan.h"
+# ifdef __FreeBSD__
+/* This should be defined on OSes that don't automatically
+ * cleanup released devices */
+# define VIR_NETDEV_TAP_REQUIRE_MANUAL_CLEANUP 1
+# endif
+
int virNetDevTapCreate(char **ifname,
int *tapfd,
int tapfdSize,
--
1.8.4.3