From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:50273) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Qy3Av-000818-LZ for qemu-devel@nongnu.org; Mon, 29 Aug 2011 10:50:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Qy3At-0000Xl-U7 for qemu-devel@nongnu.org; Mon, 29 Aug 2011 10:50:57 -0400 Received: from mx1.redhat.com ([209.132.183.28]:23815) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Qy3At-0000Xc-G3 for qemu-devel@nongnu.org; Mon, 29 Aug 2011 10:50:55 -0400 From: Kevin Wolf Date: Mon, 29 Aug 2011 16:53:17 +0200 Message-Id: <1314629618-8308-10-git-send-email-kwolf@redhat.com> In-Reply-To: <1314629618-8308-1-git-send-email-kwolf@redhat.com> References: <1314629618-8308-1-git-send-email-kwolf@redhat.com> Subject: [Qemu-devel] [PATCH 09/30] block/curl: Handle failed reads gracefully. List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: anthony@codemonkey.ws Cc: kwolf@redhat.com, qemu-devel@nongnu.org From: Nicholas Thomas 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 Signed-off-by: Kevin Wolf --- 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