Defer MAC registration until net devices are actually going
to be used by the guest. This patch does so by setting the
devices online just before starting guest CPUs.
This approach is an alternative to my previously proposed
'network: Defer online of macvtap during qemu migration'
Laine/Wangrui, is this the sort of thing you had in mind?
Previous thread:
https://www.redhat.com/archives/libvir-list/2014-May/msg00427.html
Associated BZ:
https://bugzilla.redhat.com/show_bug.cgi?id=1081461
Signed-off-by: Matthew Rosato <mjrosato(a)linux.vnet.ibm.com>
---
src/qemu/qemu_command.c | 45 +++++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_command.h | 3 +++
src/qemu/qemu_process.c | 3 +++
src/util/virnetdevmacvlan.c | 5 -----
src/util/virnetdevtap.c | 3 ---
5 files changed, 51 insertions(+), 8 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index e6acced..c161d73 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -571,6 +571,51 @@ qemuNetworkPrepareDevices(virDomainDefPtr def)
return ret;
}
+void
+qemuNetworkIfaceUp(virDomainNetDefPtr net)
+{
+ if (virNetDevSetOnline(net->ifname, true) < 0) {
+ ignore_value(virNetDevTapDelete(net->ifname));
+ }
+ return;
+}
+
+void
+qemuPhysIfaceUp(virDomainNetDefPtr net)
+{
+ if (virNetDevSetOnline(net->ifname, true) < 0) {
+ ignore_value(virNetDevVPortProfileDisassociate(net->ifname,
+
virDomainNetGetActualVirtPortProfile(net),
+ &net->mac,
+
virDomainNetGetActualDirectDev(net),
+ -1,
+
VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_FINISH));
+ ignore_value(virNetDevMacVLanDelete(net->ifname));
+ }
+ return;
+}
+
+void
+qemuNetworkInitializeDevices(virDomainDefPtr def)
+{
+ size_t i;
+
+ for (i = 0; i < def->nnets; i++) {
+ virDomainNetDefPtr net = def->nets[i];
+ switch(virDomainNetGetActualType(net)) {
+ case VIR_DOMAIN_NET_TYPE_BRIDGE:
+ case VIR_DOMAIN_NET_TYPE_NETWORK:
+ qemuNetworkIfaceUp(net);
+ break;
+ case VIR_DOMAIN_NET_TYPE_DIRECT:
+ qemuPhysIfaceUp(net);
+ break;
+ }
+ }
+
+ return;
+}
+
static int qemuDomainDeviceAliasIndex(const virDomainDeviceInfo *info,
const char *prefix)
{
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index afbd6ff..4a44464 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -206,6 +206,9 @@ int qemuOpenVhostNet(virDomainDefPtr def,
int *vhostfdSize);
int qemuNetworkPrepareDevices(virDomainDefPtr def);
+void qemuNetworkIfaceUp(virDomainNetDefPtr net);
+void qemuPhysIfaceUp(virDomainNetDefPtr net);
+void qemuNetworkInitializeDevices(virDomainDefPtr def);
/*
* NB: def->name can be NULL upon return and the caller
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index d719716..bbc11f3 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -2765,6 +2765,9 @@ qemuProcessStartCPUs(virQEMUDriverPtr driver, virDomainObjPtr vm,
qemuDomainObjPrivatePtr priv = vm->privateData;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ /* Bring up netdevs before starting CPUs */
+ qemuNetworkInitializeDevices(vm->def);
+
VIR_DEBUG("Using lock state '%s'", NULLSTR(priv->lockState));
if (virDomainLockProcessResume(driver->lockManager, cfg->uri,
vm, priv->lockState) < 0) {
diff --git a/src/util/virnetdevmacvlan.c b/src/util/virnetdevmacvlan.c
index cb85b74..3748527 100644
--- a/src/util/virnetdevmacvlan.c
+++ b/src/util/virnetdevmacvlan.c
@@ -898,11 +898,6 @@ int virNetDevMacVLanCreateWithVPortProfile(const char *tgifname,
goto link_del_exit;
}
- if (virNetDevSetOnline(cr_ifname, true) < 0) {
- rc = -1;
- goto disassociate_exit;
- }
-
if (withTap) {
if ((rc = virNetDevMacVLanTapOpen(cr_ifname, 10)) < 0)
goto disassociate_exit;
diff --git a/src/util/virnetdevtap.c b/src/util/virnetdevtap.c
index 0b444fa..09b9c12 100644
--- a/src/util/virnetdevtap.c
+++ b/src/util/virnetdevtap.c
@@ -574,9 +574,6 @@ int virNetDevTapCreateInBridgePort(const char *brname,
goto error;
}
- if (virNetDevSetOnline(*ifname, !!(flags & VIR_NETDEV_TAP_CREATE_IFUP)) < 0)
- goto error;
-
return 0;
error:
--
1.7.9.5