[virt-tools-list] [PATCH] Regression: make networks states updated again

Cole Robinson crobinso at redhat.com
Wed Nov 20 19:49:45 UTC 2013


On 11/20/2013 08:42 AM, Cédric Bosdonnat wrote:
> The previous implementation of the network state refresh was using
> poll. The new way is expecting signals to come, but those were not
> implemented on the libvirt side.
> 
> Open the networks tab on the connection details, and watch the changes
> when running virsh net-* commands.

Indeed current git is 'broken' here, but it was a deliberate change to get
away from the massive amount of polling we do by default. I figured until
network events etc. were implemented in libvirt it wouldn't be considered too
painful a lose of functionality for the benefit of snappier UI operation.

But I see you've posted libvirt patches for these events, nice work!

However this approach isn't entirely sufficient, because it isn't cautious
enough. For example if I tried to run your patch against any released version
of libvirt, virt-manager would fall over because you unconditonally call the
new API even though libvirt might not support it. There's also the fact that
the hypervisor might not support it. So we need to be cautious here.

I'd also want the net-start/net-stop signals to come from the vmmNetwork
object themselves. That will take some rework independent of this patch.

Domain events are one of the things on my short todo list that I wanted to
look at before the end of the year. When there's ground work layed down for
those, plugging in networking events should be pretty simple as well, and you
can follow the pattern they use for only using them when libvirt and the HV
supports it.

Thanks,
Cole

> ---
>  virtManager/connection.py | 18 +++++++++++++++++-
>  virtManager/host.py       |  4 ++++
>  virtinst/connection.py    | 12 +++++++++++-
>  3 files changed, 32 insertions(+), 2 deletions(-)
> 
> diff --git a/virtManager/connection.py b/virtManager/connection.py
> index 1a3b2aa..29d0431 100644
> --- a/virtManager/connection.py
> +++ b/virtManager/connection.py
> @@ -886,6 +886,22 @@ class vmmConnection(vmmGObject):
>                  (self.get_uri(), str(e), "".join(traceback.format_exc())))
>              return -1
>  
> +    def _net_event_cb(self, conn, net, event, opaque):
> +        if event == libvirt.VIR_NETWORK_EVENT_DEFINED:
> +            self.emit('net-added', net.UUIDString())
> +            action = "defined"
> +        elif event == libvirt.VIR_NETWORK_EVENT_UNDEFINED:
> +            self.emit('net-removed', net.UUIDString())
> +            action = "undefined"
> +        elif event == libvirt.VIR_NETWORK_EVENT_STARTED:
> +            self.emit('net-started', net.UUIDString())
> +            action = "started"
> +        elif event == libvirt.VIR_NETWORK_EVENT_STOPPED:
> +            self.emit('net-stopped', net.UUIDString())
> +            action = "stopped"
> +
> +        logging.debug("network_event_cb: %s[uuid: %s] %s" % (net.name(), net.UUIDString(), action))
> +
>      def _open_thread(self):
>          logging.debug("Background 'open connection' thread is running")
>  
> @@ -895,7 +911,7 @@ class vmmConnection(vmmGObject):
>              tb = None
>              warnconsole = False
>              try:
> -                self._backend.open(self._do_creds_password)
> +                self._backend.open(self._do_creds_password, self._net_event_cb)
>              except libvirt.libvirtError, libexc:
>                  tb = "".join(traceback.format_exc())
>              except Exception, exc:
> diff --git a/virtManager/host.py b/virtManager/host.py
> index cf815af..5b4ce3a 100644
> --- a/virtManager/host.py
> +++ b/virtManager/host.py
> @@ -515,9 +515,12 @@ class vmmHost(vmmGObjectUI):
>              return
>  
>      def refresh_network(self, src_ignore, uuid):
> +        logging.debug("refresh_network %s" % uuid)
>          uilist = self.widget("net-list")
>          sel = uilist.get_selection()
>          active = sel.get_selected()
> +        # We may have a newly created temporary network
> +        self.conn.tick(stats_update=False,pollnet=True)
>          net = self.conn.get_net(uuid)
>          net.tick()
>  
> @@ -676,6 +679,7 @@ class vmmHost(vmmGObjectUI):
>          self.disable_net_apply()
>  
>      def repopulate_networks(self, src_ignore=None, uuid_ignore=None):
> +        self.conn.tick(stats_update=False,pollnet=True)
>          self.populate_networks(self.widget("net-list").get_model())
>  
>      def populate_networks(self, model):
> diff --git a/virtinst/connection.py b/virtinst/connection.py
> index 70bb603..0fd605a 100644
> --- a/virtinst/connection.py
> +++ b/virtinst/connection.py
> @@ -73,6 +73,7 @@ class VirtualConnection(object):
>          self._fake_conn_version = None
>          self._daemon_version = None
>          self._conn_version = None
> +        self._networkEventCallbackId = None
>  
>          if _initial_uri.startswith(_virtinst_uri_magic):
>              # virtinst unit test URI handling
> @@ -136,6 +137,9 @@ class VirtualConnection(object):
>      ##############
>  
>      def close(self):
> +        if self._networkEventCallbackId is not None and self._libvirtconn is not None:
> +            logging.debug("Deregistering network event, callback Id: %d" % self._networkEventCallbackId)
> +            self._libvirtconn.networkEventDeregisterAny(self._networkEventCallbackId)
>          self._libvirtconn = None
>          self._uri = None
>          self._fetch_cache = {}
> @@ -146,7 +150,7 @@ class VirtualConnection(object):
>      def is_open(self):
>          return bool(self._libvirtconn)
>  
> -    def open(self, passwordcb):
> +    def open(self, passwordcb, network_event_cb = None):
>          open_flags = 0
>          valid_auth_options = [libvirt.VIR_CRED_AUTHNAME,
>                                libvirt.VIR_CRED_PASSPHRASE]
> @@ -160,6 +164,12 @@ class VirtualConnection(object):
>  
>          self._fixup_virtinst_test_uri(conn)
>          self._libvirtconn = conn
> +
> +        if network_event_cb is not None:
> +            eventId = (libvirt.VIR_EVENT_NAMESPACE_NETWORK << 8) + libvirt.VIR_NETWORK_EVENT_ID_LIFECYCLE;
> +            self._networkEventCallbackId = self._libvirtconn.networkEventRegisterAny(None, eventId, network_event_cb, None)
> +            logging.debug("Registered network event, callback Id: %d" % self._networkEventCallbackId)
> +
>          if not self._open_uri:
>              self._uri = self._libvirtconn.getURI()
>              self._urisplits = util.uri_split(self._uri)
> 




More information about the virt-tools-list mailing list