|
|
f87237 |
commit 164c03d33bd9d58844921888560baf3f156a1f05
|
|
|
f87237 |
Author: Christophe Fergeau <cfergeau@redhat.com>
|
|
|
f87237 |
Date: Mon Sep 10 12:17:07 2012 +0200
|
|
|
f87237 |
|
|
|
f87237 |
Fix unwanted closing of libvirt client connection
|
|
|
f87237 |
|
|
|
f87237 |
e5a1bee07 introduced a regression in Boxes: when Boxes is left idle
|
|
|
f87237 |
(it's still doing some libvirt calls in the background), the
|
|
|
f87237 |
libvirt connection gets closed after a few minutes. What happens is
|
|
|
f87237 |
that this code in virNetClientIOHandleOutput gets triggered:
|
|
|
f87237 |
|
|
|
f87237 |
if (!thecall)
|
|
|
f87237 |
return -1; /* Shouldn't happen, but you never know... */
|
|
|
f87237 |
|
|
|
f87237 |
and after the changes in e5a1bee07, this causes the libvirt connection
|
|
|
f87237 |
to be closed.
|
|
|
f87237 |
|
|
|
f87237 |
Upon further investigation, what happens is that
|
|
|
f87237 |
virNetClientIOHandleOutput is called from gvir_event_handle_dispatch
|
|
|
f87237 |
in libvirt-glib, which is triggered because the client fd became
|
|
|
f87237 |
writable. However, between the times gvir_event_handle_dispatch
|
|
|
f87237 |
is called, and the time the client lock is grabbed and
|
|
|
f87237 |
virNetClientIOHandleOutput is called, another thread runs and
|
|
|
f87237 |
completes the current call. 'thecall' is then NULL when the first
|
|
|
f87237 |
thread gets to run virNetClientIOHandleOutput.
|
|
|
f87237 |
|
|
|
f87237 |
After describing this situation on IRC, danpb suggested this:
|
|
|
f87237 |
|
|
|
f87237 |
11:37 < danpb> In that case I think the correct thing would be to change
|
|
|
f87237 |
'return -1' above to 'return 0' since that's not actually an
|
|
|
f87237 |
error - its a rare, but expected event
|
|
|
f87237 |
|
|
|
f87237 |
which is what this patch is doing. I've tested it against master
|
|
|
f87237 |
libvirt, and I didn't get disconnected in ~10 minutes while this
|
|
|
f87237 |
happens in less than 5 minutes without this patch.
|
|
|
f87237 |
|
|
|
f87237 |
diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
|
|
|
f87237 |
index 43a9814..727ed67 100644
|
|
|
f87237 |
--- a/src/rpc/virnetclient.c
|
|
|
f87237 |
+++ b/src/rpc/virnetclient.c
|
|
|
f87237 |
@@ -1205,7 +1205,10 @@ virNetClientIOHandleOutput(virNetClientPtr client)
|
|
|
f87237 |
thecall = thecall->next;
|
|
|
f87237 |
|
|
|
f87237 |
if (!thecall)
|
|
|
f87237 |
- return -1; /* Shouldn't happen, but you never know... */
|
|
|
f87237 |
+ return 0; /* This can happen if another thread raced with us and
|
|
|
f87237 |
+ * completed the call between the time this thread woke
|
|
|
f87237 |
+ * up from poll()ing and the time we locked the client
|
|
|
f87237 |
+ */
|
|
|
f87237 |
|
|
|
f87237 |
while (thecall) {
|
|
|
f87237 |
ssize_t ret = virNetClientIOWriteMessage(client, thecall);
|