[libvirt] [PATCH 0/3] allow fixing tap-bridge connections when network is restarted

Laine Stump posted 3 patches 7 years, 1 month ago
Failed in applying to current master (apply log)
src/libvirt_private.syms    |   2 +
src/network/bridge_driver.c |  30 +++++++++++-
src/util/virnetdev.c        |  49 +++++++++++++++++++
src/util/virnetdev.h        |   3 ++
src/util/virnetdevtap.c     | 111 +++++++++++++++++++++++++++++---------------
src/util/virnetdevtap.h     |  12 +++++
6 files changed, 169 insertions(+), 38 deletions(-)
[libvirt] [PATCH 0/3] allow fixing tap-bridge connections when network is restarted
Posted by Laine Stump 7 years, 1 month ago
It's been a long-standing problem that when you stop and restart a
libvirt network, the guest tap devices are no longer connected to the
network. Until now the only way to recover from this was to either
shutdown and restart all the affected guests, or to detach and then
re-attach all affected guest network devices.

These patches permit the situation to be remedied by just restarting
libvirtd - when the hypervisor drivers are notifying the network
drivers of each connection, the network can retrieve the current
"master" for the tap device and compare it to the network's bridge
device. If they don't match, then it disconnects the tap from any
incorrect bridge and connects to the correct bridge.

***

For now, that's as far as we go - *semi*-automated (since you need to
restart libvirtd for it to happen). My intent is for this to be
completely automated, but the logic to do that is a bit "convoluted"
so I've deferred trying to implement it until I've given it more
thought - a few different trains of thought have led to dead-ends, and
so far only one seems reasonably doable:

* add a networkStartCallback list to the network driver state object.

* as each hypervisor driver that uses the network driver is
  initialized, it will call an internal-only function in the network
  driver to register a callback.

* whenever a network is started, it will call all the registered
  callback functions (sending the name of the network being started,
  and some HV-specific context pointer).

* Each hypervisor's callback function will look through all of its
  active domains for interfaces that are using the given network, and
  for each such interface, will call networkNotifyActualDevice() (the
  function that has been updated in Patch 3/3 to reconnect taps to
  bridges).

The "convoluted" part here is that we need to make sure there is
enough (but not too much!) locking/refcounting both when adding items
to the callback list (which should only be done single threaded, since
it happens during the driver initializations) and when the
networkStart() function (in some state of lockedness/refcountedness)
calls over to some e.g. qemu function that will then need to do some
amount of locking (at least on each domain as it is processed) and
then calls back into the network driver (which will need "some amount"
of locking/refcounting). Since we're calling from network driver into
qemu into network driver, while the normal nesting is just calling
from qemu into network, I want to be sure there is no possibility for
a deadlock. (Also, I want to avoid making the list of callbacks any
more complicated than absolutely necessary - the "in" thing to do
these days seems to be to allocate a hash table, but there's a lot of
extra code required for that (see util/virclosecallbacks.[hc]) which
seems like overkill for a list of maximum 4-5 items that will *never*
change after the driver initialization - if anyone has ideas/opinions
about that, please speak up.


Laine Stump (2):
  util: new function virNetDevGetMaster()
  util: new function virNetDevTapAttachBridge()

root (1):
  network: reconnect tap devices during networkNotifyActualDevice

 src/libvirt_private.syms    |   2 +
 src/network/bridge_driver.c |  30 +++++++++++-
 src/util/virnetdev.c        |  49 +++++++++++++++++++
 src/util/virnetdev.h        |   3 ++
 src/util/virnetdevtap.c     | 111 +++++++++++++++++++++++++++++---------------
 src/util/virnetdevtap.h     |  12 +++++
 6 files changed, 169 insertions(+), 38 deletions(-)

-- 
2.9.3

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 0/3] allow fixing tap-bridge connections when network is restarted
Posted by Michal Privoznik 7 years, 1 month ago
On 03/21/2017 04:03 PM, Laine Stump wrote:
> It's been a long-standing problem that when you stop and restart a
> libvirt network, the guest tap devices are no longer connected to the
> network. Until now the only way to recover from this was to either
> shutdown and restart all the affected guests, or to detach and then
> re-attach all affected guest network devices.
>
> These patches permit the situation to be remedied by just restarting
> libvirtd - when the hypervisor drivers are notifying the network
> drivers of each connection, the network can retrieve the current
> "master" for the tap device and compare it to the network's bridge
> device. If they don't match, then it disconnects the tap from any
> incorrect bridge and connects to the correct bridge.
>
> ***
>
> For now, that's as far as we go - *semi*-automated (since you need to
> restart libvirtd for it to happen). My intent is for this to be
> completely automated, but the logic to do that is a bit "convoluted"
> so I've deferred trying to implement it until I've given it more
> thought - a few different trains of thought have led to dead-ends, and
> so far only one seems reasonably doable:
>
> * add a networkStartCallback list to the network driver state object.
>
> * as each hypervisor driver that uses the network driver is
>   initialized, it will call an internal-only function in the network
>   driver to register a callback.
>
> * whenever a network is started, it will call all the registered
>   callback functions (sending the name of the network being started,
>   and some HV-specific context pointer).
>
> * Each hypervisor's callback function will look through all of its
>   active domains for interfaces that are using the given network, and
>   for each such interface, will call networkNotifyActualDevice() (the
>   function that has been updated in Patch 3/3 to reconnect taps to
>   bridges).
>
> The "convoluted" part here is that we need to make sure there is
> enough (but not too much!) locking/refcounting both when adding items
> to the callback list (which should only be done single threaded, since
> it happens during the driver initializations) and when the
> networkStart() function (in some state of lockedness/refcountedness)
> calls over to some e.g. qemu function that will then need to do some
> amount of locking (at least on each domain as it is processed) and
> then calls back into the network driver (which will need "some amount"
> of locking/refcounting). Since we're calling from network driver into
> qemu into network driver, while the normal nesting is just calling
> from qemu into network, I want to be sure there is no possibility for
> a deadlock. (Also, I want to avoid making the list of callbacks any
> more complicated than absolutely necessary - the "in" thing to do
> these days seems to be to allocate a hash table, but there's a lot of
> extra code required for that (see util/virclosecallbacks.[hc]) which
> seems like overkill for a list of maximum 4-5 items that will *never*
> change after the driver initialization - if anyone has ideas/opinions
> about that, please speak up.
>
>
> Laine Stump (2):
>   util: new function virNetDevGetMaster()
>   util: new function virNetDevTapAttachBridge()
>
> root (1):
>   network: reconnect tap devices during networkNotifyActualDevice

You might want to reset the owner here ;-)

>
>  src/libvirt_private.syms    |   2 +
>  src/network/bridge_driver.c |  30 +++++++++++-
>  src/util/virnetdev.c        |  49 +++++++++++++++++++
>  src/util/virnetdev.h        |   3 ++
>  src/util/virnetdevtap.c     | 111 +++++++++++++++++++++++++++++---------------
>  src/util/virnetdevtap.h     |  12 +++++
>  6 files changed, 169 insertions(+), 38 deletions(-)
>

ACK series.

Michal

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list