daemonStreamEvent() holds priv->lock across its whole body and closes
the client from every error path. The close hook runs in the same
thread and takes priv->lock again, so the daemon main loop deadlocks
against itself and the host stops answering RPC entirely while its
guests keep running. Only a restart of the daemon recovers.

We hit this in the field on 9.5.0, and current master is affected the
same way. Getting there needs a client already marked wantClose while
one of its streams still delivers events, which is presumably why it
has gone unnoticed since 9.2.0.

Patch 1 closes the client after the lock guard has gone out of scope.
Patch 2 adds a test for it, which needs remote_daemon_stream.c compiled
into a test binary; that is the only build change and it pulls in the
generated protocol headers via remote_daemon.h. The test deadlocks
without patch 1 and passes with it.

Signed-off-by: Denis V. Lunev <[email protected]>

Denis V. Lunev (2):
  remote: fix daemon deadlock when a stream event closes its client
  tests: add daemonstreamtest covering the stream close deadlock

 src/remote/meson.build            |   7 +-
 src/remote/remote_daemon_stream.c |  58 ++++----
 tests/daemonstreamtest.c          | 212 ++++++++++++++++++++++++++++++
 tests/meson.build                 |   9 ++
 4 files changed, 262 insertions(+), 24 deletions(-)
 create mode 100644 tests/daemonstreamtest.c


base-commit: 91d4618734bd6d02174b909aadb7d84a99560ebe
-- 
2.53.0

Reply via email to