[libvirt] [PATCH v3] network: Bring netdevs online later
Matthew Rosato
mjrosato at linux.vnet.ibm.com
Wed Sep 24 15:45:16 UTC 2014
On 09/16/2014 04:50 PM, Matthew Rosato wrote:
> Currently, MAC registration occurs during device creation, which is
> early enough that, during live migration, you end up with duplicate
> MAC addresses on still-running source and target devices, even though
> the target device isn't actually being used yet.
> This patch proposes to defer MAC registration until right before
> the guest can actually use the device -- In other words, right
> before starting guest CPUs.
>
> Signed-off-by: Matthew Rosato <mjrosato at linux.vnet.ibm.com>
> ---
Ping
>
> Associated BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1081461
>
> Changes for v3:
> * Some minor formatting fixes.
> * in qemuNetworkIfaceConnect, set VIR_NETDEV_TAP_CREATE_IFUP
> unconditionally.
> * in qemuDomainAttachNetDevice, call qemuInterfaceStartDevice only for
> VIR_DOMAIN_NET_TYPE_DIRECT, _BRIDGE and _NETWORK.
> * in qemuProcessStartCPUs, use 'reason' to determine whether or not
> qemuInterfaceStartDevices needs to be called. Basically, it needs
> to be called for any reason that the system would be initializing
> (or re-initializing).
>
> src/Makefile.am | 3 +-
> src/conf/domain_conf.h | 2 ++
> src/lxc/lxc_process.c | 4 ++-
> src/qemu/qemu_command.c | 3 ++
> src/qemu/qemu_hotplug.c | 8 +++++
> src/qemu/qemu_interface.c | 78 +++++++++++++++++++++++++++++++++++++++++++
> src/qemu/qemu_interface.h | 32 ++++++++++++++++++
> src/qemu/qemu_process.c | 7 ++++
> src/util/virnetdevmacvlan.c | 8 +++--
> src/util/virnetdevmacvlan.h | 2 ++
> 10 files changed, 142 insertions(+), 5 deletions(-)
> create mode 100644 src/qemu/qemu_interface.c
> create mode 100644 src/qemu/qemu_interface.h
>
> diff --git a/src/Makefile.am b/src/Makefile.am
> index fa741a8..035120e 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -703,7 +703,8 @@ QEMU_DRIVER_SOURCES = \
> qemu/qemu_monitor_text.h \
> qemu/qemu_monitor_json.c \
> qemu/qemu_monitor_json.h \
> - qemu/qemu_driver.c qemu/qemu_driver.h
> + qemu/qemu_driver.c qemu/qemu_driver.h \
> + qemu/qemu_interface.c qemu/qemu_interface.h
>
> XENAPI_DRIVER_SOURCES = \
> xenapi/xenapi_driver.c xenapi/xenapi_driver.h \
> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> index 0862bd7..5f328cf 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -951,6 +951,8 @@ struct _virDomainNetDef {
> virNetDevBandwidthPtr bandwidth;
> virNetDevVlan vlan;
> int linkstate;
> + /* vmOp value saved if deferring interface start */
> + virNetDevVPortProfileOp vmOp;
> };
>
> /* Used for prefix of ifname of any network name generated dynamically
> diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
> index ed30c37..b2256c0 100644
> --- a/src/lxc/lxc_process.c
> +++ b/src/lxc/lxc_process.c
> @@ -300,6 +300,7 @@ char *virLXCProcessSetupInterfaceDirect(virConnectPtr conn,
> virNetDevBandwidthPtr bw;
> virNetDevVPortProfilePtr prof;
> virLXCDriverConfigPtr cfg = virLXCDriverGetConfig(driver);
> + unsigned int macvlan_create_flags = VIR_NETDEV_MACVLAN_CREATE_IFUP;
>
> /* XXX how todo bandwidth controls ?
> * Since the 'net-ifname' is about to be moved to a different
> @@ -336,7 +337,8 @@ char *virLXCProcessSetupInterfaceDirect(virConnectPtr conn,
> &res_ifname,
> VIR_NETDEV_VPORT_PROFILE_OP_CREATE,
> cfg->stateDir,
> - virDomainNetGetActualBandwidth(net), 0) < 0)
> + virDomainNetGetActualBandwidth(net),
> + macvlan_create_flags) < 0)
> goto cleanup;
>
> ret = res_ifname;
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index e5270bd..229dff4 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -199,6 +199,9 @@ qemuPhysIfaceConnect(virDomainDefPtr def,
> net->ifname = res_ifname;
> }
>
> + /* Save vport profile op for later */
> + net->vmOp = vmop;
> +
> virObjectUnref(cfg);
> return rc;
> }
> diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
> index 7bc19cd..530e6da 100644
> --- a/src/qemu/qemu_hotplug.c
> +++ b/src/qemu/qemu_hotplug.c
> @@ -30,6 +30,7 @@
> #include "qemu_domain.h"
> #include "qemu_command.h"
> #include "qemu_hostdev.h"
> +#include "qemu_interface.h"
> #include "domain_audit.h"
> #include "domain_nwfilter.h"
> #include "virlog.h"
> @@ -922,6 +923,8 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
> priv->qemuCaps, tapfd, &tapfdSize) < 0)
> goto cleanup;
> iface_connected = true;
> + /* Set device online immediately */
> + qemuInterfaceStartDevice(net);
> if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, vhostfd, &vhostfdSize) < 0)
> goto cleanup;
> } else if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
> @@ -937,6 +940,8 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
> VIR_NETDEV_VPORT_PROFILE_OP_CREATE)) < 0)
> goto cleanup;
> iface_connected = true;
> + /* Set device online immediately */
> + qemuInterfaceStartDevice(net);
> if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, vhostfd, &vhostfdSize) < 0)
> goto cleanup;
> } else if (actualType == VIR_DOMAIN_NET_TYPE_ETHERNET) {
> @@ -2070,6 +2075,9 @@ qemuDomainChangeNet(virQEMUDriverPtr driver,
> goto cleanup;
> }
>
> + /* Set device online immediately */
> + qemuInterfaceStartDevice(newdev);
> +
> newType = virDomainNetGetActualType(newdev);
>
> if (newType == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
> diff --git a/src/qemu/qemu_interface.c b/src/qemu/qemu_interface.c
> new file mode 100644
> index 0000000..dccfcc4
> --- /dev/null
> +++ b/src/qemu/qemu_interface.c
> @@ -0,0 +1,78 @@
> +/*
> + * qemu_interface.c: QEMU interface management
> + *
> + * Copyright IBM Corp. 2014
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library. If not, see
> + * <http://www.gnu.org/licenses/>.
> + *
> + * Authors:
> + * Matthew J. Rosato <mjrosato at linux.vnet.ibm.com>
> + */
> +
> +#include <config.h>
> +
> +#include "qemu_interface.h"
> +#include "virnetdev.h"
> +#include "virnetdevtap.h"
> +#include "virnetdevmacvlan.h"
> +#include "virnetdevvportprofile.h"
> +
> +/**
> + * qemuInterfaceStartDevice:
> + * @net: net device to start
> + *
> + * Based upon the type of device provided, perform the appropriate
> + * work to set the device online.
> + */
> +void
> +qemuInterfaceStartDevice(virDomainNetDefPtr net)
> +{
> + switch (virDomainNetGetActualType(net)) {
> + case VIR_DOMAIN_NET_TYPE_BRIDGE:
> + case VIR_DOMAIN_NET_TYPE_NETWORK:
> + if (virNetDevSetOnline(net->ifname, true) < 0) {
> + ignore_value(virNetDevTapDelete(net->ifname));
> + }
> + break;
> + case VIR_DOMAIN_NET_TYPE_DIRECT:
> + if (virNetDevSetOnline(net->ifname, true) < 0) {
> + ignore_value(virNetDevVPortProfileDisassociate(net->ifname,
> + virDomainNetGetActualVirtPortProfile(net),
> + &net->mac,
> + virDomainNetGetActualDirectDev(net),
> + -1,
> + net->vmOp));
> + }
> + break;
> + }
> +}
> +
> +/**
> + * qemuInterfaceStartDevices:
> + * @def: domain definition
> + *
> + * Set all ifaces associated with this domain to the online state.
> + */
> +void
> +qemuInterfaceStartDevices(virDomainDefPtr def)
> +{
> + size_t i;
> +
> + for (i = 0; i < def->nnets; i++) {
> + qemuInterfaceStartDevice(def->nets[i]);
> + }
> +
> + return;
> +}
> diff --git a/src/qemu/qemu_interface.h b/src/qemu/qemu_interface.h
> new file mode 100644
> index 0000000..5810cda
> --- /dev/null
> +++ b/src/qemu/qemu_interface.h
> @@ -0,0 +1,32 @@
> +/*
> + * qemu_interface.h: QEMU interface management
> + *
> + * Copyright IBM Corp. 2014
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library. If not, see
> + * <http://www.gnu.org/licenses/>.
> + *
> + * Authors:
> + * Matthew J. Rosato <mjrosato at linux.vnet.ibm.com>
> + */
> +
> +#ifndef __QEMU_INTERFACE_H__
> +# define __QEMU_INTERFACE_H__
> +
> +# include "domain_conf.h"
> +
> +void qemuInterfaceStartDevice(virDomainNetDefPtr net);
> +void qemuInterfaceStartDevices(virDomainDefPtr def);
> +
> +#endif /* __QEMU_INTERFACE_H__ */
> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
> index f391743..3fc50a0 100644
> --- a/src/qemu/qemu_process.c
> +++ b/src/qemu/qemu_process.c
> @@ -42,6 +42,7 @@
> #include "qemu_hostdev.h"
> #include "qemu_hotplug.h"
> #include "qemu_migration.h"
> +#include "qemu_interface.h"
>
> #include "cpu/cpu.h"
> #include "datatypes.h"
> @@ -2947,6 +2948,12 @@ qemuProcessStartCPUs(virQEMUDriverPtr driver, virDomainObjPtr vm,
> qemuDomainObjPrivatePtr priv = vm->privateData;
> virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
>
> + /* Bring up netdevs before starting CPUs */
> + if (reason != VIR_DOMAIN_RUNNING_UNPAUSED &&
> + reason != VIR_DOMAIN_RUNNING_SAVE_CANCELED) {
> + qemuInterfaceStartDevices(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 c83341c..1edf3ae 100644
> --- a/src/util/virnetdevmacvlan.c
> +++ b/src/util/virnetdevmacvlan.c
> @@ -902,9 +902,11 @@ int virNetDevMacVLanCreateWithVPortProfile(const char *tgifname,
> goto link_del_exit;
> }
>
> - if (virNetDevSetOnline(cr_ifname, true) < 0) {
> - rc = -1;
> - goto disassociate_exit;
> + if (flags & VIR_NETDEV_MACVLAN_CREATE_IFUP) {
> + if (virNetDevSetOnline(cr_ifname, true) < 0) {
> + rc = -1;
> + goto disassociate_exit;
> + }
> }
>
> if (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) {
> diff --git a/src/util/virnetdevmacvlan.h b/src/util/virnetdevmacvlan.h
> index 41aa4e2..41b4014 100644
> --- a/src/util/virnetdevmacvlan.h
> +++ b/src/util/virnetdevmacvlan.h
> @@ -44,6 +44,8 @@ typedef enum {
> VIR_NETDEV_MACVLAN_CREATE_NONE = 0,
> /* Create with a tap device */
> VIR_NETDEV_MACVLAN_CREATE_WITH_TAP = 1 << 0,
> + /* Bring the interface up */
> + VIR_NETDEV_MACVLAN_CREATE_IFUP = 1 << 1,
> } virNetDevMacVLanCreateFlags;
>
> int virNetDevMacVLanCreate(const char *ifname,
>
More information about the libvir-list
mailing list