diff mbox

[9/9] fdstream: don't raise error on SIGPIPE if abort requested

Message ID 91d2625c622a066d9b48dd0fbe2b399dee354c2d.1461609759.git.crobinso@redhat.com
State Accepted
Commit a5481546d66f8972fc7ee6dc6938a63509664af9
Headers show

Commit Message

Cole Robinson April 25, 2016, 6:46 p.m. UTC
The iohelper dies on SIGPIPE if the stream is closed before all data
is processed. IMO this should be an error condition for virStreamFinish
according to docs like:

  * This method is a synchronization point for all asynchronous
  * errors, so if this returns a success code the application can
  * be sure that all data has been successfully processed.

However for virStreamAbort, not so much:

  * Request that the in progress data transfer be cancelled
  * abnormally before the end of the stream has been reached.
  * For output streams this can be used to inform the driver
  * that the stream is being terminated early. For input
  * streams this can be used to inform the driver that it
  * should stop sending data.

Without this, virStreamAbort will realistically always error for
active streams like domain console. So, treat the SIGPIPE case
as non-fatal if abort is requested.

Note, this will only affect an explicit user requested abort. An
abnormal abort, like from a server error, always raises an error
in the daemon.
---
 src/fdstream.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

-- 
2.7.3

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

Patch

diff --git a/src/fdstream.c b/src/fdstream.c
index 155311a..f22107c 100644
--- a/src/fdstream.c
+++ b/src/fdstream.c
@@ -242,7 +242,7 @@  virFDStreamAddCallback(virStreamPtr st,
 }
 
 static int
-virFDStreamCloseCommand(struct virFDStreamData *fdst)
+virFDStreamCloseCommand(struct virFDStreamData *fdst, bool streamAbort)
 {
     char buf[1024];
     ssize_t len;
@@ -265,6 +265,12 @@  virFDStreamCloseCommand(struct virFDStreamData *fdst)
         if (buf[0] != '\0') {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s", buf);
         } else if (WIFSIGNALED(status) && WTERMSIG(status) == SIGPIPE) {
+            if (streamAbort) {
+                /* Explicit abort request means the caller doesn't care
+                   if there's data left over, so skip the error */
+                goto out;
+            }
+
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("I/O helper exited "
                              "before all data was processed"));
@@ -278,6 +284,7 @@  virFDStreamCloseCommand(struct virFDStreamData *fdst)
         goto error;
     }
 
+ out:
     ret = 0;
  error:
     virCommandFree(fdst->cmd);
@@ -329,7 +336,7 @@  virFDStreamCloseInt(virStreamPtr st, bool streamAbort)
 
     /* mutex locked */
     ret = VIR_CLOSE(fdst->fd);
-    if (virFDStreamCloseCommand(fdst) < 0)
+    if (virFDStreamCloseCommand(fdst, streamAbort) < 0)
         ret = -1;
 
     if (VIR_CLOSE(fdst->errfd) < 0)