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@xxxxxx> Suggested-by: Cole Robinson <crobinso@xxxxxxxxxx> --- 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 _______________________________________________ virt-tools-list mailing list virt-tools-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/virt-tools-list