[PATCH 2/3] python/qemu: Kill QEMU process if 'quit' doesn't work

Kevin Wolf posted 3 patches 5 years, 11 months ago
Maintainers: Cleber Rosa <crosa@redhat.com>, Kevin Wolf <kwolf@redhat.com>, Max Reitz <mreitz@redhat.com>, Eduardo Habkost <ehabkost@redhat.com>
[PATCH 2/3] python/qemu: Kill QEMU process if 'quit' doesn't work
Posted by Kevin Wolf 5 years, 11 months ago
With a QEMU bug, it can happen that the QEMU process doesn't react to a
'quit' QMP command. If we got an exception during previous QMP
communication (e.g. iotests Timeout expiring), we could also be in an
inconsistent state where after sending 'quit' we immediately read an old
response and close the socket even though the 'quit' command wasn't
processed yet. Both cases would lead to a hanging test.

Fix this by waiting for the QEMU process to exit after sending 'quit'
with a timeout, and if it doesn't happen within three seconds, send
SIGKILL.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 python/qemu/machine.py | 1 +
 1 file changed, 1 insertion(+)

diff --git a/python/qemu/machine.py b/python/qemu/machine.py
index 183d8f3d38..c837ee8723 100644
--- a/python/qemu/machine.py
+++ b/python/qemu/machine.py
@@ -358,6 +358,7 @@ class QEMUMachine(object):
                     if not has_quit:
                         self._qmp.cmd('quit')
                     self._qmp.close()
+                    self._popen.wait(timeout=3)
                 except:
                     self._popen.kill()
             self._popen.wait()
-- 
2.20.1


Re: [PATCH 2/3] python/qemu: Kill QEMU process if 'quit' doesn't work
Posted by Philippe Mathieu-Daudé 5 years, 10 months ago
On 3/13/20 9:36 AM, Kevin Wolf wrote:
> With a QEMU bug, it can happen that the QEMU process doesn't react to a
> 'quit' QMP command. If we got an exception during previous QMP
> communication (e.g. iotests Timeout expiring), we could also be in an
> inconsistent state where after sending 'quit' we immediately read an old
> response and close the socket even though the 'quit' command wasn't
> processed yet. Both cases would lead to a hanging test.
> 
> Fix this by waiting for the QEMU process to exit after sending 'quit'
> with a timeout, and if it doesn't happen within three seconds, send
> SIGKILL.
> 
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> ---
>   python/qemu/machine.py | 1 +
>   1 file changed, 1 insertion(+)
> 
> diff --git a/python/qemu/machine.py b/python/qemu/machine.py
> index 183d8f3d38..c837ee8723 100644
> --- a/python/qemu/machine.py
> +++ b/python/qemu/machine.py
> @@ -358,6 +358,7 @@ class QEMUMachine(object):
>                       if not has_quit:
>                           self._qmp.cmd('quit')
>                       self._qmp.close()
> +                    self._popen.wait(timeout=3)
>                   except:
>                       self._popen.kill()
>               self._popen.wait()
> 

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>


Re: [PATCH 2/3] python/qemu: Kill QEMU process if 'quit' doesn't work
Posted by John Snow 5 years, 10 months ago

On 3/13/20 4:36 AM, Kevin Wolf wrote:
> With a QEMU bug, it can happen that the QEMU process doesn't react to a
> 'quit' QMP command. If we got an exception during previous QMP
> communication (e.g. iotests Timeout expiring), we could also be in an
> inconsistent state where after sending 'quit' we immediately read an old
> response and close the socket even though the 'quit' command wasn't
> processed yet. Both cases would lead to a hanging test.
> 
> Fix this by waiting for the QEMU process to exit after sending 'quit'
> with a timeout, and if it doesn't happen within three seconds, send
> SIGKILL.
> 
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>

Reviewed-by: John Snow <jsnow@redhat.com>

> ---
>  python/qemu/machine.py | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/python/qemu/machine.py b/python/qemu/machine.py
> index 183d8f3d38..c837ee8723 100644
> --- a/python/qemu/machine.py
> +++ b/python/qemu/machine.py
> @@ -358,6 +358,7 @@ class QEMUMachine(object):
>                      if not has_quit:
>                          self._qmp.cmd('quit')
>                      self._qmp.close()
> +                    self._popen.wait(timeout=3)
>                  except:
>                      self._popen.kill()
>              self._popen.wait()
> 

-- 
—js