On 12/12/2014 11:34 AM, Laine Stump wrote: > We now have a qemuInterfaceStartDevices() which does the final > activation needed for the host-side tap/macvtap devices that are used > for qemu network connections. It will soon make sense to have the > converse qemuInterfaceStopDevices() which will undo whatever was done > during qemuInterfaceStartDevices(). > > A function to "stop" a single device has also been added, and is > called from the appropriate place in qemuDomainDetachNetDevice(), > although this is currently unnecessary - the device is going to > immediately be deleted anyway, so any extra "deactivation" will be for > naught. The call is included for completeness, though, in anticipation > that in the future there may be some required action that *isn't* > nullified by deleting the device. > > This patch is a part of a more complete fix for: > > https://bugzilla.redhat.com/show_bug.cgi?id=1081461 > --- > src/qemu/qemu_hotplug.c | 8 ++++++ > src/qemu/qemu_interface.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++ > src/qemu/qemu_interface.h | 2 ++ > src/qemu/qemu_process.c | 3 +++ > 4 files changed, 79 insertions(+) > > diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c > index 8c0642e..e56cffe 100644 > --- a/src/qemu/qemu_hotplug.c > +++ b/src/qemu/qemu_hotplug.c > @@ -3513,6 +3513,14 @@ qemuDomainDetachNetDevice(virQEMUDriverPtr driver, > VIR_WARN("cannot clear bandwidth setting for device : %s", > detach->ifname); > > + /* deactivate the tap/macvtap device on the host (currently this > + * isn't necessary, as everything done in > + * qemuInterfaceStopDevice() is made meaningless when the device > + * is deleted anyway, but in the future it may be important, and > + * doesn't hurt anything for now) > + */ > + ignore_value(qemuInterfaceStopDevice(detach)); > + > qemuDomainMarkDeviceForRemoval(vm, &detach->info); > > qemuDomainObjEnterMonitor(driver, vm); > diff --git a/src/qemu/qemu_interface.c b/src/qemu/qemu_interface.c > index b0f0c5d..b9694c8 100644 > --- a/src/qemu/qemu_interface.c > +++ b/src/qemu/qemu_interface.c > @@ -98,3 +98,69 @@ qemuInterfaceStartDevices(virDomainDefPtr def) > } > return 0; > } > + > + > +/** > + * qemuInterfaceStopDevice: > + * @net: net device to stop > + * > + * Based upon the type of device provided, perform the appropriate > + * work to deactivate the device so that packets aren't forwarded to > + * it from the rest of the network. > + */ > +int > +qemuInterfaceStopDevice(virDomainNetDefPtr net) > +{ > + int ret = -1; > + > + switch (virDomainNetGetActualType(net)) { > + case VIR_DOMAIN_NET_TYPE_BRIDGE: > + case VIR_DOMAIN_NET_TYPE_NETWORK: > + break; > + > + case VIR_DOMAIN_NET_TYPE_DIRECT: > + /* macvtap interfaces need to be marked !IFF_UP (ie "down") to > + * prevent any host-generated traffic sent from this interface > + * from putting bad info into the arp caches of other machines > + * on this network. > + */ > + if (virNetDevSetOnline(net->ifname, false) < 0) > + goto cleanup; > + break; > + > + case VIR_DOMAIN_NET_TYPE_USER: > + case VIR_DOMAIN_NET_TYPE_ETHERNET: > + case VIR_DOMAIN_NET_TYPE_VHOSTUSER: > + case VIR_DOMAIN_NET_TYPE_SERVER: > + case VIR_DOMAIN_NET_TYPE_CLIENT: > + case VIR_DOMAIN_NET_TYPE_MCAST: > + case VIR_DOMAIN_NET_TYPE_INTERNAL: > + case VIR_DOMAIN_NET_TYPE_HOSTDEV: > + case VIR_DOMAIN_NET_TYPE_LAST: > + /* these types all require no action */ > + break; > + } > + > + ret = 0; > + cleanup: > + return ret; > +} > + > +/** > + * qemuInterfaceStopDevices: > + * @def: domain definition > + * > + * Make all interfaces associated with this domain inaccessible from > + * the rest of the network. > + */ > +int > +qemuInterfaceStopDevices(virDomainDefPtr def) > +{ > + size_t i; > + > + for (i = 0; i < def->nnets; i++) { > + if (qemuInterfaceStopDevice(def->nets[i]) < 0) > + return -1; > + } > + return 0; > +} > diff --git a/src/qemu/qemu_interface.h b/src/qemu/qemu_interface.h > index d040f52..b4c1efc 100644 > --- a/src/qemu/qemu_interface.h > +++ b/src/qemu/qemu_interface.h > @@ -28,5 +28,7 @@ > > int qemuInterfaceStartDevice(virDomainNetDefPtr net); > int qemuInterfaceStartDevices(virDomainDefPtr def); > +int qemuInterfaceStopDevice(virDomainNetDefPtr net); > +int qemuInterfaceStopDevices(virDomainDefPtr def); > > #endif /* __QEMU_INTERFACE_H__ */ > diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c > index 0028283..a19e71a 100644 > --- a/src/qemu/qemu_process.c > +++ b/src/qemu/qemu_process.c > @@ -3182,6 +3182,9 @@ int qemuProcessStopCPUs(virQEMUDriverPtr driver, > if (ret < 0) > goto cleanup; > > + /* de-activate netdevs after stopping CPUs */ > + ignore_value(qemuInterfaceStopDevices(vm->def)); > + > if (priv->job.current) > ignore_value(virTimeMillisNow(&priv->job.current->stopped)); > Reviewed by: Matthew Rosato <mjrosato@xxxxxxxxxxxxxxxxxx> -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list