[virt-tools-list] [virt-manager PATCH 2/2] virtManager: object: domain: Async set guest time
Michael Weiser
michael.weiser at gmx.de
Wed Dec 18 22:26:12 UTC 2019
Sleeping in a loop waiting for the qemu guest agent to come online would
leave an annoying progress dialog while the domain would actually be
fully useable already. Additionally, multiple progress dialogs could
actually accumulate on screen if the user managed to suspend/resume fast
enough or the timeout was just long enough.
Defer regular retries into a callback using a timeout to allow the
progress dialog to disappear immediately after the actual action
completed.
Since it would be hard to reliably disable the timeout on every state
change, we just leave the timeout running even if the domain is switched
back off. Use a Lock to protect against multiple timeouts being started
by consecutive actions.
With the potential for annoyance eliminated, raise the maximum timeout
to 30 seconds.
Signed-off-by: Michael Weiser <michael.weiser at gmx.de>
Suggested-by: Cole Robinson <crobinso at redhat.com>
---
virtManager/object/domain.py | 49 ++++++++++++++++++++++++++++--------
1 file changed, 38 insertions(+), 11 deletions(-)
diff --git a/virtManager/object/domain.py b/virtManager/object/domain.py
index 778d1fee..4f21550e 100644
--- a/virtManager/object/domain.py
+++ b/virtManager/object/domain.py
@@ -197,6 +197,10 @@ class vmmDomain(vmmLibvirtObject):
self._domain_caps = None
self._status_reason = None
self._ip_cache = None
+ self._set_time_retrying = threading.Lock()
+ self._set_time_attempts = 0
+ self.set_time_retry_wait = 0.5
+ self.set_time_maxwait = 30
self.managedsave_supported = False
self._domain_state_supported = False
@@ -1185,19 +1189,42 @@ class vmmDomain(vmmLibvirtObject):
if not self._get_agent():
return
- # wait for agent to come online
- maxwait = 5
- sleep = 0.5
- for _ in range(0, int(maxwait / sleep)):
- if self._agent_ready():
- break
- log.debug("Waiting for qemu guest agent to come online...")
- time.sleep(sleep)
- else:
- if not self._agent_ready():
- log.debug("Giving up on qemu guest agent for time sync")
+ # defer setting the time if guest agent isn't ready yet
+ if not self._agent_ready():
+ if not self._set_time_retrying.acquire(False):
+ # just reset counter if retries are already underway
+ log.debug("Restarting guest time sync because of action")
+ self._set_time_attempts = 0
return
+ # we start a timer and just leave it running even if domain state
+ # changes because it would be hard to reliably track all state
+ # changes
+ log.debug("Agent not ready for time sync, retrying")
+ self._set_time_attempts = 0
+ self.timeout_add(self.set_time_retry_wait * 1000,
+ self._retry_set_time)
+ return
+
+ self._do_set_time()
+
+ def _retry_set_time(self):
+ if self._agent_ready():
+ self._do_set_time()
+ self._set_time_retrying.release()
+ return False
+
+ max_attempts = int(self.set_time_maxwait / self.set_time_retry_wait)
+ if self._set_time_attempts >= max_attempts:
+ log.debug("Giving up on qemu guest agent for time sync")
+ self._set_time_retrying.release()
+ return False
+
+ self._set_time_attempts += 1
+ log.debug("Waiting for qemu guest agent to come online...")
+ return True
+
+ def _do_set_time(self):
t = time.time()
seconds = int(t)
nseconds = int((t - seconds) * 10 ** 9)
--
2.24.1
More information about the virt-tools-list
mailing list