|
|
4ec855 |
From 23f5a846f6702c456cf7cc9490e50cfd23368910 Mon Sep 17 00:00:00 2001
|
|
|
4ec855 |
From: Max Reitz <mreitz@redhat.com>
|
|
|
4ec855 |
Date: Tue, 19 Nov 2019 15:29:59 +0000
|
|
|
4ec855 |
Subject: [PATCH 7/8] curl: Handle success in multi_check_completion
|
|
|
4ec855 |
MIME-Version: 1.0
|
|
|
4ec855 |
Content-Type: text/plain; charset=UTF-8
|
|
|
4ec855 |
Content-Transfer-Encoding: 8bit
|
|
|
4ec855 |
|
|
|
4ec855 |
RH-Author: Max Reitz <mreitz@redhat.com>
|
|
|
4ec855 |
Message-id: <20191119153000.101646-7-mreitz@redhat.com>
|
|
|
4ec855 |
Patchwork-id: 92520
|
|
|
4ec855 |
O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 6/7] curl: Handle success in multi_check_completion
|
|
|
4ec855 |
Bugzilla: 1744602
|
|
|
4ec855 |
RH-Acked-by: Maxim Levitsky <mlevitsk@redhat.com>
|
|
|
4ec855 |
RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
|
|
4ec855 |
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
|
|
|
4ec855 |
|
|
|
4ec855 |
Background: As of cURL 7.59.0, it verifies that several functions are
|
|
|
4ec855 |
not called from within a callback. Among these functions is
|
|
|
4ec855 |
curl_multi_add_handle().
|
|
|
4ec855 |
|
|
|
4ec855 |
curl_read_cb() is a callback from cURL and not a coroutine. Waking up
|
|
|
4ec855 |
acb->co will lead to entering it then and there, which means the current
|
|
|
4ec855 |
request will settle and the caller (if it runs in the same coroutine)
|
|
|
4ec855 |
may then issue the next request. In such a case, we will enter
|
|
|
4ec855 |
curl_setup_preadv() effectively from within curl_read_cb().
|
|
|
4ec855 |
|
|
|
4ec855 |
Calling curl_multi_add_handle() will then fail and the new request will
|
|
|
4ec855 |
not be processed.
|
|
|
4ec855 |
|
|
|
4ec855 |
Fix this by not letting curl_read_cb() wake up acb->co. Instead, leave
|
|
|
4ec855 |
the whole business of settling the AIOCB objects to
|
|
|
4ec855 |
curl_multi_check_completion() (which is called from our timer callback
|
|
|
4ec855 |
and our FD handler, so not from any cURL callbacks).
|
|
|
4ec855 |
|
|
|
4ec855 |
Reported-by: Natalie Gavrielov <ngavrilo@redhat.com>
|
|
|
4ec855 |
Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1740193
|
|
|
4ec855 |
Cc: qemu-stable@nongnu.org
|
|
|
4ec855 |
Signed-off-by: Max Reitz <mreitz@redhat.com>
|
|
|
4ec855 |
Message-id: 20190910124136.10565-7-mreitz@redhat.com
|
|
|
4ec855 |
Reviewed-by: John Snow <jsnow@redhat.com>
|
|
|
4ec855 |
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
|
|
|
4ec855 |
Signed-off-by: Max Reitz <mreitz@redhat.com>
|
|
|
4ec855 |
(cherry picked from commit bfb23b480a49114315877aacf700b49453e0f9d9)
|
|
|
4ec855 |
Signed-off-by: Max Reitz <mreitz@redhat.com>
|
|
|
4ec855 |
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
|
|
|
4ec855 |
---
|
|
|
4ec855 |
block/curl.c | 69 +++++++++++++++++++++++++-----------------------------------
|
|
|
4ec855 |
1 file changed, 29 insertions(+), 40 deletions(-)
|
|
|
4ec855 |
|
|
|
4ec855 |
diff --git a/block/curl.c b/block/curl.c
|
|
|
4ec855 |
index f776615..b5899e1 100644
|
|
|
4ec855 |
--- a/block/curl.c
|
|
|
4ec855 |
+++ b/block/curl.c
|
|
|
4ec855 |
@@ -238,7 +238,6 @@ static size_t curl_read_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
|
|
|
4ec855 |
{
|
|
|
4ec855 |
CURLState *s = ((CURLState*)opaque);
|
|
|
4ec855 |
size_t realsize = size * nmemb;
|
|
|
4ec855 |
- int i;
|
|
|
4ec855 |
|
|
|
4ec855 |
DPRINTF("CURL: Just reading %zd bytes\n", realsize);
|
|
|
4ec855 |
|
|
|
4ec855 |
@@ -254,32 +253,6 @@ static size_t curl_read_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
|
|
|
4ec855 |
memcpy(s->orig_buf + s->buf_off, ptr, realsize);
|
|
|
4ec855 |
s->buf_off += realsize;
|
|
|
4ec855 |
|
|
|
4ec855 |
- for(i=0; i
|
|
|
4ec855 |
- CURLAIOCB *acb = s->acb[i];
|
|
|
4ec855 |
-
|
|
|
4ec855 |
- if (!acb)
|
|
|
4ec855 |
- continue;
|
|
|
4ec855 |
-
|
|
|
4ec855 |
- if ((s->buf_off >= acb->end)) {
|
|
|
4ec855 |
- size_t request_length = acb->bytes;
|
|
|
4ec855 |
-
|
|
|
4ec855 |
- qemu_iovec_from_buf(acb->qiov, 0, s->orig_buf + acb->start,
|
|
|
4ec855 |
- acb->end - acb->start);
|
|
|
4ec855 |
-
|
|
|
4ec855 |
- if (acb->end - acb->start < request_length) {
|
|
|
4ec855 |
- size_t offset = acb->end - acb->start;
|
|
|
4ec855 |
- qemu_iovec_memset(acb->qiov, offset, 0,
|
|
|
4ec855 |
- request_length - offset);
|
|
|
4ec855 |
- }
|
|
|
4ec855 |
-
|
|
|
4ec855 |
- acb->ret = 0;
|
|
|
4ec855 |
- s->acb[i] = NULL;
|
|
|
4ec855 |
- qemu_mutex_unlock(&s->s->mutex);
|
|
|
4ec855 |
- aio_co_wake(acb->co);
|
|
|
4ec855 |
- qemu_mutex_lock(&s->s->mutex);
|
|
|
4ec855 |
- }
|
|
|
4ec855 |
- }
|
|
|
4ec855 |
-
|
|
|
4ec855 |
read_end:
|
|
|
4ec855 |
/* curl will error out if we do not return this value */
|
|
|
4ec855 |
return size * nmemb;
|
|
|
4ec855 |
@@ -360,13 +333,14 @@ static void curl_multi_check_completion(BDRVCURLState *s)
|
|
|
4ec855 |
break;
|
|
|
4ec855 |
|
|
|
4ec855 |
if (msg->msg == CURLMSG_DONE) {
|
|
|
4ec855 |
+ int i;
|
|
|
4ec855 |
CURLState *state = NULL;
|
|
|
4ec855 |
+ bool error = msg->data.result != CURLE_OK;
|
|
|
4ec855 |
+
|
|
|
4ec855 |
curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE,
|
|
|
4ec855 |
(char **)&state);
|
|
|
4ec855 |
|
|
|
4ec855 |
- /* ACBs for successful messages get completed in curl_read_cb */
|
|
|
4ec855 |
- if (msg->data.result != CURLE_OK) {
|
|
|
4ec855 |
- int i;
|
|
|
4ec855 |
+ if (error) {
|
|
|
4ec855 |
static int errcount = 100;
|
|
|
4ec855 |
|
|
|
4ec855 |
/* Don't lose the original error message from curl, since
|
|
|
4ec855 |
@@ -378,20 +352,35 @@ static void curl_multi_check_completion(BDRVCURLState *s)
|
|
|
4ec855 |
error_report("curl: further errors suppressed");
|
|
|
4ec855 |
}
|
|
|
4ec855 |
}
|
|
|
4ec855 |
+ }
|
|
|
4ec855 |
|
|
|
4ec855 |
- for (i = 0; i < CURL_NUM_ACB; i++) {
|
|
|
4ec855 |
- CURLAIOCB *acb = state->acb[i];
|
|
|
4ec855 |
+ for (i = 0; i < CURL_NUM_ACB; i++) {
|
|
|
4ec855 |
+ CURLAIOCB *acb = state->acb[i];
|
|
|
4ec855 |
|
|
|
4ec855 |
- if (acb == NULL) {
|
|
|
4ec855 |
- continue;
|
|
|
4ec855 |
- }
|
|
|
4ec855 |
+ if (acb == NULL) {
|
|
|
4ec855 |
+ continue;
|
|
|
4ec855 |
+ }
|
|
|
4ec855 |
+
|
|
|
4ec855 |
+ if (!error) {
|
|
|
4ec855 |
+ /* Assert that we have read all data */
|
|
|
4ec855 |
+ assert(state->buf_off >= acb->end);
|
|
|
4ec855 |
+
|
|
|
4ec855 |
+ qemu_iovec_from_buf(acb->qiov, 0,
|
|
|
4ec855 |
+ state->orig_buf + acb->start,
|
|
|
4ec855 |
+ acb->end - acb->start);
|
|
|
4ec855 |
|
|
|
4ec855 |
- acb->ret = -EIO;
|
|
|
4ec855 |
- state->acb[i] = NULL;
|
|
|
4ec855 |
- qemu_mutex_unlock(&s->mutex);
|
|
|
4ec855 |
- aio_co_wake(acb->co);
|
|
|
4ec855 |
- qemu_mutex_lock(&s->mutex);
|
|
|
4ec855 |
+ if (acb->end - acb->start < acb->bytes) {
|
|
|
4ec855 |
+ size_t offset = acb->end - acb->start;
|
|
|
4ec855 |
+ qemu_iovec_memset(acb->qiov, offset, 0,
|
|
|
4ec855 |
+ acb->bytes - offset);
|
|
|
4ec855 |
+ }
|
|
|
4ec855 |
}
|
|
|
4ec855 |
+
|
|
|
4ec855 |
+ acb->ret = error ? -EIO : 0;
|
|
|
4ec855 |
+ state->acb[i] = NULL;
|
|
|
4ec855 |
+ qemu_mutex_unlock(&s->mutex);
|
|
|
4ec855 |
+ aio_co_wake(acb->co);
|
|
|
4ec855 |
+ qemu_mutex_lock(&s->mutex);
|
|
|
4ec855 |
}
|
|
|
4ec855 |
|
|
|
4ec855 |
curl_clean_state(state);
|
|
|
4ec855 |
--
|
|
|
4ec855 |
1.8.3.1
|
|
|
4ec855 |
|