From patchwork Fri Apr 12 20:48:01 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 236196 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id A77342C00AA for ; Sat, 13 Apr 2013 06:49:20 +1000 (EST) Received: from localhost ([::1]:59298 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UQkuM-0002df-Sr for incoming@patchwork.ozlabs.org; Fri, 12 Apr 2013 16:49:18 -0400 Received: from eggs.gnu.org ([208.118.235.92]:57513) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UQkte-0002Ij-DC for qemu-devel@nongnu.org; Fri, 12 Apr 2013 16:48:39 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UQktZ-0004mA-D5 for qemu-devel@nongnu.org; Fri, 12 Apr 2013 16:48:34 -0400 Received: from mx1.redhat.com ([209.132.183.28]:20998) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UQktZ-0004lp-6A for qemu-devel@nongnu.org; Fri, 12 Apr 2013 16:48:29 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r3CKmSIp002797 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 12 Apr 2013 16:48:28 -0400 Received: from dhcp-200-207.str.redhat.com (ovpn-116-52.ams2.redhat.com [10.36.116.52]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r3CKmCIx009994; Fri, 12 Apr 2013 16:48:27 -0400 From: Kevin Wolf To: qemu-devel@nongnu.org Date: Fri, 12 Apr 2013 22:48:01 +0200 Message-Id: <1365799688-19918-9-git-send-email-kwolf@redhat.com> In-Reply-To: <1365799688-19918-1-git-send-email-kwolf@redhat.com> References: <1365799688-19918-1-git-send-email-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: kwolf@redhat.com, stefanha@redhat.com Subject: [Qemu-devel] [PATCH 08/15] curl: Use bdrv_open options instead of filename X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Signed-off-by: Kevin Wolf Reviewed-by: Eric Blake --- block/curl.c | 153 +++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 102 insertions(+), 51 deletions(-) diff --git a/block/curl.c b/block/curl.c index 186e3b0..61bc3db 100644 --- a/block/curl.c +++ b/block/curl.c @@ -335,12 +335,9 @@ static void curl_clean_state(CURLState *s) s->in_use = 0; } -static int curl_open(BlockDriverState *bs, const char *filename, - QDict *options, int flags) +static void curl_parse_filename(const char *filename, QDict *options, + Error **errp) { - BDRVCURLState *s = bs->opaque; - CURLState *state = NULL; - double d; #define RA_OPTSTR ":readahead=" char *file; @@ -348,19 +345,17 @@ static int curl_open(BlockDriverState *bs, const char *filename, const char *ra_val; int parse_state = 0; - static int inited = 0; - file = g_strdup(filename); - s->readahead_size = READ_AHEAD_SIZE; /* Parse a trailing ":readahead=#:" param, if present. */ ra = file + strlen(file) - 1; while (ra >= file) { if (parse_state == 0) { - if (*ra == ':') + if (*ra == ':') { parse_state++; - else + } else { break; + } } else if (parse_state == 1) { if (*ra > '9' || *ra < '0') { char *opt_start = ra - strlen(RA_OPTSTR) + 1; @@ -369,29 +364,78 @@ static int curl_open(BlockDriverState *bs, const char *filename, ra_val = ra + 1; ra -= strlen(RA_OPTSTR) - 1; *ra = '\0'; - s->readahead_size = atoi(ra_val); - break; - } else { - break; + qdict_put(options, "readahead", qstring_from_str(ra_val)); } + break; } } ra--; } + qdict_put(options, "url", qstring_from_str(file)); + + g_free(file); +} + +static QemuOptsList runtime_opts = { + .name = "curl", + .head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head), + .desc = { + { + .name = "url", + .type = QEMU_OPT_STRING, + .help = "URL to open", + }, + { + .name = "readahead", + .type = QEMU_OPT_SIZE, + .help = "Readahead size", + }, + { /* end of list */ } + }, +}; + +static int curl_open(BlockDriverState *bs, const char *dummy, + QDict *options, int flags) +{ + BDRVCURLState *s = bs->opaque; + CURLState *state = NULL; + QemuOpts *opts; + Error *local_err = NULL; + const char *file; + double d; + + static int inited = 0; + + opts = qemu_opts_create_nofail(&runtime_opts); + qemu_opts_absorb_qdict(opts, options, &local_err); + if (error_is_set(&local_err)) { + qerror_report_err(local_err); + error_free(local_err); + goto out_noclean; + } + + s->readahead_size = qemu_opt_get_size(opts, "readahead", READ_AHEAD_SIZE); if ((s->readahead_size & 0x1ff) != 0) { fprintf(stderr, "HTTP_READAHEAD_SIZE %zd is not a multiple of 512\n", s->readahead_size); goto out_noclean; } + file = qemu_opt_get(opts, "url"); + if (file == NULL) { + qerror_report(ERROR_CLASS_GENERIC_ERROR, "curl block driver requires " + "an 'url' option"); + goto out_noclean; + } + if (!inited) { curl_global_init(CURL_GLOBAL_ALL); inited = 1; } DPRINTF("CURL: Opening %s\n", file); - s->url = file; + s->url = g_strdup(file); state = curl_init_state(s); if (!state) goto out_noclean; @@ -423,6 +467,7 @@ static int curl_open(BlockDriverState *bs, const char *filename, curl_multi_setopt( s->multi, CURLMOPT_SOCKETFUNCTION, curl_sock_cb ); curl_multi_do(s); + qemu_opts_del(opts); return 0; out: @@ -430,7 +475,8 @@ out: curl_easy_cleanup(state->curl); state->curl = NULL; out_noclean: - g_free(file); + g_free(s->url); + qemu_opts_del(opts); return -EINVAL; } @@ -568,63 +614,68 @@ static int64_t curl_getlength(BlockDriverState *bs) } static BlockDriver bdrv_http = { - .format_name = "http", - .protocol_name = "http", + .format_name = "http", + .protocol_name = "http", - .instance_size = sizeof(BDRVCURLState), - .bdrv_file_open = curl_open, - .bdrv_close = curl_close, - .bdrv_getlength = curl_getlength, + .instance_size = sizeof(BDRVCURLState), + .bdrv_parse_filename = curl_parse_filename, + .bdrv_file_open = curl_open, + .bdrv_close = curl_close, + .bdrv_getlength = curl_getlength, - .bdrv_aio_readv = curl_aio_readv, + .bdrv_aio_readv = curl_aio_readv, }; static BlockDriver bdrv_https = { - .format_name = "https", - .protocol_name = "https", + .format_name = "https", + .protocol_name = "https", - .instance_size = sizeof(BDRVCURLState), - .bdrv_file_open = curl_open, - .bdrv_close = curl_close, - .bdrv_getlength = curl_getlength, + .instance_size = sizeof(BDRVCURLState), + .bdrv_parse_filename = curl_parse_filename, + .bdrv_file_open = curl_open, + .bdrv_close = curl_close, + .bdrv_getlength = curl_getlength, - .bdrv_aio_readv = curl_aio_readv, + .bdrv_aio_readv = curl_aio_readv, }; static BlockDriver bdrv_ftp = { - .format_name = "ftp", - .protocol_name = "ftp", + .format_name = "ftp", + .protocol_name = "ftp", - .instance_size = sizeof(BDRVCURLState), - .bdrv_file_open = curl_open, - .bdrv_close = curl_close, - .bdrv_getlength = curl_getlength, + .instance_size = sizeof(BDRVCURLState), + .bdrv_parse_filename = curl_parse_filename, + .bdrv_file_open = curl_open, + .bdrv_close = curl_close, + .bdrv_getlength = curl_getlength, - .bdrv_aio_readv = curl_aio_readv, + .bdrv_aio_readv = curl_aio_readv, }; static BlockDriver bdrv_ftps = { - .format_name = "ftps", - .protocol_name = "ftps", + .format_name = "ftps", + .protocol_name = "ftps", - .instance_size = sizeof(BDRVCURLState), - .bdrv_file_open = curl_open, - .bdrv_close = curl_close, - .bdrv_getlength = curl_getlength, + .instance_size = sizeof(BDRVCURLState), + .bdrv_parse_filename = curl_parse_filename, + .bdrv_file_open = curl_open, + .bdrv_close = curl_close, + .bdrv_getlength = curl_getlength, - .bdrv_aio_readv = curl_aio_readv, + .bdrv_aio_readv = curl_aio_readv, }; static BlockDriver bdrv_tftp = { - .format_name = "tftp", - .protocol_name = "tftp", + .format_name = "tftp", + .protocol_name = "tftp", - .instance_size = sizeof(BDRVCURLState), - .bdrv_file_open = curl_open, - .bdrv_close = curl_close, - .bdrv_getlength = curl_getlength, + .instance_size = sizeof(BDRVCURLState), + .bdrv_parse_filename = curl_parse_filename, + .bdrv_file_open = curl_open, + .bdrv_close = curl_close, + .bdrv_getlength = curl_getlength, - .bdrv_aio_readv = curl_aio_readv, + .bdrv_aio_readv = curl_aio_readv, }; static void curl_block_init(void)