summaryrefslogtreecommitdiff
path: root/virtManager
diff options
context:
space:
mode:
authorMichael Weiser <michael.weiser@gmx.de>2020-01-03 21:12:33 +0100
committerCole Robinson <crobinso@redhat.com>2020-01-14 14:10:28 -0500
commitbfafe1e4b24b84087905d1dcbb1c1259b998dfe0 (patch)
tree35852d353cc6a77b4703e98c75472930f8397d86 /virtManager
parent4f8a27688dc1d7eac1044b9fdead84dd1007a6b0 (diff)
downloadvirt-manager-bfafe1e4b24b84087905d1dcbb1c1259b998dfe0.tar.gz
virtManager: object: domain: Spawn thread for set time
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 separate thread to allow the progress dialog to disappear immediately after the actual action completed. The thread is encapsulated in a new class _vmmDomainSetTimeThread which holds state, decides whether to at all wait for an agent to come online or even try to set the guest time in the first place. It also holds state (thread running or not), configuration (timeout and retry interval) and provides an interface to start and stop the time setting operation. A later patch will wire up stopping the operation. Reviewed-by: Cole Robinson <crobinso@redhat.com> Signed-off-by: Michael Weiser <michael.weiser@gmx.de> Suggested-by: Cole Robinson <crobinso@redhat.com>
Diffstat (limited to 'virtManager')
-rw-r--r--virtManager/object/domain.py73
1 files changed, 59 insertions, 14 deletions
diff --git a/virtManager/object/domain.py b/virtManager/object/domain.py
index 355fca97..584a57a0 100644
--- a/virtManager/object/domain.py
+++ b/virtManager/object/domain.py
@@ -181,39 +181,84 @@ class vmmDomainSnapshot(vmmLibvirtObject):
class _vmmDomainSetTimeThread(vmmGObject):
+ """
+ A separate thread handling time setting operations as not to block the main
+ UI.
+ """
def __init__(self, domain):
vmmGObject.__init__(self)
self._domain = domain
+ self._do_cancel = threading.Event()
+ self._do_cancel.clear()
+ self._thread = None
def start(self):
+ """
+ Start time setting thread if setting time is supported by the
+ connection. Stop the old thread first. May block until the old thread
+ terminates.
+ """
+ self.stop()
+
# Only run the API for qemu and test drivers, they are the only ones
# that support it. This will save spamming logs with error output.
if not self._domain.conn.is_qemu() and not self._domain.conn.is_test():
return
- if self._domain.conn.is_qemu():
- # For qemu, only run the API if the VM has the qemu guest agent in
- # the XML.
- if not self._domain.has_agent():
- return
+ # For qemu, only run the API if the VM has the qemu guest agent in
+ # the XML.
+ if self._domain.conn.is_qemu() and not self._domain.has_agent():
+ return
+
+ log.debug("Starting time setting thread")
+ self._thread = threading.Thread(name='settime thread',
+ target=self._do_loop)
+ self._thread.start()
+
+ def stop(self):
+ """
+ Signal running thread to terminate and wait for it to do so.
+ """
+ if not self._thread:
+ return
+
+ log.debug("Stopping time setting thread")
+ self._do_cancel.set()
+ # thread may be in a loop waiting for an agent to come online or just
+ # waiting for a set time operation to finish
+ self._thread.join()
+ self._thread = None
+ self._do_cancel.clear()
- # wait for agent to come online
+ def _do_loop(self):
+ """
+ Run the domain's set time operation. Potentially wait for a guest agent
+ to come online beforehand.
+ """
+ if self._domain.conn.is_qemu():
+ # Setting time of a qemu domain can only work if an agent is
+ # defined and online. We only get here if one is defined. So wait
+ # for it to come online now.
maxwait = 5
sleep = 0.5
- for _ in range(0, int(maxwait / sleep)):
- if self._domain.agent_ready():
- break
+ waited = 0
+ while waited < maxwait and not self._domain.agent_ready():
log.debug("Waiting for qemu guest agent to come online...")
- time.sleep(sleep)
- else:
- if not self._domain.agent_ready():
- log.debug("Giving up on qemu guest agent for time sync")
+
+ # sleep some time and potentially abort
+ if self._do_cancel.wait(sleep):
return
+ waited += sleep
+
+ if not self._domain.agent_ready():
+ log.debug("Giving up on qemu guest agent for time sync")
+ return
+
self._domain.set_time()
def _cleanup(self):
- pass
+ self.stop()
class vmmDomain(vmmLibvirtObject):