[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 09/30] block/curl: Handle failed reads gracefully.
From: |
Kevin Wolf |
Subject: |
[Qemu-devel] [PATCH 09/30] block/curl: Handle failed reads gracefully. |
Date: |
Mon, 29 Aug 2011 16:53:17 +0200 |
From: Nicholas Thomas <address@hidden>
Current behaviour if a read fails is for the acb to not get finished.
This causes an infinite loop in bdrv_read_em (block.c). The read failure
never gets reported to the guest and if the error condition clears, the
process never recovers.
With this patch, when curl reports a failure we finish the acb as a
failure. This results in the guest receiving an I/O error (rather than
the read hanging indefinitely) and if the error condition subsequently
clears, retries work as expected.
The simplest test is to put an ISO on a web server you have control over
and open it with qemu-io. Then move the ISO out of the way and attempt
to read some data - you should see behaviour matching the above.
Signed-off-by: Nick Thomas <address@hidden>
Signed-off-by: Kevin Wolf <address@hidden>
---
block/curl.c | 20 +++++++++++++++++++-
1 files changed, 19 insertions(+), 1 deletions(-)
diff --git a/block/curl.c b/block/curl.c
index 5c157bc..f3f61cc 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -229,6 +229,23 @@ static void curl_multi_do(void *arg)
{
CURLState *state = NULL;
curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE,
(char**)&state);
+
+ /* ACBs for successful messages get completed in curl_read_cb
*/
+ if (msg->data.result != CURLE_OK) {
+ int i;
+ for (i = 0; i < CURL_NUM_ACB; i++) {
+ CURLAIOCB *acb = state->acb[i];
+
+ if (acb == NULL) {
+ continue;
+ }
+
+ acb->common.cb(acb->common.opaque, -EIO);
+ qemu_aio_release(acb);
+ state->acb[i] = NULL;
+ }
+ }
+
curl_clean_state(state);
break;
}
@@ -277,7 +294,8 @@ static CURLState *curl_init_state(BDRVCURLState *s)
curl_easy_setopt(state->curl, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(state->curl, CURLOPT_NOSIGNAL, 1);
curl_easy_setopt(state->curl, CURLOPT_ERRORBUFFER, state->errmsg);
-
+ curl_easy_setopt(state->curl, CURLOPT_FAILONERROR, 1);
+
#ifdef DEBUG_VERBOSE
curl_easy_setopt(state->curl, CURLOPT_VERBOSE, 1);
#endif
--
1.7.6
- [Qemu-devel] [PULL 00/30] Block patches, Kevin Wolf, 2011/08/29
- [Qemu-devel] [PATCH 02/30] block: parse cache mode flags in a single place, Kevin Wolf, 2011/08/29
- [Qemu-devel] [PATCH 01/30] coroutine: Add CoRwlock support, Kevin Wolf, 2011/08/29
- [Qemu-devel] [PATCH 06/30] qcow2: fix typo in documentation for qcow2_get_cluster_offset(), Kevin Wolf, 2011/08/29
- [Qemu-devel] [PATCH 03/30] block: add cache=directsync parameter to -drive, Kevin Wolf, 2011/08/29
- [Qemu-devel] [PATCH 07/30] qcow: initialize coroutine mutex, Kevin Wolf, 2011/08/29
- [Qemu-devel] [PATCH 04/30] qcow2: Fix DEBUG_* compilation, Kevin Wolf, 2011/08/29
- [Qemu-devel] [PATCH 05/30] qemu-img: Use qemu_blockalign, Kevin Wolf, 2011/08/29
- [Qemu-devel] [PATCH 09/30] block/curl: Handle failed reads gracefully.,
Kevin Wolf <=
- [Qemu-devel] [PATCH 11/30] posix-aio-compat: fix latency issues, Kevin Wolf, 2011/08/29
- [Qemu-devel] [PATCH 10/30] block: include flush requests in info blockstats, Kevin Wolf, 2011/08/29
- [Qemu-devel] [PATCH 12/30] qcow/qcow2: Allocate QCowAIOCB structure using stack, Kevin Wolf, 2011/08/29
- [Qemu-devel] [PATCH 19/30] qcow2: remove l2meta from QCowAIOCB, Kevin Wolf, 2011/08/29
- [Qemu-devel] [PATCH 13/30] qcow: QCowAIOCB field cleanup, Kevin Wolf, 2011/08/29
- [Qemu-devel] [PATCH 08/30] qemu-img: print error codes when convert fails, Kevin Wolf, 2011/08/29
- [Qemu-devel] [PATCH 15/30] qcow: Remove QCowAIOCB, Kevin Wolf, 2011/08/29
- [Qemu-devel] [PATCH 14/30] qcow: move some blocks of code to avoid useless variable initialization, Kevin Wolf, 2011/08/29
- [Qemu-devel] [PATCH 20/30] qcow2: remove cluster_offset from QCowAIOCB, Kevin Wolf, 2011/08/29
- [Qemu-devel] [PATCH 21/30] qcow2: remove common from QCowAIOCB, Kevin Wolf, 2011/08/29