From a5481546d66f8972fc7ee6dc6938a63509664af9 Mon Sep 17 00:00:00 2001 From: Cole Robinson Date: Mon, 25 Apr 2016 14:00:58 -0400 Subject: [PATCH] fdstream: don't raise error on SIGPIPE if abort requested 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(-) diff --git a/src/fdstream.c b/src/fdstream.c index a019af6429..3e92577c79 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 cleanup; } + out: ret = 0; cleanup: 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)