From patchwork Wed Jan 15 17:23:58 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 23241 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-vb0-f72.google.com (mail-vb0-f72.google.com [209.85.212.72]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 381D4202DA for ; Wed, 15 Jan 2014 17:24:04 +0000 (UTC) Received: by mail-vb0-f72.google.com with SMTP id x8sf2073591vbf.11 for ; Wed, 15 Jan 2014 09:24:03 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:x-original-sender:x-original-authentication-results :precedence:mailing-list:list-id:list-post:list-help:list-archive :list-unsubscribe; bh=EbAkj9vxoQIgqC7Nrppn7hojCziCKPJiqsIwa6WSgCE=; b=SQCfKlADQGmh/7ApWqw3TMBHobj5XSYM2kKbjJHPKaqtzykaX6fAYa5joqkr7hbeAw PmPYhUKJ+ZY9Bvl0wZrqbwYJGUiI7gK4VmaYP2XeDFszDM558hotuH9Xe92mUJj1lTuI 3clq+vDfZ/QDDHgOBzTbxIlTz+rG119CrPU/URnzLpiW96dsl/dnEANjxSwLnqXXC7zd 3rvlz/RJE0PbWtih/1S3did+o4IgCZj10qVjjmQDuvoFL7jLDA8bNHafJm1o4WJku9fX QeRZvQl2vWURJ8+iuL4XMKLJQS1LQVDRPGhLUjXa4N/lZ9Aid/BowXeFR/lCO2F5cMbe rbzA== X-Gm-Message-State: ALoCoQldSfF2nJCPGxhErnJM/Cqga76DFgwmtUE9Vz66h1Xp7PmN7JxTY7Z8sqSItjLmjLai2XWg X-Received: by 10.236.26.83 with SMTP id b59mr998443yha.51.1389806643389; Wed, 15 Jan 2014 09:24:03 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.34.76 with SMTP id k70ls10390qgk.30.gmail; Wed, 15 Jan 2014 09:24:03 -0800 (PST) X-Received: by 10.53.5.230 with SMTP id cp6mr1349288vdd.65.1389806643253; Wed, 15 Jan 2014 09:24:03 -0800 (PST) Received: from mail-vb0-f49.google.com (mail-vb0-f49.google.com [209.85.212.49]) by mx.google.com with ESMTPS id w5si1963771vcn.26.2014.01.15.09.24.03 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 15 Jan 2014 09:24:03 -0800 (PST) Received-SPF: neutral (google.com: 209.85.212.49 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.212.49; Received: by mail-vb0-f49.google.com with SMTP id x14so515012vbb.36 for ; Wed, 15 Jan 2014 09:24:03 -0800 (PST) X-Received: by 10.58.85.133 with SMTP id h5mr2739483vez.4.1389806642283; Wed, 15 Jan 2014 09:24:02 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.59.13.131 with SMTP id ey3csp289944ved; Wed, 15 Jan 2014 09:24:01 -0800 (PST) X-Received: by 10.194.216.68 with SMTP id oo4mr3270042wjc.79.1389806641155; Wed, 15 Jan 2014 09:24:01 -0800 (PST) Received: from mnementh.archaic.org.uk (mnementh.archaic.org.uk. [2001:8b0:1d0::1]) by mx.google.com with ESMTPS id u9si6941402wib.84.2014.01.15.09.24.00 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Wed, 15 Jan 2014 09:24:01 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::1 as permitted sender) client-ip=2001:8b0:1d0::1; Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.80) (envelope-from ) id 1W3UC6-0000oi-V6; Wed, 15 Jan 2014 17:23:58 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Cc: patches@linaro.org, Kevin Wolf , Stefan Hajnoczi , qemu-stable@nongnu.org Subject: [PATCH] block/curl: Implement the libcurl timer callback interface Date: Wed, 15 Jan 2014 17:23:58 +0000 Message-Id: <1389806638-3114-1-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.10.4 X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: peter.maydell@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.212.49 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , libcurl versions 7.16.0 and later have a timer callback interface which must be implemented in order for libcurl to make forward progress (it will sometimes rely on being called back on the timeout if there are no file descriptors registered). Implement the callback, and use a QEMU AIO timer to ensure we prod libcurl again when it asks us to. Signed-off-by: Peter Maydell --- This fixes the problem I was seeing where trying to use the curl block backend just hung. I'm not sure whether all libcurl versions that provide the timer callback API require its use, but it shouldn't hurt. This is probably a candidate for stable if it passes code review. block/curl.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/block/curl.c b/block/curl.c index a603936..3c4c5fc 100644 --- a/block/curl.c +++ b/block/curl.c @@ -34,6 +34,11 @@ #define DPRINTF(fmt, ...) do { } while (0) #endif +#if LIBCURL_VERSION_NUM >= 0x071000 +/* The multi interface timer callback was introduced in 7.16.0 */ +#define NEED_CURL_TIMER_CALLBACK +#endif + #define PROTOCOLS (CURLPROTO_HTTP | CURLPROTO_HTTPS | \ CURLPROTO_FTP | CURLPROTO_FTPS | \ CURLPROTO_TFTP) @@ -77,6 +82,7 @@ typedef struct CURLState typedef struct BDRVCURLState { CURLM *multi; + QEMUTimer timer; size_t len; CURLState states[CURL_NUM_STATES]; char *url; @@ -87,6 +93,23 @@ typedef struct BDRVCURLState { static void curl_clean_state(CURLState *s); static void curl_multi_do(void *arg); +#ifdef NEED_CURL_TIMER_CALLBACK +static int curl_timer_cb(CURLM *multi, long timeout_ms, void *opaque) +{ + BDRVCURLState *s = opaque; + + DPRINTF("CURL: timer callback timeout_ms %ld\n", timeout_ms); + if (timeout_ms == -1) { + timer_del(&s->timer); + } else { + int64_t timeout_ns = (int64_t)timeout_ms * 1000 * 1000; + timer_mod(&s->timer, + qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + timeout_ns); + } + return 0; +} +#endif + static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action, void *s, void *sp) { @@ -473,12 +496,20 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags, curl_easy_cleanup(state->curl); state->curl = NULL; + aio_timer_init(bdrv_get_aio_context(bs), &s->timer, + QEMU_CLOCK_REALTIME, SCALE_NS, + curl_multi_do, s); + // Now we know the file exists and its size, so let's // initialize the multi interface! s->multi = curl_multi_init(); curl_multi_setopt(s->multi, CURLMOPT_SOCKETDATA, s); curl_multi_setopt(s->multi, CURLMOPT_SOCKETFUNCTION, curl_sock_cb); +#ifdef NEED_CURL_TIMER_CALLBACK + curl_multi_setopt(s->multi, CURLMOPT_TIMERDATA, s); + curl_multi_setopt(s->multi, CURLMOPT_TIMERFUNCTION, curl_timer_cb); +#endif curl_multi_do(s); qemu_opts_del(opts); @@ -597,6 +628,9 @@ static void curl_close(BlockDriverState *bs) } if (s->multi) curl_multi_cleanup(s->multi); + + timer_del(&s->timer); + g_free(s->url); }