From patchwork Wed Jul 10 13:51:13 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 258061 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id A1E7F2C02B1 for ; Wed, 10 Jul 2013 23:58:39 +1000 (EST) Received: from localhost ([::1]:55986 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Uwuuh-0007nZ-Rw for incoming@patchwork.ozlabs.org; Wed, 10 Jul 2013 09:58:35 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47728) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Uwung-0004uV-24 for qemu-devel@nongnu.org; Wed, 10 Jul 2013 09:51:21 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Uwune-0005QB-FA for qemu-devel@nongnu.org; Wed, 10 Jul 2013 09:51:19 -0400 Received: from mx1.redhat.com ([209.132.183.28]:10643) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Uwune-0005Q4-7d for qemu-devel@nongnu.org; Wed, 10 Jul 2013 09:51:18 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r6ADpHZV006672 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 10 Jul 2013 09:51:17 -0400 Received: from dhcp-200-207.str.redhat.com (dhcp-192-197.str.redhat.com [10.33.192.197]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r6ADpGE3001367; Wed, 10 Jul 2013 09:51:16 -0400 From: Kevin Wolf To: qemu-devel@nongnu.org Date: Wed, 10 Jul 2013 15:51:13 +0200 Message-Id: <1373464273-7934-1-git-send-email-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: kwolf@redhat.com Subject: [Qemu-devel] [PATCH] block: Don't parse protocol from file.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 One of the major reasons for doing something new for -blockdev and blockdev-add was that the old block layer code parses filenames instead of just taking them literally. So we should really leave it untouched when it's passing using the new interfaces (like -drive file.filename=...). This allows opening relative file names that contain a colon. Signed-off-by: Kevin Wolf Reviewed-by: Eric Blake --- block.c | 17 ++++++++++++----- block/sheepdog.c | 2 +- include/block/block.h | 3 ++- qemu-img.c | 4 ++-- tests/qemu-iotests/051 | 12 ++++++++++++ tests/qemu-iotests/051.out | 14 ++++++++++++++ 6 files changed, 43 insertions(+), 9 deletions(-) diff --git a/block.c b/block.c index 183fec8..2df65c8 100644 --- a/block.c +++ b/block.c @@ -417,7 +417,7 @@ int bdrv_create_file(const char* filename, QEMUOptionParameter *options) { BlockDriver *drv; - drv = bdrv_find_protocol(filename); + drv = bdrv_find_protocol(filename, true); if (drv == NULL) { return -ENOENT; } @@ -482,7 +482,8 @@ static BlockDriver *find_hdev_driver(const char *filename) return drv; } -BlockDriver *bdrv_find_protocol(const char *filename) +BlockDriver *bdrv_find_protocol(const char *filename, + bool allow_protocol_prefix) { BlockDriver *drv1; char protocol[128]; @@ -503,9 +504,10 @@ BlockDriver *bdrv_find_protocol(const char *filename) return drv1; } - if (!path_has_protocol(filename)) { + if (!path_has_protocol(filename) || !allow_protocol_prefix) { return bdrv_find_format("file"); } + p = strchr(filename, ':'); assert(p != NULL); len = p - filename; @@ -784,6 +786,7 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, BlockDriverState *bs; BlockDriver *drv; const char *drvname; + bool allow_protocol_prefix = false; int ret; /* NULL means an empty set of options */ @@ -800,6 +803,7 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, filename = qdict_get_try_str(options, "filename"); } else if (filename && !qdict_haskey(options, "filename")) { qdict_put(options, "filename", qstring_from_str(filename)); + allow_protocol_prefix = true; } else { qerror_report(ERROR_CLASS_GENERIC_ERROR, "Can't specify 'file' and " "'filename' options at the same time"); @@ -813,7 +817,10 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, drv = bdrv_find_whitelisted_format(drvname, !(flags & BDRV_O_RDWR)); qdict_del(options, "driver"); } else if (filename) { - drv = bdrv_find_protocol(filename); + drv = bdrv_find_protocol(filename, allow_protocol_prefix); + if (!drv) { + qerror_report(ERROR_CLASS_GENERIC_ERROR, "Unknown protocol"); + } } else { qerror_report(ERROR_CLASS_GENERIC_ERROR, "Must specify either driver or file"); @@ -4452,7 +4459,7 @@ void bdrv_img_create(const char *filename, const char *fmt, return; } - proto_drv = bdrv_find_protocol(filename); + proto_drv = bdrv_find_protocol(filename, true); if (!proto_drv) { error_setg(errp, "Unknown protocol '%s'", filename); return; diff --git a/block/sheepdog.c b/block/sheepdog.c index b397b5b..6a41ad9 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -1510,7 +1510,7 @@ static int sd_create(const char *filename, QEMUOptionParameter *options) BlockDriver *drv; /* Currently, only Sheepdog backing image is supported. */ - drv = bdrv_find_protocol(backing_file); + drv = bdrv_find_protocol(backing_file, true); if (!drv || strcmp(drv->protocol_name, "sheepdog") != 0) { error_report("backing_file must be a sheepdog image"); ret = -EINVAL; diff --git a/include/block/block.h b/include/block/block.h index dd8eca1..eeb4816 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -111,7 +111,8 @@ bool bdrv_io_limits_enabled(BlockDriverState *bs); void bdrv_init(void); void bdrv_init_with_whitelist(void); -BlockDriver *bdrv_find_protocol(const char *filename); +BlockDriver *bdrv_find_protocol(const char *filename, + bool allow_protocol_prefix); BlockDriver *bdrv_find_format(const char *format_name); BlockDriver *bdrv_find_whitelisted_format(const char *format_name, bool readonly); diff --git a/qemu-img.c b/qemu-img.c index f8c97d3..c55ca5c 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -240,7 +240,7 @@ static int print_block_option_help(const char *filename, const char *fmt) return 1; } - proto_drv = bdrv_find_protocol(filename); + proto_drv = bdrv_find_protocol(filename, true); if (!proto_drv) { error_report("Unknown protocol '%s'", filename); return 1; @@ -1261,7 +1261,7 @@ static int img_convert(int argc, char **argv) goto out; } - proto_drv = bdrv_find_protocol(out_filename); + proto_drv = bdrv_find_protocol(out_filename, true); if (!proto_drv) { error_report("Unknown protocol '%s'", out_filename); ret = -1; diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051 index 8039e23..1cf8bf7 100755 --- a/tests/qemu-iotests/051 +++ b/tests/qemu-iotests/051 @@ -149,6 +149,18 @@ echo run_qemu -drive file=$TEST_IMG,file.driver=file run_qemu -drive file=$TEST_IMG,file.driver=qcow2 +echo +echo === Parsing protocol from file name === +echo + +# Protocol strings are supposed to be parsed from traditional option strings, +# but not when using driver-specific options. We can distinguish them by the +# error message for non-existing files. + +run_qemu -hda foo:bar +run_qemu -drive file=foo:bar +run_qemu -drive file.filename=foo:bar + # success, all done echo "*** done" rm -f $seq.full diff --git a/tests/qemu-iotests/051.out b/tests/qemu-iotests/051.out index 3d1ac7b..6b3d636 100644 --- a/tests/qemu-iotests/051.out +++ b/tests/qemu-iotests/051.out @@ -169,4 +169,18 @@ Testing: -drive file=TEST_DIR/t.qcow2,file.driver=qcow2 QEMU_PROG: -drive file=TEST_DIR/t.qcow2,file.driver=qcow2: Can't use 'qcow2' as a block driver for the protocol level QEMU_PROG: -drive file=TEST_DIR/t.qcow2,file.driver=qcow2: could not open disk image TEST_DIR/t.qcow2: Invalid argument + +=== Parsing protocol from file name === + +Testing: -hda foo:bar +QEMU_PROG: -hda foo:bar: Unknown protocol +QEMU_PROG: -hda foo:bar: could not open disk image foo:bar: No such file or directory + +Testing: -drive file=foo:bar +QEMU_PROG: -drive file=foo:bar: Unknown protocol +QEMU_PROG: -drive file=foo:bar: could not open disk image foo:bar: No such file or directory + +Testing: -drive file.filename=foo:bar +QEMU_PROG: -drive file.filename=foo:bar: could not open disk image ide0-hd0: No such file or directory + *** done