storagepool: Don't double invoke 'refresh' when events are present
We need to tweak refresh() handling to work similar to the shared XML and status caching in libvirtobject.py: when the user manually invokes the refresh() operation, and storage events are set up, we just invoke the refresh() but let the event loop handle refreshing the cache. This fixes a backtrace when invoking a manual refresh via the host details dialog
This commit is contained in:
parent
cdf5d32434
commit
9a67fc4d6e
|
@ -778,9 +778,10 @@ class vmmConnection(vmmGObject):
|
|||
name = pool.name()
|
||||
logging.debug("storage pool lifecycle event: storage=%s event=%s "
|
||||
"reason=%s", name, event, reason)
|
||||
is_event_refreshed = (event == getattr(
|
||||
libvirt, "VIR_STORAGE_POOL_EVENT_REFRESHED", 4))
|
||||
|
||||
if (not self.is_active() and
|
||||
event == getattr(libvirt, "VIR_STORAGE_POOL_EVENT_REFRESHED", 4)):
|
||||
if is_event_refreshed and not self.is_active():
|
||||
# We refresh() pools during connection startup, and this spams
|
||||
# the logs, so skip it.
|
||||
return
|
||||
|
@ -788,7 +789,10 @@ class vmmConnection(vmmGObject):
|
|||
obj = self.get_pool(name)
|
||||
|
||||
if obj:
|
||||
self.idle_add(obj.recache_from_event_loop)
|
||||
if is_event_refreshed:
|
||||
self.idle_add(obj.refresh_pool_cache_from_event_loop)
|
||||
else:
|
||||
self.idle_add(obj.recache_from_event_loop)
|
||||
else:
|
||||
self.schedule_priority_tick(pollpool=True, force=True)
|
||||
|
||||
|
|
|
@ -153,7 +153,7 @@ class vmmStoragePool(vmmLibvirtObject):
|
|||
# since the pools may be out of date. But if a storage pool
|
||||
# shows up while the conn is connected, this means it was
|
||||
# just 'defined' recently and doesn't need to be refreshed.
|
||||
self.refresh(_do_refresh_xml=False)
|
||||
self.refresh(_from_object_init=True)
|
||||
for vol in self.get_volumes():
|
||||
vol.init_libvirt_state()
|
||||
|
||||
|
@ -180,16 +180,27 @@ class vmmStoragePool(vmmLibvirtObject):
|
|||
self._backend.undefine()
|
||||
self._backend = None
|
||||
|
||||
def refresh(self, _do_refresh_xml=True):
|
||||
def refresh(self, _from_object_init=False):
|
||||
"""
|
||||
:param _do_refresh_xml: We want this by default. It's only skipped
|
||||
to avoid double updating XML via init_libvirt_state
|
||||
:param _from_object_init: Only used for the refresh() call from
|
||||
_init_libvirt_state. Tells us to not refresh the XML, since
|
||||
we just updated it.
|
||||
"""
|
||||
if not self.is_active():
|
||||
return
|
||||
|
||||
self._backend.refresh(0)
|
||||
if _do_refresh_xml:
|
||||
if self._using_events() and not _from_object_init:
|
||||
# If we are using events, we let the event loop trigger
|
||||
# the cache update for us. Except if from init_libvirt_state,
|
||||
# we want the update to be done immediately
|
||||
return
|
||||
|
||||
self.refresh_pool_cache_from_event_loop(
|
||||
_from_object_init=_from_object_init)
|
||||
|
||||
def refresh_pool_cache_from_event_loop(self, _from_object_init=False):
|
||||
if not _from_object_init:
|
||||
self.ensure_latest_xml()
|
||||
self._update_volumes(force=True)
|
||||
self.idle_emit("refreshed")
|
||||
|
@ -220,8 +231,7 @@ class vmmStoragePool(vmmLibvirtObject):
|
|||
if not force and self._volumes is not None:
|
||||
return
|
||||
|
||||
self._volumes = []
|
||||
keymap = dict((o.get_connkey(), o) for o in self._volumes)
|
||||
keymap = dict((o.get_connkey(), o) for o in self._volumes or [])
|
||||
(ignore, ignore, allvols) = pollhelpers.fetch_volumes(
|
||||
self.conn.get_backend(), self.get_backend(), keymap,
|
||||
lambda obj, key: vmmStorageVolume(self.conn, obj, key))
|
||||
|
|
Loading…
Reference in New Issue