[PATCH 2/2] rpc: client: stream: notify streams of closing connection

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



It not done yet. As a result if we doing 'virsh console' and
libvirtd is killed we get [1] message as virsh tracks connection
status but virsh itself won't exit because it won't get notification
that stream is broken. Only after we press a key and virsh
tries to write that key code to stream we get an error. So
let's add notification that stream's underlying connection is closed.

[1] error: Disconnected from qemu:///system due to end of file

Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy@xxxxxxxxxxxxx>
---
 src/rpc/virnetclient.c       |  4 ++++
 src/rpc/virnetclientstream.c | 30 ++++++++++++++++++++++++++++--
 src/rpc/virnetclientstream.h |  2 ++
 3 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
index 0393587..3fa0320 100644
--- a/src/rpc/virnetclient.c
+++ b/src/rpc/virnetclient.c
@@ -785,6 +785,7 @@ static void
 virNetClientCloseLocked(virNetClientPtr client)
 {
     virKeepAlivePtr ka;
+    size_t i;
 
     VIR_DEBUG("client=%p, sock=%p, reason=%d", client, client->sock, client->closeReason);
 
@@ -825,6 +826,9 @@ virNetClientCloseLocked(virNetClientPtr client)
         virObjectLock(client);
         virObjectUnref(client);
     }
+
+    for (i = 0; i < client->nstreams; i++)
+        virNetClientStreamSetClientClosed(client->streams[i]);
 }
 
 static void virNetClientCloseInternal(virNetClientPtr client,
diff --git a/src/rpc/virnetclientstream.c b/src/rpc/virnetclientstream.c
index 834c448..de0c961 100644
--- a/src/rpc/virnetclientstream.c
+++ b/src/rpc/virnetclientstream.c
@@ -50,6 +50,7 @@ struct _virNetClientStream {
     virNetMessagePtr rx;
     bool incomingEOF;
     virNetClientStreamClosed closed;
+    bool clientClosed;
 
     bool allowSkip;
     long long holeLength;  /* Size of incoming hole in stream. */
@@ -85,7 +86,11 @@ virNetClientStreamEventTimerUpdate(virNetClientStreamPtr st)
 
     VIR_DEBUG("Check timer rx=%p cbEvents=%d", st->rx, st->cbEvents);
 
-    if (((st->rx || st->incomingEOF || st->err.code != VIR_ERR_OK || st->closed) &&
+    if (((st->rx ||
+          st->incomingEOF ||
+          st->err.code != VIR_ERR_OK ||
+          st->closed ||
+          st->clientClosed) &&
          (st->cbEvents & VIR_STREAM_EVENT_READABLE)) ||
         (st->cbEvents & VIR_STREAM_EVENT_WRITABLE)) {
         VIR_DEBUG("Enabling event timer");
@@ -107,7 +112,11 @@ virNetClientStreamEventTimer(int timer ATTRIBUTE_UNUSED, void *opaque)
 
     if (st->cb &&
         (st->cbEvents & VIR_STREAM_EVENT_READABLE) &&
-        (st->rx || st->incomingEOF || st->err.code != VIR_ERR_OK || st->closed))
+        (st->rx ||
+         st->incomingEOF ||
+         st->err.code != VIR_ERR_OK ||
+         st->closed ||
+         st->clientClosed))
         events |= VIR_STREAM_EVENT_READABLE;
     if (st->cb &&
         (st->cbEvents & VIR_STREAM_EVENT_WRITABLE))
@@ -204,6 +213,12 @@ int virNetClientStreamCheckState(virNetClientStreamPtr st)
         return -1;
     }
 
+    if (st->clientClosed) {
+        virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+                       _("client socket is closed"));
+        return -1;
+    }
+
     if (st->closed) {
         virReportError(VIR_ERR_OPERATION_FAILED, "%s",
                        _("stream is closed"));
@@ -247,6 +262,17 @@ int virNetClientStreamCheckSendStatus(virNetClientStreamPtr st,
 }
 
 
+void virNetClientStreamSetClientClosed(virNetClientStreamPtr st)
+{
+    virObjectLock(st);
+
+    st->clientClosed = true;
+    virNetClientStreamEventTimerUpdate(st);
+
+    virObjectUnlock(st);
+}
+
+
 void virNetClientStreamSetClosed(virNetClientStreamPtr st,
                                  virNetClientStreamClosed closed)
 {
diff --git a/src/rpc/virnetclientstream.h b/src/rpc/virnetclientstream.h
index 33a2af3..f1df4e2 100644
--- a/src/rpc/virnetclientstream.h
+++ b/src/rpc/virnetclientstream.h
@@ -49,6 +49,8 @@ int virNetClientStreamCheckSendStatus(virNetClientStreamPtr st,
 int virNetClientStreamSetError(virNetClientStreamPtr st,
                                virNetMessagePtr msg);
 
+void virNetClientStreamSetClientClosed(virNetClientStreamPtr st);
+
 void virNetClientStreamSetClosed(virNetClientStreamPtr st,
                                  virNetClientStreamClosed closed);
 
-- 
1.8.3.1


[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux