When the I/O thread quits (e.g. due to an I/O error, lseek()
error, whatever), any subsequent virFDStream API should return
error too. Moreover, when invoking stream event callback, we must
set the VIR_STREAM_EVENT_ERROR flag so that the callback knows
something bad happened.

Signed-off-by: Michal Privoznik <mpriv...@redhat.com>
---
 src/util/virfdstream.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/src/util/virfdstream.c b/src/util/virfdstream.c
index 7ee58be13..cd24757e6 100644
--- a/src/util/virfdstream.c
+++ b/src/util/virfdstream.c
@@ -312,6 +312,9 @@ static void virFDStreamEvent(int watch ATTRIBUTE_UNUSED,
         return;
     }
 
+    if (fdst->threadErr)
+        events |= VIR_STREAM_EVENT_ERROR;
+
     cb = fdst->cb;
     cbopaque = fdst->opaque;
     ff = fdst->ff;
@@ -787,10 +790,10 @@ static int virFDStreamWrite(virStreamPtr st, const char 
*bytes, size_t nbytes)
     if (fdst->thread) {
         char *buf;
 
-        if (fdst->threadQuit) {
+        if (fdst->threadQuit || fdst->threadErr) {
             virReportSystemError(EBADF, "%s",
                                  _("cannot write to stream"));
-            return -1;
+            goto cleanup;
         }
 
         if (VIR_ALLOC(msg) < 0 ||
@@ -866,7 +869,7 @@ static int virFDStreamRead(virStreamPtr st, char *bytes, 
size_t nbytes)
         virFDStreamMsgPtr msg = NULL;
 
         while (!(msg = fdst->msg)) {
-            if (fdst->threadQuit) {
+            if (fdst->threadQuit || fdst->threadErr) {
                 if (nbytes) {
                     virReportSystemError(EBADF, "%s",
                                          _("stream is not open"));
@@ -959,6 +962,9 @@ virFDStreamSendHole(virStreamPtr st,
         fdst->offset += length;
     }
 
+    if (fdst->threadErr)
+        goto cleanup;
+
     if (fdst->thread) {
         /* Things are a bit complicated here. If FDStream is in a
          * read mode, then if the message at the queue head is
@@ -1018,6 +1024,9 @@ virFDStreamInData(virStreamPtr st,
 
     virObjectLock(fdst);
 
+    if (fdst->threadErr)
+        goto cleanup;
+
     if (fdst->thread) {
         virFDStreamMsgPtr msg;
 
-- 
2.13.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to